Commit 55df3b3f authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Introduced initial partitioner.

parent c3cc7b1a
...@@ -16,15 +16,15 @@ ...@@ -16,15 +16,15 @@
namespace AMDiS { namespace AMDiS {
CheckerPartitioner::CheckerPartitioner(MPI::Intracomm *comm) CheckerPartitioner::CheckerPartitioner(string name, MPI::Intracomm *comm)
: MeshPartitioner(comm), : MeshPartitioner(name, comm),
mpiRank(mpiComm->Get_rank()), mpiRank(mpiComm->Get_rank()),
mpiSize(mpiComm->Get_size()), mpiSize(mpiComm->Get_size()),
mode(0), mode(0),
multilevel(false) multilevel(false)
{ {
string modestr = ""; string modestr = "";
Parameters::get("parallel->partitioner->mode", modestr); Parameters::get(initFileStr + "->mode", modestr);
if (modestr == "x-stripes") if (modestr == "x-stripes")
mode = 1; mode = 1;
......
...@@ -35,7 +35,7 @@ namespace AMDiS { ...@@ -35,7 +35,7 @@ namespace AMDiS {
class CheckerPartitioner : public MeshPartitioner class CheckerPartitioner : public MeshPartitioner
{ {
public: public:
CheckerPartitioner(MPI::Intracomm *comm); CheckerPartitioner(string name, MPI::Intracomm *comm);
~CheckerPartitioner() {} ~CheckerPartitioner() {}
......
...@@ -77,6 +77,7 @@ namespace AMDiS { ...@@ -77,6 +77,7 @@ namespace AMDiS {
mesh(NULL), mesh(NULL),
refineManager(NULL), refineManager(NULL),
partitioner(NULL), partitioner(NULL),
initialPartitioner(NULL),
deserialized(false), deserialized(false),
writeSerializationFile(false), writeSerializationFile(false),
repartitioningAllowed(false), repartitioningAllowed(false),
...@@ -104,36 +105,57 @@ namespace AMDiS { ...@@ -104,36 +105,57 @@ namespace AMDiS {
Parameters::get(name + "->repartition ith change", repartitionIthChange); Parameters::get(name + "->repartition ith change", repartitionIthChange);
Parameters::get(name + "->repartition wait after fail", repartitioningWaitAfterFail); Parameters::get(name + "->repartition wait after fail", repartitioningWaitAfterFail);
Parameters::get(name + "->mesh adaptivity", meshAdaptivity); Parameters::get(name + "->mesh adaptivity", meshAdaptivity);
// === Create partitioner object. ===
string partStr = "parmetis"; string partStr = "parmetis";
Parameters::get(name + "->partitioner", partStr); Parameters::get(name + "->partitioner", partStr);
if (partStr == "parmetis") if (partStr == "parmetis")
partitioner = new ParMetisPartitioner(&mpiComm); partitioner = new ParMetisPartitioner("parallel->partitioner", &mpiComm);
if (partStr == "zoltan") { if (partStr == "zoltan") {
#ifdef HAVE_ZOLTAN #ifdef HAVE_ZOLTAN
partitioner = new ZoltanPartitioner(&mpiComm); partitioner = new ZoltanPartitioner("parallel->partitioner", &mpiComm);
#else #else
ERROR_EXIT("AMDiS was compiled without Zoltan support. Therefore you cannot make use of it!\n"); ERROR_EXIT("AMDiS was compiled without Zoltan support. Therefore you cannot make use of it!\n");
#endif #endif
} }
if (partStr == "checker") if (partStr == "checker")
partitioner = new CheckerPartitioner(&mpiComm); partitioner = new CheckerPartitioner("parallel->partitioner", &mpiComm);
if (partStr == "simple") if (partStr == "simple")
partitioner = new SimplePartitioner(&mpiComm); partitioner = new SimplePartitioner("parallel->partitioner", &mpiComm);
// === Create initial partitioner object. ===
partStr = "";
Parameters::get(name + "->initial partitioner", partStr);
if (partStr == "") {
initialPartitioner = partitioner;
} else {
if (partStr == "checker") {
initialPartitioner =
new CheckerPartitioner("parallel->initial partitioner", &mpiComm);
} else {
ERROR_EXIT("Not yet supported, but very easy to implement!\n");
}
}
// === And read some more parameters. ===
int tmp = 0; int tmp = 0;
Parameters::get(name + "->box partitioning", tmp); Parameters::get(name + "->box partitioning", tmp);
partitioner->setBoxPartitioning(static_cast<bool>(tmp)); partitioner->setBoxPartitioning(static_cast<bool>(tmp));
initialPartitioner->setBoxPartitioning(static_cast<bool>(tmp));
Parameters::get(name + "->print timings", printTimings); Parameters::get(name + "->print timings", printTimings);
Parameters::get(name + "->print memory usage", printMemoryUsage); Parameters::get(name + "->print memory usage", printMemoryUsage);
TEST_EXIT(partitioner)("Could not create partitioner \"%s\"!\n", partStr.c_str());
// If required, create hierarchical mesh level structure. // If required, create hierarchical mesh level structure.
createMeshLevelStructure(); createMeshLevelStructure();
} }
...@@ -141,8 +163,10 @@ namespace AMDiS { ...@@ -141,8 +163,10 @@ namespace AMDiS {
MeshDistributor::~MeshDistributor() MeshDistributor::~MeshDistributor()
{ {
if (partitioner) if (partitioner) {
delete partitioner; delete partitioner;
partitioner = NULL;
}
} }
...@@ -357,18 +381,24 @@ namespace AMDiS { ...@@ -357,18 +381,24 @@ namespace AMDiS {
createMacroElementInfo(); createMacroElementInfo();
// create an initial partitioning of the mesh // create an initial partitioning of the mesh
bool useInitialPartitioning = partitioner->createInitialPartitioning(); bool useInitialPartitioning =
initialPartitioner->createInitialPartitioning();
// set the element weights, which are 1 at the very first begin // set the element weights, which are 1 at the very first begin
setInitialElementWeights(); setInitialElementWeights();
if (!useInitialPartitioning) { if (!useInitialPartitioning) {
// and now partition the mesh // and now partition the mesh
bool partitioningSucceed = partitioner->partition(elemWeights, INITIAL); bool partitioningSucceed =
initialPartitioner->partition(elemWeights, INITIAL);
TEST_EXIT(partitioningSucceed)("Initial partitioning does not work!\n"); TEST_EXIT(partitioningSucceed)("Initial partitioning does not work!\n");
} }
partitioner->createPartitionMap(partitionMap); initialPartitioner->createPartitionMap(partitionMap);
if (initialPartitioner != partitioner) {
*partitioner = *initialPartitioner;
}
} }
...@@ -462,6 +492,7 @@ namespace AMDiS { ...@@ -462,6 +492,7 @@ namespace AMDiS {
} }
partitioner->setMesh(mesh); partitioner->setMesh(mesh);
initialPartitioner->setMesh(mesh);
// === Check whether the stationary problem should be serialized. === // === Check whether the stationary problem should be serialized. ===
...@@ -1446,15 +1477,7 @@ namespace AMDiS { ...@@ -1446,15 +1477,7 @@ namespace AMDiS {
if (!partitioner->meshChanged()) { if (!partitioner->meshChanged()) {
MSG("Mesh partition does not create a new partition!\n"); MSG("Mesh partition does not create a new partition!\n");
MSG("Try to refine partitioning!\n"); MSG("Try to refine partitioning!\n");
partitioningSucceed = partitioner->partition(elemWeights, REFINE_PART); partitioningSucceed = partitioner->partition(elemWeights, REFINE_PART);
if (partitioningSucceed) {
MSG("OKAY, ERST MAL GUT!\n");
if (partitioner->meshChanged())
MSG("UND JA, DAS WARS!\n");
else
MSG("NE, LEIDER NICHT!\n");
}
if (!partitioningSucceed || !partitioner->meshChanged()) { if (!partitioningSucceed || !partitioner->meshChanged()) {
mpiComm.Barrier(); mpiComm.Barrier();
repartitioningFailed = repartitioningWaitAfterFail;; repartitioningFailed = repartitioningWaitAfterFail;;
......
...@@ -504,6 +504,12 @@ namespace AMDiS { ...@@ -504,6 +504,12 @@ namespace AMDiS {
/// the ranks. /// the ranks.
MeshPartitioner *partitioner; MeshPartitioner *partitioner;
/// Pointer to a mesh partitioner that is used for the very first
/// partitioning of the mesh. In most cases, this pointer points to the
/// same object as \ref partitioner, but this must not be the case in
/// general.
MeshPartitioner *initialPartitioner;
/// Weights for the elements, i.e., the number of leaf elements within /// Weights for the elements, i.e., the number of leaf elements within
/// this element. /// this element.
map<int, double> elemWeights; map<int, double> elemWeights;
......
...@@ -34,7 +34,8 @@ namespace AMDiS { ...@@ -34,7 +34,8 @@ namespace AMDiS {
map<int, int> arhElCodeSize; map<int, int> arhElCodeSize;
string partitioningFile = ""; string partitioningFile = "";
Parameters::get("parallel->initial partitioning file", partitioningFile); Parameters::get(initFileStr + "->initial partitioning file",
partitioningFile);
if (partitioningFile != "") { if (partitioningFile != "") {
MSG("Read initial partitioning file: %s\n", partitioningFile.c_str()); MSG("Read initial partitioning file: %s\n", partitioningFile.c_str());
...@@ -54,7 +55,8 @@ namespace AMDiS { ...@@ -54,7 +55,8 @@ namespace AMDiS {
useInitialPartitioning = true; useInitialPartitioning = true;
} else { } else {
string arhMetaFile = ""; string arhMetaFile = "";
Parameters::get("parallel->partitioner->read meta arh", arhMetaFile); Parameters::get(initFileStr + "->read meta arh",
arhMetaFile);
bool partitioningArhBased = (arhMetaFile != ""); bool partitioningArhBased = (arhMetaFile != "");
if (partitioningArhBased) { if (partitioningArhBased) {
int nProc = ArhReader::readMetaData(arhMetaFile, mapElInRank, arhElCodeSize); int nProc = ArhReader::readMetaData(arhMetaFile, mapElInRank, arhElCodeSize);
......
...@@ -53,8 +53,9 @@ namespace AMDiS { ...@@ -53,8 +53,9 @@ namespace AMDiS {
class MeshPartitioner class MeshPartitioner
{ {
public: public:
MeshPartitioner(MPI::Intracomm *comm) MeshPartitioner(string name, MPI::Intracomm *comm)
: mpiComm(comm), : initFileStr(name),
mpiComm(comm),
mesh(NULL), mesh(NULL),
boxPartitioning(false), boxPartitioning(false),
mapLocalGlobal(NULL) mapLocalGlobal(NULL)
...@@ -149,6 +150,9 @@ namespace AMDiS { ...@@ -149,6 +150,9 @@ namespace AMDiS {
} }
protected: protected:
/// Prefix for reading parameters from init file.
string initFileStr;
/// Pointer to the MPI communicator the mesh partitioner should make use of. /// Pointer to the MPI communicator the mesh partitioner should make use of.
MPI::Intracomm *mpiComm; MPI::Intracomm *mpiComm;
......
...@@ -168,8 +168,8 @@ namespace AMDiS { ...@@ -168,8 +168,8 @@ namespace AMDiS {
class ParMetisPartitioner : public MeshPartitioner class ParMetisPartitioner : public MeshPartitioner
{ {
public: public:
ParMetisPartitioner(MPI::Intracomm *comm) ParMetisPartitioner(string name, MPI::Intracomm *comm)
: MeshPartitioner(comm), : MeshPartitioner(name, comm),
parMetisMesh(NULL), parMetisMesh(NULL),
itr(1000000.0) itr(1000000.0)
{} {}
......
...@@ -40,8 +40,8 @@ namespace AMDiS { ...@@ -40,8 +40,8 @@ namespace AMDiS {
class SimplePartitioner : public MeshPartitioner class SimplePartitioner : public MeshPartitioner
{ {
public: public:
SimplePartitioner(MPI::Intracomm *comm) SimplePartitioner(string name, MPI::Intracomm *comm)
: MeshPartitioner(comm) : MeshPartitioner(name, comm)
{} {}
~SimplePartitioner() {} ~SimplePartitioner() {}
......
...@@ -18,8 +18,9 @@ ...@@ -18,8 +18,9 @@
namespace AMDiS { namespace AMDiS {
ZoltanPartitioner::ZoltanPartitioner(MPI::Intracomm *comm) ZoltanPartitioner::ZoltanPartitioner(string name,
: MeshPartitioner(comm), MPI::Intracomm *comm)
: MeshPartitioner(name, comm),
zoltan(*comm), zoltan(*comm),
elWeights(NULL) elWeights(NULL)
{} {}
......
...@@ -37,7 +37,7 @@ namespace AMDiS { ...@@ -37,7 +37,7 @@ namespace AMDiS {
class ZoltanPartitioner : public MeshPartitioner class ZoltanPartitioner : public MeshPartitioner
{ {
public: public:
ZoltanPartitioner(MPI::Intracomm *comm); ZoltanPartitioner(string name, MPI::Intracomm *comm);
~ZoltanPartitioner() {} ~ZoltanPartitioner() {}
......
Supports Markdown
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