30template<
class Tvec,
class Tmorton,
template<
class>
class SPHKernel>
31void shammodels::sph::modules::NeighbourCache<Tvec, Tmorton, SPHKernel>::start_neighbors_cache() {
34 using GhostHandle = sph::BasicSPHGhostHandler<Tvec>;
35 using GhostHandleCache =
typename GhostHandle::CacheMap;
44 auto build_neigh_cache = [&](
u64 patch_id) {
45 shamlog_debug_ln(
"BasicSPH",
"build particle cache id =", patch_id);
49 auto &mfield = storage.merged_xyzh.get().get(patch_id);
55 = storage.rtree_rint_field.get().get(patch_id).buf_field;
57 RTree &tree = storage.merged_pos_trees.get().get(patch_id);
58 auto obj_it = tree.get_object_iterator();
62 sycl::range range_npart{obj_cnt};
64 Tscal h_tolerance = solver_config.htol_up_coarse_cycle;
73 obj_cnt, shamsys::instance::get_compute_scheduler_ptr());
75 shamlog_debug_sycl_ln(
"Cache",
"generate cache for N=", obj_cnt);
83 const Tvec *__restrict
xyz,
84 const Tscal *__restrict
hpart,
85 const Tscal *__restrict rint_tree,
87 u32 *__restrict neigh_cnt) {
88 constexpr Tscal Rker2 = Kernel::Rkern * Kernel::Rkern;
90 Tscal rint_a =
hpart[id_a] * h_tolerance;
92 Tvec xyz_a =
xyz[id_a];
94 Tvec inter_box_a_min = xyz_a - rint_a * Kernel::Rkern;
95 Tvec inter_box_a_max = xyz_a + rint_a * Kernel::Rkern;
99 particle_looper.rtree_for(
101 Tscal int_r_max_cell = rint_tree[node_id] * Kernel::Rkern;
103 using namespace walker::interaction_crit;
105 return sph_radix_cell_crit(
115 Tvec dr = xyz_a -
xyz[id_b];
116 Tscal rab2 = sycl::dot(dr, dr);
117 Tscal rint_b =
hpart[id_b] * h_tolerance;
120 = rab2 > rint_a * rint_a * Rker2 && rab2 > rint_b * rint_b * Rker2;
122 cnt += (no_interact) ? 0 : 1;
125 neigh_cnt[id_a] = cnt;
128 tree::ObjectCache pcache = tree::prepare_object_cache(std::move(neigh_count), obj_cnt);
133 sham::MultiRef{buf_xyz, buf_hpart, tree_field_rint, pcache.scanned_cnt, obj_it},
138 const Tvec *__restrict
xyz,
139 const Tscal *__restrict
hpart,
140 const Tscal *__restrict rint_tree,
141 const u32 *__restrict scanned_neigh_cnt,
142 auto particle_looper,
143 u32 *__restrict neigh) {
144 constexpr Tscal Rker2 = Kernel::Rkern * Kernel::Rkern;
146 Tscal rint_a =
hpart[id_a] * h_tolerance;
148 Tvec xyz_a =
xyz[id_a];
150 Tvec inter_box_a_min = xyz_a - rint_a * Kernel::Rkern;
151 Tvec inter_box_a_max = xyz_a + rint_a * Kernel::Rkern;
153 u32 cnt = scanned_neigh_cnt[id_a];
155 particle_looper.rtree_for(
157 Tscal int_r_max_cell = rint_tree[node_id] * Kernel::Rkern;
159 using namespace walker::interaction_crit;
161 return sph_radix_cell_crit(
171 Tvec dr = xyz_a -
xyz[id_b];
172 Tscal rab2 = sycl::dot(dr, dr);
173 Tscal rint_b =
hpart[id_b] * h_tolerance;
176 = rab2 > rint_a * rint_a * Rker2 && rab2 > rint_b * rint_b * Rker2;
181 cnt += (no_interact) ? 0 : 1;
190 using namespace shamrock::patch;
193 ncache.neigh_cache.add_obj(cur_p.
id_patch, build_neigh_cache(cur_p.
id_patch));
197 storage.timings_details.neighbors += time_neigh.
elapsed_sec();
200template<
class Tvec,
class Tmorton,
template<
class>
class SPHKernel>
205 using GhostHandle = sph::BasicSPHGhostHandler<Tvec>;
206 using GhostHandleCache =
typename GhostHandle::CacheMap;
215 auto build_neigh_cache = [&](
u64 patch_id) {
216 shamlog_debug_ln(
"BasicSPH",
"build particle cache id =", patch_id);
220 auto &mfield = storage.merged_xyzh.get().get(patch_id);
226 = storage.rtree_rint_field.get().get(patch_id).buf_field;
228 RTree &tree = storage.merged_pos_trees.get().get(patch_id);
229 auto obj_it = tree.get_object_iterator();
230 auto leaf_it = tree.get_traverser();
232 u32 leaf_cnt = tree.get_leaf_cell_count();
233 u32 intnode_cnt = tree.get_internal_cell_count();
237 sycl::range range_nleaf{leaf_cnt};
238 sycl::range range_nobj{obj_cnt};
243 Tscal h_tolerance = solver_config.htol_up_coarse_cycle;
250 leaf_cnt, shamsys::instance::get_compute_scheduler_ptr());
252 shamlog_debug_sycl_ln(
"Cache",
"generate cache for Nleaf=", leaf_cnt);
261 const Tscal *__restrict rint_tree,
263 u32 *__restrict neigh_cnt) {
264 u32 offset_leaf = intnode_cnt;
266 Tscal leaf_a_rint = rint_tree[offset_leaf + id_a] * Kernel::Rkern;
267 Tvec leaf_a_bmin = leaf_looper.aabb_min[offset_leaf + id_a];
268 Tvec leaf_a_bmax = leaf_looper.aabb_max[offset_leaf + id_a];
269 Tvec leaf_a_bmin_ext = leaf_a_bmin - leaf_a_rint;
270 Tvec leaf_a_bmax_ext = leaf_a_bmax + leaf_a_rint;
274 leaf_looper.rtree_for(
276 Tscal int_r_max_cell = rint_tree[node_id] * Kernel::Rkern;
278 Tvec ext_bmin = node_aabb.
lower - int_r_max_cell;
279 Tvec ext_bmax = node_aabb.
upper + int_r_max_cell;
281 return BBAA::cella_neigh_b(leaf_a_bmin, leaf_a_bmax, ext_bmin, ext_bmax)
282 || BBAA::cella_neigh_b(
292 neigh_cnt[id_a] = cnt;
312 = tree::prepare_object_cache(std::move(neigh_count_leaf), leaf_cnt);
320 sham::MultiRef{tree_field_rint, pleaf_cache.scanned_cnt, leaf_it},
325 const Tscal *__restrict rint_tree,
326 const u32 *__restrict scanned_neigh_cnt,
328 u32 *__restrict neigh) {
329 u32 offset_leaf = intnode_cnt;
331 Tscal leaf_a_rint = rint_tree[offset_leaf + id_a] * Kernel::Rkern;
332 Tvec leaf_a_bmin = leaf_looper.aabb_min[offset_leaf + id_a];
333 Tvec leaf_a_bmax = leaf_looper.aabb_max[offset_leaf + id_a];
334 Tvec leaf_a_bmin_ext = leaf_a_bmin - leaf_a_rint;
335 Tvec leaf_a_bmax_ext = leaf_a_bmax + leaf_a_rint;
337 u32 cnt = scanned_neigh_cnt[id_a];
339 leaf_looper.rtree_for(
341 Tscal int_r_max_cell = rint_tree[node_id] * Kernel::Rkern;
343 Tvec ext_bmin = node_aabb.
lower - int_r_max_cell;
344 Tvec ext_bmax = node_aabb.
upper + int_r_max_cell;
346 return BBAA::cella_neigh_b(leaf_a_bmin, leaf_a_bmax, ext_bmin, ext_bmax)
347 || BBAA::cella_neigh_b(
361 obj_cnt, shamsys::instance::get_compute_scheduler_ptr());
369 u32 id_a,
const Tvec *__restrict
xyz,
auto leaf_looper,
u32 *__restrict found_id) {
370 u32 offset_leaf = intnode_cnt;
372 Tvec r_a =
xyz[id_a];
377 leaf_looper.rtree_for(
379 return BBAA::is_coord_in_range_incl_max(
383 found_id_ = leaf_b - offset_leaf;
388 found_id[id_a] = found_id_;
404 obj_cnt, shamsys::instance::get_compute_scheduler_ptr());
406 shamlog_debug_sycl_ln(
"Cache",
"generate cache for N=", obj_cnt);
410 sham::MultiRef{buf_xyz, buf_hpart, pleaf_cache, obj_it.cell_iterator, leaf_part_id},
413 [intnode_cnt, h_tolerance](
415 const Tvec *__restrict
xyz,
416 const Tscal *__restrict
hpart,
417 auto acc_neigh_leaf_looper,
418 auto particle_looper,
419 const u32 *__restrict leaf_owner,
420 u32 *__restrict neigh_cnt) {
423 u32 offset_leaf = intnode_cnt;
425 constexpr Tscal Rker2 = Kernel::Rkern * Kernel::Rkern;
427 Tscal rint_a =
hpart[id_a] * h_tolerance;
429 Tvec xyz_a =
xyz[id_a];
433 u32 leaf_own_a = leaf_owner[id_a];
435 neigh_leaf_looper.for_each_object(leaf_own_a, [&](
u32 leaf_b) {
438 particle_looper.for_each_in_leaf_cell(leaf_b - offset_leaf, [&](
u32 id_b) {
439 Tvec dr = xyz_a -
xyz[id_b];
440 Tscal rab2 = sycl::dot(dr, dr);
441 Tscal rint_b =
hpart[id_b] * h_tolerance;
444 = rab2 > rint_a * rint_a * Rker2 && rab2 > rint_b * rint_b * Rker2;
446 cnt += (no_interact) ? 0 : 1;
450 neigh_cnt[id_a] = cnt;
453 tree::ObjectCache pcache = tree::prepare_object_cache(std::move(neigh_count), obj_cnt);
464 obj_it.cell_iterator,
468 [intnode_cnt, h_tolerance](
470 const Tvec *__restrict
xyz,
471 const Tscal *__restrict
hpart,
472 auto acc_neigh_leaf_looper,
473 const u32 *__restrict scanned_neigh_cnt,
474 auto particle_looper,
475 const u32 *__restrict leaf_owner,
476 u32 *__restrict neigh) {
479 u32 offset_leaf = intnode_cnt;
481 constexpr Tscal Rker2 = Kernel::Rkern * Kernel::Rkern;
483 Tscal rint_a =
hpart[id_a] * h_tolerance;
485 Tvec xyz_a =
xyz[id_a];
487 u32 cnt = scanned_neigh_cnt[id_a];
489 u32 leaf_own_a = leaf_owner[id_a];
491 neigh_leaf_looper.for_each_object(leaf_own_a, [&](
u32 leaf_b) {
494 particle_looper.for_each_in_leaf_cell(leaf_b - offset_leaf, [&](
u32 id_b) {
495 Tvec dr = xyz_a -
xyz[id_b];
496 Tscal rab2 = sycl::dot(dr, dr);
497 Tscal rint_b =
hpart[id_b] * h_tolerance;
500 = rab2 > rint_a * rint_a * Rker2 && rab2 > rint_b * rint_b * Rker2;
505 cnt += (no_interact) ? 0 : 1;
514 using namespace shamrock::patch;
517 ncache.neigh_cache.add_obj(cur_p.
id_patch, build_neigh_cache(cur_p.
id_patch));
521 storage.timings_details.neighbors += time_neigh.
elapsed_sec();
constexpr const char * xyz
Position field (3D coordinates).
constexpr const char * hpart
Smoothing length field.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
Shamrock assertion utility.
#define SHAM_ASSERT(x)
Shorthand for SHAM_ASSERT_NAMED without a message.
A buffer allocated in USM (Unified Shared Memory).
A SYCL queue associated with a device and a context.
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.
PatchDataLayer container class, the layout is described in patchdata_layout.
A Compressed Leaf Bounding Volume Hierarchy (CLBVH) for neighborhood queries.
void kernel_call(sham::DeviceQueue &q, RefIn in, RefOut in_out, u32 n, Functor &&func, SourceLocation &&callsite=SourceLocation{})
Submit a kernel to a SYCL queue.
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 main framework
constexpr i32 i32_max
i32 max value
shambase::details::NamedBasicStackEntry NamedStackEntry
Alias for shambase::details::NamedBasicStackEntry.
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.
A class that references multiple buffers or similar objects.
Axis-Aligned bounding box.
T lower
Lower bound of the AABB.
T upper
Upper bound of the AABB.
Patch object that contain generic patch information.
u64 id_patch
unique key that identify the patch