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 {
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