Commit 78ddaebe authored by Backofen, Rainer's avatar Backofen, Rainer
Browse files

added functionality to initialise partitioning directly by arh-files

parent 090aa484
......@@ -24,6 +24,9 @@
#include "Arh2Reader.h"
#include "detail/Arh2Reader.h"
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/zlib.hpp>
namespace AMDiS { namespace io {
......@@ -285,7 +288,7 @@ namespace AMDiS { namespace io {
else
arhFilename += "-p" + boost::lexical_cast<string>(*it) + "-.arh";
MSG("ARH file read from: %s\n", arhFilename.c_str());
MSG("ARH2 file read from: %s\n", arhFilename.c_str());
detail::read(arhFilename, mesh, vecs);
}
}
......@@ -347,6 +350,162 @@ namespace AMDiS { namespace io {
file.close();
return nProc;
}
int readMetaFromArh(std::string filename,
std::map<int, int> &elInRank,
std::map<int, int> &elCodeSize){
int nProcs = MPI::COMM_WORLD.Get_size();
std::vector<std::set<std::pair<int, int> > > data(nProcs);
// data format: (rank ; (elIndex; elCodeSize) )
//collect data
for (int i = 0; i < nProcs; i++) {
string fn = filename + "-p" + boost::lexical_cast<string>(i) + "-.arh";
ifstream file;
file.open(fn.c_str(), ios::in | ios::binary);
if (!file.is_open()) {
cout << "Cannot open file \"" << fn << "\"\n";
exit(0);
}
cout << MPI::COMM_WORLD.Get_rank() <<" Read file \"" << fn << "\"\n";
string typeId(4, ' ');
file.read(const_cast<char*>(typeId.data()), 4);
if(typeId == "arh2")
readMetaFromSgArh(file, typeId, i, data);
else
{
cout << "file \"" << fn << "\"is not arh file.\n";
cout << "should not happen.\n";
exit(0);
}
file.close();
}
//make elInRank and elCodeSize-Map
for (int i = 0; i < nProcs; i++) {
for (std::set<pair<int, int> >::iterator it = data[i].begin();
it != data[i].end(); ++it){
elInRank[it->first]=i;
elCodeSize[it->first]=it->second;
}
}
return nProcs;
}
void readMetaFromSgArh(std::ifstream& file, string typeId, int nProc,
std::vector< std::set<std::pair<int, int> > >& data)
{
uint8_t major = 0, minor = 0;
uint32_t dow = 0, dim = 0;
uint32_t headerLen = 0;
uint32_t nMacroElements = 0;
uint32_t nValueVectors = 0;
uint32_t nFeSpaces = 0;
string cps(4, ' ');
file.read(reinterpret_cast<char*>(&major), 1);
file.read(reinterpret_cast<char*>(&minor), 1);
file.read(reinterpret_cast<char*>(&headerLen), 4);
file.read(reinterpret_cast<char*>(&dow), 4);
file.read(reinterpret_cast<char*>(&dim), 4);
file.read(reinterpret_cast<char*>(&nFeSpaces), 4);
file.read(reinterpret_cast<char*>(&nValueVectors), 4);
file.read(reinterpret_cast<char*>(&nMacroElements), 4);
switch(minor) {
case 1:
file.read(const_cast<char*>(cps.data()), 4);
break;
default:
cps = "null";break;
}
vector<int> macroElIndex(nMacroElements);
vector<int> macroElSize(nMacroElements);
vector<vector<int> > sortedFeSpaces(nFeSpaces);
// Read macro table
for(int i = 0; i < nMacroElements; i++)
{
file.read(reinterpret_cast<char*>(&macroElIndex[i]), 4);
uint32_t elpos = 0;
file.read(reinterpret_cast<char*>(&macroElSize[i]), 4);
}
// Read feSpace table
for(int i = 0; i < nFeSpaces; i++)
{
for(int j = 0; j < 4; j++)
{
uint32_t perDOFs = 0;
file.read(reinterpret_cast<char*>(&perDOFs), 4);
}
}
// Read value table
for(int i = 0; i < nValueVectors; i++)
{
string tmpString("");
uint32_t tmpInt = 0;
file.read(reinterpret_cast<char*>(&tmpInt), 4);
tmpString.resize(tmpInt, ' ');
file.read(const_cast<char*>(tmpString.data()), tmpInt); //
file.read(reinterpret_cast<char*>(&tmpInt), 4);
sortedFeSpaces[tmpInt].push_back(i);
}
for (unsigned int i = 0; i < nMacroElements; i++) {
stringstream dataStream(ios::out | ios::in | ios::binary);
int size = macroElSize[i];
char* buffer = new char[size];
file.read(buffer, size);
dataStream.write(buffer, size);
delete[] buffer;
if(cps == "zlib") {
stringstream tmp(ios::out | ios::in);
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::zlib_decompressor());
in.push(dataStream);
boost::iostreams::copy(in, tmp);
dataStream.str(tmp.str());
}
uint32_t nStructureCodes = 0;
uint32_t codeSize = 0;
dataStream.read(reinterpret_cast<char*>(&nStructureCodes), 4);
dataStream.read(reinterpret_cast<char*>(&codeSize), 4);
cout << " -> macro el " << macroElIndex[i] << "\n";
data[nProc].insert(make_pair(macroElIndex[i], codeSize));
vector<uint64_t> structureCode(nStructureCodes);
dataStream.read(reinterpret_cast<char*>(&(structureCode[0])), 8 * nStructureCodes);
if (nValueVectors > 0) {
vector<vector<double> > values(nValueVectors);
int valuePos = 0;
for(unsigned int j = 0; j < nFeSpaces; j++)
{
uint32_t nValuesPerVector = 0;
dataStream.read(reinterpret_cast<char*>(&nValuesPerVector), 4);
for(unsigned k = 0; k < sortedFeSpaces[j].size(); k++)
{
values[valuePos + k].resize(nValuesPerVector);
dataStream.read(reinterpret_cast<char*>(&(values[valuePos + k][0])), 8 * nValuesPerVector);
}
valuePos += sortedFeSpaces[j].size();
}
}
}
cout << MPI::COMM_WORLD.Get_rank() <<" Read ko " <<"\n";
}
} // end namespace Arh2Reader
} } // end namespace io, AMDiS
} } // end namespace io, AMDiS
......@@ -469,6 +469,7 @@ namespace AMDiS { namespace io {
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
string procFilename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
read(procFilename, mesh, vecs, byName);
MSG("ARH file read from: %s\n", procFilename.c_str());
#else
ERROR_EXIT("Reading parallel ARH files in sequential computations requires to specify the number of nodes on which the ARH file was created!\n");
#endif
......@@ -476,6 +477,7 @@ namespace AMDiS { namespace io {
for (int i = 0; i < nProcs; i++) {
string procFilename = name + "-p" + lexical_cast<string>(i) + "-.arh";
read(procFilename, mesh, vecs, byName);
MSG("ARH file read from: %s\n", procFilename.c_str());
}
}
} else {
......
......@@ -46,6 +46,7 @@ namespace AMDiS { namespace Parallel {
map<int, int> arhElCodeSize;
string partitioningFile = "";
cout <<"DDDD "<<initFileStr<<"\n";
Parameters::get(initFileStr + "->initial partitioning file",
partitioningFile);
if (partitioningFile != "") {
......@@ -69,8 +70,17 @@ namespace AMDiS { namespace Parallel {
string arhMetaFile = "";
Parameters::get(initFileStr + "->read meta arh",
arhMetaFile);
bool partitioningArhBased = (arhMetaFile != "");
if (partitioningArhBased) {
bool partitioningMetaArhBased = (arhMetaFile != "");
string arhFile = "";
Parameters::get(initFileStr + "->read arh",
arhFile);
bool partitioningArhBased = (arhFile != "");
TEST_EXIT(!(partitioningMetaArhBased && partitioningArhBased))
("decide for meta arh or arh files for initialise partition!\n");
if (partitioningMetaArhBased) {
MSG("Read Meta-Arh partitioning file: %s\n", arhMetaFile.c_str());
int nProc = io::Arh2Reader::readMetaData(arhMetaFile, mapElInRank, arhElCodeSize);
if (nProc != mpiSize)
......@@ -78,6 +88,17 @@ namespace AMDiS { namespace Parallel {
else
useInitialPartitioning = true;
}
if (partitioningArhBased) {
MSG("Read Arh partitioning files: %s\n", arhFile.c_str());
int nProc = io::Arh2Reader::readMetaFromArh(arhFile, mapElInRank, arhElCodeSize);
if (nProc != mpiSize)
useInitialPartitioning = false;
else
useInitialPartitioning = true;
}
}
......@@ -175,6 +196,17 @@ namespace AMDiS { namespace Parallel {
for (map<int, std::set<int> >::iterator it = boxSplitting.begin();
it != boxSplitting.end(); ++it) {
int boxInRank = std::min(it->first / boxPerRank, mpiSize - 1);
// check if data compatible to boxpartition mode.
// That is, every element of a box belongs to the same processor
if(!mapElInRank.empty()) {
std::set<int>::iterator elIt = it->second.begin();
boxInRank=mapElInRank[*elIt];
for ( ;elIt != it->second.end(); ++elIt) {
TEST_EXIT(mapElInRank[*elIt]== boxInRank)
("initial partion read from arh-file is not compatible to boxpartitioning. \n ");
}
}
for (std::set<int>::iterator elIt = it->second.begin();
elIt != it->second.end(); ++elIt) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment