From 1e77d2f8957a54c47ebbb97f59d956a008179f1b Mon Sep 17 00:00:00 2001 From: Ben Prather Date: Tue, 22 Aug 2023 16:54:57 -0600 Subject: [PATCH 01/18] First shot at fixing a subtle bug During re-meshing, track which meshblocks are newly created. After prolongating shared boundaries, but before prolongating internal boundaries, update elements on block faces to respect the ownership model. Still needs tweaks to the new-mesh priority! --- src/bvals/bvals.hpp | 6 +++-- src/bvals/bvals_base.cpp | 14 ++++++------ src/defs.hpp | 4 ++-- src/mesh/amr_loadbalance.cpp | 42 ++++++++++++++++++++++++++--------- src/mesh/logical_location.hpp | 17 ++++++++++---- src/mesh/mesh.cpp | 22 +++++------------- 6 files changed, 63 insertions(+), 42 deletions(-) diff --git a/src/bvals/bvals.hpp b/src/bvals/bvals.hpp index 827abac792ca..c36aebbb25cf 100644 --- a/src/bvals/bvals.hpp +++ b/src/bvals/bvals.hpp @@ -20,6 +20,7 @@ // \brief defines BoundaryBase, BoundaryValues classes used for setting BCs on all data #include +#include #include #include @@ -78,7 +79,8 @@ class BoundaryBase { static int BufferID(int dim, bool multilevel); static int FindBufferID(int ox1, int ox2, int ox3, int fi1, int fi2); - void SearchAndSetNeighbors(MeshBlockTree &tree, int *ranklist, int *nslist); + void SearchAndSetNeighbors(MeshBlockTree &tree, int *ranklist, int *nslist, + const std::set &newly_refined = {}); protected: // 1D refined or unrefined=2 @@ -90,7 +92,7 @@ class BoundaryBase { RegionSize block_size_; ParArrayND sarea_[2]; - void SetNeighborOwnership(); + void SetNeighborOwnership(const std::set &newly_refined = {}); private: // calculate 3x shared static data members when constructing only the 1st class instance diff --git a/src/bvals/bvals_base.cpp b/src/bvals/bvals_base.cpp index d9ad5317ac93..e92623935fb3 100644 --- a/src/bvals/bvals_base.cpp +++ b/src/bvals/bvals_base.cpp @@ -300,8 +300,8 @@ int BoundaryBase::CreateBvalsMPITag(int lid, int bufid) { // TODO(felker): break-up this long function -void BoundaryBase::SearchAndSetNeighbors(MeshBlockTree &tree, int *ranklist, - int *nslist) { +void BoundaryBase::SearchAndSetNeighbors(MeshBlockTree &tree, int *ranklist, int *nslist, + const std::set &newly_refined) { Kokkos::Profiling::pushRegion("SearchAndSetNeighbors"); MeshBlockTree *neibt; int myox1, myox2 = 0, myox3 = 0, myfx1, myfx2, myfx3; @@ -368,7 +368,7 @@ void BoundaryBase::SearchAndSetNeighbors(MeshBlockTree &tree, int *ranklist, } } if (block_size_.nx(X2DIR) == 1) { - SetNeighborOwnership(); + SetNeighborOwnership(newly_refined); Kokkos::Profiling::popRegion(); // SearchAndSetNeighbors return; } @@ -503,7 +503,7 @@ void BoundaryBase::SearchAndSetNeighbors(MeshBlockTree &tree, int *ranklist, } if (block_size_.nx(X3DIR) == 1) { - SetNeighborOwnership(); + SetNeighborOwnership(newly_refined); Kokkos::Profiling::popRegion(); // SearchAndSetNeighbors return; } @@ -626,11 +626,11 @@ void BoundaryBase::SearchAndSetNeighbors(MeshBlockTree &tree, int *ranklist, } } - SetNeighborOwnership(); + SetNeighborOwnership(newly_refined); Kokkos::Profiling::popRegion(); // SearchAndSetNeighbors } -void BoundaryBase::SetNeighborOwnership() { +void BoundaryBase::SetNeighborOwnership(const std::set &newly_refined) { // Set neighbor block ownership std::set allowed_neighbors; allowed_neighbors.insert(loc); // Insert the location of this block @@ -642,7 +642,7 @@ void BoundaryBase::SetNeighborOwnership() { RootGridInfo rg_info = pmy_mesh_->GetRootGridInfo(); for (int n = 0; n < nneighbor; ++n) { neighbor[n].ownership = - DetermineOwnership(neighbor[n].loc, allowed_neighbors, rg_info); + DetermineOwnership(neighbor[n].loc, allowed_neighbors, rg_info, newly_refined); neighbor[n].ownership.initialized = true; } } diff --git a/src/defs.hpp b/src/defs.hpp index 15dc0d031f83..5f0d96eb950b 100644 --- a/src/defs.hpp +++ b/src/defs.hpp @@ -73,8 +73,8 @@ struct RegionSize { RegionSize() = default; RegionSize(std::array xmin, std::array xmax, std::array xrat, std::array nx) - : xmin_(xmin), xmax_(xmax), xrat_(xrat), - nx_(nx), symmetry_{nx[0] == 1, nx[1] == 1, nx[2] == 1} {} + : xmin_(xmin), xmax_(xmax), xrat_(xrat), nx_(nx), + symmetry_{nx[0] == 1, nx[1] == 1, nx[2] == 1} {} RegionSize(std::array xmin, std::array xmax, std::array xrat, std::array nx, std::array symmetry) : xmin_(xmin), xmax_(xmax), xrat_(xrat), nx_(nx), symmetry_(symmetry) {} diff --git a/src/mesh/amr_loadbalance.cpp b/src/mesh/amr_loadbalance.cpp index fb33d645f842..0681931cfbee 100644 --- a/src/mesh/amr_loadbalance.cpp +++ b/src/mesh/amr_loadbalance.cpp @@ -789,6 +789,7 @@ void Mesh::RedistributeAndRefineMeshBlocks(ParameterInput *pin, ApplicationInput RegionSize block_size = GetBlockSize(); BlockList_t new_block_list(nbe - nbs + 1); + std::set newly_refined; for (int n = nbs; n <= nbe; n++) { int on = newtoold[n]; if ((ranklist[on] == Globals::my_rank) && @@ -810,6 +811,7 @@ void Mesh::RedistributeAndRefineMeshBlocks(ParameterInput *pin, ApplicationInput new_block_list[n - nbs] = MeshBlock::Make(n, n - nbs, newloc[n], block_size, block_bcs, this, pin, app_in, packages, resolved_packages, gflag); + if (newloc[n].level() > loclist[on].level()) newly_refined.insert(newloc[n]); } } @@ -913,29 +915,47 @@ void Mesh::RedistributeAndRefineMeshBlocks(ParameterInput *pin, ApplicationInput } } prolongation_cache.CopyToDevice(); + refinement::ProlongateShared(resolved_packages.get(), prolongation_cache, block_list[0]->cellbounds, block_list[0]->c_cellbounds); - refinement::ProlongateInternal(resolved_packages.get(), prolongation_cache, - block_list[0]->cellbounds, block_list[0]->c_cellbounds); - -#ifdef MPI_PARALLEL - if (send_reqs.size() != 0) - PARTHENON_MPI_CHECK( - MPI_Waitall(send_reqs.size(), send_reqs.data(), MPI_STATUSES_IGNORE)); -#endif - Kokkos::Profiling::popRegion(); // AMR: Recv data and unpack // update the lists loclist = std::move(newloc); ranklist = std::move(newrank); costlist = std::move(newcost); - // re-initialize the MeshBlocks + // A block newly refined and prolongated may have neighbors which were + // already refined to the new level. + // If so, the prolongated versions of shared elements will not reflect + // the true, finer versions present in the neighbor block. + // We must create any new fine buffers and fill them from these neighbors + // in order to maintain a consistent global state. + // Thus we rebuild and synchronize the mesh now, but using a unique + // neighbor precedence favoring the "old" fine blocks over "new" ones for (auto &pmb : block_list) { - pmb->pbval->SearchAndSetNeighbors(tree, ranklist.data(), nslist.data()); + pmb->pbval->SearchAndSetNeighbors(tree, ranklist.data(), nslist.data(), + newly_refined); } Initialize(false, pin, app_in); + // Internal refinement relies on the fine shared values, which are only consistent after + // being updated with any previously fine versions + refinement::ProlongateInternal(resolved_packages.get(), prolongation_cache, + block_list[0]->cellbounds, block_list[0]->c_cellbounds); + + // Rebuild the ownership model, this time weighting the "new" fine blocks just like + // any other blocks at their level. + for (auto &pmb : block_list) { + pmb->pbval->SearchAndSetNeighbors(tree, ranklist.data(), nslist.data()); + } + +#ifdef MPI_PARALLEL + if (send_reqs.size() != 0) + PARTHENON_MPI_CHECK( + MPI_Waitall(send_reqs.size(), send_reqs.data(), MPI_STATUSES_IGNORE)); +#endif + Kokkos::Profiling::popRegion(); // AMR: Recv data and unpack + ResetLoadBalanceVariables(); Kokkos::Profiling::popRegion(); // RedistributeAndRefineMeshBlocks diff --git a/src/mesh/logical_location.hpp b/src/mesh/logical_location.hpp index 21dd7a52f513..0519a9f822d6 100644 --- a/src/mesh/logical_location.hpp +++ b/src/mesh/logical_location.hpp @@ -251,15 +251,24 @@ struct block_ownership_t { inline block_ownership_t DetermineOwnership(const LogicalLocation &main_block, const std::set &allowed_neighbors, - const RootGridInfo &rg_info = RootGridInfo()) { + const RootGridInfo &rg_info = RootGridInfo(), + const std::set &newly_refined = {}) { block_ownership_t main_owns; - auto ownership_less_than = [](const LogicalLocation &a, const LogicalLocation &b) { + auto ownership_level = [&](const LogicalLocation &a) { + // Newly-refined blocks must be treated as their parent level in the first sync + // during refinement. + if (newly_refined.count(a)) return a.level() - 1; + return a.level(); + }; + + auto ownership_less_than = [ownership_level](const LogicalLocation &a, + const LogicalLocation &b) { // Ownership is first determined by block with the highest level, then by maximum // Morton number this is reversed in precedence from the normal comparators where // Morton number takes precedence - if (a.level() == b.level()) return a.morton() < b.morton(); - return a.level() < b.level(); + if (ownership_level(a) == ownership_level(b)) return a.morton() < b.morton(); + return ownership_level(a) < ownership_level(b); }; for (int ox1 : {-1, 0, 1}) { diff --git a/src/mesh/mesh.cpp b/src/mesh/mesh.cpp index a53c89f647a1..cff06851f811 100644 --- a/src/mesh/mesh.cpp +++ b/src/mesh/mesh.cpp @@ -98,9 +98,9 @@ Mesh::Mesh(ParameterInput *pin, ApplicationInput *app_in, Packages_t &packages, // private members: num_mesh_threads_(pin->GetOrAddInteger("parthenon/mesh", "num_threads", 1)), tree(this), use_uniform_meshgen_fn_{true, true, true, true}, lb_flag_(true), - lb_automatic_(), lb_manual_(), MeshGenerator_{nullptr, UniformMeshGenerator, - UniformMeshGenerator, - UniformMeshGenerator}, + lb_automatic_(), lb_manual_(), + MeshGenerator_{nullptr, UniformMeshGenerator, UniformMeshGenerator, + UniformMeshGenerator}, MeshBndryFnctn{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr} { std::stringstream msg; RegionSize block_size; @@ -475,11 +475,6 @@ Mesh::Mesh(ParameterInput *pin, ApplicationInput *app_in, Packages_t &packages, } ResetLoadBalanceVariables(); - - // Output variables in use in this run - if (Globals::my_rank == 0) { - std::cout << "#Variables in use:\n" << *(resolved_packages) << std::endl; - } } //---------------------------------------------------------------------------------------- @@ -524,9 +519,9 @@ Mesh::Mesh(ParameterInput *pin, ApplicationInput *app_in, RestartReader &rr, // private members: num_mesh_threads_(pin->GetOrAddInteger("parthenon/mesh", "num_threads", 1)), tree(this), use_uniform_meshgen_fn_{true, true, true, true}, lb_flag_(true), - lb_automatic_(), lb_manual_(), MeshGenerator_{nullptr, UniformMeshGenerator, - UniformMeshGenerator, - UniformMeshGenerator}, + lb_automatic_(), lb_manual_(), + MeshGenerator_{nullptr, UniformMeshGenerator, UniformMeshGenerator, + UniformMeshGenerator}, MeshBndryFnctn{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr} { std::stringstream msg; RegionSize block_size; @@ -738,11 +733,6 @@ Mesh::Mesh(ParameterInput *pin, ApplicationInput *app_in, RestartReader &rr, } ResetLoadBalanceVariables(); - - // Output variables in use in this run - if (Globals::my_rank == 0) { - std::cout << "#Variables in use:\n" << *(resolved_packages) << std::endl; - } } //---------------------------------------------------------------------------------------- From d9820e8bc90fe2b1134d1cb2ace6d6fe205c9b94 Mon Sep 17 00:00:00 2001 From: Ben Prather Date: Tue, 22 Aug 2023 17:22:52 -0600 Subject: [PATCH 02/18] Make the new-block ownership hierarchy a little more nuanced --- src/mesh/logical_location.hpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/mesh/logical_location.hpp b/src/mesh/logical_location.hpp index 0519a9f822d6..937608961213 100644 --- a/src/mesh/logical_location.hpp +++ b/src/mesh/logical_location.hpp @@ -256,10 +256,11 @@ DetermineOwnership(const LogicalLocation &main_block, block_ownership_t main_owns; auto ownership_level = [&](const LogicalLocation &a) { - // Newly-refined blocks must be treated as their parent level in the first sync - // during refinement. - if (newly_refined.count(a)) return a.level() - 1; - return a.level(); + // Newly-refined blocks are treated as higher-level than blocks at their + // parent level, but lower-level than previously-refined blocks at their + // current level. + if (newly_refined.count(a)) return 2*a.level() - 1; + return 2*a.level(); }; auto ownership_less_than = [ownership_level](const LogicalLocation &a, From 45b64d6e643712860d55144e1b418cfa1ea897c8 Mon Sep 17 00:00:00 2001 From: par-hermes Date: Tue, 22 Aug 2023 23:44:17 +0000 Subject: [PATCH 03/18] cpp-py-formatter --- src/defs.hpp | 4 ++-- src/mesh/logical_location.hpp | 4 ++-- src/mesh/mesh.cpp | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/defs.hpp b/src/defs.hpp index 5f0d96eb950b..15dc0d031f83 100644 --- a/src/defs.hpp +++ b/src/defs.hpp @@ -73,8 +73,8 @@ struct RegionSize { RegionSize() = default; RegionSize(std::array xmin, std::array xmax, std::array xrat, std::array nx) - : xmin_(xmin), xmax_(xmax), xrat_(xrat), nx_(nx), - symmetry_{nx[0] == 1, nx[1] == 1, nx[2] == 1} {} + : xmin_(xmin), xmax_(xmax), xrat_(xrat), + nx_(nx), symmetry_{nx[0] == 1, nx[1] == 1, nx[2] == 1} {} RegionSize(std::array xmin, std::array xmax, std::array xrat, std::array nx, std::array symmetry) : xmin_(xmin), xmax_(xmax), xrat_(xrat), nx_(nx), symmetry_(symmetry) {} diff --git a/src/mesh/logical_location.hpp b/src/mesh/logical_location.hpp index 937608961213..7362cecf6eab 100644 --- a/src/mesh/logical_location.hpp +++ b/src/mesh/logical_location.hpp @@ -259,8 +259,8 @@ DetermineOwnership(const LogicalLocation &main_block, // Newly-refined blocks are treated as higher-level than blocks at their // parent level, but lower-level than previously-refined blocks at their // current level. - if (newly_refined.count(a)) return 2*a.level() - 1; - return 2*a.level(); + if (newly_refined.count(a)) return 2 * a.level() - 1; + return 2 * a.level(); }; auto ownership_less_than = [ownership_level](const LogicalLocation &a, diff --git a/src/mesh/mesh.cpp b/src/mesh/mesh.cpp index cff06851f811..f5411c70d013 100644 --- a/src/mesh/mesh.cpp +++ b/src/mesh/mesh.cpp @@ -98,9 +98,9 @@ Mesh::Mesh(ParameterInput *pin, ApplicationInput *app_in, Packages_t &packages, // private members: num_mesh_threads_(pin->GetOrAddInteger("parthenon/mesh", "num_threads", 1)), tree(this), use_uniform_meshgen_fn_{true, true, true, true}, lb_flag_(true), - lb_automatic_(), lb_manual_(), - MeshGenerator_{nullptr, UniformMeshGenerator, UniformMeshGenerator, - UniformMeshGenerator}, + lb_automatic_(), lb_manual_(), MeshGenerator_{nullptr, UniformMeshGenerator, + UniformMeshGenerator, + UniformMeshGenerator}, MeshBndryFnctn{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr} { std::stringstream msg; RegionSize block_size; @@ -519,9 +519,9 @@ Mesh::Mesh(ParameterInput *pin, ApplicationInput *app_in, RestartReader &rr, // private members: num_mesh_threads_(pin->GetOrAddInteger("parthenon/mesh", "num_threads", 1)), tree(this), use_uniform_meshgen_fn_{true, true, true, true}, lb_flag_(true), - lb_automatic_(), lb_manual_(), - MeshGenerator_{nullptr, UniformMeshGenerator, UniformMeshGenerator, - UniformMeshGenerator}, + lb_automatic_(), lb_manual_(), MeshGenerator_{nullptr, UniformMeshGenerator, + UniformMeshGenerator, + UniformMeshGenerator}, MeshBndryFnctn{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr} { std::stringstream msg; RegionSize block_size; From 02912891cb00038c46d50f2b7bcd4a945da7b7a4 Mon Sep 17 00:00:00 2001 From: Ben Prather Date: Tue, 5 Sep 2023 13:00:38 -0600 Subject: [PATCH 04/18] Use unordered_map for newly refined blocks, keep full list (all ranks) --- src/bvals/bvals.hpp | 10 ++++++---- src/bvals/bvals_base.cpp | 9 ++++++--- src/mesh/amr_loadbalance.cpp | 22 ++++++++++++++-------- src/mesh/logical_location.hpp | 35 +++++++++++++++++++++++------------ 4 files changed, 49 insertions(+), 27 deletions(-) diff --git a/src/bvals/bvals.hpp b/src/bvals/bvals.hpp index c36aebbb25cf..718499a9f804 100644 --- a/src/bvals/bvals.hpp +++ b/src/bvals/bvals.hpp @@ -20,8 +20,8 @@ // \brief defines BoundaryBase, BoundaryValues classes used for setting BCs on all data #include -#include #include +#include #include #include "basic_types.hpp" @@ -79,8 +79,9 @@ class BoundaryBase { static int BufferID(int dim, bool multilevel); static int FindBufferID(int ox1, int ox2, int ox3, int fi1, int fi2); - void SearchAndSetNeighbors(MeshBlockTree &tree, int *ranklist, int *nslist, - const std::set &newly_refined = {}); + void + SearchAndSetNeighbors(MeshBlockTree &tree, int *ranklist, int *nslist, + const std::unordered_set &newly_refined = {}); protected: // 1D refined or unrefined=2 @@ -92,7 +93,8 @@ class BoundaryBase { RegionSize block_size_; ParArrayND sarea_[2]; - void SetNeighborOwnership(const std::set &newly_refined = {}); + void + SetNeighborOwnership(const std::unordered_set &newly_refined = {}); private: // calculate 3x shared static data members when constructing only the 1st class instance diff --git a/src/bvals/bvals_base.cpp b/src/bvals/bvals_base.cpp index e92623935fb3..057493f186e8 100644 --- a/src/bvals/bvals_base.cpp +++ b/src/bvals/bvals_base.cpp @@ -29,6 +29,7 @@ #include // c_str() #include "globals.hpp" +#include "mesh/logical_location.hpp" #include "mesh/mesh.hpp" #include "utils/buffer_utils.hpp" #include "utils/error_checking.hpp" @@ -300,8 +301,9 @@ int BoundaryBase::CreateBvalsMPITag(int lid, int bufid) { // TODO(felker): break-up this long function -void BoundaryBase::SearchAndSetNeighbors(MeshBlockTree &tree, int *ranklist, int *nslist, - const std::set &newly_refined) { +void BoundaryBase::SearchAndSetNeighbors( + MeshBlockTree &tree, int *ranklist, int *nslist, + const std::unordered_set &newly_refined) { Kokkos::Profiling::pushRegion("SearchAndSetNeighbors"); MeshBlockTree *neibt; int myox1, myox2 = 0, myox3 = 0, myfx1, myfx2, myfx3; @@ -630,7 +632,8 @@ void BoundaryBase::SearchAndSetNeighbors(MeshBlockTree &tree, int *ranklist, int Kokkos::Profiling::popRegion(); // SearchAndSetNeighbors } -void BoundaryBase::SetNeighborOwnership(const std::set &newly_refined) { +void BoundaryBase::SetNeighborOwnership( + const std::unordered_set &newly_refined) { // Set neighbor block ownership std::set allowed_neighbors; allowed_neighbors.insert(loc); // Insert the location of this block diff --git a/src/mesh/amr_loadbalance.cpp b/src/mesh/amr_loadbalance.cpp index 0681931cfbee..1436d877d92a 100644 --- a/src/mesh/amr_loadbalance.cpp +++ b/src/mesh/amr_loadbalance.cpp @@ -698,6 +698,7 @@ void Mesh::RedistributeAndRefineMeshBlocks(ParameterInput *pin, ApplicationInput oldtonew[mb_idx] = ntot - 1; current_level = 0; + std::unordered_set newly_refined; for (int n = 0; n < ntot; n++) { // "on" = "old n" = "old gid" = "old global MeshBlock ID" int on = newtoold[n]; @@ -705,6 +706,10 @@ void Mesh::RedistributeAndRefineMeshBlocks(ParameterInput *pin, ApplicationInput current_level = newloc[n].level(); if (newloc[n].level() >= loclist[on].level()) { // same or refined newcost[n] = costlist[on]; + // Keep a list of all blocks refined for below + if (newloc[n].level() > loclist[on].level()) { + newly_refined.insert(newloc[n]); + } } else { double acost = 0.0; for (int l = 0; l < nleaf; l++) @@ -789,7 +794,6 @@ void Mesh::RedistributeAndRefineMeshBlocks(ParameterInput *pin, ApplicationInput RegionSize block_size = GetBlockSize(); BlockList_t new_block_list(nbe - nbs + 1); - std::set newly_refined; for (int n = nbs; n <= nbe; n++) { int on = newtoold[n]; if ((ranklist[on] == Globals::my_rank) && @@ -811,7 +815,6 @@ void Mesh::RedistributeAndRefineMeshBlocks(ParameterInput *pin, ApplicationInput new_block_list[n - nbs] = MeshBlock::Make(n, n - nbs, newloc[n], block_size, block_bcs, this, pin, app_in, packages, resolved_packages, gflag); - if (newloc[n].level() > loclist[on].level()) newly_refined.insert(newloc[n]); } } @@ -936,6 +939,14 @@ void Mesh::RedistributeAndRefineMeshBlocks(ParameterInput *pin, ApplicationInput pmb->pbval->SearchAndSetNeighbors(tree, ranklist.data(), nslist.data(), newly_refined); } + // Make sure all old sends/receives are done before we reconfigure the mesh +#ifdef MPI_PARALLEL + if (send_reqs.size() != 0) + PARTHENON_MPI_CHECK( + MPI_Waitall(send_reqs.size(), send_reqs.data(), MPI_STATUSES_IGNORE)); +#endif + // Re-initialize the mesh with our temporary ownership/neighbor configurations. + // No buffers are different when we switch to the final precedence order. Initialize(false, pin, app_in); // Internal refinement relies on the fine shared values, which are only consistent after @@ -943,17 +954,12 @@ void Mesh::RedistributeAndRefineMeshBlocks(ParameterInput *pin, ApplicationInput refinement::ProlongateInternal(resolved_packages.get(), prolongation_cache, block_list[0]->cellbounds, block_list[0]->c_cellbounds); - // Rebuild the ownership model, this time weighting the "new" fine blocks just like + // Rebuild just the ownership model, this time weighting the "new" fine blocks just like // any other blocks at their level. for (auto &pmb : block_list) { pmb->pbval->SearchAndSetNeighbors(tree, ranklist.data(), nslist.data()); } -#ifdef MPI_PARALLEL - if (send_reqs.size() != 0) - PARTHENON_MPI_CHECK( - MPI_Waitall(send_reqs.size(), send_reqs.data(), MPI_STATUSES_IGNORE)); -#endif Kokkos::Profiling::popRegion(); // AMR: Recv data and unpack ResetLoadBalanceVariables(); diff --git a/src/mesh/logical_location.hpp b/src/mesh/logical_location.hpp index 937608961213..33abdebb96d8 100644 --- a/src/mesh/logical_location.hpp +++ b/src/mesh/logical_location.hpp @@ -23,12 +23,25 @@ #include #include #include +#include #include #include +#include "logical_location.hpp" #include "utils/error_checking.hpp" #include "utils/morton_number.hpp" +namespace parthenon { +class LogicalLocation; +} + +// This must be declared before an unordered_set of LogicalLocation is used +// below, but must be *implemented* after the class definition +template <> +struct std::hash { + std::size_t operator()(const parthenon::LogicalLocation &key) const noexcept; +}; + namespace parthenon { struct RootGridInfo { @@ -252,15 +265,15 @@ inline block_ownership_t DetermineOwnership(const LogicalLocation &main_block, const std::set &allowed_neighbors, const RootGridInfo &rg_info = RootGridInfo(), - const std::set &newly_refined = {}) { + const std::unordered_set &newly_refined = {}) { block_ownership_t main_owns; auto ownership_level = [&](const LogicalLocation &a) { // Newly-refined blocks are treated as higher-level than blocks at their // parent level, but lower-level than previously-refined blocks at their // current level. - if (newly_refined.count(a)) return 2*a.level() - 1; - return 2*a.level(); + if (newly_refined.count(a)) return 2 * a.level() - 1; + return 2 * a.level(); }; auto ownership_less_than = [ownership_level](const LogicalLocation &a, @@ -356,14 +369,12 @@ inline auto GetIndexRangeMaskFromOwnership(TopologicalElement el, } // namespace parthenon -template <> -struct std::hash { - std::size_t operator()(const parthenon::LogicalLocation &key) const noexcept { - // TODO(LFR): Think more carefully about what the best choice for this key is, - // probably the least significant sizeof(size_t) * 8 bits of the morton number - // with 3 * (level - 21) trailing bits removed. - return key.morton().bits[0]; - } -}; +inline std::size_t std::hash::operator()( + const parthenon::LogicalLocation &key) const noexcept { + // TODO(LFR): Think more carefully about what the best choice for this key is, + // probably the least significant sizeof(size_t) * 8 bits of the morton number + // with 3 * (level - 21) trailing bits removed. + return key.morton().bits[0]; +} #endif // MESH_LOGICAL_LOCATION_HPP_ From a4e08833ae0facf4c00a5012ca5edc6ac75d402d Mon Sep 17 00:00:00 2001 From: Ben Prather Date: Wed, 6 Sep 2023 09:03:53 -0600 Subject: [PATCH 05/18] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index befb895a8a5a..90f89540140d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - [[PR 885]](https://github.com/parthenon-hpc-lab/parthenon/pull/885) Expose PackDescriptor and use uids in SparsePacks ### Fixed (not changing behavior/API/variables/...) +- [[PR 928]](https://github.com/parthenon-hpc-lab/parthenon/pull/928) Fix boundary comms during refinement next to refined blocks - [[PR 933]](https://github.com/parthenon-hpc-lab/parthenon/pull/933) Remove extraneous debug check - [[PR 917]](https://github.com/parthenon-hpc-lab/parthenon/pull/917) Update Iterative Tasking Infrastructure - [[PR 890]](https://github.com/parthenon-hpc-lab/parthenon/pull/890) Fix bugs in sparse communication and prolongation From 9b197e843d5ef12c0a37c3a30e65a17c0c33215c Mon Sep 17 00:00:00 2001 From: Philipp Grete Date: Mon, 25 Sep 2023 17:31:04 +0200 Subject: [PATCH 06/18] Fix typo --- src/bvals/comms/boundary_communication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bvals/comms/boundary_communication.cpp b/src/bvals/comms/boundary_communication.cpp index 2deabe4ef81c..bee917ac32b8 100644 --- a/src/bvals/comms/boundary_communication.cpp +++ b/src/bvals/comms/boundary_communication.cpp @@ -143,7 +143,7 @@ template TaskStatus StartReceiveBoundBufs(std::shared_ptr> &md) { Kokkos::Profiling::pushRegion("Task_StartReceiveBoundBufs"); Mesh *pmesh = md->GetMeshPointer(); - auto &cache = md->GetBvarsCache().GetSubCache(BoundaryType::flxcor_send, false); + auto &cache = md->GetBvarsCache().GetSubCache(bound_type, false); if (cache.buf_vec.size() == 0) InitializeBufferCache(md, &(pmesh->boundary_comm_map), &cache, ReceiveKey, false); From fb2790bf205670c9d9b78ccf2d97372306e94372 Mon Sep 17 00:00:00 2001 From: jdolence Date: Thu, 28 Sep 2023 11:23:35 -0600 Subject: [PATCH 07/18] move sparse pack identifier to descriptor --- src/interface/sparse_pack_base.cpp | 55 ++++++++++++------------------ src/interface/sparse_pack_base.hpp | 25 ++++++++++---- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/interface/sparse_pack_base.cpp b/src/interface/sparse_pack_base.cpp index 6ddc77194fba..06f910472741 100644 --- a/src/interface/sparse_pack_base.cpp +++ b/src/interface/sparse_pack_base.cpp @@ -276,21 +276,28 @@ template SparsePackBase SparsePackBase::Build>(MeshData *, template SparsePackBase &SparsePackCache::Get(T *pmd, const PackDescriptor &desc, const std::vector &include_block) { - std::string ident = GetIdentifier(desc, include_block); - if (pack_map.count(ident) > 0) { - auto &pack = pack_map[ident].first; + if (pack_map.count(desc.identifier) > 0) { + auto &cache_tuple = pack_map[desc.identifier]; + auto &pack = std::get<0>(cache_tuple); auto alloc_status_in = SparsePackBase::GetAllocStatus(pmd, desc, include_block); - auto &alloc_status = pack_map[ident].second; + auto &alloc_status = std::get<1>(cache_tuple); if (alloc_status.size() != alloc_status_in.size()) - return BuildAndAdd(pmd, desc, ident, include_block); + return BuildAndAdd(pmd, desc, include_block); for (int i = 0; i < alloc_status_in.size(); ++i) { if (alloc_status[i] != alloc_status_in[i]) - return BuildAndAdd(pmd, desc, ident, include_block); + return BuildAndAdd(pmd, desc, include_block); + } + auto &include_status = std::get<2>(cache_tuple); + if (include_status.size() != include_block.size()) + return BuildAndAdd(pmd, desc, include_block); + for (int i = 0; i < include_block.size(); ++i) { + if (include_status[i] != include_block[i]) + return BuildAndAdd(pmd, desc, include_block); } // Cached version is not stale, so just return a reference to it - return pack_map[ident].first; + return std::get<0>(cache_tuple); } - return BuildAndAdd(pmd, desc, ident, include_block); + return BuildAndAdd(pmd, desc, include_block); } template SparsePackBase &SparsePackCache::Get>(MeshData *, const PackDescriptor &, @@ -301,37 +308,17 @@ SparsePackCache::Get>(MeshBlockData *, const PackDescr template SparsePackBase &SparsePackCache::BuildAndAdd(T *pmd, const PackDescriptor &desc, - const std::string &ident, const std::vector &include_block) { - if (pack_map.count(ident) > 0) pack_map.erase(ident); - pack_map[ident] = {SparsePackBase::Build(pmd, desc, include_block), - SparsePackBase::GetAllocStatus(pmd, desc, include_block)}; - return pack_map[ident].first; + if (pack_map.count(desc.identifier) > 0) pack_map.erase(desc.identifier); + pack_map[desc.identifier] = {SparsePackBase::Build(pmd, desc, include_block), + SparsePackBase::GetAllocStatus(pmd, desc, include_block), + include_block}; + return std::get<0>(pack_map[desc.identifier]); } template SparsePackBase & SparsePackCache::BuildAndAdd>(MeshData *, const PackDescriptor &, - const std::string &, const std::vector &); template SparsePackBase &SparsePackCache::BuildAndAdd>( - MeshBlockData *, const PackDescriptor &, const std::string &, - const std::vector &); - -std::string SparsePackCache::GetIdentifier(const PackDescriptor &desc, - const std::vector &include_block) const { - std::string identifier(""); - for (const auto &vgroup : desc.var_groups) { - for (const auto &[vid, uid] : vgroup) { - identifier += std::to_string(uid) + "_"; - } - identifier += "|"; - } - identifier += std::to_string(desc.with_fluxes); - identifier += std::to_string(desc.coarse); - identifier += std::to_string(desc.flat); - for (const auto b : include_block) { - identifier += std::to_string(b); - } - return identifier; -} + MeshBlockData *, const PackDescriptor &, const std::vector &); } // namespace parthenon diff --git a/src/interface/sparse_pack_base.hpp b/src/interface/sparse_pack_base.hpp index 7970d86f330a..780825b87aed 100644 --- a/src/interface/sparse_pack_base.hpp +++ b/src/interface/sparse_pack_base.hpp @@ -54,6 +54,7 @@ class SparsePackBase { friend class SparsePackCache; using alloc_t = std::vector; + using include_t = std::vector; using pack_t = ParArray3D>; using bounds_t = ParArray3D; using bounds_h_t = typename ParArray3D::HostMirror; @@ -114,12 +115,9 @@ class SparsePackCache { template SparsePackBase &BuildAndAdd(T *pmd, const impl::PackDescriptor &desc, - const std::string &ident, const std::vector &include_block); - std::string GetIdentifier(const impl::PackDescriptor &desc, - const std::vector &include_block) const; - std::unordered_map> + std::unordered_map> pack_map; friend class SparsePackBase; @@ -136,7 +134,7 @@ struct PackDescriptor { // default constructor needed for certain use cases PackDescriptor() : nvar_groups(0), var_group_names({}), var_groups({}), with_fluxes(false), - coarse(false), flat(false) {} + coarse(false), flat(false), identifier("") {} template PackDescriptor(StateDescriptor *psd, const std::vector &var_groups_in, @@ -144,7 +142,8 @@ struct PackDescriptor { : nvar_groups(var_groups_in.size()), var_group_names(MakeGroupNames(var_groups_in)), var_groups(BuildUids(var_groups_in.size(), psd, selector)), with_fluxes(options.count(PDOpt::WithFluxes)), - coarse(options.count(PDOpt::Coarse)), flat(options.count(PDOpt::Flatten)) { + coarse(options.count(PDOpt::Coarse)), flat(options.count(PDOpt::Flatten)), + identifier(GetIdentifier()) { PARTHENON_REQUIRE(!(with_fluxes && coarse), "Probably shouldn't be making a coarse pack with fine fluxes."); } @@ -155,8 +154,22 @@ struct PackDescriptor { const bool with_fluxes; const bool coarse; const bool flat; + const std::string identifier; private: + std::string GetIdentifier() { + std::string ident(""); + for (const auto &vgroup : var_groups) { + for (const auto &[vid, uid] : vgroup) { + ident += std::to_string(uid) + "_"; + } + ident += "|"; + } + ident += std::to_string(with_fluxes); + ident += std::to_string(coarse); + ident += std::to_string(flat); + return ident; + } template std::vector BuildUids(int nvgs, const StateDescriptor *const psd, const FUNC_t &selector) { From 4f428d3bf294e922d9b89cc02ad67d4f185138c8 Mon Sep 17 00:00:00 2001 From: jdolence Date: Thu, 28 Sep 2023 11:51:40 -0600 Subject: [PATCH 08/18] formatting --- src/interface/sparse_pack_base.cpp | 4 ++-- src/interface/sparse_pack_base.hpp | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/interface/sparse_pack_base.cpp b/src/interface/sparse_pack_base.cpp index 06f910472741..d370c0f5f734 100644 --- a/src/interface/sparse_pack_base.cpp +++ b/src/interface/sparse_pack_base.cpp @@ -311,8 +311,8 @@ SparsePackBase &SparsePackCache::BuildAndAdd(T *pmd, const PackDescriptor &desc, const std::vector &include_block) { if (pack_map.count(desc.identifier) > 0) pack_map.erase(desc.identifier); pack_map[desc.identifier] = {SparsePackBase::Build(pmd, desc, include_block), - SparsePackBase::GetAllocStatus(pmd, desc, include_block), - include_block}; + SparsePackBase::GetAllocStatus(pmd, desc, include_block), + include_block}; return std::get<0>(pack_map[desc.identifier]); } template SparsePackBase & diff --git a/src/interface/sparse_pack_base.hpp b/src/interface/sparse_pack_base.hpp index 780825b87aed..26a5f3fd7b61 100644 --- a/src/interface/sparse_pack_base.hpp +++ b/src/interface/sparse_pack_base.hpp @@ -117,7 +117,8 @@ class SparsePackCache { SparsePackBase &BuildAndAdd(T *pmd, const impl::PackDescriptor &desc, const std::vector &include_block); - std::unordered_map> + std::unordered_map> pack_map; friend class SparsePackBase; From 06868acde5a57b6b14b5cd122bae924e48a3393c Mon Sep 17 00:00:00 2001 From: jdolence Date: Thu, 28 Sep 2023 11:58:28 -0600 Subject: [PATCH 09/18] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f996c16fb20..d9ebb4347039 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ - [[PR 890]](https://github.com/parthenon-hpc-lab/parthenon/pull/890) Fix bugs in sparse communication and prolongation ### Infrastructure (changes irrelevant to downstream codes) +- [[PR 944]](https://github.com/parthenon-hpc-lab/parthenon/pull/944) Move sparse pack identifier creation to descriptor - [[PR 904]](https://github.com/parthenon-hpc-lab/parthenon/pull/904) Move to prolongation/restriction in one for AMR and communicate non-cell centered fields - [[PR 918]](https://github.com/parthenon-hpc-lab/parthenon/pull/918) Refactor RegionSize - [[PR 901]](https://github.com/parthenon-hpc-lab/parthenon/pull/901) Implement shared element ownership model From cd8db2ef277a0ab02fa84f71f21d3b8aaa7a1fd9 Mon Sep 17 00:00:00 2001 From: Patrick Mullen Date: Tue, 3 Oct 2023 11:49:25 -0600 Subject: [PATCH 10/18] Add missing ForceRemeshComm dependencies --- src/interface/variable.cpp | 9 ++++++--- src/mesh/mesh.cpp | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/interface/variable.cpp b/src/interface/variable.cpp index fd8b534c95e5..03baf6ffb570 100644 --- a/src/interface/variable.cpp +++ b/src/interface/variable.cpp @@ -81,7 +81,8 @@ void Variable::CopyFluxesAndBdryVar(const Variable *src) { } } - if (IsSet(Metadata::FillGhost) || IsSet(Metadata::Independent)) { + if (IsSet(Metadata::FillGhost) || IsSet(Metadata::Independent) || + IsSet(Metadata::ForceRemeshComm)) { // no need to check mesh->multilevel, if false, we're just making a shallow copy of // an empty ParArrayND coarse_s = src->coarse_s; @@ -172,7 +173,8 @@ void Variable::AllocateFluxesAndCoarse(std::weak_ptr wpmb) { } // Create the boundary object - if (IsSet(Metadata::FillGhost) || IsSet(Metadata::Independent)) { + if (IsSet(Metadata::FillGhost) || IsSet(Metadata::Independent) || + IsSet(Metadata::ForceRemeshComm)) { if (wpmb.expired()) return; std::shared_ptr pmb = wpmb.lock(); @@ -205,7 +207,8 @@ std::int64_t Variable::Deallocate() { } } - if (IsSet(Metadata::FillGhost) || IsSet(Metadata::Independent)) { + if (IsSet(Metadata::FillGhost) || IsSet(Metadata::Independent) || + IsSet(Metadata::ForceRemeshComm)) { mem_size += coarse_s.size() * sizeof(T); coarse_s.Reset(); } diff --git a/src/mesh/mesh.cpp b/src/mesh/mesh.cpp index 32f4d1b3245a..4197c4158b2f 100644 --- a/src/mesh/mesh.cpp +++ b/src/mesh/mesh.cpp @@ -1272,7 +1272,8 @@ void Mesh::SetupMPIComms() { auto &metadata = pair.second; // Create both boundary and flux communicators for everything with either FillGhost // or WithFluxes just to be safe - if (metadata.IsSet(Metadata::FillGhost) || metadata.IsSet(Metadata::WithFluxes)) { + if (metadata.IsSet(Metadata::FillGhost) || metadata.IsSet(Metadata::WithFluxes) || + IsSet(Metadata::ForceRemeshComm)) { MPI_Comm mpi_comm; PARTHENON_MPI_CHECK(MPI_Comm_dup(MPI_COMM_WORLD, &mpi_comm)); const auto ret = mpi_comm_map_.insert({pair.first.label(), mpi_comm}); From 3fcf407ddc8a85c9610338be6331cd52d9677a47 Mon Sep 17 00:00:00 2001 From: Patrick Mullen Date: Tue, 3 Oct 2023 11:57:37 -0600 Subject: [PATCH 11/18] Update Changelog and copyrights --- CHANGELOG.md | 3 ++- src/interface/variable.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f74ad17ac4c..221df3353602 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - [[PR 885]](https://github.com/parthenon-hpc-lab/parthenon/pull/885) Expose PackDescriptor and use uids in SparsePacks ### Fixed (not changing behavior/API/variables/...) +- [[PR 946]](https://github.com/parthenon-hpc-lab/parthenon/pull/928) Add missing ForceRemeshComm dependencies - [[PR 928]](https://github.com/parthenon-hpc-lab/parthenon/pull/928) Fix boundary comms during refinement next to refined blocks - [[PR 937]](https://github.com/parthenon-hpc-lab/parthenon/pull/937) Fix multiple line continuations - [[PR 933]](https://github.com/parthenon-hpc-lab/parthenon/pull/933) Remove extraneous debug check @@ -34,7 +35,7 @@ ### Infrastructure (changes irrelevant to downstream codes) - [[PR 944]](https://github.com/parthenon-hpc-lab/parthenon/pull/944) Move sparse pack identifier creation to descriptor - [[PR 904]](https://github.com/parthenon-hpc-lab/parthenon/pull/904) Move to prolongation/restriction in one for AMR and communicate non-cell centered fields -- [[PR 918]](https://github.com/parthenon-hpc-lab/parthenon/pull/918) Refactor RegionSize +- [[PR 918]](https://github.com/parthenon-hpc-lab/parthenon/pull/918) Refactor RegionSize - [[PR 901]](https://github.com/parthenon-hpc-lab/parthenon/pull/901) Implement shared element ownership model ### Removed (removing behavior/API/varaibles/...) diff --git a/src/interface/variable.cpp b/src/interface/variable.cpp index 03baf6ffb570..ce62354f0631 100644 --- a/src/interface/variable.cpp +++ b/src/interface/variable.cpp @@ -1,5 +1,5 @@ //======================================================================================== -// (C) (or copyright) 2020-2022. Triad National Security, LLC. All rights reserved. +// (C) (or copyright) 2020-2023. Triad National Security, LLC. All rights reserved. // // This program was produced under U.S. Government contract 89233218CNA000001 for Los // Alamos National Laboratory (LANL), which is operated by Triad National Security, LLC From f86e01f05367bb95a851396481db1415c54acc1b Mon Sep 17 00:00:00 2001 From: Patrick Mullen Date: Tue, 3 Oct 2023 11:59:08 -0600 Subject: [PATCH 12/18] Fix changelog edits --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 221df3353602..1a1421f9e3cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ - [[PR 885]](https://github.com/parthenon-hpc-lab/parthenon/pull/885) Expose PackDescriptor and use uids in SparsePacks ### Fixed (not changing behavior/API/variables/...) -- [[PR 946]](https://github.com/parthenon-hpc-lab/parthenon/pull/928) Add missing ForceRemeshComm dependencies +- [[PR 947]](https://github.com/parthenon-hpc-lab/parthenon/pull/947) Add missing ForceRemeshComm dependencies - [[PR 928]](https://github.com/parthenon-hpc-lab/parthenon/pull/928) Fix boundary comms during refinement next to refined blocks - [[PR 937]](https://github.com/parthenon-hpc-lab/parthenon/pull/937) Fix multiple line continuations - [[PR 933]](https://github.com/parthenon-hpc-lab/parthenon/pull/933) Remove extraneous debug check From e031760308c132218fb0d41471a1ace50e051c6b Mon Sep 17 00:00:00 2001 From: Patrick Mullen Date: Tue, 3 Oct 2023 13:08:55 -0600 Subject: [PATCH 13/18] Attempt to fix failing CI pipelines --- src/mesh/mesh.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mesh/mesh.cpp b/src/mesh/mesh.cpp index 4197c4158b2f..ed81e3e4e219 100644 --- a/src/mesh/mesh.cpp +++ b/src/mesh/mesh.cpp @@ -1273,7 +1273,7 @@ void Mesh::SetupMPIComms() { // Create both boundary and flux communicators for everything with either FillGhost // or WithFluxes just to be safe if (metadata.IsSet(Metadata::FillGhost) || metadata.IsSet(Metadata::WithFluxes) || - IsSet(Metadata::ForceRemeshComm)) { + metadata.IsSet(Metadata::ForceRemeshComm)) { MPI_Comm mpi_comm; PARTHENON_MPI_CHECK(MPI_Comm_dup(MPI_COMM_WORLD, &mpi_comm)); const auto ret = mpi_comm_map_.insert({pair.first.label(), mpi_comm}); From 58c33a49935728537a70860e23702d500ced5451 Mon Sep 17 00:00:00 2001 From: Luke Roberts Date: Thu, 5 Oct 2023 11:13:20 -0600 Subject: [PATCH 14/18] Update example/poisson_gmg/parthenon_app_inputs.cpp --- example/poisson_gmg/parthenon_app_inputs.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/example/poisson_gmg/parthenon_app_inputs.cpp b/example/poisson_gmg/parthenon_app_inputs.cpp index 3cf7da0ec9f3..54515d562cf3 100644 --- a/example/poisson_gmg/parthenon_app_inputs.cpp +++ b/example/poisson_gmg/parthenon_app_inputs.cpp @@ -74,13 +74,6 @@ void ProblemGenerator(Mesh *pm, ParameterInput *pin, MeshData *md) { if (rad < radius0) { val = 1.0; // / (4.0 / 3.0 * M_PI * std::pow(rad, 3)); } - // val = 1.0 * exp(-rad * 10.0 * rad * 10.0); - // val = std::sin(2.0 * M_PI * x1); - // if (ndim > 1) val *= std::sin(2.0 * M_PI * x2); - // if (ndim > 2) val *= std::sin(2.0 * M_PI * x3); - // val = 2.0 * (1.0 - 6.0 * x1 * x1) * x2 * x2 * (1.0 - x2 * x2) + 2.0 * (1.0 - //- 6.0 * x2 * x2) * x1 * x1 * (1.0 - x1 * x1); - // val = 0.0; pack(b, te, poisson_package::rhs(), k, j, i) = val; pack(b, te, poisson_package::res_err(), k, j, i) = 0.0; // + x2; pack(b, te, poisson_package::u(), k, j, i) = 0.0; // + x2; From e3556b9d1f1cb97bc245b1666737f76c47959e2a Mon Sep 17 00:00:00 2001 From: Luke Roberts Date: Thu, 5 Oct 2023 11:13:35 -0600 Subject: [PATCH 15/18] Update example/poisson_gmg/parthenon_app_inputs.cpp --- example/poisson_gmg/parthenon_app_inputs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/poisson_gmg/parthenon_app_inputs.cpp b/example/poisson_gmg/parthenon_app_inputs.cpp index 54515d562cf3..65d361e3144d 100644 --- a/example/poisson_gmg/parthenon_app_inputs.cpp +++ b/example/poisson_gmg/parthenon_app_inputs.cpp @@ -75,8 +75,8 @@ void ProblemGenerator(Mesh *pm, ParameterInput *pin, MeshData *md) { val = 1.0; // / (4.0 / 3.0 * M_PI * std::pow(rad, 3)); } pack(b, te, poisson_package::rhs(), k, j, i) = val; - pack(b, te, poisson_package::res_err(), k, j, i) = 0.0; // + x2; - pack(b, te, poisson_package::u(), k, j, i) = 0.0; // + x2; + pack(b, te, poisson_package::res_err(), k, j, i) = 0.0; + pack(b, te, poisson_package::u(), k, j, i) = 0.0; pack(b, te, poisson_package::exact(), k, j, i) = -exp(-10.0 * rad * rad); auto inside_region = [ndim](Real x, Real y, Real z) { From a49ee344d204adf68124be242da8f85823540aef Mon Sep 17 00:00:00 2001 From: Luke Roberts Date: Thu, 5 Oct 2023 11:13:55 -0600 Subject: [PATCH 16/18] Update doc/sphinx/src/mesh/mesh.rst --- doc/sphinx/src/mesh/mesh.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx/src/mesh/mesh.rst b/doc/sphinx/src/mesh/mesh.rst index 0301c9cc7ffe..70a2b934b799 100644 --- a/doc/sphinx/src/mesh/mesh.rst +++ b/doc/sphinx/src/mesh/mesh.rst @@ -66,7 +66,7 @@ level that are neighbors to finer blocks, which implies that below the root grid level the blocks may not cover the entire mesh. For levels above the root grid, blocks may change shape so that they only cover the domain of the root grid. Note that leaf blocks may be contained in multiple blocklists, and the lists all point -to the same block (not a separate copy). +to the same block (not a separate copy). To be explicit, when ``parthenon/mesh/multigrid`` is set to ``true`` blocks corresponding to *all* internal nodes of the refinement tree are created, in addition to the leaf node blocks that are normally created. *GMG Implementation Note:* The reason for including two levels in the GMG block lists is for dealing with From e2a712c8557280081d7c9decd63430192ecb4871 Mon Sep 17 00:00:00 2001 From: Luke Roberts Date: Thu, 5 Oct 2023 11:14:11 -0600 Subject: [PATCH 17/18] Update doc/sphinx/src/mesh/mesh.rst --- doc/sphinx/src/mesh/mesh.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx/src/mesh/mesh.rst b/doc/sphinx/src/mesh/mesh.rst index 70a2b934b799..1c046bc14c87 100644 --- a/doc/sphinx/src/mesh/mesh.rst +++ b/doc/sphinx/src/mesh/mesh.rst @@ -85,7 +85,7 @@ To work with these GMG levels, ``MeshData`` objects containing these blocks can be recovered from a ``Mesh`` pointer using .. code:: c++ - auto &md = pmesh->gmg_mesh_data[level].GetOrAdd(level, "base", i); + auto &md = pmesh->gmg_mesh_data[level].GetOrAdd(level, "base", partition_idx); This ``MeshData`` will include blocks at the current level and possibly some blocks at the next coarser level. Often, one will only want to operate on blocks From 13135b3747518811311fb05fb68faf3b431e0429 Mon Sep 17 00:00:00 2001 From: Luke Roberts Date: Thu, 5 Oct 2023 13:09:15 -0600 Subject: [PATCH 18/18] format --- src/bvals/bvals_base.cpp | 4 ++-- src/mesh/amr_loadbalance.cpp | 3 ++- src/mesh/mesh-gmg.cpp | 11 ++++++----- src/mesh/mesh.hpp | 9 +++++---- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/bvals/bvals_base.cpp b/src/bvals/bvals_base.cpp index 12e0df7279d1..7c43c4917197 100644 --- a/src/bvals/bvals_base.cpp +++ b/src/bvals/bvals_base.cpp @@ -334,8 +334,8 @@ int BoundaryBase::CreateBvalsMPITag(int lid, int bufid) { // TODO(felker): break-up this long function -void BoundaryBase::SearchAndSetNeighbors(Mesh *mesh, - MeshBlockTree &tree, int *ranklist, int *nslist, +void BoundaryBase::SearchAndSetNeighbors( + Mesh *mesh, MeshBlockTree &tree, int *ranklist, int *nslist, const std::unordered_set &newly_refined) { Kokkos::Profiling::pushRegion("SearchAndSetNeighbors"); MeshBlockTree *neibt; diff --git a/src/mesh/amr_loadbalance.cpp b/src/mesh/amr_loadbalance.cpp index 5c921a840121..c8b18dab8314 100644 --- a/src/mesh/amr_loadbalance.cpp +++ b/src/mesh/amr_loadbalance.cpp @@ -953,7 +953,8 @@ void Mesh::RedistributeAndRefineMeshBlocks(ParameterInput *pin, ApplicationInput #endif // Re-initialize the mesh with our temporary ownership/neighbor configurations. // No buffers are different when we switch to the final precedence order. - SetSameLevelNeighbors(block_list, leaf_grid_locs, this->GetRootGridInfo(), nbs, false, 0, newly_refined); + SetSameLevelNeighbors(block_list, leaf_grid_locs, this->GetRootGridInfo(), nbs, false, + 0, newly_refined); BuildGMGHierarchy(nbs, pin, app_in); Initialize(false, pin, app_in); diff --git a/src/mesh/mesh-gmg.cpp b/src/mesh/mesh-gmg.cpp index 0417231f110a..8b025776ff39 100644 --- a/src/mesh/mesh-gmg.cpp +++ b/src/mesh/mesh-gmg.cpp @@ -51,10 +51,10 @@ void Mesh::PopulateLeafLocationMap() { } } -void Mesh::SetSameLevelNeighbors(BlockList_t &block_list, const LogicalLocMap_t &loc_map, - RootGridInfo root_grid, int nbs, bool gmg_neighbors, - int composite_logical_level, - const std::unordered_set &newly_refined) { +void Mesh::SetSameLevelNeighbors( + BlockList_t &block_list, const LogicalLocMap_t &loc_map, RootGridInfo root_grid, + int nbs, bool gmg_neighbors, int composite_logical_level, + const std::unordered_set &newly_refined) { for (auto &pmb : block_list) { auto loc = pmb->loc; auto gid = pmb->gid; @@ -109,7 +109,8 @@ void Mesh::SetSameLevelNeighbors(BlockList_t &block_list, const LogicalLocMap_t for (auto &nb : *neighbor_list) allowed_neighbors.insert(nb.loc); for (auto &nb : *neighbor_list) { - nb.ownership = DetermineOwnership(nb.loc, allowed_neighbors, root_grid, newly_refined); + nb.ownership = + DetermineOwnership(nb.loc, allowed_neighbors, root_grid, newly_refined); nb.ownership.initialized = true; } } diff --git a/src/mesh/mesh.hpp b/src/mesh/mesh.hpp index 6b1e8bcf3fe4..a27044db8559 100644 --- a/src/mesh/mesh.hpp +++ b/src/mesh/mesh.hpp @@ -289,10 +289,11 @@ class Mesh { void RedistributeAndRefineMeshBlocks(ParameterInput *pin, ApplicationInput *app_in, int ntot); void BuildGMGHierarchy(int nbs, ParameterInput *pin, ApplicationInput *app_in); - void SetSameLevelNeighbors(BlockList_t &block_list, const LogicalLocMap_t &loc_map, - RootGridInfo root_grid, int nbs, bool gmg_neighbors, - int composite_logical_level = 0, - const std::unordered_set &newly_refined = {}); + void + SetSameLevelNeighbors(BlockList_t &block_list, const LogicalLocMap_t &loc_map, + RootGridInfo root_grid, int nbs, bool gmg_neighbors, + int composite_logical_level = 0, + const std::unordered_set &newly_refined = {}); // defined in either the prob file or default_pgen.cpp in ../pgen/ static void InitUserMeshDataDefault(Mesh *mesh, ParameterInput *pin); std::function InitUserMeshData =