From ff250c55cd9a2a6eb4c38b7bb77a0af8939e4f02 Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Tue, 30 Oct 2012 11:43:03 +0000 Subject: [PATCH] Some performance issues. --- AMDiS/src/Global.cc | 13 ++ AMDiS/src/Marker.h | 34 ++---- AMDiS/src/parallel/MeshDistributor.cc | 154 ++++++++++++++---------- AMDiS/src/parallel/MeshDistributor.h | 6 + AMDiS/src/parallel/ParallelDofMapping.h | 8 +- 5 files changed, 128 insertions(+), 87 deletions(-) diff --git a/AMDiS/src/Global.cc b/AMDiS/src/Global.cc index ff24e8d9..c570cd82 100644 --- a/AMDiS/src/Global.cc +++ b/AMDiS/src/Global.cc @@ -200,6 +200,13 @@ namespace AMDiS { const char *file, int line) { +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS +#if (DEBUG == 0) + if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0) + return; +#endif +#endif + static int old_line = -1; if (!out) @@ -229,6 +236,12 @@ namespace AMDiS { void Msg::print_warn(const char *format, ...) { +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS +#if (DEBUG == 0) + if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0) + return; +#endif +#endif va_list arg; char buff[255]; diff --git a/AMDiS/src/Marker.h b/AMDiS/src/Marker.h index e7908950..a6fae8e0 100644 --- a/AMDiS/src/Marker.h +++ b/AMDiS/src/Marker.h @@ -64,11 +64,9 @@ namespace AMDiS { /// destructor virtual ~Marker() {} - /** \brief - * Marks element with newMark. If \ref maximumMarking is set, the element - * is marked only if the new mark is bigger than the old one. The return - * value specifies whether the element has been marked, or not. - */ + /// Marks element with newMark. If \ref maximumMarking is set, the element + /// is marked only if the new mark is bigger than the old one. The return + /// value specifies whether the element has been marked, or not. inline void setMark(Element *el, char newMark) { char oldMark = el->getMark(); @@ -120,7 +118,7 @@ namespace AMDiS { return elMarkCoarsen; } - // Returns \ref name of the Marker + /// Returns \ref name of the Marker inline std::string getName() const { return name; @@ -133,10 +131,8 @@ namespace AMDiS { /// Name of the scalar marker. std::string name; - /** \brief - * Equal to -1 for scalar problems. Component number if marker is - * part of a vector valued marker. - */ + /// Equal to -1 for scalar problems. Component number if marker is + /// part of a vector valued marker. int row; /// estimation sum @@ -145,22 +141,16 @@ namespace AMDiS { /// estmation maximum double estMax; - /** \brief - * If true, elements are marked only if the new value is bigger than - * the current marking. - */ + /// If true, elements are marked only if the new value is bigger than + /// the current marking. bool maximumMarking; - /** \brief - * Lower limit for error estimation, from which an element is marked for - * refinement - */ + /// Lower limit for error estimation, from which an element is marked for + /// refinement double markRLimit; - /** \brief - * Upper limit for error estimation, from which an element is marked for - * coarsening - */ + /// Upper limit for error estimation, from which an element is marked for + /// coarsening double markCLimit; /// power in estimator norm diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc index 8ca851aa..20eb83d3 100644 --- a/AMDiS/src/parallel/MeshDistributor.cc +++ b/AMDiS/src/parallel/MeshDistributor.cc @@ -87,7 +87,8 @@ namespace AMDiS { createBoundaryDofFlag(0), boundaryDofInfo(1), meshAdaptivity(true), - hasPeriodicBoundary(false) + hasPeriodicBoundary(false), + printTimings(false) { FUNCNAME("MeshDistributor::ParalleDomainBase()"); @@ -99,7 +100,7 @@ namespace AMDiS { Parameters::get(name + "->debug output dir", debugOutputDir); Parameters::get(name + "->repartition ith change", repartitionIthChange); Parameters::get(name + "->mesh adaptivity", meshAdaptivity); - + string partStr = "parmetis"; Parameters::get(name + "->partitioner", partStr); @@ -124,6 +125,8 @@ namespace AMDiS { Parameters::get(name + "->box partitioning", tmp); partitioner->setBoxPartitioning(static_cast<bool>(tmp)); + Parameters::get(name + "->print timings", printTimings); + TEST_EXIT(partitioner)("Could not create partitioner \"%s\"!\n", partStr.c_str()); } @@ -1584,6 +1587,10 @@ namespace AMDiS { { FUNCNAME("MeshDistributor::createBoundaryDofs()"); + if (printTimings) + MPI::COMM_WORLD.Barrier(); + double first = MPI::Wtime(); + // === Create DOF communicator. === dofComm.init(0, levelData, feSpaces); @@ -1596,52 +1603,57 @@ namespace AMDiS { // === If requested, create more information on communication DOFs. === - if (!createBoundaryDofFlag.isSet(BOUNDARY_SUBOBJ_SORTED)) - return; - - int nLevels = levelData.getLevelNumber(); - boundaryDofInfo.resize(nLevels); - - for (unsigned int i = 0; i < feSpaces.size(); i++) { - const FiniteElemSpace *feSpace = feSpaces[i]; + if (createBoundaryDofFlag.isSet(BOUNDARY_SUBOBJ_SORTED)) { - for (int level = 0; level < nLevels; level++) { - - // === Clear data. === - for (int geo = FACE; geo >= VERTEX; geo--) - boundaryDofInfo[level][feSpace].geoDofs[static_cast<GeoIndex>(geo)].clear(); + int nLevels = levelData.getLevelNumber(); + boundaryDofInfo.resize(nLevels); + + for (unsigned int i = 0; i < feSpaces.size(); i++) { + const FiniteElemSpace *feSpace = feSpaces[i]; - // === Create send DOFs. === - for (int geo = FACE; geo >= VERTEX; geo--) { - for (InteriorBoundary::iterator it(intBoundary.getOwn(), level); - !it.end(); ++it) { - if (it->rankObj.subObj == geo) { - DofContainer dofs; - it->rankObj.el->getAllDofs(feSpace, it->rankObj, dofs); - - if (createBoundaryDofFlag.isSet(BOUNDARY_FILL_INFO_SEND_DOFS)) - boundaryDofInfo[level][feSpace]. - geoDofs[static_cast<GeoIndex>(geo)].insert(dofs.begin(), dofs.end()); + for (int level = 0; level < nLevels; level++) { + + // === Clear data. === + for (int geo = FACE; geo >= VERTEX; geo--) + boundaryDofInfo[level][feSpace].geoDofs[static_cast<GeoIndex>(geo)].clear(); + + // === Create send DOFs. === + for (int geo = FACE; geo >= VERTEX; geo--) { + for (InteriorBoundary::iterator it(intBoundary.getOwn(), level); + !it.end(); ++it) { + if (it->rankObj.subObj == geo) { + DofContainer dofs; + it->rankObj.el->getAllDofs(feSpace, it->rankObj, dofs); + + if (createBoundaryDofFlag.isSet(BOUNDARY_FILL_INFO_SEND_DOFS)) + boundaryDofInfo[level][feSpace]. + geoDofs[static_cast<GeoIndex>(geo)].insert(dofs.begin(), dofs.end()); + } } } - } - - // === Create recv DOFs. === - for (int geo = FACE; geo >= VERTEX; geo--) { - for (InteriorBoundary::iterator it(intBoundary.getOther(), level); - !it.end(); ++it) { - if (it->rankObj.subObj == geo) { - DofContainer dofs; - it->rankObj.el->getAllDofs(feSpace, it->rankObj, dofs); - - if (createBoundaryDofFlag.isSet(BOUNDARY_FILL_INFO_RECV_DOFS)) - boundaryDofInfo[level][feSpace]. - geoDofs[static_cast<GeoIndex>(geo)].insert(dofs.begin(), dofs.end()); + + // === Create recv DOFs. === + for (int geo = FACE; geo >= VERTEX; geo--) { + for (InteriorBoundary::iterator it(intBoundary.getOther(), level); + !it.end(); ++it) { + if (it->rankObj.subObj == geo) { + DofContainer dofs; + it->rankObj.el->getAllDofs(feSpace, it->rankObj, dofs); + + if (createBoundaryDofFlag.isSet(BOUNDARY_FILL_INFO_RECV_DOFS)) + boundaryDofInfo[level][feSpace]. + geoDofs[static_cast<GeoIndex>(geo)].insert(dofs.begin(), dofs.end()); + } } } } } } + + if (printTimings) { + MPI::COMM_WORLD.Barrier(); + MSG("MESHDIST 01 (createBoundaryDofs) needed %.5f seconds\n", MPI::Wtime() - first); + } } @@ -1679,22 +1691,8 @@ namespace AMDiS { // === Update all registered DOF mapping objects. === - - TEST_EXIT(dofMaps.size())("No DOF mapping defined!\n"); - for (int i = 0; i < static_cast<int>(dofMaps.size()); i++) { - vector<const FiniteElemSpace*>& dofMapSpaces = dofMaps[i]->getFeSpaces(); - - dofMaps[i]->clear(); - - for (int j = 0; j < static_cast<int>(dofMapSpaces.size()); j++) - updateLocalGlobalNumbering(*(dofMaps[i]), dofMapSpaces[j]); - - dofMaps[i]->update(); -#if (DEBUG != 0) - // dofMaps[i]->printInfo(); -#endif - } + updateParallelDofMappings(); // === Create periodic DOF maps, if there are periodic boundaries. === @@ -1769,6 +1767,37 @@ namespace AMDiS { } + void MeshDistributor::updateParallelDofMappings() + { + FUNCNAME("MeshDistributor::updateParallelDofMappings()"); + + if (printTimings) + MPI::COMM_WORLD.Barrier(); + double first = MPI::Wtime(); + + TEST_EXIT(dofMaps.size())("No DOF mapping defined!\n"); + + for (int i = 0; i < static_cast<int>(dofMaps.size()); i++) { + vector<const FiniteElemSpace*>& dofMapSpaces = dofMaps[i]->getFeSpaces(); + + dofMaps[i]->clear(); + + for (int j = 0; j < static_cast<int>(dofMapSpaces.size()); j++) + updateLocalGlobalNumbering(*(dofMaps[i]), dofMapSpaces[j]); + + dofMaps[i]->update(); +#if (DEBUG != 0) + // dofMaps[i]->printInfo(); +#endif + } + + if (printTimings) { + MPI::COMM_WORLD.Barrier(); + MSG("MESHDIST 02 (update DOF mappings) needed %.5f seconds\n", MPI::Wtime() - first); + } + } + + void MeshDistributor::updateLocalGlobalNumbering(ParallelDofMapping &dofMap, const FiniteElemSpace *feSpace) { @@ -1776,6 +1805,7 @@ namespace AMDiS { DofComm &dcom = dofMap.getDofComm(); + // === Get all DOFs in ranks partition. === std::set<const DegreeOfFreedom*> rankDofSet; @@ -1792,14 +1822,14 @@ namespace AMDiS { !it.end(); it.nextRank()) for (; !it.endDofIter(); it.nextDof()) nonRankDofs.insert(it.getDof()); - - for (unsigned int i = 0; i < rankDofs.size(); i++) - if (nonRankDofs.count(rankDofs[i]) == 0) - dofMap[feSpace].insertRankDof(*(rankDofs[i])); - - for (DofContainerSet::iterator it = nonRankDofs.begin(); - it != nonRankDofs.end(); ++it) - dofMap[feSpace].insertNonRankDof(**it); + + for (DofContainer::iterator it = rankDofs.begin(); + it != rankDofs.end(); ++it) { + if (nonRankDofs.count(*it)) + dofMap[feSpace].insertNonRankDof(**it); + else + dofMap[feSpace].insertRankDof(**it); + } } diff --git a/AMDiS/src/parallel/MeshDistributor.h b/AMDiS/src/parallel/MeshDistributor.h index e8a5a791..3022c26c 100644 --- a/AMDiS/src/parallel/MeshDistributor.h +++ b/AMDiS/src/parallel/MeshDistributor.h @@ -322,6 +322,9 @@ namespace AMDiS { return levelData; } + /// Updates all registered parallel DOF mappings, see \ref dofMaps. + void updateParallelDofMappings(); + void updateLocalGlobalNumbering(); /// Updates the local and global DOF numbering after the mesh has been @@ -583,6 +586,9 @@ namespace AMDiS { /// solver objects and must be updated automatically after mesh change. vector<ParallelDofMapping*> dofMaps; + /// If true, detailed timings for benchmarking are printed. + bool printTimings; + public: /// The boundary DOFs are sorted by subobject entities, i.e., first all /// face DOFs, edge DOFs and to the last vertex DOFs will be set to diff --git a/AMDiS/src/parallel/ParallelDofMapping.h b/AMDiS/src/parallel/ParallelDofMapping.h index 0bb64f7e..f2774941 100644 --- a/AMDiS/src/parallel/ParallelDofMapping.h +++ b/AMDiS/src/parallel/ParallelDofMapping.h @@ -161,7 +161,8 @@ namespace AMDiS { /// Inserts a new DOF to rank's mapping. The DOF is assumed to be owend by /// the rank. - void insertRankDof(DegreeOfFreedom dof0, DegreeOfFreedom dof1 = -1) + inline void insertRankDof(DegreeOfFreedom dof0, + DegreeOfFreedom dof1 = -1) { FUNCNAME("ComponentDofMap::insertRankDof()"); @@ -176,7 +177,8 @@ namespace AMDiS { /// Inserts a new DOF to rank's mapping. The DOF exists in rank's subdomain /// but is owned by a different rank, thus it is part of an interior boundary. - void insertNonRankDof(DegreeOfFreedom dof0, DegreeOfFreedom dof1 = -1) + inline void insertNonRankDof(DegreeOfFreedom dof0, + DegreeOfFreedom dof1 = -1) { FUNCNAME("ComponentDofMap::insertNonRankDof()"); @@ -281,7 +283,7 @@ namespace AMDiS { DofMap dofMap; /// Set of all DOFs that are in mapping but are not owned by the rank. - boost::container::flat_set<DegreeOfFreedom> nonRankDofs; + boost::container::flat_set<DegreeOfFreedom> nonRankDofs; /// If true, a global index mapping will be computed for all DOFs. bool globalMapping; -- GitLab