38 template<
class Tvec,
class Tgr
idVec>
41 using namespace shamrock::patch;
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};
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) {
93 = tree_cell.get_intersect(sender_bsize_off_aabb).is_not_empty();
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>
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>
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);
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();
413 return MergedPatchData{or_elem, total_elements, std::move(pdat_new), ghost_layout};
416 mpdat.total_elements += pdat_interf.get_obj_cnt();
417 mpdat.pdat.insert_elements(pdat_interf);
422 "Merged patch",
id,
",", mpdat.original_elements,
"->", mpdat.total_elements);
426 storage.timings_details.interface += timer_interf.
elasped_sec();
429template<
class Tvec,
class Tgr
idVec>
437 timer_interf.
start();
439 using namespace shamrock::patch;
443 using GZData = GhostZonesData<Tvec, TgridVec>;
444 using InterfaceBuildInfos =
typename GZData::InterfaceBuildInfos;
445 using InterfaceIdTable =
typename GZData::InterfaceIdTable;
447 using AMRBlock =
typename Config::AMRBlock;
450 GZData &gen_ghost = storage.ghost_zone_infos.get();
451 auto pdat_interf = gen_ghost.template build_interface_native<PatchDataField<T>>(
452 [&](
u64 sender,
u64, InterfaceBuildInfos binfo, sycl::buffer<u32> &buf_idx,
u32 cnt) {
462 = communicate_pdat_field<T>(std::move(pdat_interf));
464 std::map<u64, u64> sz_interf_map;
466 sz_interf_map[r] += pdat_interf.get_obj_cnt();
470 scheduler().for_each_patchdata_nonempty(
477 if (receiver == p.id_patch) {
478 new_pdat.insert(interface);
482 out.field_data.
add_obj(p.id_patch, std::move(new_pdat));
486 storage.timings_details.interface += timer_interf.
elasped_sec();
497 template class GhostZones<f64_3, i64_3>;
504 communicate_pdat_field<f64_8>(
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.
DeviceQueue & get_queue(u32 id=0)
Get a reference to a DeviceQueue.
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.
void end()
Stops the timer and stores the elapsed time in nanoseconds.
f64 elasped_sec() const
Converts the stored nanosecond time to a floating point representation in seconds.
void start()
Starts the timer.
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.
Axis-Aligned bounding box.
Patch object that contain generic patch information.
u64 id_patch
unique key that identify the patch