From 55df3b3f01aba71aa0f0b4265dc5741d35814b9a Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Sat, 8 Dec 2012 18:29:20 +0000 Subject: [PATCH] Introduced initial partitioner. --- AMDiS/src/parallel/CheckerPartitioner.cc | 6 +-- AMDiS/src/parallel/CheckerPartitioner.h | 2 +- AMDiS/src/parallel/MeshDistributor.cc | 63 ++++++++++++++++-------- AMDiS/src/parallel/MeshDistributor.h | 6 +++ AMDiS/src/parallel/MeshPartitioner.cc | 6 ++- AMDiS/src/parallel/MeshPartitioner.h | 8 ++- AMDiS/src/parallel/ParMetisPartitioner.h | 4 +- AMDiS/src/parallel/SimplePartitioner.h | 4 +- AMDiS/src/parallel/ZoltanPartitioner.cc | 5 +- AMDiS/src/parallel/ZoltanPartitioner.h | 2 +- 10 files changed, 71 insertions(+), 35 deletions(-) diff --git a/AMDiS/src/parallel/CheckerPartitioner.cc b/AMDiS/src/parallel/CheckerPartitioner.cc index 5142e61a..a44e00ca 100644 --- a/AMDiS/src/parallel/CheckerPartitioner.cc +++ b/AMDiS/src/parallel/CheckerPartitioner.cc @@ -16,15 +16,15 @@ namespace AMDiS { - CheckerPartitioner::CheckerPartitioner(MPI::Intracomm *comm) - : MeshPartitioner(comm), + CheckerPartitioner::CheckerPartitioner(string name, MPI::Intracomm *comm) + : MeshPartitioner(name, comm), mpiRank(mpiComm->Get_rank()), mpiSize(mpiComm->Get_size()), mode(0), multilevel(false) { string modestr = ""; - Parameters::get("parallel->partitioner->mode", modestr); + Parameters::get(initFileStr + "->mode", modestr); if (modestr == "x-stripes") mode = 1; diff --git a/AMDiS/src/parallel/CheckerPartitioner.h b/AMDiS/src/parallel/CheckerPartitioner.h index 4933e8a1..2844be67 100644 --- a/AMDiS/src/parallel/CheckerPartitioner.h +++ b/AMDiS/src/parallel/CheckerPartitioner.h @@ -35,7 +35,7 @@ namespace AMDiS { class CheckerPartitioner : public MeshPartitioner { public: - CheckerPartitioner(MPI::Intracomm *comm); + CheckerPartitioner(string name, MPI::Intracomm *comm); ~CheckerPartitioner() {} diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc index ba828905..740b171b 100644 --- a/AMDiS/src/parallel/MeshDistributor.cc +++ b/AMDiS/src/parallel/MeshDistributor.cc @@ -77,6 +77,7 @@ namespace AMDiS { mesh(NULL), refineManager(NULL), partitioner(NULL), + initialPartitioner(NULL), deserialized(false), writeSerializationFile(false), repartitioningAllowed(false), @@ -104,36 +105,57 @@ namespace AMDiS { Parameters::get(name + "->repartition ith change", repartitionIthChange); Parameters::get(name + "->repartition wait after fail", repartitioningWaitAfterFail); Parameters::get(name + "->mesh adaptivity", meshAdaptivity); + + // === Create partitioner object. === + string partStr = "parmetis"; Parameters::get(name + "->partitioner", partStr); if (partStr == "parmetis") - partitioner = new ParMetisPartitioner(&mpiComm); + partitioner = new ParMetisPartitioner("parallel->partitioner", &mpiComm); if (partStr == "zoltan") { #ifdef HAVE_ZOLTAN - partitioner = new ZoltanPartitioner(&mpiComm); + partitioner = new ZoltanPartitioner("parallel->partitioner", &mpiComm); #else ERROR_EXIT("AMDiS was compiled without Zoltan support. Therefore you cannot make use of it!\n"); #endif } if (partStr == "checker") - partitioner = new CheckerPartitioner(&mpiComm); + partitioner = new CheckerPartitioner("parallel->partitioner", &mpiComm); 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; Parameters::get(name + "->box partitioning", tmp); partitioner->setBoxPartitioning(static_cast<bool>(tmp)); + initialPartitioner->setBoxPartitioning(static_cast<bool>(tmp)); Parameters::get(name + "->print timings", printTimings); 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. createMeshLevelStructure(); } @@ -141,8 +163,10 @@ namespace AMDiS { MeshDistributor::~MeshDistributor() { - if (partitioner) + if (partitioner) { delete partitioner; + partitioner = NULL; + } } @@ -357,18 +381,24 @@ namespace AMDiS { createMacroElementInfo(); // 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 setInitialElementWeights(); - if (!useInitialPartitioning) { + if (!useInitialPartitioning) { // 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"); } - partitioner->createPartitionMap(partitionMap); + initialPartitioner->createPartitionMap(partitionMap); + + if (initialPartitioner != partitioner) { + *partitioner = *initialPartitioner; + } } @@ -462,6 +492,7 @@ namespace AMDiS { } partitioner->setMesh(mesh); + initialPartitioner->setMesh(mesh); // === Check whether the stationary problem should be serialized. === @@ -1446,15 +1477,7 @@ namespace AMDiS { if (!partitioner->meshChanged()) { MSG("Mesh partition does not create a new partition!\n"); MSG("Try to refine partitioning!\n"); - 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"); - } - + partitioningSucceed = partitioner->partition(elemWeights, REFINE_PART); if (!partitioningSucceed || !partitioner->meshChanged()) { mpiComm.Barrier(); repartitioningFailed = repartitioningWaitAfterFail;; diff --git a/AMDiS/src/parallel/MeshDistributor.h b/AMDiS/src/parallel/MeshDistributor.h index e0884ef7..a5578de7 100644 --- a/AMDiS/src/parallel/MeshDistributor.h +++ b/AMDiS/src/parallel/MeshDistributor.h @@ -504,6 +504,12 @@ namespace AMDiS { /// the ranks. 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 /// this element. map<int, double> elemWeights; diff --git a/AMDiS/src/parallel/MeshPartitioner.cc b/AMDiS/src/parallel/MeshPartitioner.cc index 195e0187..0206f5f1 100644 --- a/AMDiS/src/parallel/MeshPartitioner.cc +++ b/AMDiS/src/parallel/MeshPartitioner.cc @@ -34,7 +34,8 @@ namespace AMDiS { map<int, int> arhElCodeSize; string partitioningFile = ""; - Parameters::get("parallel->initial partitioning file", partitioningFile); + Parameters::get(initFileStr + "->initial partitioning file", + partitioningFile); if (partitioningFile != "") { MSG("Read initial partitioning file: %s\n", partitioningFile.c_str()); @@ -54,7 +55,8 @@ namespace AMDiS { useInitialPartitioning = true; } else { string arhMetaFile = ""; - Parameters::get("parallel->partitioner->read meta arh", arhMetaFile); + Parameters::get(initFileStr + "->read meta arh", + arhMetaFile); bool partitioningArhBased = (arhMetaFile != ""); if (partitioningArhBased) { int nProc = ArhReader::readMetaData(arhMetaFile, mapElInRank, arhElCodeSize); diff --git a/AMDiS/src/parallel/MeshPartitioner.h b/AMDiS/src/parallel/MeshPartitioner.h index 396a6bd7..2401d1cd 100644 --- a/AMDiS/src/parallel/MeshPartitioner.h +++ b/AMDiS/src/parallel/MeshPartitioner.h @@ -53,8 +53,9 @@ namespace AMDiS { class MeshPartitioner { public: - MeshPartitioner(MPI::Intracomm *comm) - : mpiComm(comm), + MeshPartitioner(string name, MPI::Intracomm *comm) + : initFileStr(name), + mpiComm(comm), mesh(NULL), boxPartitioning(false), mapLocalGlobal(NULL) @@ -149,6 +150,9 @@ namespace AMDiS { } protected: + /// Prefix for reading parameters from init file. + string initFileStr; + /// Pointer to the MPI communicator the mesh partitioner should make use of. MPI::Intracomm *mpiComm; diff --git a/AMDiS/src/parallel/ParMetisPartitioner.h b/AMDiS/src/parallel/ParMetisPartitioner.h index 210e3738..f896eb29 100644 --- a/AMDiS/src/parallel/ParMetisPartitioner.h +++ b/AMDiS/src/parallel/ParMetisPartitioner.h @@ -168,8 +168,8 @@ namespace AMDiS { class ParMetisPartitioner : public MeshPartitioner { public: - ParMetisPartitioner(MPI::Intracomm *comm) - : MeshPartitioner(comm), + ParMetisPartitioner(string name, MPI::Intracomm *comm) + : MeshPartitioner(name, comm), parMetisMesh(NULL), itr(1000000.0) {} diff --git a/AMDiS/src/parallel/SimplePartitioner.h b/AMDiS/src/parallel/SimplePartitioner.h index be853289..43387178 100644 --- a/AMDiS/src/parallel/SimplePartitioner.h +++ b/AMDiS/src/parallel/SimplePartitioner.h @@ -40,8 +40,8 @@ namespace AMDiS { class SimplePartitioner : public MeshPartitioner { public: - SimplePartitioner(MPI::Intracomm *comm) - : MeshPartitioner(comm) + SimplePartitioner(string name, MPI::Intracomm *comm) + : MeshPartitioner(name, comm) {} ~SimplePartitioner() {} diff --git a/AMDiS/src/parallel/ZoltanPartitioner.cc b/AMDiS/src/parallel/ZoltanPartitioner.cc index cce8a3a3..214780fc 100644 --- a/AMDiS/src/parallel/ZoltanPartitioner.cc +++ b/AMDiS/src/parallel/ZoltanPartitioner.cc @@ -18,8 +18,9 @@ namespace AMDiS { - ZoltanPartitioner::ZoltanPartitioner(MPI::Intracomm *comm) - : MeshPartitioner(comm), + ZoltanPartitioner::ZoltanPartitioner(string name, + MPI::Intracomm *comm) + : MeshPartitioner(name, comm), zoltan(*comm), elWeights(NULL) {} diff --git a/AMDiS/src/parallel/ZoltanPartitioner.h b/AMDiS/src/parallel/ZoltanPartitioner.h index a54e32f8..fa1ecbff 100644 --- a/AMDiS/src/parallel/ZoltanPartitioner.h +++ b/AMDiS/src/parallel/ZoltanPartitioner.h @@ -37,7 +37,7 @@ namespace AMDiS { class ZoltanPartitioner : public MeshPartitioner { public: - ZoltanPartitioner(MPI::Intracomm *comm); + ZoltanPartitioner(string name, MPI::Intracomm *comm); ~ZoltanPartitioner() {} -- GitLab