Commit c7d1d2cb authored by Praetorius, Simon's avatar Praetorius, Simon

arh3 reader corrected, especially the parh reader part

parent 77592d44
......@@ -1292,6 +1292,7 @@ namespace AMDiS {
string macroFilename("");
string valueFilename("");
string periodicFilename("");
string arhFilename("");
int check = 1;
int strategy = 0;
bool preserveMacroFileInfo = false;
......@@ -1299,6 +1300,7 @@ namespace AMDiS {
Parameters::get(name + "->macro file name", macroFilename);
Parameters::get(name + "->value file name", valueFilename);
Parameters::get(name + "->periodic file", periodicFilename);
Parameters::get(name + "->arh file name", arhFilename);
Parameters::get(name + "->check", check);
Parameters::get(name + "->preserve coarse dofs", preserveCoarseDOFs);
Parameters::get(name + "->preserve macroFileInfo", preserveMacroFileInfo);
......@@ -1326,8 +1328,6 @@ namespace AMDiS {
initialized = true;
string arhFilename("");
Parameters::get(name + "->arh file name", arhFilename);
if (arhFilename != "")
io::readFile(arhFilename, this);
}
......
......@@ -193,7 +193,9 @@ namespace AMDiS { namespace io {
{
using boost::lexical_cast;
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
string filename_ = filename;
string name = filename.substr(0, sPos);
......@@ -398,4 +400,4 @@ namespace AMDiS { namespace io {
}
} // end namespace Arh2Reader
} } // end namespace io, AMDiS
\ No newline at end of file
} } // end namespace io, AMDiS
......@@ -225,36 +225,18 @@ namespace AMDiS { namespace io {
{
FUNCNAME("Arh3Reader::isReadable()");
ifstream file;
if (writeParallel) {
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
using boost::lexical_cast;
using boost::filesystem::path;
path file_name = filename;
path file_onlyname = file_name.filename();
path file_path = file_name.remove_filename();
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
using boost::lexical_cast;
using boost::filesystem::path;
path file_name = filename; // /path/to/filename.arh
path extension = file_name.extension(); // .arh
path file_stem = file_name.stem(); // filename
path file_path = file_name.parent_path(); // /path/to/
ifstream file;
if (extension.string() == ".parh") {
std::string base_dir = detail::readParallelFile(filename);
filename = file_path.string() + "/" + base_dir + "/" + file_stem.string() + "_p0.arh";
}
file.open(filename.c_str(), ios::in | ios::binary);
......@@ -410,44 +392,14 @@ namespace AMDiS { namespace io {
return nProc;
}
int readMetaFromArh(std::string filename,
std::map<int, int> &elInRank,
std::map<int, int> &elCodeSize)
int readMetaFromPArh(string filename,
map<int, int> &elInRank)
{
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
int nProcs = MPI::COMM_WORLD.Get_size();
#else
int nProcs = -1;
#endif
// 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;
int nFiles = 0;
int nMacros = 0;
string macroFilename = "";
detail::readParallelFile(filename, elInRank, nFiles, nMacros, macroFilename);
return nFiles;
}
} // end namespace Arh3Reader
......
......@@ -189,9 +189,8 @@ namespace AMDiS { namespace io {
}
/// Same as readMetaData but collects inform^ation from a set of ARH-files
int readMetaFromArh(std::string filename,
std::map<int, int> &elInRank,
std::map<int, int> &elCodeSize);
int readMetaFromPArh(std::string filename,
std::map<int, int> &elInRank);
/// Only returns just the number of subdomains a meta ARH file is defined for.
int readMetaData(std::string filename);
......
......@@ -25,6 +25,8 @@
#define AMDIS_READER_H
#include <cstring>
#include <boost/filesystem.hpp>
#include "DOFVector.h"
#include "SystemVector.h"
......@@ -62,8 +64,9 @@ namespace AMDiS
void readFile(std::string filename,
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);
if (ext == ".1d" || ext == ".2d" || ext == ".3d")
{
......@@ -73,12 +76,12 @@ namespace AMDiS
Parameters::get(mesh->getName() + "->check", check);
MacroReader::readMacro(filename, mesh, periodicFilename, check);
}
else if (ext == ".arh")
else if (ext == ".arh" || ext == ".parh")
{
if (Arh2Reader::isReadable(filename))
Arh2Reader::readFile(filename, container);
else if (Arh3Reader::isReadable(filename))
if (Arh3Reader::isReadable(filename))
Arh3Reader::readFile(filename, container);
else if (Arh2Reader::isReadable(filename))
Arh2Reader::readFile(filename, container);
else
ArhReader::readFile(filename, container);
}
......@@ -133,8 +136,9 @@ namespace AMDiS
void readFile(std::string filename,
Mesh *mesh)
{
std::string ext = filename.substr(filename.find_last_of("."));
using boost::filesystem::path;
std::string ext = path(filename).extension().string();
if (ext == ".1d" || ext == ".2d" || ext == ".3d")
{
std::string periodicFilename = "";
......@@ -143,12 +147,12 @@ namespace AMDiS
Parameters::get(mesh->getName() + "->check", check);
MacroReader::readMacro(filename, mesh, periodicFilename, check);
}
else if (ext == ".arh")
else if (ext == ".arh" || ext == ".parh")
{
if (Arh2Reader::isReadable(filename))
Arh2Reader::readFile(filename, mesh);
else if (Arh3Reader::isReadable(filename))
if (Arh3Reader::isReadable(filename))
Arh3Reader::readFile(filename, mesh);
else if (Arh2Reader::isReadable(filename))
Arh2Reader::readFile(filename, mesh);
else
ArhReader::readFile(filename, mesh);
}
......
......@@ -7,6 +7,9 @@
#include "Debug.h"
#include "../Arh3Reader.h"
#include "Arh3Writer.h"
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
#include "parallel/MpiHelper.h"
#endif
#include <boost/filesystem.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
......@@ -543,6 +546,10 @@ namespace AMDiS { namespace io {
bool byName)
{
FUNCNAME("Arh3Reader::detail::readFile()");
using boost::lexical_cast;
using boost::filesystem::path;
//The last element in vecs must NOT be NULL
std::set<string> nameSet;
pair<std::set<string>::iterator,bool> ret;
......@@ -573,135 +580,42 @@ namespace AMDiS { namespace io {
WARNING("You haven't specified the target, no mesh or DOFVectors is given.\n");
return;
}
if (writeParallel) {
using boost::lexical_cast;
using boost::filesystem::path;
path file_name = filename;
path file_onlyname = file_name.filename();
path file_path = file_name.remove_filename();
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);
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_) : ".";
path file_name = filename; // /path/to/filename.arh
path extension = file_name.extension(); // .arh
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);
if (extension.string() == ".arh") {
// read sequential file
read(filename, mesh, vecs, byName);
} else if (extension.string() == ".parh") {
// read parallel file
std::map<int,int> partition;
int nFiles = 0;
int nMacros = 0;
std::string macroFilename = "";
filenameWithoutExt = file_path.string() + '/' + basedir + '/' + onlynameWithoutExt;
if (nProcs == -1) {
std::string base_dir = readParallelFile(filename, partition, nFiles, nMacros, macroFilename);
TEST_EXIT(nFiles > 0 && nMacros > 0 && nMacros >= nFiles)
("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
string procFilename = filenameWithoutExt + "_p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + ".arh";
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)
Parallel::mpi::globalAdd(nMacrosInMesh);
#endif
for(int i = 0; i < nProcs; i++)
nMacros_ += readNumOfMacrosFromSgArh(filename, i, newFilename);
}
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_);
}
TEST_EXIT(nMacros == nMacrosInMesh)
("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);
if (!parhExists) {
if (newFilename) {
for (int i = 0; i < nProcs; i++) {
string procFilename = filenameWithoutExt + "_p" + lexical_cast<string>(i) + ".arh";
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);
}
}
}
// TODO: read macro from macro-filename
for (int i = 0; i < nFiles; i++) {
std::string procFilename = file_path.string() + "/" + base_dir + "/" + file_stem.string() + "_p" + lexical_cast<string>(i) + ".arh";
read(procFilename, mesh, vecs, byName);
}
} 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());
}
......@@ -948,9 +862,11 @@ namespace AMDiS { namespace io {
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()");
using boost::lexical_cast;
checkMeshconvParh1_0(filename);
......@@ -962,8 +878,8 @@ namespace AMDiS { namespace io {
string fd(16, ' ');
file.read(&fd[0], 16);
string Id = fd.substr(0, 4);
int major = boost::lexical_cast<int>(fd.substr(5, 1));
int minor = boost::lexical_cast<int>(fd.substr(7, 1));
int major = lexical_cast<int>(fd.substr(5, 1));
int minor = lexical_cast<int>(fd.substr(7, 1));
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");
......@@ -971,7 +887,7 @@ namespace AMDiS { namespace io {
firstRead(Id, major, minor, "parh", PARH_MAJOR, PARH_MINOR);
uint32_t baseDirLen = 0, macroFile_nl = 0;
string baseDir, macroFilename;
string baseDir;
file.read(reinterpret_cast<char*>(&baseDirLen), 4);
baseDir.resize(baseDirLen, ' ');
......@@ -987,7 +903,7 @@ namespace AMDiS { namespace io {
uint32_t rank = 0;
for (int i = 0; i < nMacros; i++) {
file.read(reinterpret_cast<char*>(&rank), 4);
partition.push_back(rank);
partition[i] = rank;
}
return baseDir;
......
......@@ -84,9 +84,10 @@ namespace AMDiS { namespace io {
// Pass excat parh path
std::string readParallelFile(std::string filename,
std::vector<int>& partition,
int& nFiles,
int& nMacros);
std::map<int,int>& partition,
int& nFiles,
int& nMacros,
std::string& macroFilename);
// Pass excat parh path
std::string readParallelFile(std::string filename);
......
......@@ -92,15 +92,18 @@ namespace AMDiS { namespace Parallel {
if (partitioningArhBased) {
MSG("Read Arh partitioning files: %s\n", arhFile.c_str());
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);
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;
else
mapElInRank.clear();
} else {
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