From 07e8d678bace346848582dd04d4bf23e2dd89d78 Mon Sep 17 00:00:00 2001 From: Guo-astro Date: Fri, 23 Jan 2026 20:13:23 +0900 Subject: [PATCH 1/2] [GSPH] migrate ghost_cache to solvergraph Add GhostCacheEdge for ghost interface cache management via solvergraph. Changes: - Add GhostCacheEdge.hpp for GSPH ghost cache edge - Add solver_graph and ghost_cache edge to SolverStorage - Register edge in init_solver_graph() - Update build_ghost_cache() to use solvergraph edge - Update clear_ghost_cache() to use free_alloc() - Update all ghost_cache usages to solvergraph pattern Part of GSPH solvergraph migration (1 object per PR). --- .../shammodels/gsph/modules/SolverStorage.hpp | 19 ++++- .../gsph/solvergraph/GhostCacheEdge.hpp | 82 +++++++++++++++++++ src/shammodels/gsph/src/Solver.cpp | 26 +++--- 3 files changed, 116 insertions(+), 11 deletions(-) create mode 100644 src/shammodels/gsph/include/shammodels/gsph/solvergraph/GhostCacheEdge.hpp diff --git a/src/shammodels/gsph/include/shammodels/gsph/modules/SolverStorage.hpp b/src/shammodels/gsph/include/shammodels/gsph/modules/SolverStorage.hpp index 118dadc45..c1217ebba 100644 --- a/src/shammodels/gsph/include/shammodels/gsph/modules/SolverStorage.hpp +++ b/src/shammodels/gsph/include/shammodels/gsph/modules/SolverStorage.hpp @@ -35,7 +35,11 @@ #include "shamrock/solvergraph/FieldRefs.hpp" #include "shamrock/solvergraph/Indexes.hpp" #include "shamrock/solvergraph/ScalarsEdge.hpp" +#include "shamrock/solvergraph/SolverGraph.hpp" #include "shamsys/legacy/log.hpp" + +// GSPH solvergraph edges +#include "shammodels/gsph/solvergraph/GhostCacheEdge.hpp" #include "shamtree/CompressedLeafBVH.hpp" #include "shamtree/KarrasRadixTreeField.hpp" #include "shamtree/RadixTree.hpp" @@ -70,6 +74,17 @@ namespace shammodels::gsph { using RTree = shamtree::CompressedLeafBVH; + // ===================================================================== + // SolverGraph infrastructure + // ===================================================================== + + /// Central graph for managing edges (data) and nodes (operations) + shamrock::solvergraph::SolverGraph solver_graph; + + // ===================================================================== + // SolverGraph edges + // ===================================================================== + /// Particle counts per patch std::shared_ptr> part_counts; std::shared_ptr> part_counts_with_ghost; @@ -89,7 +104,9 @@ namespace shammodels::gsph { /// Ghost handler for boundary particles Component ghost_handler; - Component ghost_patch_cache; + + /// Ghost interface cache - managed via SolverGraph + std::shared_ptr> ghost_cache; /// Merged position-h data for neighbor search Component> merged_xyzh; diff --git a/src/shammodels/gsph/include/shammodels/gsph/solvergraph/GhostCacheEdge.hpp b/src/shammodels/gsph/include/shammodels/gsph/solvergraph/GhostCacheEdge.hpp new file mode 100644 index 000000000..ad563cffd --- /dev/null +++ b/src/shammodels/gsph/include/shammodels/gsph/solvergraph/GhostCacheEdge.hpp @@ -0,0 +1,82 @@ +// -------------------------------------------------------// +// +// SHAMROCK code for hydrodynamics +// Copyright (c) 2021-2026 Timothée David--Cléris +// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1 +// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information +// +// -------------------------------------------------------// + +#pragma once + +/** + * @file GhostCacheEdge.hpp + * @author Guo Yansong (guo.yansong.ngy@gmail.com) + * @brief SolverGraph edge for GSPH ghost cache + */ + +#include "shambase/memory.hpp" +#include "shammodels/gsph/modules/GSPHGhostHandler.hpp" +#include "shamrock/solvergraph/IEdgeNamed.hpp" +#include + +namespace shammodels::gsph::solvergraph { + + /** + * @brief SolverGraph edge wrapping the ghost interface cache + * + * This edge stores the cache map used for ghost particle communication. + * The cache is built per timestep based on the current particle distribution + * and freed after the force computation. + * + * @tparam Tvec Vector type (e.g., f64_3) + */ + template + class GhostCacheEdge : public shamrock::solvergraph::IEdgeNamed { + public: + using IEdgeNamed::IEdgeNamed; + using GhostHandle = GSPHGhostHandler; + using CacheMap = typename GhostHandle::CacheMap; + + std::optional cache; + + /** + * @brief Get the ghost cache + * @throws std::runtime_error if cache is not set + */ + CacheMap &get() { + if (!cache.has_value()) { + shambase::throw_with_loc("GhostCache not set"); + } + return cache.value(); + } + + /** + * @brief Get the ghost cache (const) + * @throws std::runtime_error if cache is not set + */ + const CacheMap &get() const { + if (!cache.has_value()) { + shambase::throw_with_loc("GhostCache not set"); + } + return cache.value(); + } + + /** + * @brief Check if the cache is set + */ + bool has_value() const { return cache.has_value(); } + + /** + * @brief Set the ghost cache + * @param c The cache map to store + */ + void set(CacheMap &&c) { cache = std::move(c); } + + /** + * @brief Free the allocated cache + */ + inline virtual void free_alloc() override { cache.reset(); } + }; + +} // namespace shammodels::gsph::solvergraph diff --git a/src/shammodels/gsph/src/Solver.cpp b/src/shammodels/gsph/src/Solver.cpp index 6ff34dbc3..283aad2e4 100644 --- a/src/shammodels/gsph/src/Solver.cpp +++ b/src/shammodels/gsph/src/Solver.cpp @@ -87,6 +87,11 @@ void shammodels::gsph::Solver::init_solver_graph() { storage.neigh_cache = std::make_shared(edges::neigh_cache, "neigh"); + // Register ghost cache edge for dependency tracking + storage.ghost_cache = storage.solver_graph.register_edge( + "ghost_cache", + solvergraph::GhostCacheEdge("ghost_cache", "\\mathcal{C}_{\\rm ghost}")); + storage.omega = std::make_shared>(1, "omega", "\\Omega"); storage.density = std::make_shared>(1, "density", "\\rho"); storage.pressure = std::make_shared>(1, "pressure", "P"); @@ -174,24 +179,25 @@ void shammodels::gsph::Solver::build_ghost_cache() { using GSPHUtils = GSPHUtilities; GSPHUtils gsph_utils(scheduler()); - storage.ghost_patch_cache.set(gsph_utils.build_interf_cache( - storage.ghost_handler.get(), - storage.serial_patch_tree.get(), - solver_config.htol_up_coarse_cycle)); + shambase::get_check_ref(storage.ghost_cache) + .set(gsph_utils.build_interf_cache( + storage.ghost_handler.get(), + storage.serial_patch_tree.get(), + solver_config.htol_up_coarse_cycle)); } template class Kern> void shammodels::gsph::Solver::clear_ghost_cache() { StackEntry stack_loc{}; - storage.ghost_patch_cache.reset(); + shambase::get_check_ref(storage.ghost_cache).free_alloc(); } template class Kern> void shammodels::gsph::Solver::merge_position_ghost() { StackEntry stack_loc{}; - storage.merged_xyzh.set( - storage.ghost_handler.get().build_comm_merge_positions(storage.ghost_patch_cache.get())); + storage.merged_xyzh.set(storage.ghost_handler.get().build_comm_merge_positions( + shambase::get_check_ref(storage.ghost_cache).get())); // Get field indices from xyzh_ghost_layout const u32 ixyz_ghost @@ -683,7 +689,7 @@ void shammodels::gsph::Solver::communicate_merge_ghosts_fields() { // Build interface data from ghost cache auto pdat_interf = ghost_handle.template build_interface_native( - storage.ghost_patch_cache.get(), + shambase::get_check_ref(storage.ghost_cache).get(), [&](u64 sender, u64, InterfaceBuildInfos binfo, sham::DeviceBuffer &buf_idx, u32 cnt) { PatchDataLayer pdat(ghost_layout_ptr); pdat.reserve(cnt); @@ -692,7 +698,7 @@ void shammodels::gsph::Solver::communicate_merge_ghosts_fields() { // Populate interface data with field values ghost_handle.template modify_interface_native( - storage.ghost_patch_cache.get(), + shambase::get_check_ref(storage.ghost_cache).get(), pdat_interf, [&](u64 sender, u64, @@ -733,7 +739,7 @@ void shammodels::gsph::Solver::communicate_merge_ghosts_fields() { // Apply velocity offset for periodic boundaries ghost_handle.template modify_interface_native( - storage.ghost_patch_cache.get(), + shambase::get_check_ref(storage.ghost_cache).get(), pdat_interf, [&](u64 sender, u64, From aa01f393bb0a710834d2af4178d4c52eddb59b0c Mon Sep 17 00:00:00 2001 From: Guo-astro Date: Sun, 25 Jan 2026 09:14:01 +0900 Subject: [PATCH 2/2] Remove gratuitous doc changes per maintainer feedback --- .../shammodels/gsph/modules/SolverStorage.hpp | 9 ------ .../gsph/solvergraph/GhostCacheEdge.hpp | 30 +------------------ 2 files changed, 1 insertion(+), 38 deletions(-) diff --git a/src/shammodels/gsph/include/shammodels/gsph/modules/SolverStorage.hpp b/src/shammodels/gsph/include/shammodels/gsph/modules/SolverStorage.hpp index c1217ebba..e55df8709 100644 --- a/src/shammodels/gsph/include/shammodels/gsph/modules/SolverStorage.hpp +++ b/src/shammodels/gsph/include/shammodels/gsph/modules/SolverStorage.hpp @@ -74,17 +74,8 @@ namespace shammodels::gsph { using RTree = shamtree::CompressedLeafBVH; - // ===================================================================== - // SolverGraph infrastructure - // ===================================================================== - - /// Central graph for managing edges (data) and nodes (operations) shamrock::solvergraph::SolverGraph solver_graph; - // ===================================================================== - // SolverGraph edges - // ===================================================================== - /// Particle counts per patch std::shared_ptr> part_counts; std::shared_ptr> part_counts_with_ghost; diff --git a/src/shammodels/gsph/include/shammodels/gsph/solvergraph/GhostCacheEdge.hpp b/src/shammodels/gsph/include/shammodels/gsph/solvergraph/GhostCacheEdge.hpp index ad563cffd..a0206dd43 100644 --- a/src/shammodels/gsph/include/shammodels/gsph/solvergraph/GhostCacheEdge.hpp +++ b/src/shammodels/gsph/include/shammodels/gsph/solvergraph/GhostCacheEdge.hpp @@ -22,15 +22,7 @@ namespace shammodels::gsph::solvergraph { - /** - * @brief SolverGraph edge wrapping the ghost interface cache - * - * This edge stores the cache map used for ghost particle communication. - * The cache is built per timestep based on the current particle distribution - * and freed after the force computation. - * - * @tparam Tvec Vector type (e.g., f64_3) - */ + /// SolverGraph edge for ghost interface cache template class GhostCacheEdge : public shamrock::solvergraph::IEdgeNamed { public: @@ -40,10 +32,6 @@ namespace shammodels::gsph::solvergraph { std::optional cache; - /** - * @brief Get the ghost cache - * @throws std::runtime_error if cache is not set - */ CacheMap &get() { if (!cache.has_value()) { shambase::throw_with_loc("GhostCache not set"); @@ -51,10 +39,6 @@ namespace shammodels::gsph::solvergraph { return cache.value(); } - /** - * @brief Get the ghost cache (const) - * @throws std::runtime_error if cache is not set - */ const CacheMap &get() const { if (!cache.has_value()) { shambase::throw_with_loc("GhostCache not set"); @@ -62,20 +46,8 @@ namespace shammodels::gsph::solvergraph { return cache.value(); } - /** - * @brief Check if the cache is set - */ bool has_value() const { return cache.has_value(); } - - /** - * @brief Set the ghost cache - * @param c The cache map to store - */ void set(CacheMap &&c) { cache = std::move(c); } - - /** - * @brief Free the allocated cache - */ inline virtual void free_alloc() override { cache.reset(); } };