Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
GSPHGhostHandler.hpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
10#pragma once
11
21#include "shambackends/vec.hpp"
33#include <utility>
34#include <variant>
35
36namespace shammodels::gsph {
37
38 template<class vec>
40
41 using Tscal = shambase::VecComponent<vec>;
42
43 struct Free {};
44 struct Periodic {};
46 i32_3 shear_base;
47 i32_3 shear_dir;
48 Tscal shear_value;
49 Tscal shear_speed;
50 };
51
52 using Variant = std::variant<Free, Periodic, ShearingPeriodic>;
53 };
54
55 template<class vec>
57
59 using Config = typename CfgClass::Variant;
60
61 PatchScheduler &sched;
62 Config ghost_config;
63
64 public:
65 using flt = shambase::VecComponent<vec>;
67 using per_index = sycl::vec<i32, dim>;
68
70 vec offset;
71 vec offset_speed;
72 per_index periodicity_index;
74 flt volume_ratio;
75 };
76
78 InterfaceBuildInfos build_infos;
79 sham::DeviceBuffer<u32> ids_interf;
80 f64 part_cnt_ratio;
81 };
82
84
85 std::shared_ptr<shamrock::patch::PatchDataLayerLayout> &xyzh_ghost_layout;
86
87 std::shared_ptr<shamrock::solvergraph::RankGetter> patch_rank_owner;
88
90 PatchScheduler &sched,
91 Config ghost_config,
92 std::shared_ptr<shamrock::solvergraph::RankGetter> patch_rank_owner,
93 std::shared_ptr<shamrock::patch::PatchDataLayerLayout> &xyzh_ghost_layout)
94 : sched(sched), ghost_config(ghost_config),
95 patch_rank_owner(std::move(patch_rank_owner)), xyzh_ghost_layout(xyzh_ghost_layout) {}
96
97 GeneratorMap find_interfaces(
99 shamrock::patch::PatchtreeField<flt> &int_range_max_tree,
100 shamrock::patch::PatchField<flt> &int_range_max);
101
103 GeneratorMap &&gen);
104
105 void gen_debug_patch_ghost(shambase::DistributedDataShared<InterfaceIdTable> &interf_info);
106
108
109 CacheMap make_interface_cache(
110 SerialPatchTree<vec> &sptree,
111 shamrock::patch::PatchtreeField<flt> &int_range_max_tree,
112 shamrock::patch::PatchField<flt> &int_range_max) {
113 StackEntry stack_loc{};
114
115 return gen_id_table_interfaces(
116 find_interfaces(sptree, int_range_max_tree, int_range_max));
117 }
118
119 template<class T>
120 shambase::DistributedDataShared<T> build_interface_native(
122 std::function<T(u64, u64, InterfaceBuildInfos, sham::DeviceBuffer<u32> &, u32)> fct) {
123 StackEntry stack_loc{};
124
125 return builder.template map<T>([&](u64 sender,
126 u64 receiver,
127 InterfaceIdTable &build_table) {
128 if (build_table.ids_interf.get_size() == 0) {
129 throw shambase::make_except_with_loc<std::runtime_error>(
130 "there is an empty id table in the interface, it should have been removed");
131 }
132
133 return fct(
134 sender,
135 receiver,
136 build_table.build_infos,
137 build_table.ids_interf,
138 build_table.ids_interf.get_size());
139 });
140 }
141
142 template<class T>
143 void modify_interface_native(
146 std::function<void(u64, u64, InterfaceBuildInfos, sham::DeviceBuffer<u32> &, u32, T &)>
147 fct) {
148 StackEntry stack_loc{};
149
150 struct Args {
151 u64 sender;
152 u64 receiver;
153 InterfaceIdTable &build_table;
154 };
155
156 std::vector<Args> vecarg;
157
158 builder.for_each([&](u64 sender, u64 receiver, InterfaceIdTable &build_table) {
159 if (build_table.ids_interf.get_size() == 0) {
160 throw shambase::make_except_with_loc<std::runtime_error>(
161 "there is an empty id table in the interface, it should have been removed");
162 }
163
164 vecarg.push_back({sender, receiver, build_table});
165 });
166
167 u32 i = 0;
168 mod.for_each([&](u64 sender, u64 receiver, T &ref) {
169 InterfaceIdTable &build_table = vecarg[i].build_table;
170
171 fct(sender,
172 receiver,
173 build_table.build_infos,
174 build_table.ids_interf,
175 build_table.ids_interf.get_size(),
176 ref);
177
178 i++;
179 });
180 }
181
183 // interface generation/communication utility //////////////////////////////////////////////
185
187 build_position_interf_field(shambase::DistributedDataShared<InterfaceIdTable> &builder) {
188 StackEntry stack_loc{};
189
190 const u32 ixyz = sched.pdl_old().template get_field_idx<vec>("xyz");
191 const u32 ihpart = sched.pdl_old().template get_field_idx<flt>("hpart");
192
193 // Get field indices from xyzh_ghost_layout for accessing ghost data
194 const u32 ixyz_ghost = xyzh_ghost_layout->template get_field_idx<vec>("xyz");
195 const u32 ihpart_ghost = xyzh_ghost_layout->template get_field_idx<flt>("hpart");
196
197 return build_interface_native<shamrock::patch::PatchDataLayer>(
198 builder,
199 [&, ixyz_ghost, ihpart_ghost](
200 u64 sender,
201 u64 /*receiver*/,
202 InterfaceBuildInfos binfo,
204 u32 cnt) {
205 using namespace shamrock::patch;
206
207 PatchDataLayer &sender_pdat = sched.patch_data.get_pdat(sender);
208
209 shamrock::patch::PatchDataLayer ret(xyzh_ghost_layout);
210
211 sender_pdat.get_field<vec>(ixyz).append_subset_to(
212 buf_idx, cnt, ret.get_field<vec>(ixyz_ghost));
213 sender_pdat.get_field<flt>(ihpart).append_subset_to(
214 buf_idx, cnt, ret.get_field<flt>(ihpart_ghost));
215
216 ret.get_field<vec>(ixyz_ghost).apply_offset(binfo.offset);
217
218 return ret;
219 });
220 }
221
223 const std::shared_ptr<shamrock::patch::PatchDataLayerLayout> &pdl_ptr,
225 StackEntry stack_loc{};
226
227 std::shared_ptr<shamrock::solvergraph::PatchDataLayerDDShared> exchange_gz_edge
228 = std::make_shared<shamrock::solvergraph::PatchDataLayerDDShared>("", "");
229
230 exchange_gz_edge->patchdatas
231 = std::forward<shambase::DistributedDataShared<shamrock::patch::PatchDataLayer>>(
232 interf);
233
234 std::shared_ptr<shamrock::solvergraph::ExchangeGhostLayer> exchange_gz_node
235 = std::make_shared<shamrock::solvergraph::ExchangeGhostLayer>(pdl_ptr);
236 exchange_gz_node->set_edges(this->patch_rank_owner, exchange_gz_edge);
237
238 exchange_gz_node->evaluate();
239
241 recv_dat = std::move(exchange_gz_edge->patchdatas);
242
243 return recv_dat;
244 }
245
246 template<class T>
247 inline shambase::DistributedDataShared<PatchDataField<T>> communicate_pdatfield(
249 StackEntry stack_loc{};
250
251 std::shared_ptr<shamrock::solvergraph::PatchDataFieldDDShared<T>> exchange_gz_edge
252 = std::make_shared<shamrock::solvergraph::PatchDataFieldDDShared<T>>("", "");
253
254 exchange_gz_edge->patchdata_fields
255 = std::forward<shambase::DistributedDataShared<PatchDataField<T>>>(interf);
256
257 std::shared_ptr<shamrock::solvergraph::ExchangeGhostField<T>> exchange_gz_node
258 = std::make_shared<shamrock::solvergraph::ExchangeGhostField<T>>();
259 exchange_gz_node->set_edges(this->patch_rank_owner, exchange_gz_edge);
260
261 exchange_gz_node->evaluate();
262
264 recv_dat = std::move(exchange_gz_edge->patchdata_fields);
265
266 return recv_dat;
267 }
268
270 build_communicate_positions(shambase::DistributedDataShared<InterfaceIdTable> &builder) {
271 auto pos_interf = build_position_interf_field(builder);
272 return communicate_pdat(xyzh_ghost_layout, std::move(pos_interf));
273 }
274
275 template<class T, class Tmerged>
276 inline shambase::DistributedData<Tmerged> merge_native(
278 std::function<
280 std::function<void(Tmerged &, T &)> appender) {
281
282 StackEntry stack_loc{};
283
285
286 sched.for_each_patchdata_nonempty(
288 Tmerged tmp_merge = init(p, pdat);
289
290 interfs.for_each([&](u64 sender, u64 receiver, T &interface) {
291 if (receiver == p.id_patch) {
292 appender(tmp_merge, interface);
293 }
294 });
295
296 merge_f.add_obj(p.id_patch, std::move(tmp_merge));
297 });
298
299 return merge_f;
300 }
301
304 StackEntry stack_loc{};
305
306 const u32 ixyz = sched.pdl_old().template get_field_idx<vec>("xyz");
307 const u32 ihpart = sched.pdl_old().template get_field_idx<flt>("hpart");
308
309 // Get field indices from xyzh_ghost_layout for accessing ghost data
310 const u32 ixyz_ghost = xyzh_ghost_layout->template get_field_idx<vec>("xyz");
311 const u32 ihpart_ghost = xyzh_ghost_layout->template get_field_idx<flt>("hpart");
312
313 return merge_native<shamrock::patch::PatchDataLayer, shamrock::patch::PatchDataLayer>(
315 positioninterfs),
317 PatchDataField<vec> &pos = pdat.get_field<vec>(ixyz);
318 PatchDataField<flt> &hpart = pdat.get_field<flt>(ihpart);
319
320 shamrock::patch::PatchDataLayer ret(xyzh_ghost_layout);
321
322 ret.get_field<vec>(ixyz_ghost).insert(pos);
323 ret.get_field<flt>(ihpart_ghost).insert(hpart);
324 ret.check_field_obj_cnt_match();
325
326 return ret;
327 },
329 merged.insert_elements(pint);
330
332 });
333 }
334
336 build_comm_merge_positions(shambase::DistributedDataShared<InterfaceIdTable> &builder) {
337 auto pos_interf = build_position_interf_field(builder);
338 return merge_position_buf(communicate_pdat(xyzh_ghost_layout, std::move(pos_interf)));
339 }
340 };
341
342} // namespace shammodels::gsph
Solver graph node for exchanging ghost field data between distributed processes.
Solver graph node for exchanging ghost layer data between distributed processes.
constexpr const char * hpart
Smoothing length field.
Header file describing a Node Instance.
Shared distributed data layer for patch data management in solver graphs.
MPI scheduler.
double f64
Alias for double.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
The MPI scheduler.
SchedulerPatchData patch_data
handle the data of the patches of the scheduler
A buffer allocated in USM (Unified Shared Memory)
void for_each(std::function< void(u64, u64, T &)> &&f)
Apply a function to all stored objects.
Represents a collection of objects distributed across patches identified by a u64 id.
iterator add_obj(u64 id, T &&obj)
Adds a new object to the collection.
PatchDataLayer container class, the layout is described in patchdata_layout.
void check_field_obj_cnt_match()
check that all contained field have the same obj cnt
void append_subset_to(const sham::DeviceBuffer< T > &buf, const sham::DeviceBuffer< u32 > &idxs_buf, u32 nvar, sham::DeviceBuffer< T > &buf_other, u32 start_enque)
Appends a subset of elements from one buffer to another.
STL namespace.
This file contains the definition for the stacktrace related functionality.
Patch object that contain generic patch information.
Definition Patch.hpp:33