Commit 5f0ca3b5 authored by Praetorius, Simon's avatar Praetorius, Simon

Merge branch 'issue/arh3_reader' into 'master'

arh3 reader corrected, especially the parh reader part

Rewriting of some functions in the ARH3 reader, partitioned meshes are now read from the PARH files directly and all the information about partitions is extracted from the PARH file.

See merge request !2
parents 34885294 c7d1d2cb
...@@ -1292,6 +1292,7 @@ namespace AMDiS { ...@@ -1292,6 +1292,7 @@ namespace AMDiS {
string macroFilename(""); string macroFilename("");
string valueFilename(""); string valueFilename("");
string periodicFilename(""); string periodicFilename("");
string arhFilename("");
int check = 1; int check = 1;
int strategy = 0; int strategy = 0;
bool preserveMacroFileInfo = false; bool preserveMacroFileInfo = false;
...@@ -1299,6 +1300,7 @@ namespace AMDiS { ...@@ -1299,6 +1300,7 @@ namespace AMDiS {
Parameters::get(name + "->macro file name", macroFilename); Parameters::get(name + "->macro file name", macroFilename);
Parameters::get(name + "->value file name", valueFilename); Parameters::get(name + "->value file name", valueFilename);
Parameters::get(name + "->periodic file", periodicFilename); Parameters::get(name + "->periodic file", periodicFilename);
Parameters::get(name + "->arh file name", arhFilename);
Parameters::get(name + "->check", check); Parameters::get(name + "->check", check);
Parameters::get(name + "->preserve coarse dofs", preserveCoarseDOFs); Parameters::get(name + "->preserve coarse dofs", preserveCoarseDOFs);
Parameters::get(name + "->preserve macroFileInfo", preserveMacroFileInfo); Parameters::get(name + "->preserve macroFileInfo", preserveMacroFileInfo);
...@@ -1326,8 +1328,6 @@ namespace AMDiS { ...@@ -1326,8 +1328,6 @@ namespace AMDiS {
initialized = true; initialized = true;
string arhFilename("");
Parameters::get(name + "->arh file name", arhFilename);
if (arhFilename != "") if (arhFilename != "")
io::readFile(arhFilename, this); io::readFile(arhFilename, this);
} }
......
...@@ -193,7 +193,9 @@ namespace AMDiS { namespace io { ...@@ -193,7 +193,9 @@ namespace AMDiS { namespace io {
{ {
using boost::lexical_cast; using boost::lexical_cast;
int sPos = filename.find(".arh"); int sPos = filename.find(".arh");
TEST_EXIT(sPos >= 0)("Failed to find file postfix: \"arh \"!\n"); if (sPos == std::string::npos)
return false;
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
string filename_ = filename; string filename_ = filename;
string name = filename.substr(0, sPos); string name = filename.substr(0, sPos);
...@@ -398,4 +400,4 @@ namespace AMDiS { namespace io { ...@@ -398,4 +400,4 @@ namespace AMDiS { namespace io {
} }
} // end namespace Arh2Reader } // end namespace Arh2Reader
} } // end namespace io, AMDiS } } // end namespace io, AMDiS
\ No newline at end of file
...@@ -225,36 +225,18 @@ namespace AMDiS { namespace io { ...@@ -225,36 +225,18 @@ namespace AMDiS { namespace io {
{ {
FUNCNAME("Arh3Reader::isReadable()"); FUNCNAME("Arh3Reader::isReadable()");
ifstream file; using boost::lexical_cast;
using boost::filesystem::path;
if (writeParallel) {
path file_name = filename; // /path/to/filename.arh
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS path extension = file_name.extension(); // .arh
using boost::lexical_cast; path file_stem = file_name.stem(); // filename
using boost::filesystem::path; path file_path = file_name.parent_path(); // /path/to/
path file_name = filename; ifstream file;
path file_onlyname = file_name.filename(); if (extension.string() == ".parh") {
path file_path = file_name.remove_filename(); std::string base_dir = detail::readParallelFile(filename);
filename = file_path.string() + "/" + base_dir + "/" + file_stem.string() + "_p0.arh";
int sPos = filename.find(".arh");
string filenameWithoutExt = filename.substr(0, sPos);
string parh = filenameWithoutExt + ".parh";
sPos = file_onlyname.string().find(".arh");
string onlynameWithoutExt = file_onlyname.string().substr(0, sPos);
bool parhExists = boost::filesystem::exists(parh);
string basedir = parhExists ? detail::readParallelFile(parh) : ".";
filenameWithoutExt = file_path.string() + '/' + basedir + '/' + onlynameWithoutExt;
filename = filenameWithoutExt + "_p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + ".arh";
if(!boost::filesystem::exists(filename))
filename = filenameWithoutExt + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
TEST_EXIT(boost::filesystem::exists(filename))("Arh data file not found in: %s\n", filename.c_str());
#endif
} }
file.open(filename.c_str(), ios::in | ios::binary); file.open(filename.c_str(), ios::in | ios::binary);
...@@ -410,44 +392,14 @@ namespace AMDiS { namespace io { ...@@ -410,44 +392,14 @@ namespace AMDiS { namespace io {
return nProc; return nProc;
} }
int readMetaFromArh(std::string filename, int readMetaFromPArh(string filename,
std::map<int, int> &elInRank, map<int, int> &elInRank)
std::map<int, int> &elCodeSize)
{ {
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS int nFiles = 0;
int nProcs = MPI::COMM_WORLD.Get_size(); int nMacros = 0;
#else string macroFilename = "";
int nProcs = -1; detail::readParallelFile(filename, elInRank, nFiles, nMacros, macroFilename);
#endif return nFiles;
// check for consistency
// That is, if there are no more or less files as nProcs
int i = 0;
for (; i < nProcs + 1; i++) {
string fn = filename + "-p" + boost::lexical_cast<string>(i) + "-.arh";
if(!boost::filesystem::exists(fn)) break;
}
TEST_EXIT(i == nProcs)
("Number of arh files doesn't match number of processors \n");
// data format: (rank ; (elIndex; elCodeSize) )
vector<std::set<pair<int, int> > > data(nProcs);
//collect data
for (int i = 0; i < nProcs; i++) {
string fn = filename + "-p" + boost::lexical_cast<string>(i) + "-.arh";
detail::readMetaFromSgArh(fn, i, data);
}
//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;
} }
} // end namespace Arh3Reader } // end namespace Arh3Reader
......
...@@ -189,9 +189,8 @@ namespace AMDiS { namespace io { ...@@ -189,9 +189,8 @@ namespace AMDiS { namespace io {
} }
/// Same as readMetaData but collects inform^ation from a set of ARH-files /// Same as readMetaData but collects inform^ation from a set of ARH-files
int readMetaFromArh(std::string filename, int readMetaFromPArh(std::string filename,
std::map<int, int> &elInRank, std::map<int, int> &elInRank);
std::map<int, int> &elCodeSize);
/// Only returns just the number of subdomains a meta ARH file is defined for. /// Only returns just the number of subdomains a meta ARH file is defined for.
int readMetaData(std::string filename); int readMetaData(std::string filename);
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#define AMDIS_READER_H #define AMDIS_READER_H
#include <cstring> #include <cstring>
#include <boost/filesystem.hpp>
#include "DOFVector.h" #include "DOFVector.h"
#include "SystemVector.h" #include "SystemVector.h"
...@@ -62,8 +64,9 @@ namespace AMDiS ...@@ -62,8 +64,9 @@ namespace AMDiS
void readFile(std::string filename, void readFile(std::string filename,
Container &container) Container &container)
{ {
std::string ext = filename.substr(filename.find_last_of(".")); using boost::filesystem::path;
std::string ext = path(filename).extension().string();
Mesh* mesh = detail::getMesh(container); Mesh* mesh = detail::getMesh(container);
if (ext == ".1d" || ext == ".2d" || ext == ".3d") if (ext == ".1d" || ext == ".2d" || ext == ".3d")
{ {
...@@ -73,12 +76,12 @@ namespace AMDiS ...@@ -73,12 +76,12 @@ namespace AMDiS
Parameters::get(mesh->getName() + "->check", check); Parameters::get(mesh->getName() + "->check", check);
MacroReader::readMacro(filename, mesh, periodicFilename, check); MacroReader::readMacro(filename, mesh, periodicFilename, check);
} }
else if (ext == ".arh") else if (ext == ".arh" || ext == ".parh")
{ {
if (Arh2Reader::isReadable(filename)) if (Arh3Reader::isReadable(filename))
Arh2Reader::readFile(filename, container);
else if (Arh3Reader::isReadable(filename))
Arh3Reader::readFile(filename, container); Arh3Reader::readFile(filename, container);
else if (Arh2Reader::isReadable(filename))
Arh2Reader::readFile(filename, container);
else else
ArhReader::readFile(filename, container); ArhReader::readFile(filename, container);
} }
...@@ -133,8 +136,9 @@ namespace AMDiS ...@@ -133,8 +136,9 @@ namespace AMDiS
void readFile(std::string filename, void readFile(std::string filename,
Mesh *mesh) Mesh *mesh)
{ {
using boost::filesystem::path;
std::string ext = filename.substr(filename.find_last_of(".")); std::string ext = path(filename).extension().string();
if (ext == ".1d" || ext == ".2d" || ext == ".3d") if (ext == ".1d" || ext == ".2d" || ext == ".3d")
{ {
std::string periodicFilename = ""; std::string periodicFilename = "";
...@@ -143,12 +147,12 @@ namespace AMDiS ...@@ -143,12 +147,12 @@ namespace AMDiS
Parameters::get(mesh->getName() + "->check", check); Parameters::get(mesh->getName() + "->check", check);
MacroReader::readMacro(filename, mesh, periodicFilename, check); MacroReader::readMacro(filename, mesh, periodicFilename, check);
} }
else if (ext == ".arh") else if (ext == ".arh" || ext == ".parh")
{ {
if (Arh2Reader::isReadable(filename)) if (Arh3Reader::isReadable(filename))
Arh2Reader::readFile(filename, mesh);
else if (Arh3Reader::isReadable(filename))
Arh3Reader::readFile(filename, mesh); Arh3Reader::readFile(filename, mesh);
else if (Arh2Reader::isReadable(filename))
Arh2Reader::readFile(filename, mesh);
else else
ArhReader::readFile(filename, mesh); ArhReader::readFile(filename, mesh);
} }
......
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
#include "Debug.h" #include "Debug.h"
#include "../Arh3Reader.h" #include "../Arh3Reader.h"
#include "Arh3Writer.h" #include "Arh3Writer.h"
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
#include "parallel/MpiHelper.h"
#endif
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/iostreams/filtering_streambuf.hpp> #include <boost/iostreams/filtering_streambuf.hpp>
...@@ -543,6 +546,10 @@ namespace AMDiS { namespace io { ...@@ -543,6 +546,10 @@ namespace AMDiS { namespace io {
bool byName) bool byName)
{ {
FUNCNAME("Arh3Reader::detail::readFile()"); FUNCNAME("Arh3Reader::detail::readFile()");
using boost::lexical_cast;
using boost::filesystem::path;
//The last element in vecs must NOT be NULL //The last element in vecs must NOT be NULL
std::set<string> nameSet; std::set<string> nameSet;
pair<std::set<string>::iterator,bool> ret; pair<std::set<string>::iterator,bool> ret;
...@@ -573,135 +580,42 @@ namespace AMDiS { namespace io { ...@@ -573,135 +580,42 @@ namespace AMDiS { namespace io {
WARNING("You haven't specified the target, no mesh or DOFVectors is given.\n"); WARNING("You haven't specified the target, no mesh or DOFVectors is given.\n");
return; return;
} }
if (writeParallel) { path file_name = filename; // /path/to/filename.arh
using boost::lexical_cast; path extension = file_name.extension(); // .arh
using boost::filesystem::path; path file_stem = file_name.stem(); // filename
path file_path = file_name.parent_path(); // /path/to/"Number of arh files doesn't match number of processors: %d vs %d\n", nProc_f, nProcs);
path file_name = filename; if (extension.string() == ".arh") {
path file_onlyname = file_name.filename(); // read sequential file
path file_path = file_name.remove_filename(); read(filename, mesh, vecs, byName);
} else if (extension.string() == ".parh") {
int sPos = filename.find(".arh"); // read parallel file
string filenameWithoutExt = filename.substr(0, sPos); std::map<int,int> partition;
string parh = filenameWithoutExt + ".parh"; int nFiles = 0;
int nMacros = 0;
sPos = file_onlyname.string().find(".arh"); std::string macroFilename = "";
string onlynameWithoutExt = file_onlyname.string().substr(0, sPos);
int nProcs_ = 0, nMacros_ = 0, nMacros = 0;
vector<int> partition;
bool parhExists = boost::filesystem::exists(parh);
bool newFilename = parhExists;
string basedir = parhExists ? readParallelFile(parh, partition, nProcs_, nMacros_) : ".";
filenameWithoutExt = file_path.string() + '/' + basedir + '/' + onlynameWithoutExt; std::string base_dir = readParallelFile(filename, partition, nFiles, nMacros, macroFilename);
TEST_EXIT(nFiles > 0 && nMacros > 0 && nMacros >= nFiles)
if (nProcs == -1) { ("Error while reading parh file: nFiles=%d, nMacros=%d\n", nFiles, nMacros);
// Test whether parh file can be read to current mesh
int nMacrosInMesh = mesh->getNumberOfMacros();
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
string procFilename = filenameWithoutExt + "_p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + ".arh"; Parallel::mpi::globalAdd(nMacrosInMesh);
if (!boost::filesystem::exists(procFilename))
procFilename = filenameWithoutExt + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
TEST_EXIT(boost::filesystem::exists(procFilename))("Arh data file not found in: %s\n", procFilename.c_str());
read(procFilename, mesh, vecs, byName);
#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
} else {
int nProc_f = 0;
if (!parhExists) {
for (; nProc_f < nProcs + 1; nProc_f++) {
string fn = filenameWithoutExt + "-p" + boost::lexical_cast<string>(nProc_f) + "-.arh";
if(!boost::filesystem::exists(fn)) break;
}
if (nProc_f != nProcs) {
newFilename = true;
for (nProc_f = 0; nProc_f < nProcs + 1; nProc_f++) {
string fn = filenameWithoutExt + "_p" + boost::lexical_cast<string>(nProc_f) + ".arh";
if(!boost::filesystem::exists(fn)) break;
}
}
} else {
for (nProc_f = 0; nProc_f < nProcs + 1; nProc_f++) {
string fn = filenameWithoutExt + "_p" + boost::lexical_cast<string>(nProc_f) + ".arh";
if(!boost::filesystem::exists(fn)) break;
}
if (nProc_f != nProcs) {
newFilename = false;
for (nProc_f = 0; nProc_f < nProcs + 1; nProc_f++) {
string fn = filenameWithoutExt + "-p" + boost::lexical_cast<string>(nProc_f) + "-.arh";
if(!boost::filesystem::exists(fn)) break;
}
}
}
TEST_EXIT(nProc_f == nProcs)
("Number of arh files doesn't match number of processors: %d vs %d\n", nProc_f, nProcs);
if (parhExists) {
TEST_EXIT(nProc_f == nProcs_)
("Number of arh files doesn't match the label in parh file: %d vs %d", nProc_f, nProcs_);
}
if (!parhExists) {
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
if (MPI::COMM_WORLD.Get_rank() == 0)
#endif #endif
for(int i = 0; i < nProcs; i++) TEST_EXIT(nMacros == nMacrosInMesh)
nMacros_ += readNumOfMacrosFromSgArh(filename, i, newFilename); ("Number of macro elements in parallel ARH files doesn't match "
} "the number of macro elements in the mesh. %d vs %d\n",
nMacros, nMacrosInMesh);
nMacros = mesh->getNumberOfMacros();
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
Parallel::mpi::globalAdd(nMacros);
if(MPI::COMM_WORLD.Get_rank() == 0)
#endif
{
TEST_EXIT(nMacros == nMacros_)
("Number of macro elements in parallel ARH files doesn't match to the current runtime. %d vs %d\n",
nMacros, nMacros_);
}
if (!parhExists) { // TODO: read macro from macro-filename
if (newFilename) {
for (int i = 0; i < nProcs; i++) { for (int i = 0; i < nFiles; i++) {
string procFilename = filenameWithoutExt + "_p" + lexical_cast<string>(i) + ".arh"; std::string procFilename = file_path.string() + "/" + base_dir + "/" + file_stem.string() + "_p" + lexical_cast<string>(i) + ".arh";
read(procFilename, mesh, vecs, byName); read(procFilename, mesh, vecs, byName);
}
} else
{
for (int i = 0; i < nProcs; i++) {
string procFilename = filenameWithoutExt + "-p" + lexical_cast<string>(i) + "-.arh";
read(procFilename, mesh, vecs, byName);
}
}
} else {
std::set<int> needFiles;
deque<MacroElement*>::iterator it = mesh->firstMacroElement();
for (;it != mesh->endOfMacroElements(); it++)
needFiles.insert(partition[(*it)->getIndex()]);
std::set<int>::iterator it2 = needFiles.begin();
if (newFilename) {
for (;it2 != needFiles.end(); it2++) {
string procFilename = filenameWithoutExt + "_p" + lexical_cast<string>(*it2) + ".arh";
read(procFilename, mesh, vecs, byName);
}
} else {
for (;it2 != needFiles.end(); it2++) {
string procFilename = filenameWithoutExt + "-p" + lexical_cast<string>(*it2) + "-.arh";
read(procFilename, mesh, vecs, byName);
}
}
}
} }
} else { } else {
read(filename, mesh, vecs, byName); ERROR_EXIT("Unknown file-extension '%s' in ARHReader", extension.string().c_str());
} }
MSG("ARH file read from: %s\n", filename.c_str()); MSG("ARH file read from: %s\n", filename.c_str());
} }
...@@ -948,9 +862,11 @@ namespace AMDiS { namespace io { ...@@ -948,9 +862,11 @@ namespace AMDiS { namespace io {
return baseDir; return baseDir;
} }
std::string readParallelFile(string filename, vector<int>& partition, int& nFiles, int& nMacros) std::string readParallelFile(string filename, std::map<int,int>& partition, int& nFiles, int& nMacros, std::string& macroFilename)
{ {
FUNCNAME("Arh3Reader::detail::readParallelFile()"); FUNCNAME("Arh3Reader::detail::readParallelFile()");
using boost::lexical_cast;
checkMeshconvParh1_0(filename); checkMeshconvParh1_0(filename);
...@@ -962,8 +878,8 @@ namespace AMDiS { namespace io { ...@@ -962,8 +878,8 @@ namespace AMDiS { namespace io {
string fd(16, ' '); string fd(16, ' ');
file.read(&fd[0], 16); file.read(&fd[0], 16);
string Id = fd.substr(0, 4); string Id = fd.substr(0, 4);
int major = boost::lexical_cast<int>(fd.substr(5, 1)); int major = lexical_cast<int>(fd.substr(5, 1));
int minor = boost::lexical_cast<int>(fd.substr(7, 1)); int minor = lexical_cast<int>(fd.substr(7, 1));
if (major == 1 && minor == 0) if (major == 1 && minor == 0)
ERROR_EXIT("Parh file 1.0 is not supported in AMDiS anymore, you can use tools/arhTools/parh_change to update it to 2.0.\n"); ERROR_EXIT("Parh file 1.0 is not supported in AMDiS anymore, you can use tools/arhTools/parh_change to update it to 2.0.\n");
...@@ -971,7 +887,7 @@ namespace AMDiS { namespace io { ...@@ -971,7 +887,7 @@ namespace AMDiS { namespace io {
firstRead(Id, major, minor, "parh", PARH_MAJOR, PARH_MINOR); firstRead(Id, major, minor, "parh", PARH_MAJOR, PARH_MINOR);
uint32_t baseDirLen = 0, macroFile_nl = 0; uint32_t baseDirLen = 0, macroFile_nl = 0;
string baseDir, macroFilename; string baseDir;
file.read(reinterpret_cast<char*>(&baseDirLen), 4); file.read(reinterpret_cast<char*>(&baseDirLen), 4);
baseDir.resize(baseDirLen, ' '); baseDir.resize(baseDirLen, ' ');
...@@ -987,7 +903,7 @@ namespace AMDiS { namespace io { ...@@ -987,7 +903,7 @@ namespace AMDiS { namespace io {
uint32_t rank = 0; uint32_t rank = 0;
for (int i = 0; i < nMacros; i++) { for (int i = 0; i < nMacros; i++) {
file.read(reinterpret_cast<char*>(&rank), 4); file.read(reinterpret_cast<char*>(&rank), 4);
partition.push_back(rank); partition[i] = rank;
} }
return baseDir; return baseDir;
......
...@@ -84,9 +84,10 @@ namespace AMDiS { namespace io { ...@@ -84,9 +84,10 @@ namespace AMDiS { namespace io {
// Pass excat parh path // Pass excat parh path
std::string readParallelFile(std::string filename, std::string readParallelFile(std::string filename,
std::vector<int>& partition, std::map<int,int>& partition,
int& nFiles, int& nFiles,
int& nMacros); int& nMacros,
std::string& macroFilename);
// Pass excat parh path // Pass excat parh path
std::string readParallelFile(std::string filename); std::string readParallelFile(std::string filename);
......
...@@ -92,15 +92,18 @@ namespace AMDiS { namespace Parallel { ...@@ -92,15 +92,18 @@ namespace AMDiS { namespace Parallel {
if (partitioningArhBased) { if (partitioningArhBased) {
MSG("Read Arh partitioning files: %s\n", arhFile.c_str()); MSG("Read Arh partitioning files: %s\n", arhFile.c_str());
int nProc = -1; int nProc = -1;
if (io::Arh2Reader::isReadable(arhFile + ".arh")) if (io::Arh3Reader::isReadable(arhFile))
nProc = io::Arh3Reader::readMetaFromPArh(arhFile, mapElInRank);
else if (io::Arh2Reader::isReadable(arhFile + ".arh"))
nProc = io::Arh2Reader::readMetaFromArh(arhFile, mapElInRank, arhElCodeSize); nProc = io::Arh2Reader::readMetaFromArh(arhFile, mapElInRank, arhElCodeSize);
else if (io::Arh3Reader::isReadable(arhFile + ".arh"))
nProc = io::Arh3Reader::readMetaFromArh(arhFile, mapElInRank, arhElCodeSize);
if (nProc != mpiSize) MSG("nProc = %d, mpiSize = %d\n", nProc, mpiSize);
if (nProc != mpiSize) {
useInitialPartitioning = false; useInitialPartitioning = false;
else mapElInRank.clear();
} else {
useInitialPartitioning = true; useInitialPartitioning = true;
}
} }
} }
......
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