diff --git a/cmake/ExternalGitTags.cmake b/cmake/ExternalGitTags.cmake index a066d01e2..b90f6e7f9 100644 --- a/cmake/ExternalGitTags.cmake +++ b/cmake/ExternalGitTags.cmake @@ -34,7 +34,7 @@ set(EXTERN_BUTTERFLYPACK_GIT_BRANCH "Git branch for external ButterflyPACK build" ) set(EXTERN_BUTTERFLYPACK_GIT_TAG - "6bb36d00ad8deab43d74aa4fce0715e9400d994a" CACHE STRING + "7410fca61c188daab40f55c235ab7fad16ee5856" CACHE STRING "Git tag for external ButterflyPACK build" ) @@ -76,7 +76,7 @@ set(EXTERN_LIBCEED_GIT_BRANCH "Git branch for external libCEED build" ) set(EXTERN_LIBCEED_GIT_TAG - "1809c5f74680557a641e900d791842bafdfb4e8b" CACHE STRING + "ef9a992f4cf09f2be4ec72f649495c67ec03f813" CACHE STRING "Git tag for external libCEED build" ) @@ -90,7 +90,7 @@ set(EXTERN_LIBXSMM_GIT_BRANCH "Git branch for external LIBXSMM build" ) set(EXTERN_LIBXSMM_GIT_TAG - "feacc5e2112af47a0f4669e4ba20f0d01c08f944" CACHE STRING + "953405207f32369cd74d757681ce476fe89768b6" CACHE STRING "Git tag for external LIBXSMM build" ) @@ -132,7 +132,7 @@ set(EXTERN_MFEM_GIT_BRANCH "Git branch for external MFEM build" ) set(EXTERN_MFEM_GIT_TAG - "7c296d00d8a770e9f569e4db9d7e6d415902a886" CACHE STRING # master @ 05/09/2024 + "c444b17c973cc301590a6ac186fb33587b5881e6" CACHE STRING # master @ 05/18/2024 "Git tag for external MFEM build" ) @@ -146,7 +146,7 @@ set(EXTERN_MUMPS_GIT_BRANCH "Git branch for external MUMPS build" ) set(EXTERN_MUMPS_GIT_TAG - "cbdf7fc5d5bd5471a55459e92fc8b5fd1f16f651" CACHE STRING + "b00cc7c9fc6127e07d6583a8c50c727508ea1c6e" CACHE STRING "Git tag for external MUMPS build" ) @@ -174,7 +174,7 @@ set(EXTERN_PETSC_GIT_BRANCH "Git branch for external PETSc build" ) set(EXTERN_PETSC_GIT_TAG - "3d77ad52841f320b3f6ad02ce14f35e73e722480" CACHE STRING + "e6938432041f05a2617386d95f6ba21e1677d3e7" CACHE STRING "Git tag for external PETSc build" ) @@ -202,7 +202,7 @@ set(EXTERN_SLEPC_GIT_BRANCH "Git branch for external SLEPc build" ) set(EXTERN_SLEPC_GIT_TAG - "1b1a6e4c08bfc150112594b09cc439adf16f4899" CACHE STRING + "2c2766ada27519a79c9f9d9634b730afb4010d95" CACHE STRING "Git tag for external SLEPc build" ) @@ -230,7 +230,7 @@ set(EXTERN_SUPERLU_GIT_BRANCH "Git branch for external SuperLU_DIST build" ) set(EXTERN_SUPERLU_GIT_TAG - "c6896d85b22384880db409ba042a03966530678e" CACHE STRING + "2e39ceca001f594dc63426f2b500c82f5ce312a3" CACHE STRING "Git tag for external SuperLU_DIST build" ) @@ -244,7 +244,7 @@ set(EXTERN_ZFP_GIT_BRANCH "Git branch for external ZFP build" ) set(EXTERN_ZFP_GIT_TAG - "6814a4ebbbee6002f1d7f39a0acc9e8429545bce" CACHE STRING + "6aa2dae1c1bf700f062f386e81cc71796929c30e" CACHE STRING "Git tag for external ZFP build" ) diff --git a/extern/patch/mfem/patch_mesh_part_const.diff b/extern/patch/mfem/patch_mesh_part_const.diff index ea000c64d..70567000f 100644 --- a/extern/patch/mfem/patch_mesh_part_const.diff +++ b/extern/patch/mfem/patch_mesh_part_const.diff @@ -1,35 +1,160 @@ +diff --git a/mesh/mesh.cpp b/mesh/mesh.cpp +index e18def619..afee9d8f9 100644 +--- a/mesh/mesh.cpp ++++ b/mesh/mesh.cpp +@@ -13600,22 +13600,23 @@ Mesh &MeshPart::GetMesh() + + MeshPartitioner::MeshPartitioner(Mesh &mesh_, + int num_parts_, +- int *partitioning_, ++ const int *partitioning_, + int part_method) + : mesh(mesh_) + { + if (partitioning_) + { +- partitioning.MakeRef(partitioning_, mesh.GetNE(), false); ++ partitioning.MakeRef(const_cast(partitioning_), mesh.GetNE(), ++ false); + } + else + { +- partitioning_ = mesh.GeneratePartitioning(num_parts_, part_method); + // Mesh::GeneratePartitioning always uses new[] to allocate the, + // partitioning, so we need to tell the memory manager to free it with + // delete[] (even if a different host memory type has been selected). +- const MemoryType mt = MemoryType::HOST; +- partitioning.MakeRef(partitioning_, mesh.GetNE(), mt, true); ++ constexpr MemoryType mt = MemoryType::HOST; ++ partitioning.MakeRef(mesh.GeneratePartitioning(num_parts_, part_method), ++ mesh.GetNE(), mt, true); + } + + Transpose(partitioning, part_to_element, num_parts_); +diff --git a/mesh/mesh.hpp b/mesh/mesh.hpp +index f328f6c29..1431a484e 100644 +--- a/mesh/mesh.hpp ++++ b/mesh/mesh.hpp +@@ -2726,8 +2726,8 @@ public: + Mesh::GeneratePartitioning() when the provided + input partitioning is NULL. + */ +- MeshPartitioner(Mesh &mesh_, int num_parts_, int *partitioning_ = NULL, +- int part_method = 1); ++ MeshPartitioner(Mesh &mesh_, int num_parts_, ++ const int *partitioning_ = nullptr, int part_method = 1); + + /** @brief Construct a MeshPart corresponding to the given @a part_id. + diff --git a/mesh/nurbs.cpp b/mesh/nurbs.cpp -index 32223524c..b156fecaf 100644 +index 06c80c967..8ab5e5650 100644 --- a/mesh/nurbs.cpp +++ b/mesh/nurbs.cpp -@@ -4730,7 +4730,7 @@ ParNURBSExtension::ParNURBSExtension(const ParNURBSExtension &orig) +@@ -4722,19 +4722,15 @@ const Array& NURBSExtension::GetPatchBdrElements(int patch) + #ifdef MFEM_USE_MPI + ParNURBSExtension::ParNURBSExtension(const ParNURBSExtension &orig) + : NURBSExtension(orig), +- partitioning(orig.partitioning ? new int[orig.GetGNE()] : NULL), ++ partitioning(orig.partitioning), + gtopo(orig.gtopo), + ldof_group(orig.ldof_group) + { +- // Copy the partitioning, if not NULL +- if (partitioning) +- { +- std::memcpy(partitioning, orig.partitioning, orig.GetGNE()*sizeof(int)); +- } } ParNURBSExtension::ParNURBSExtension(MPI_Comm comm, NURBSExtension *parent, - int *part, const Array &active_bel) -+ const int *part, const Array &active_bel) ++ const int *partitioning_, ++ const Array &active_bel) : gtopo(comm) { if (parent->NumOfActiveElems < parent->NumOfElements) +@@ -4772,11 +4768,11 @@ ParNURBSExtension::ParNURBSExtension(MPI_Comm comm, NURBSExtension *parent, + CountElements(); + CountBdrElements(); + +- // copy 'part' to 'partitioning' +- partitioning = new int[GetGNE()]; ++ // copy 'partitioning_' to 'partitioning' ++ partitioning.SetSize(GetGNE()); + for (int i = 0; i < GetGNE(); i++) + { +- partitioning[i] = part[i]; ++ partitioning[i] = partitioning_[i]; + } + SetActive(partitioning, active_bel); + +@@ -4867,8 +4863,6 @@ ParNURBSExtension::ParNURBSExtension(NURBSExtension *parent, + + delete parent; + +- partitioning = NULL; +- + MFEM_VERIFY(par_parent->partitioning, + "parent ParNURBSExtension has no partitioning!"); + diff --git a/mesh/nurbs.hpp b/mesh/nurbs.hpp -index 54aa364a1..65ef12d51 100644 +index b1c772bd3..7212774e9 100644 --- a/mesh/nurbs.hpp +++ b/mesh/nurbs.hpp -@@ -624,7 +624,8 @@ public: +@@ -872,7 +872,7 @@ class ParNURBSExtension : public NURBSExtension + { + private: + /// Partitioning of the global elements by MPI rank +- int *partitioning; ++ mfem::Array partitioning; + + /// Construct and return a table of DOFs for each global element. + Table *GetGlobalElementDofTable(); +@@ -882,9 +882,10 @@ private: + /** @brief Set active global elements and boundary elements based on MPI + ranks in @a partition and the array @a active_bel. */ +- void SetActive(const int *partition, const Array &active_bel); ++ void SetActive(const int *partitioning_, const Array &active_bel); ++ + /// Set up GroupTopology @a gtopo for MPI communication. +- void BuildGroups(const int *partition, const Table &elem_dof); ++ void BuildGroups(const int *partitioning_, const Table &elem_dof); + + public: + GroupTopology gtopo; +@@ -895,11 +896,12 @@ public: ParNURBSExtension(const ParNURBSExtension &orig); -- ParNURBSExtension(MPI_Comm comm, NURBSExtension *parent, int *partitioning, + /** @brief Constructor for an MPI communicator @a comm, a global +- NURBSExtension @a parent, a partitioning @a part of the global elements +- by MPI rank, and a marker @a active_bel of active global boundary +- elements on this rank. The partitioning is deep-copied and will not be +- deleted by this object. */ +- ParNURBSExtension(MPI_Comm comm, NURBSExtension *parent, int *part, ++ NURBSExtension @a parent, a partitioning @a partitioning_ of the global ++ elements by MPI rank, and a marker @a active_bel of active global ++ boundary elements on this rank. The partitioning is deep-copied and will ++ not be deleted by this object. */ + ParNURBSExtension(MPI_Comm comm, NURBSExtension *parent, -+ const int *partitioning, ++ const int *partitioning_, const Array &active_bel); - // Create a parallel version of 'parent' with partitioning as in + /** @brief Create a parallel version of @a parent with partitioning as in +@@ -907,8 +909,6 @@ public: + The @a parent can be either a local NURBSExtension or a global one. */ + ParNURBSExtension(NURBSExtension *parent, + const ParNURBSExtension *par_parent); +- +- virtual ~ParNURBSExtension() { delete [] partitioning; } + }; + #endif + diff --git a/mesh/pmesh.cpp b/mesh/pmesh.cpp -index 46ceb35e2..a46d9e315 100644 +index 46ceb35e2..9556bcbd2 100644 --- a/mesh/pmesh.cpp +++ b/mesh/pmesh.cpp -@@ -103,13 +103,13 @@ ParMesh& ParMesh::operator=(ParMesh &&mesh) +@@ -103,29 +103,32 @@ ParMesh& ParMesh::operator=(ParMesh &&mesh) return *this; } @@ -41,34 +166,39 @@ index 46ceb35e2..a46d9e315 100644 , gtopo(comm) { - int *partitioning = NULL; -+ const int *partitioning = partitioning_ ? partitioning_ : nullptr; - Array activeBdrElem; - +- Array activeBdrElem; +- MyComm = comm; -@@ -118,18 +118,16 @@ ParMesh::ParMesh(MPI_Comm comm, Mesh &mesh, int *partitioning_, + MPI_Comm_size(MyComm, &NRanks); + MPI_Comm_rank(MyComm, &MyRank); ++ Array partitioning; ++ Array activeBdrElem; ++ ++ if (partitioning_) ++ { ++ partitioning.MakeRef(const_cast(partitioning_), mesh.GetNE(), ++ false); ++ } ++ if (mesh.Nonconforming()) { - if (partitioning_) - { - partitioning = partitioning_; - } - ncmesh = pncmesh = new ParNCMesh(comm, *mesh.ncmesh, partitioning); +- ncmesh = pncmesh = new ParNCMesh(comm, *mesh.ncmesh, partitioning); +- if (!partitioning) ++ ncmesh = pncmesh = new ParNCMesh(comm, *mesh.ncmesh, partitioning_); + - if (!partitioning) ++ if (!partitioning_) { - partitioning = new int[mesh.GetNE()]; -+ int *part = new int[mesh.GetNE()]; ++ partitioning.SetSize(mesh.GetNE()); for (int i = 0; i < mesh.GetNE(); i++) { -- partitioning[i] = pncmesh->InitialPartition(i); -+ part[i] = pncmesh->InitialPartition(i); - } -+ partitioning = part; - } - - pncmesh->Prune(); -@@ -158,11 +156,7 @@ ParMesh::ParMesh(MPI_Comm comm, Mesh &mesh, int *partitioning_, + partitioning[i] = pncmesh->InitialPartition(i); +@@ -158,13 +161,14 @@ ParMesh::ParMesh(MPI_Comm comm, Mesh &mesh, int *partitioning_, ncmesh = pncmesh = NULL; @@ -77,11 +207,31 @@ index 46ceb35e2..a46d9e315 100644 - partitioning = partitioning_; - } - else -+ if (!partitioning) ++ if (!partitioning_) { - partitioning = mesh.GeneratePartitioning(NRanks, part_method); +- partitioning = mesh.GeneratePartitioning(NRanks, part_method); ++ // Mesh::GeneratePartitioning always uses new[] to allocate the, ++ // partitioning, so we need to tell the memory manager to free it with ++ // delete[] (even if a different host memory type has been selected). ++ constexpr MemoryType mt = MemoryType::HOST; ++ partitioning.MakeRef(mesh.GeneratePartitioning(NRanks, part_method), ++ mesh.GetNE(), mt, true); } -@@ -730,7 +724,7 @@ void ParMesh::BuildVertexGroup(int ngroups, const Table &vert_element) + + // re-enumerate the partitions to better map to actual processor +@@ -306,11 +310,6 @@ ParMesh::ParMesh(MPI_Comm comm, Mesh &mesh, int *partitioning_, + SetVerticesFromNodes(Nodes); + } + +- if (partitioning != partitioning_) +- { +- delete [] partitioning; +- } +- + have_face_nbr_data = false; + } + +@@ -730,7 +729,7 @@ void ParMesh::BuildVertexGroup(int ngroups, const Table &vert_element) } void ParMesh::BuildSharedFaceElems(int ntri_faces, int nquad_faces, @@ -91,7 +241,7 @@ index 46ceb35e2..a46d9e315 100644 const Array &face_group, const Array &vert_global_local) diff --git a/mesh/pmesh.hpp b/mesh/pmesh.hpp -index e33db8e43..44ce3be15 100644 +index e33db8e43..c6ceaed22 100644 --- a/mesh/pmesh.hpp +++ b/mesh/pmesh.hpp @@ -241,7 +241,7 @@ protected: @@ -108,7 +258,7 @@ index e33db8e43..44ce3be15 100644 meshes (elements of nonconforming meshes should ideally be ordered as a sequence of face-neighbors). */ - ParMesh(MPI_Comm comm, Mesh &mesh, int *partitioning_ = NULL, -+ ParMesh(MPI_Comm comm, Mesh &mesh, const int *partitioning_ = NULL, ++ ParMesh(MPI_Comm comm, Mesh &mesh, const int *partitioning_ = nullptr, int part_method = 1); /** Copy constructor. Performs a deep copy of (almost) all data, so that the @@ -122,28 +272,85 @@ index e33db8e43..44ce3be15 100644 ///@{ @name These methods require group > 0 diff --git a/mesh/pncmesh.cpp b/mesh/pncmesh.cpp -index 218faebfc..e90849e16 100644 +index 218faebfc..4b5b62096 100644 --- a/mesh/pncmesh.cpp +++ b/mesh/pncmesh.cpp -@@ -28,7 +28,7 @@ namespace mfem +@@ -28,7 +28,8 @@ namespace mfem using namespace bin_io; -ParNCMesh::ParNCMesh(MPI_Comm comm, const NCMesh &ncmesh, int *part) -+ParNCMesh::ParNCMesh(MPI_Comm comm, const NCMesh &ncmesh, const int *part) ++ParNCMesh::ParNCMesh(MPI_Comm comm, const NCMesh &ncmesh, ++ const int *partitioning) : NCMesh(ncmesh) { MyComm = comm; +@@ -39,7 +40,8 @@ ParNCMesh::ParNCMesh(MPI_Comm comm, const NCMesh &ncmesh, int *part) + // sequence of leaf elements into 'NRanks' parts + for (int i = 0; i < leaf_elements.Size(); i++) + { +- elements[leaf_elements[i]].rank = part ? part[i] : InitialPartition(i); ++ elements[leaf_elements[i]].rank = ++ partitioning ? partitioning[i] : InitialPartition(i); + } + + Update(); diff --git a/mesh/pncmesh.hpp b/mesh/pncmesh.hpp -index 2f4e1eb74..497d73f93 100644 +index 2f4e1eb74..e4c54e8b6 100644 --- a/mesh/pncmesh.hpp +++ b/mesh/pncmesh.hpp -@@ -67,7 +67,7 @@ public: +@@ -67,7 +67,8 @@ public: /// Construct by partitioning a serial NCMesh. /** SFC partitioning is used by default. A user-specified partition can be passed in 'part', where part[i] is the desired MPI rank for element i. */ - ParNCMesh(MPI_Comm comm, const NCMesh& ncmesh, int* part = NULL); -+ ParNCMesh(MPI_Comm comm, const NCMesh& ncmesh, const int* part = NULL); ++ ParNCMesh(MPI_Comm comm, const NCMesh& ncmesh, ++ const int *partitioning = nullptr); /** Load from a stream, parallel version. See the serial NCMesh::NCMesh counterpart for a description of the parameters. */ +@@ -81,7 +82,8 @@ public: + + /** An override of NCMesh::Refine, which is called eventually, after making + sure that refinements that occur on the processor boundary are sent to +- the neighbor processors so they can keep their ghost layers up to date.*/ ++ the neighbor processors so they can keep their ghost layers up to ++ date. */ + void Refine(const Array &refinements) override; + + /// Parallel version of NCMesh::LimitNCLevel. +@@ -229,8 +231,8 @@ public: + const Table &deref_table); + + /** Extension of NCMesh::GetBoundaryClosure. Filters out ghost vertices and +- ghost edges from 'bdr_vertices' and 'bdr_edges', and uncovers hidden internal +- boundary faces. */ ++ ghost edges from 'bdr_vertices' and 'bdr_edges', and uncovers hidden ++ internal boundary faces. */ + void GetBoundaryClosure(const Array &bdr_attr_is_ess, + Array &bdr_vertices, + Array &bdr_edges, Array &bdr_faces) override; +@@ -252,8 +254,9 @@ protected: // interface for ParMesh + friend class ParMesh; + + /** For compatibility with conforming code in ParMesh and ParFESpace. +- Initializes shared structures in ParMesh: gtopo, shared_*, group_s*, s*_l*. +- The ParMesh then acts as a parallel mesh cut along the NC interfaces. */ ++ Initializes shared structures in ParMesh: gtopo, shared_*, group_s*, ++ s*_l*. The ParMesh then acts as a parallel mesh cut along the NC ++ interfaces. */ + void GetConformingSharedStructures(class ParMesh &pmesh); + + /** Populate face neighbor members of ParMesh from the ghost layer, without +@@ -519,8 +522,9 @@ protected: // implementation + owners, keeping the ghost layer up to date. Used by Rebalance() and + Derefine(). 'target_elements' is the number of elements this rank + is supposed to own after the exchange. If this number is not known +- a priori, the parameter can be set to -1, but more expensive communication +- (synchronous sends and a barrier) will be used in that case. */ ++ a priori, the parameter can be set to -1, but more expensive ++ communication (synchronous sends and a barrier) will be used in that ++ case. */ + void RedistributeElements(Array &new_ranks, int target_elements, + bool record_comm); +