25 sycl::vec<T, 3> shift;
26 sycl::vec<T, 3> shift_speed;
30using ShearPeriodicInfo =
35 i32_3 ioff, ShearPeriodicInfo<T> shear, sycl::vec<T, 3> bsize) {
37 i32 dx = ioff.x() * shear.shear_base.x();
38 i32 dy = ioff.y() * shear.shear_base.y();
39 i32 dz = ioff.z() * shear.shear_base.z();
44 = {(d * shear.shear_dir.x()) * shear.shear_value + bsize.x() * ioff.x(),
45 (d * shear.shear_dir.y()) * shear.shear_value + bsize.y() * ioff.y(),
46 (d * shear.shear_dir.z()) * shear.shear_value + bsize.z() * ioff.z()};
47 sycl::vec<T, 3> shift_speed
48 = {(d * shear.shear_dir.x()) * shear.shear_speed,
49 (d * shear.shear_dir.y()) * shear.shear_speed,
50 (d * shear.shear_dir.z()) * shear.shear_speed};
52 return {shift, shift_speed};
56inline void for_each_patch_shift(
57 ShearPeriodicInfo<T> shearinfo,
58 sycl::vec<T, 3> bsize,
61 i32_3 loop_offset = {0, 0, 0};
63 std::vector<i32_3> list_possible;
65 i32 repetition_x = 1 + abs(shearinfo.shear_dir.x());
66 i32 repetition_y = 1 + abs(shearinfo.shear_dir.y());
67 i32 repetition_z = 1 + abs(shearinfo.shear_dir.z());
69 T sz = bsize.x() * shearinfo.shear_dir.x() + bsize.y() * shearinfo.shear_dir.y()
70 + bsize.z() * shearinfo.shear_dir.z();
72 for (
i32 xoff = -repetition_x; xoff <= repetition_x; xoff++) {
73 for (
i32 yoff = -repetition_y; yoff <= repetition_y; yoff++) {
74 for (
i32 zoff = -repetition_z; zoff <= repetition_z; zoff++) {
76 i32 dx = xoff * shearinfo.shear_base.x();
77 i32 dy = yoff * shearinfo.shear_base.y();
78 i32 dz = zoff * shearinfo.shear_base.z();
82 i32 df = -int(d * shearinfo.shear_value / sz);
85 = {shearinfo.shear_dir.x() * df,
86 shearinfo.shear_dir.y() * df,
87 shearinfo.shear_dir.z() * df};
89 list_possible.resize(list_possible.size() + 1);
90 list_possible[list_possible.size() - 1]
91 = i32_3{xoff + off_d.x(), yoff + off_d.y(), zoff + off_d.z()};
96 for (i32_3 off : list_possible) {
98 auto shift = compute_shift_infos(off, shearinfo, bsize);
104using namespace shammodels::gsph;
114 using namespace shamrock::patch;
117 i32 repetition_x = 1;
118 i32 repetition_y = 1;
119 i32 repetition_z = 1;
126 GeneratorMap interf_map;
129 using BCConfig =
typename CfgClass::Variant;
131 using BCFree =
typename CfgClass::Free;
132 using BCPeriodic =
typename CfgClass::Periodic;
133 using BCShearingPeriodic =
typename CfgClass::ShearingPeriodic;
135 if (BCPeriodic *cfg = std::get_if<BCPeriodic>(&ghost_config)) {
136 sycl::host_accessor acc_tf{
139 for (
i32 xoff = -repetition_x; xoff <= repetition_x; xoff++) {
140 for (
i32 yoff = -repetition_y; yoff <= repetition_y; yoff++) {
141 for (
i32 zoff = -repetition_z; zoff <= repetition_z; zoff++) {
144 vec periodic_offset =
vec{xoff * bsize.x(), yoff * bsize.y(), zoff * bsize.z()};
146 sched.for_each_local_patch([&](
const Patch &psender) {
147 CoordRange<vec> sender_bsize = patch_coord_transf.to_obj_coord(psender);
148 CoordRange<vec> sender_bsize_off = sender_bsize.add_offset(periodic_offset);
150 flt sender_volume = sender_bsize.get_volume();
152 flt sender_h_max = int_range_max.get(psender.
id_patch);
156 sptree.host_for_each_leafs(
157 [&](
u64 tree_id, PtNode n) {
158 flt receiv_h_max = acc_tf[tree_id];
160 n.box_min - receiv_h_max, n.box_max + receiv_h_max};
162 return receiv_exp.get_intersect(sender_bsize_off).is_not_empty();
164 [&](
u64 id_found, PtNode n) {
165 if ((id_found == psender.
id_patch) && (xoff == 0) && (yoff == 0)
172 int_range_max.get(id_found));
175 receiv_exp.add_offset(-periodic_offset));
184 interf_volume.get_volume() / sender_volume});
190 }
else if (BCShearingPeriodic *cfg = std::get_if<BCShearingPeriodic>(&ghost_config)) {
191 sycl::host_accessor acc_tf{
194 for_each_patch_shift<flt>(*cfg, bsize, [&](i32_3 ioff,
ShiftInfo<flt> shift) {
199 vec offset = shift.shift;
201 sched.for_each_local_patch([&](
const Patch &psender) {
202 CoordRange<vec> sender_bsize = patch_coord_transf.to_obj_coord(psender);
205 flt sender_volume = sender_bsize.get_volume();
207 flt sender_h_max = int_range_max.get(psender.
id_patch);
211 sptree.host_for_each_leafs(
212 [&](
u64 tree_id, PtNode n) {
213 flt receiv_h_max = acc_tf[tree_id];
215 n.box_min - receiv_h_max, n.box_max + receiv_h_max};
217 return receiv_exp.get_intersect(sender_bsize_off).is_not_empty();
219 [&](
u64 id_found, PtNode n) {
220 if ((id_found == psender.
id_patch) && (xoff == 0) && (yoff == 0)
227 int_range_max.get(id_found));
230 = sender_bsize.get_intersect(receiv_exp.add_offset(-offset));
239 interf_volume.get_volume() / sender_volume});
245 sycl::host_accessor acc_tf{
248 vec periodic_offset =
vec{0, 0, 0};
250 sched.for_each_local_patch([&](
const Patch &psender) {
251 CoordRange<vec> sender_bsize = patch_coord_transf.to_obj_coord(psender);
252 CoordRange<vec> sender_bsize_off = sender_bsize.add_offset(periodic_offset);
254 flt sender_volume = sender_bsize.get_volume();
256 flt sender_h_max = int_range_max.get(psender.
id_patch);
260 sptree.host_for_each_leafs(
261 [&](
u64 tree_id, PtNode n) {
262 flt receiv_h_max = acc_tf[tree_id];
263 CoordRange<vec> receiv_exp{n.box_min - receiv_h_max, n.box_max + receiv_h_max};
265 return receiv_exp.get_intersect(sender_bsize_off).is_not_empty();
267 [&](
u64 id_found, PtNode n) {
273 int_range_max.get(id_found));
276 = sender_bsize.get_intersect(receiv_exp.add_offset(-periodic_offset));
285 interf_volume.get_volume() / sender_volume});
297 using namespace shamrock::patch;
301 std::map<u64, f64> send_count_stats;
303 const u32 ixyz = sched.pdl_old().template get_field_idx<vec>(
"xyz");
305 gen.for_each([&](
u64 sender,
u64 receiver, InterfaceBuildInfos &build) {
310 [](
auto access,
u32 id,
vec vmin,
vec vmax) {
311 return Patch::is_in_patch_converted(access[
id], vmin, vmax);
313 build.cut_volume.lower,
314 build.cut_volume.upper);
316 u32 pcnt = idxs_res.get_size();
323 f64 ratio =
f64(pcnt) /
f64(src.get_obj_cnt());
336 res.
add_obj(sender, receiver, InterfaceIdTable{build, std::move(idxs_res), ratio});
338 send_count_stats[sender] += ratio;
341 bool has_warn =
false;
343 std::string warn_log =
"";
345 for (
auto &[k, v] : send_count_stats) {
347 warn_log += shambase::format(
"\n patch {} high interf/patch volume: {}", k, v);
353 warn_log =
"\n This can lead to high mpi "
354 "overhead, try to increase the patch split crit"
359 logger::warn_ln(
"InterfaceGen",
"High interface/patch volume ratio." + warn_log);
370 static u32 cnt_dump_debug = 0;
372 std::string loc_graph =
"";
373 interf_info.
for_each([&loc_graph](
u64 send,
u64 recv, InterfaceIdTable &info) {
374 loc_graph += shambase::format(
" p{} -> p{}\n", send, recv);
377 sched.for_each_patch_data(
379 if (pdat.get_obj_cnt() > 0) {
380 loc_graph += shambase::format(
381 " p{} [label= \"id={} N={}\"]\n",
id,
id, pdat.get_obj_cnt());
385 std::string dot_graph =
"";
388 dot_graph =
"strict digraph {\n" + dot_graph +
"}";
391 std::string fname = shambase::format(
"ghost_graph_{}.dot", cnt_dump_debug);
392 logger::info_ln(
"GSPH Ghost",
"writing", fname);
constexpr const char * xyz
Position field (3D coordinates)
GSPH-specific ghost handler using Newtonian physics field names.
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
A buffer allocated in USM (Unified Shared Memory)
Container for objects shared between two distributed data elements.
void for_each(std::function< void(u64, u64, T &)> &&f)
Apply a function to all stored objects.
iterator add_obj(u64 left_id, u64 right_id, T &&obj)
Add an object associated with a patch pair.
Vector class based on std::array storage and mdspan.
PatchDataLayer container class, the layout is described in patchdata_layout.
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...
This header file contains utility functions related to exception handling in the code.
MPI string gather / allgather helpers (declarations; implementations in shamalgs/src/collective/gathe...
void gather_str(const std::string &send_vec, std::string &recv_vec)
Gathers a string from all nodes and store the result in a std::string.
void write_string_to_file(std::string filename, std::string s)
dump a string to a file
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...
i32 world_rank()
Gives the rank of the current process in the MPI communicator.
namespace for math utility
Patch object that contain generic patch information.
u64 id_patch
unique key that identify the patch