38 template<
class Tvec,
class Tgr
idVec>
41 using namespace shamrock::patch;
45 static constexpr u32 dim = shambase::VectorProperties<Tvec>::dimension;
46 using InterfaceBuildInfos =
typename GZData::InterfaceBuildInfos;
47 using GeneratorMap =
typename GZData::GeneratorMap;
62 for (
i32 xoff = -repetition_x; xoff <= repetition_x; xoff++) {
63 for (
i32 yoff = -repetition_y; yoff <= repetition_y; yoff++) {
64 for (
i32 zoff = -repetition_z; zoff <= repetition_z; zoff++) {
67 TgridVec periodic_offset
68 = TgridVec{xoff * bsize.x(), yoff * bsize.y(), zoff * bsize.z()};
70 sched.for_each_local_patch([&](
const Patch &psender) {
72 = patch_coord_transf.to_obj_coord(psender);
74 = sender_bsize.add_offset(periodic_offset);
77 sender_bsize_off.lower, sender_bsize_off.upper};
79 using PtNode =
typename SerialPatchTree<TgridVec>::PtNode;
81 shamlog_debug_sycl_ln(
85 sender_bsize_off_aabb.
lower,
86 sender_bsize_off_aabb.
upper);
88 sptree.host_for_each_leafs(
89 [&](
u64 tree_id, PtNode n) {
97 [&](
u64 id_found, PtNode n) {
98 if ((id_found == psender.
id_patch) && (xoff == 0) && (yoff == 0)
103 InterfaceBuildInfos ret{
107 n.box_min - periodic_offset, n.box_max - periodic_offset}};
109 results.add_obj(psender.
id_patch, id_found, std::move(ret));
120template<
class Tvec,
class Tgr
idVec>
121void shammodels::zeus::modules::GhostZones<Tvec, TgridVec>::build_ghost_cache() {
125 using GZData = GhostZonesData<Tvec, TgridVec>;
127 storage.ghost_zone_infos.set(GZData{});
128 GZData &gen_ghost = storage.ghost_zone_infos.get();
134 gen_ghost.ghost_gen_infos
135 = find_interfaces<Tvec, TgridVec>(scheduler(), storage.serial_patch_tree.get());
137 using InterfaceBuildInfos =
typename GZData::InterfaceBuildInfos;
138 using InterfaceIdTable =
typename GZData::InterfaceIdTable;
141 gen_ghost.ghost_gen_infos.for_each([&](
u64 sender,
u64 receiver, InterfaceBuildInfos &build) {
144 log = shambase::format(
145 "{} -> {} : off = {}, {} -> {}",
149 build.volume_target.lower,
150 build.volume_target.upper);
152 shamlog_debug_ln(
"AMRZeus", log);
157 gen_ghost.ghost_gen_infos.for_each([&](
u64 sender,
u64 receiver, InterfaceBuildInfos &build) {
160 sycl::buffer<u32> is_in_interf{src.get_obj_cnt()};
164 auto cell_min = src.get_field_buf_ref<TgridVec>(0).get_read_access(depends_list);
165 auto cell_max = src.get_field_buf_ref<TgridVec>(1).get_read_access(depends_list);
167 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
168 sycl::accessor flag{is_in_interf, cgh, sycl::write_only, sycl::no_init};
172 shambase::parallel_for(cgh, src.get_obj_cnt(),
"check if in interf", [=](
u32 id_a) {
173 flag[id_a] = shammath::AABB<TgridVec>(cell_min[id_a], cell_max[id_a])
174 .get_intersect(check_volume)
179 src.get_field_buf_ref<TgridVec>(0).complete_event_state(e);
180 src.get_field_buf_ref<TgridVec>(1).complete_event_state(e);
183 f64 ratio =
f64(std::get<1>(resut)) /
f64(src.get_obj_cnt());
185 std::string s = shambase::format(
186 "{} -> {} : off = {}, test volume = {} -> {}",
190 build.volume_target.lower,
191 build.volume_target.upper);
192 s += shambase::format(
"\n found N = {}, ratio = {} %", std::get<1>(resut), ratio);
194 shamlog_debug_ln(
"AMR interf", s);
196 std::unique_ptr<sycl::buffer<u32>> ids
199 gen_ghost.ghost_id_build_map.add_obj(
200 sender, receiver, InterfaceIdTable{build, std::move(ids), ratio});
204template<
class Tvec,
class Tgr
idVec>
206 GhostZones<Tvec, TgridVec>::communicate_pdat(
207 const std::shared_ptr<shamrock::patch::PatchDataLayerLayout> &pdl_ptr,
214 shamalgs::collective::serialize_sparse_comm<shamrock::patch::PatchDataLayer>(
215 shamsys::instance::get_compute_scheduler_ptr(),
219 return scheduler().get_patch_rank_owner(
id);
223 ser.allocate(pdat.serialize_buf_byte_size());
224 pdat.serialize_buf(ser);
225 return ser.finalize();
230 shamsys::instance::get_compute_scheduler_ptr(),
232 return shamrock::patch::PatchDataLayer::deserialize_buf(ser, pdl_ptr);
239template<
class Tvec,
class Tgr
idVec>
250 shamalgs::collective::serialize_sparse_comm<PatchDataField<T>>(
251 shamsys::instance::get_compute_scheduler_ptr(),
252 std::forward<shambase::DistributedDataShared<PatchDataField<T>>>(interf),
255 return scheduler().get_patch_rank_owner(
id);
259 ser.allocate(pdat.serialize_full_byte_size());
260 pdat.serialize_buf(ser);
261 return ser.finalize();
266 shamsys::instance::get_compute_scheduler_ptr(),
275template<
class Tvec,
class Tgr
idVec>
276template<
class T,
class Tmerged>
282 std::function<
void(Tmerged &, T &)> appender) {
288 scheduler().for_each_patchdata_nonempty(
290 Tmerged tmp_merge = init(p, pdat);
292 interfs.for_each([&](
u64 sender,
u64 receiver, T &interface) {
293 if (receiver == p.id_patch) {
294 appender(tmp_merge, interface);
298 merge_f.
add_obj(p.id_patch, std::move(tmp_merge));
304template<
class Tvec,
class Tgr
idVec>
305void shammodels::zeus::modules::GhostZones<Tvec, TgridVec>::exchange_ghost() {
310 timer_interf.
start();
312 using namespace shamrock::patch;
316 using GZData = GhostZonesData<Tvec, TgridVec>;
317 using InterfaceBuildInfos =
typename GZData::InterfaceBuildInfos;
318 using InterfaceIdTable =
typename GZData::InterfaceIdTable;
320 using AMRBlock =
typename Config::AMRBlock;
323 storage.ghost_layout.set(std::make_shared<shamrock::patch::PatchDataLayerLayout>());
324 std::shared_ptr<shamrock::patch::PatchDataLayerLayout> ghost_layout_ptr
325 = storage.ghost_layout.get();
328 ghost_layout.
add_field<TgridVec>(
"cell_min", 1);
329 ghost_layout.
add_field<TgridVec>(
"cell_max", 1);
330 ghost_layout.
add_field<Tscal>(
"rho", AMRBlock::block_size);
331 ghost_layout.
add_field<Tscal>(
"eint", AMRBlock::block_size);
332 ghost_layout.
add_field<Tvec>(
"vel", AMRBlock::block_size);
343 const u32 icell_min = pdl.get_field_idx<TgridVec>(
"cell_min");
344 const u32 icell_max = pdl.get_field_idx<TgridVec>(
"cell_max");
345 const u32 irho = pdl.get_field_idx<Tscal>(
"rho");
346 const u32 ieint = pdl.get_field_idx<Tscal>(
"eint");
347 const u32 ivel = pdl.get_field_idx<Tvec>(
"vel");
350 GZData &gen_ghost = storage.ghost_zone_infos.get();
351 auto pdat_interf = gen_ghost.template build_interface_native<PatchDataLayer>(
352 [&](
u64 sender,
u64, InterfaceBuildInfos binfo, sycl::buffer<u32> &buf_idx,
u32 cnt) {
353 PatchDataLayer &sender_patch = scheduler().patch_data.get_pdat(sender);
360 buf_idx, cnt, pdat.get_field<TgridVec>(icell_min_interf));
363 buf_idx, cnt, pdat.get_field<TgridVec>(icell_max_interf));
366 buf_idx, cnt, pdat.get_field<Tscal>(irho_interf));
369 buf_idx, cnt, pdat.get_field<Tscal>(ieint_interf));
372 buf_idx, cnt, pdat.get_field<Tvec>(ivel_interf));
376 pdat.get_field<TgridVec>(icell_min_interf).apply_offset(binfo.offset);
377 pdat.get_field<TgridVec>(icell_max_interf).apply_offset(binfo.offset);
384 = communicate_pdat(ghost_layout_ptr, std::move(pdat_interf));
386 std::map<u64, u64> sz_interf_map;
388 sz_interf_map[r] += pdat_interf.get_obj_cnt();
391 storage.merged_patchdata_ghost.set(
392 merge_native<PatchDataLayer, MergedPatchData>(
393 std::move(interf_pdat),
395 shamlog_debug_ln(
"Merged patch init", p.id_patch);
399 u32 or_elem = pdat.get_obj_cnt();
400 pdat_new.reserve(or_elem + sz_interf_map[p.id_patch]);
401 u32 total_elements = or_elem;
403 pdat_new.get_field<TgridVec>(icell_min_interf)
404 .insert(pdat.get_field<TgridVec>(icell_min));
405 pdat_new.get_field<TgridVec>(icell_max_interf)
406 .insert(pdat.get_field<TgridVec>(icell_max));
407 pdat_new.get_field<Tscal>(irho_interf).insert(pdat.get_field<Tscal>(irho));
408 pdat_new.get_field<Tscal>(ieint_interf).insert(pdat.get_field<Tscal>(ieint));
409 pdat_new.get_field<Tvec>(ivel_interf).insert(pdat.get_field<Tvec>(ivel));
411 pdat_new.check_field_obj_cnt_match();
414 .original_elements = or_elem,
415 .total_elements = total_elements,
416 .pdat = std::move(pdat_new),
417 .pdl = ghost_layout};
420 mpdat.total_elements += pdat_interf.get_obj_cnt();
421 mpdat.pdat.insert_elements(pdat_interf);
426 "Merged patch",
id,
",", mpdat.original_elements,
"->", mpdat.total_elements);
430 storage.timings_details.interface += timer_interf.
elapsed_sec();
433template<
class Tvec,
class Tgr
idVec>
441 timer_interf.
start();
443 using namespace shamrock::patch;
447 using GZData = GhostZonesData<Tvec, TgridVec>;
448 using InterfaceBuildInfos =
typename GZData::InterfaceBuildInfos;
449 using InterfaceIdTable =
typename GZData::InterfaceIdTable;
451 using AMRBlock =
typename Config::AMRBlock;
454 GZData &gen_ghost = storage.ghost_zone_infos.get();
455 auto pdat_interf = gen_ghost.template build_interface_native<PatchDataField<T>>(
456 [&](
u64 sender,
u64, InterfaceBuildInfos binfo, sycl::buffer<u32> &buf_idx,
u32 cnt) {
466 = communicate_pdat_field<T>(std::move(pdat_interf));
468 std::map<u64, u64> sz_interf_map;
470 sz_interf_map[r] += pdat_interf.get_obj_cnt();
474 scheduler().for_each_patchdata_nonempty(
481 if (receiver == p.id_patch) {
482 new_pdat.insert(interface);
486 out.field_data.add_obj(p.id_patch, std::move(new_pdat));
490 storage.timings_details.interface += timer_interf.
elapsed_sec();
502 template shamrock::ComputeField<f64_8> GhostZones<f64_3, i64_3>::exchange_compute_field<f64_8>(
503 shamrock::ComputeField<f64_8> &in);
509 shambase::DistributedDataShared<PatchDataField<f64_8>> &&interf);
Container for objects shared between two distributed data patches.
Header file describing a Node Instance.
double f64
Alias for double.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
std::int32_t i32
32 bit integer
static PatchDataField deserialize_full(shamalgs::SerializeHelper &serializer)
deserialize a field inverse of serialize_full
A buffer allocated in USM (Unified Shared Memory).
A SYCL queue associated with a device and a context.
sycl::queue q
The SYCL queue associated with this context.
sycl::event submit(Fct &&fct)
Submits a kernel to the SYCL queue.
Class to manage a list of SYCL events.
Container for objects shared between two distributed data elements.
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.
Class Timer measures the time elapsed since the timer was started.
f64 elapsed_sec() const
Converts the stored nanosecond time to a floating point representation in seconds.
void start()
Starts the timer.
void stop()
Stops the timer and stores the elapsed time in nanoseconds.
Class to hold information related to ghost zones.
u32 get_field_idx(const std::string &field_name) const
Get the field id if matching name & type.
void add_field(const std::string &field_name, u32 nvar, SourceLocation loc=SourceLocation{})
add a field of type T to the layout
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
Store the information related to the size of the simulation box to convert patch integer coordinates ...
T get_bounding_box_size() const
Get the size of the stored bounding box of the domain.
PatchCoordTransform< T > get_patch_transform() const
Get a PatchCoordTransform object that describes the conversion between patch coordinates and domain c...
std::tuple< std::optional< sycl::buffer< u32 > >, u32 > stream_compact(sycl::queue &q, sycl::buffer< u32 > &buf_flags, u32 len)
Stream compaction algorithm.
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.
auto extract_value(std::optional< T > &o, SourceLocation loc=SourceLocation()) -> T
Extracts the content out of an optional.
T & get_check_ref(const std::unique_ptr< T > &ptr, SourceLocation loc=SourceLocation())
Takes a std::unique_ptr and returns a reference to the object it holds. It throws a std::runtime_erro...
namespace for math utility
namespace for the zeus model modules
auto find_interfaces(PatchScheduler &sched, SerialPatchTree< TgridVec > &sptree)
find interfaces corresponding to shared surface between domains
namespace for the main framework
This file contains the definition for the stacktrace related functionality.
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.
Axis-Aligned bounding box.
T lower
Lower bound of the AABB.
bool is_not_empty() const noexcept
Checks if the AABB is non-empty.
T upper
Upper bound of the AABB.
AABB get_intersect(AABB other) const noexcept
Compute the intersection of two AABB.
Patch object that contain generic patch information.
u64 id_patch
unique key that identify the patch