27template<
class u_morton,
class vec3>
28RadixTree<u_morton, vec3>::RadixTree(
30 std::tuple<vec3, vec3> treebox,
31 sycl::buffer<vec3> &pos_buf,
36 "number of element in patch above i32_max-1");
39 shamlog_debug_sycl_ln(
"RadixTree",
"box dim :", std::get<0>(treebox), std::get<1>(treebox));
41 bounding_box = treebox;
47 tree_reduced_morton_codes.build(
48 queue, tree_morton_codes.obj_cnt, reduc_level, tree_morton_codes, one_cell_mode);
53 tree_reduced_morton_codes.tree_leaf_count - 1,
54 *tree_reduced_morton_codes.buf_tree_morton);
56 tree_struct.build_one_cell_mode();
60template<
class u_morton,
class vec3>
61RadixTree<u_morton, vec3>::RadixTree(
63 std::tuple<vec3, vec3> treebox,
64 const std::unique_ptr<sycl::buffer<vec3>> &pos_buf,
69template<
class u_morton,
class Tvec>
70RadixTree<u_morton, Tvec>::RadixTree(
71 sham::DeviceScheduler_ptr dev_sched,
72 std::tuple<Tvec, Tvec> treebox,
77 sycl::queue &queue = dev_sched->get_queue().q;
81 "number of element in patch above i32_max-1");
84 shamlog_debug_sycl_ln(
"RadixTree",
"box dim :", std::get<0>(treebox), std::get<1>(treebox));
86 bounding_box = treebox;
92 tree_reduced_morton_codes.build(
93 queue, tree_morton_codes.obj_cnt, reduc_level, tree_morton_codes, one_cell_mode);
98 tree_reduced_morton_codes.tree_leaf_count - 1,
99 *tree_reduced_morton_codes.buf_tree_morton);
101 tree_struct.build_one_cell_mode();
105template<
class u_morton,
class vec3>
109 serializer.write(std::get<0>(bounding_box));
110 serializer.write(std::get<1>(bounding_box));
111 tree_morton_codes.serialize(serializer);
112 tree_reduced_morton_codes.serialize(serializer);
113 tree_struct.serialize(serializer);
114 tree_cell_ranges.serialize(serializer);
117template<
class u_morton,
class pos_t>
120 return H::serialize_byte_size<pos_t>() * 2 + tree_morton_codes.serialize_byte_size()
121 + tree_reduced_morton_codes.serialize_byte_size() + tree_struct.serialize_byte_size()
122 + tree_cell_ranges.serialize_byte_size();
125template<
class u_morton,
class pos_t>
132 serializer.load(std::get<0>(ret.bounding_box));
133 serializer.load(std::get<1>(ret.bounding_box));
138 ret.tree_reduced_morton_codes = TreeReducedMortonCodes<u_morton>::deserialize(serializer);
139 ret.tree_struct = TreeStructure<u_morton>::deserialize(serializer);
140 ret.tree_cell_ranges = TreeCellRanges<u_morton, pos_t>::deserialize(serializer);
145template<
class u_morton,
class vec3>
146void RadixTree<u_morton, vec3>::compute_cell_ibounding_box(sycl::queue &queue) {
148 tree_cell_ranges.build1(queue, tree_reduced_morton_codes, tree_struct);
151template<
class morton_t,
class pos_t>
152void RadixTree<morton_t, pos_t>::convert_bounding_box(sycl::queue &queue) {
154 u32 total_count = tree_struct.internal_cell_count + tree_reduced_morton_codes.tree_leaf_count;
155 tree_cell_ranges.build2(queue, total_count, bounding_box);
158template<
class u_morton,
class vec>
159auto RadixTree<u_morton, vec>::compute_int_boxes(
163 shamlog_debug_sycl_ln(
"RadixTree",
"compute int boxes");
165 auto buf_cell_interact_rad = RadixTreeField<coord_t>::make_empty(
166 1, tree_struct.internal_cell_count + tree_reduced_morton_codes.tree_leaf_count);
167 sycl::range<1> range_leaf_cell{tree_reduced_morton_codes.tree_leaf_count};
169 auto &buf_cell_int_rad_buf = buf_cell_interact_rad.radix_tree_field_buf;
174 auto h = int_rad_buf.get_read_access(depends_list);
176 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
177 u32 offset_leaf = tree_struct.internal_cell_count;
180 = buf_cell_int_rad_buf->template get_access<sycl::access::mode::discard_write>(cgh);
182 auto cell_particle_ids = tree_reduced_morton_codes.buf_reduc_index_map
183 ->template get_access<sycl::access::mode::read>(cgh);
184 auto particle_index_map = tree_morton_codes.buf_particle_index_map
185 ->template get_access<sycl::access::mode::read>(cgh);
187 coord_t tol = tolerance;
189 cgh.parallel_for(range_leaf_cell, [=](sycl::item<1> item) {
190 u32 gid = (
u32) item.get_id(0);
192 u32 min_ids = cell_particle_ids[gid];
193 u32 max_ids = cell_particle_ids[gid + 1];
196 for (
unsigned int id_s = min_ids; id_s < max_ids; id_s++) {
198 f32 h_a = h[particle_index_map[id_s]] * tol;
199 h_tmp = (h_tmp > h_a ? h_tmp : h_a);
202 h_max_cell[offset_leaf + gid] = h_tmp;
206 int_rad_buf.complete_event_state(e);
223 sycl::host_accessor rchild_id {*tree_struct.buf_rchild_id ,sycl::read_only};
224 sycl::host_accessor lchild_id {*tree_struct.buf_lchild_id ,sycl::read_only};
225 sycl::host_accessor rchild_flag {*tree_struct.buf_rchild_flag,sycl::read_only};
226 sycl::host_accessor lchild_flag {*tree_struct.buf_lchild_flag,sycl::read_only};
229 u32 lid_0 = lchild_id[gid];
230 u32 rid_0 = rchild_id[gid];
231 u32 lfl_0 = lchild_flag[gid];
232 u32 rfl_0 = rchild_flag[gid];
233 u32 offset_leaf = tree_struct.internal_cell_count;
234 u32 lid = lchild_id[gid] + offset_leaf * lchild_flag[gid];
235 u32 rid = rchild_id[gid] + offset_leaf * rchild_flag[gid];
246 logger::raw_ln(
"internal_cell_count =", tree_struct.internal_cell_count);
247 logger::raw_ln(
"tree_leaf_count =", tree_reduced_morton_codes.tree_leaf_count);
251 sycl::range<1> range_tree{tree_struct.internal_cell_count};
253 for (
u32 i = 0; i < tree_depth; i++) {
254 queue.submit([&](sycl::handler &cgh) {
255 u32 offset_leaf = tree_struct.internal_cell_count;
257 sycl::accessor h_max_cell{*buf_cell_int_rad_buf, cgh, sycl::read_write};
259 sycl::accessor rchild_id{*tree_struct.buf_rchild_id, cgh, sycl::read_only};
260 sycl::accessor lchild_id{*tree_struct.buf_lchild_id, cgh, sycl::read_only};
261 sycl::accessor rchild_flag{*tree_struct.buf_rchild_flag, cgh, sycl::read_only};
262 sycl::accessor lchild_flag{*tree_struct.buf_lchild_flag, cgh, sycl::read_only};
264 u32 len = tree_struct.internal_cell_count;
265 constexpr u32 group_size = 64;
268 u32 corrected_len = group_cnt * group_size;
271 sycl::nd_range<1>{corrected_len, group_size}, [=](sycl::nd_item<1> id) {
272 u32 local_id =
id.get_local_id(0);
273 u32 group_tile_id =
id.get_group_linear_id();
274 u32 gid = group_tile_id * group_size + local_id;
279 u32 lid = lchild_id[gid] + offset_leaf * lchild_flag[gid];
280 u32 rid = rchild_id[gid] + offset_leaf * rchild_flag[gid];
282 coord_t h_l = h_max_cell[lid];
283 coord_t h_r = h_max_cell[rid];
285 h_max_cell[gid] = (h_r > h_l ? h_r : h_l);
292 = tree_struct.internal_cell_count + tree_reduced_morton_codes.tree_leaf_count;
295 *buf_cell_int_rad_buf, int_rad_cnt, shamsys::instance::get_compute_scheduler_ptr());
297 if (shamalgs::reduction::has_nan(int_rad_dev_buf, int_rad_cnt)) {
299 *buf_cell_int_rad_buf,
300 tree_struct.internal_cell_count + tree_reduced_morton_codes.tree_leaf_count,
304 "the structure of the tree as issue in ids");
308 return std::move(buf_cell_interact_rad);
312std::string print_member(
const T &a);
315std::string print_member(
const u8 &a) {
316 return sham::format_printf(
"%d",
u32(a));
320std::string print_member(
const u32 &a) {
321 return sham::format_printf(
"%d", a);
324template<
class u_morton,
class vec3>
326void RadixTree<u_morton, vec3>::print_tree_field(sycl::buffer<T> &buf_field) {
328 sycl::host_accessor acc{buf_field, sycl::read_only};
330 u32 total_count = tree_struct.internal_cell_count + tree_reduced_morton_codes.tree_leaf_count;
332 u32 offset_leaf = tree_struct.internal_cell_count;
334 sycl::host_accessor rchild_id{*tree_struct.buf_rchild_id};
335 sycl::host_accessor lchild_id{*tree_struct.buf_lchild_id};
336 sycl::host_accessor rchild_flag{*tree_struct.buf_rchild_flag};
337 sycl::host_accessor lchild_flag{*tree_struct.buf_lchild_flag};
340 auto printer = [&]() {
342 = [&](
u32 gid, std::string prefix,
bool is_left,
auto &step_ref) -> std::string {
343 std::string ret_val =
"";
349 std::string val =
" (" + print_member(acc[gid]) +
") ";
350 std::string val_empt = std::string(val.size(),
' ');
352 ret_val += (is_left ?
"╦══" :
"╚══");
355 if (gid < offset_leaf) {
356 u32 lid = lchild_id[gid] + offset_leaf * lchild_flag[gid];
357 u32 rid = rchild_id[gid] + offset_leaf * rchild_flag[gid];
360 lid, prefix + (is_left ?
"║ " + val_empt :
" " + val_empt),
true, step_ref);
362 rid, prefix + (is_left ?
"║ " + val_empt :
" " + val_empt),
false, step_ref);
377template void RadixTree<u32, f64_3>::print_tree_field(sycl::buffer<u32> &buf_field);
378template void RadixTree<u32, f32_3>::print_tree_field(sycl::buffer<u32> &buf_field);
379template void RadixTree<u64, f64_3>::print_tree_field(sycl::buffer<u32> &buf_field);
380template void RadixTree<u64, f32_3>::print_tree_field(sycl::buffer<u32> &buf_field);
382template void RadixTree<u32, u32_3>::print_tree_field(sycl::buffer<u32> &buf_field);
383template void RadixTree<u32, u64_3>::print_tree_field(sycl::buffer<u32> &buf_field);
384template void RadixTree<u64, u32_3>::print_tree_field(sycl::buffer<u32> &buf_field);
385template void RadixTree<u64, u64_3>::print_tree_field(sycl::buffer<u32> &buf_field);
386template void RadixTree<u64, i64_3>::print_tree_field(sycl::buffer<u32> &buf_field);
388template<
class u_morton,
class vec3>
390 sycl::queue &queue, sycl::buffer<u8> &valid_node) {
392 u32 total_count = tree_struct.internal_cell_count + tree_reduced_morton_codes.tree_leaf_count;
393 sycl::range<1> range_tree{total_count};
404 sycl::buffer<u8> valid_node_new = sycl::buffer<u8>(total_count);
406 for (
u32 it = 0; it < tree_depth; it++) {
408 shamlog_debug_sycl_ln(
"Radixtree",
"cascading zeros step : ", it);
409 queue.submit([&](sycl::handler &cgh) {
410 sycl::accessor acc_valid_node_old{valid_node, cgh, sycl::read_only};
411 sycl::accessor acc_valid_node_new{
412 valid_node_new, cgh, sycl::write_only, sycl::no_init};
414 sycl::accessor acc_lchild_id{*tree_struct.buf_lchild_id, cgh, sycl::read_only};
415 sycl::accessor acc_rchild_id{*tree_struct.buf_rchild_id, cgh, sycl::read_only};
416 sycl::accessor acc_lchild_flag{
417 *tree_struct.buf_lchild_flag, cgh, sycl::read_only};
418 sycl::accessor acc_rchild_flag{
419 *tree_struct.buf_rchild_flag, cgh, sycl::read_only};
421 u32 leaf_offset = tree_struct.internal_cell_count;
424 sycl::range<1>(tree_struct.internal_cell_count), [=](sycl::item<1> item) {
425 u32 lid = acc_lchild_id[item] + leaf_offset * acc_lchild_flag[item];
426 u32 rid = acc_rchild_id[item] + leaf_offset * acc_rchild_flag[item];
428 u8 old_nid_falg = acc_valid_node_old[item];
430 if (item.get_linear_id() == 0) {
431 acc_valid_node_new[item] = old_nid_falg;
434 if (old_nid_falg == 0 || old_nid_falg == 2) {
435 acc_valid_node_new[lid] = 0;
436 acc_valid_node_new[rid] = 0;
438 u8 old_lid_falg = acc_valid_node_old[lid];
439 u8 old_rid_falg = acc_valid_node_old[rid];
441 if (old_lid_falg == 0) {
444 if (old_rid_falg == 0) {
448 acc_valid_node_new[lid] = old_lid_falg;
449 acc_valid_node_new[rid] = old_rid_falg;
454 std::swap(valid_node, valid_node_new);
464 sycl::buffer<u8> valid_tree_morton(tree_reduced_morton_codes.tree_leaf_count);
466 auto print_valid_morton = [&] {
467 shamlog_debug_sycl_ln(
"Radixtree",
"valid_tree_morton");
469 sycl::buffer<u32> print_map(total_count);
473 sycl::host_accessor acc{print_map};
474 sycl::host_accessor acc_leaf{valid_tree_morton};
476 for (
u32 i = 0; i < tree_reduced_morton_codes.tree_leaf_count; i++) {
477 acc[i + tree_struct.internal_cell_count] = acc_leaf[i];
480 for (
u32 i = 0; i < tree_struct.internal_cell_count; i++) {
481 acc[i] = acc_leaf[i];
485 print_tree_field(print_map);
490 queue.submit([&](sycl::handler &cgh) {
491 sycl::accessor acc_valid_tree_morton{
492 valid_tree_morton, cgh, sycl::write_only, sycl::no_init};
494 sycl::accessor acc_valid_node{valid_node, cgh, sycl::read_only};
496 u32 leaf_offset = tree_struct.internal_cell_count;
499 sycl::range<1>(tree_reduced_morton_codes.tree_leaf_count), [=](sycl::item<1> item) {
500 u8 leaf_val = acc_valid_node[item.get_linear_id() + leaf_offset];
502 if (item.get_linear_id() < leaf_offset) {
503 if (acc_valid_node[item] == 2) {
508 acc_valid_tree_morton[item] = leaf_val;
518 ret.bounding_box = bounding_box;
520 std::vector<u32> extract_id;
524 std::vector<u_morton> new_buf_morton;
525 std::vector<u32> new_buf_particle_index_map;
526 std::vector<u32> new_reduc_index_map;
528 u32 leaf_offset = tree_struct.internal_cell_count;
530 sycl::host_accessor cell_index_map{
531 *tree_reduced_morton_codes.buf_reduc_index_map, sycl::read_only};
532 sycl::host_accessor particle_index_map{
533 *tree_morton_codes.buf_particle_index_map, sycl::read_only};
535 sycl::host_accessor acc_valid_tree_morton{valid_tree_morton, sycl::read_only};
537 sycl::host_accessor acc_morton{*tree_morton_codes.buf_morton, sycl::read_only};
541 for (
u32 i = 0; i < tree_reduced_morton_codes.tree_leaf_count; i++) {
542 if (acc_valid_tree_morton[i] != 0) {
546 uint min_ids = cell_index_map[i];
547 uint max_ids = cell_index_map[i + 1];
549 new_reduc_index_map.push_back(cnt);
551 for (
unsigned int id_s = min_ids; id_s < max_ids; id_s++) {
554 uint id_b = particle_index_map[id_s];
558 extract_id.push_back(id_b);
559 new_buf_morton.push_back(acc_morton[id_b]);
560 new_buf_particle_index_map.push_back(cnt);
569 new_reduc_index_map.push_back(cnt);
571 std::vector<u_morton> new_morton_tree;
574 sycl::host_accessor acc_tree_morton{*tree_reduced_morton_codes.buf_tree_morton};
576 sycl::host_accessor acc_valid_tree_morton{valid_tree_morton, sycl::read_only};
578 for (
u32 i = 0; i < tree_reduced_morton_codes.tree_leaf_count; i++) {
579 if (acc_valid_tree_morton[i] != 0) {
580 new_morton_tree.push_back(acc_tree_morton[i]);
585 ret.tree_reduced_morton_codes.tree_leaf_count = new_morton_tree.size();
586 ret.tree_struct.internal_cell_count = ret.tree_reduced_morton_codes.tree_leaf_count - 1;
588 ret.tree_morton_codes.buf_morton
589 = std::make_unique<sycl::buffer<u_morton>>(new_buf_morton.size());
591 sycl::host_accessor acc{
592 *ret.tree_morton_codes.buf_morton, sycl::write_only, sycl::no_init};
593 for (
u32 i = 0; i < new_buf_morton.size(); i++) {
594 acc[i] = new_buf_morton[i];
598 ret.tree_morton_codes.buf_particle_index_map
599 = std::make_unique<sycl::buffer<u32>>(new_buf_particle_index_map.size());
601 sycl::host_accessor acc{
602 *ret.tree_morton_codes.buf_particle_index_map, sycl::write_only, sycl::no_init};
603 for (
u32 i = 0; i < new_buf_particle_index_map.size(); i++) {
604 acc[i] = new_buf_particle_index_map[i];
608 if (ret.tree_reduced_morton_codes.tree_leaf_count > 1) {
610 ret.tree_reduced_morton_codes.buf_reduc_index_map
611 = std::make_unique<sycl::buffer<u32>>(new_reduc_index_map.size());
613 sycl::host_accessor acc{
614 *ret.tree_reduced_morton_codes.buf_reduc_index_map,
617 for (
u32 i = 0; i < new_reduc_index_map.size(); i++) {
618 acc[i] = new_reduc_index_map[i];
622 ret.tree_reduced_morton_codes.buf_tree_morton
623 = std::make_unique<sycl::buffer<u_morton>>(new_morton_tree.size());
625 sycl::host_accessor acc{
626 *ret.tree_reduced_morton_codes.buf_tree_morton,
629 for (
u32 i = 0; i < new_morton_tree.size(); i++) {
630 acc[i] = new_morton_tree[i];
634 ret.tree_struct.build(
636 ret.tree_struct.internal_cell_count,
637 *ret.tree_reduced_morton_codes.buf_tree_morton);
644 ret.compute_cell_ibounding_box(queue);
645 ret.convert_bounding_box(queue);
648 std::unique_ptr<sycl::buffer<u32>> new_node_id_to_old_naive = std::make_unique<sycl::buffer<u32>>(ret.tree_leaf_count + ret.tree_internal_count);
651 auto & new_node_id_to_old = new_node_id_to_old_naive;
655 sycl::host_accessor acc{* new_node_id_to_old, sycl::write_only, sycl::no_init};
656 for (
u32 i = 0 ; i < new_node_id_to_old->size(); i++) {
662 sycl::host_accessor acc_new_node_id_to_old {*new_node_id_to_old,sycl::write_only, sycl::no_init};
664 sycl::host_accessor new_tree_acc_pos_min_cell{*ret.buf_pos_min_cell,sycl::read_only};
665 sycl::host_accessor new_tree_acc_pos_max_cell{*ret.buf_pos_max_cell,sycl::read_only};
667 sycl::host_accessor old_tree_acc_pos_min_cell{*buf_pos_min_cell,sycl::read_only};
668 sycl::host_accessor old_tree_acc_pos_max_cell{*buf_pos_max_cell,sycl::read_only};
670 for(
u32 i = 0 ; i < ret.tree_leaf_count + ret.tree_internal_count; i++){
672 vec3i cur_pos_min_cell_a = new_tree_acc_pos_min_cell[i];
673 vec3i cur_pos_max_cell_a = new_tree_acc_pos_max_cell[i];
675 for(
u32 j = 0 ; j < tree_leaf_count + tree_internal_count; j++){
677 vec3i cur_pos_min_cell_b = old_tree_acc_pos_min_cell[j];
678 vec3i cur_pos_max_cell_b = old_tree_acc_pos_max_cell[j];
681 auto is_same_box = [&]() ->
bool {
683 (cur_pos_min_cell_a.x() == cur_pos_min_cell_b.x()) &&
684 (cur_pos_min_cell_a.y() == cur_pos_min_cell_b.y()) &&
685 (cur_pos_min_cell_a.z() == cur_pos_min_cell_b.z()) &&
686 (cur_pos_max_cell_a.x() == cur_pos_max_cell_b.x()) &&
687 (cur_pos_max_cell_a.y() == cur_pos_max_cell_b.y()) &&
688 (cur_pos_max_cell_a.z() == cur_pos_max_cell_b.z()) ;
695 logger::raw_ln(
"i ->",cur_pos_min_cell_a,cur_pos_max_cell_a ,
"| ptr ->",cur_pos_min_cell_b,cur_pos_max_cell_b);
698 if(store_val >= tree_internal_count){
699 store_val -= tree_internal_count;
702 acc_new_node_id_to_old[i] = store_val;
712 ret.print_tree_field(*new_node_id_to_old_naive);
713 std::unique_ptr<sycl::buffer<u32>> new_node_id_to_old_v1 = std::make_unique<sycl::buffer<u32>>(ret.tree_leaf_count + ret.tree_internal_count);
716 auto & new_node_id_to_old = new_node_id_to_old_v1;
720 sycl::host_accessor acc{* new_node_id_to_old, sycl::write_only, sycl::no_init};
721 for (
u32 i = 0 ; i < new_node_id_to_old->size(); i++) {
727 sycl::host_accessor acc_new_node_id_to_old {*new_node_id_to_old,sycl::write_only, sycl::no_init};
729 sycl::host_accessor new_tree_acc_pos_min_cell{*ret.buf_pos_min_cell,sycl::read_only};
730 sycl::host_accessor new_tree_acc_pos_max_cell{*ret.buf_pos_max_cell,sycl::read_only};
732 sycl::host_accessor old_tree_acc_pos_min_cell{*buf_pos_min_cell,sycl::read_only};
733 sycl::host_accessor old_tree_acc_pos_max_cell{*buf_pos_max_cell,sycl::read_only};
735 sycl::host_accessor old_tree_lchild_id {*buf_lchild_id ,sycl::read_only};
736 sycl::host_accessor old_tree_rchild_id {*buf_rchild_id ,sycl::read_only};
737 sycl::host_accessor old_tree_lchild_flag {*buf_lchild_flag,sycl::read_only};
738 sycl::host_accessor old_tree_rchild_flag {*buf_rchild_flag,sycl::read_only};
740 u32 old_tree_leaf_offset = tree_internal_count;
743 for(
u32 i = 0 ; i < ret.tree_leaf_count + ret.tree_internal_count; i++){
747 vec3i cur_pos_min_cell_a = new_tree_acc_pos_min_cell[i];
748 vec3i cur_pos_max_cell_a = new_tree_acc_pos_max_cell[i];
751 vec3i cur_pos_min_cell_b = old_tree_acc_pos_min_cell[cur_id];
752 vec3i cur_pos_max_cell_b = old_tree_acc_pos_max_cell[cur_id];
758 auto is_same_box = [&]() ->
bool {
760 (cur_pos_min_cell_a.x() == cur_pos_min_cell_b.x()) &&
761 (cur_pos_min_cell_a.y() == cur_pos_min_cell_b.y()) &&
762 (cur_pos_min_cell_a.z() == cur_pos_min_cell_b.z()) &&
763 (cur_pos_max_cell_a.x() == cur_pos_max_cell_b.x()) &&
764 (cur_pos_max_cell_a.y() == cur_pos_max_cell_b.y()) &&
765 (cur_pos_max_cell_a.z() == cur_pos_max_cell_b.z()) ;
768 auto potential_cell = [&](vec3i other_min, vec3i other_max) ->
bool {
770 (cur_pos_min_cell_a.x() >= other_min.x()) &&
771 (cur_pos_min_cell_a.y() >= other_min.y()) &&
772 (cur_pos_min_cell_a.z() >= other_min.z()) &&
773 (cur_pos_max_cell_a.x() <= other_max.x()) &&
774 (cur_pos_max_cell_a.y() <= other_max.y()) &&
775 (cur_pos_max_cell_a.z() <= other_max.z()) ;
782 u32 store_val = cur_id;
784 if(store_val >= tree_internal_count){
785 store_val -= tree_internal_count;
788 acc_new_node_id_to_old[i] = store_val;
794 u32 lid = old_tree_lchild_id[cur_id] + old_tree_leaf_offset * old_tree_lchild_flag[cur_id];
795 u32 rid = old_tree_rchild_id[cur_id] + old_tree_leaf_offset * old_tree_rchild_flag[cur_id];
797 vec3i cur_pos_min_cell_bl = old_tree_acc_pos_min_cell[lid];
798 vec3i cur_pos_max_cell_bl = old_tree_acc_pos_max_cell[lid];
800 vec3i cur_pos_min_cell_br = old_tree_acc_pos_min_cell[rid];
801 vec3i cur_pos_max_cell_br = old_tree_acc_pos_max_cell[rid];
803 bool l_ok = potential_cell(cur_pos_min_cell_bl,cur_pos_max_cell_bl);
804 bool r_ok = potential_cell(cur_pos_min_cell_br,cur_pos_max_cell_br);
811 cur_pos_min_cell_b = cur_pos_min_cell_bl;
812 cur_pos_max_cell_b = cur_pos_max_cell_bl;
818 cur_pos_min_cell_b = cur_pos_min_cell_br;
819 cur_pos_max_cell_b = cur_pos_max_cell_br;
838 ret.print_tree_field(*new_node_id_to_old_v1);
842 std::unique_ptr<sycl::buffer<u32>> new_node_id_to_old_v2
843 = std::make_unique<sycl::buffer<u32>>(
844 ret.tree_reduced_morton_codes.tree_leaf_count
845 + ret.tree_struct.internal_cell_count);
848 auto &new_node_id_to_old = new_node_id_to_old_v2;
852 sycl::host_accessor acc{*new_node_id_to_old, sycl::write_only, sycl::no_init};
853 for (
u32 i = 0; i < new_node_id_to_old->size(); i++) {
859 sycl::accessor acc_new_node_id_to_old{
860 *new_node_id_to_old, cgh, sycl::write_only, sycl::no_init};
862 sycl::accessor new_tree_acc_pos_min_cell{
863 *ret.tree_cell_ranges.buf_pos_min_cell, cgh, sycl::read_write};
864 sycl::accessor new_tree_acc_pos_max_cell{
865 *ret.tree_cell_ranges.buf_pos_max_cell, cgh, sycl::read_write};
867 sycl::accessor old_tree_acc_pos_min_cell{
868 *tree_cell_ranges.buf_pos_min_cell, cgh, sycl::read_only};
869 sycl::accessor old_tree_acc_pos_max_cell{
870 *tree_cell_ranges.buf_pos_max_cell, cgh, sycl::read_only};
872 sycl::accessor old_tree_lchild_id{*tree_struct.buf_lchild_id, cgh, sycl::read_only};
873 sycl::accessor old_tree_rchild_id{*tree_struct.buf_rchild_id, cgh, sycl::read_only};
874 sycl::accessor old_tree_lchild_flag{
875 *tree_struct.buf_lchild_flag, cgh, sycl::read_only};
876 sycl::accessor old_tree_rchild_flag{
877 *tree_struct.buf_rchild_flag, cgh, sycl::read_only};
879 u32 old_tree_leaf_offset = tree_struct.internal_cell_count;
881 sycl::range<1> range_node = sycl::range<1>{
882 ret.tree_reduced_morton_codes.tree_leaf_count
883 + ret.tree_struct.internal_cell_count};
887 cgh.parallel_for(range_node, [=](sycl::item<1> item) {
890 ipos_t cur_pos_min_cell_a = new_tree_acc_pos_min_cell[item];
891 ipos_t cur_pos_max_cell_a = new_tree_acc_pos_max_cell[item];
894 ipos_t cur_pos_min_cell_b = old_tree_acc_pos_min_cell[cur_id];
895 ipos_t cur_pos_max_cell_b = old_tree_acc_pos_max_cell[cur_id];
902 auto is_same_box = [&]() ->
bool {
903 return (cur_pos_min_cell_a.x() == cur_pos_min_cell_b.x())
904 && (cur_pos_min_cell_a.y() == cur_pos_min_cell_b.y())
905 && (cur_pos_min_cell_a.z() == cur_pos_min_cell_b.z())
906 && (cur_pos_max_cell_a.x() == cur_pos_max_cell_b.x())
907 && (cur_pos_max_cell_a.y() == cur_pos_max_cell_b.y())
908 && (cur_pos_max_cell_a.z() == cur_pos_max_cell_b.z());
911 auto potential_cell = [&](ipos_t other_min, ipos_t other_max) ->
bool {
912 return (cur_pos_min_cell_a.x() >= other_min.x())
913 && (cur_pos_min_cell_a.y() >= other_min.y())
914 && (cur_pos_min_cell_a.z() >= other_min.z())
915 && (cur_pos_max_cell_a.x() <= other_max.x())
916 && (cur_pos_max_cell_a.y() <= other_max.y())
917 && (cur_pos_max_cell_a.z() <= other_max.z());
920 auto contain_cell = [&](ipos_t other_min, ipos_t other_max) ->
bool {
921 return (cur_pos_min_cell_a.x() <= other_min.x())
922 && (cur_pos_min_cell_a.y() <= other_min.y())
923 && (cur_pos_min_cell_a.z() <= other_min.z())
924 && (cur_pos_max_cell_a.x() >= other_max.x())
925 && (cur_pos_max_cell_a.y() >= other_max.y())
926 && (cur_pos_max_cell_a.z() >= other_max.z());
933 u32 store_val = cur_id;
939 acc_new_node_id_to_old[item] = store_val;
944 u32 lid = old_tree_lchild_id[cur_id]
945 + old_tree_leaf_offset * old_tree_lchild_flag[cur_id];
946 u32 rid = old_tree_rchild_id[cur_id]
947 + old_tree_leaf_offset * old_tree_rchild_flag[cur_id];
949 ipos_t cur_pos_min_cell_bl = old_tree_acc_pos_min_cell[lid];
950 ipos_t cur_pos_max_cell_bl = old_tree_acc_pos_max_cell[lid];
952 ipos_t cur_pos_min_cell_br = old_tree_acc_pos_min_cell[rid];
953 ipos_t cur_pos_max_cell_br = old_tree_acc_pos_max_cell[rid];
955 bool l_ok = potential_cell(cur_pos_min_cell_bl, cur_pos_max_cell_bl);
956 bool r_ok = potential_cell(cur_pos_min_cell_br, cur_pos_max_cell_br);
965 cur_pos_min_cell_b = cur_pos_min_cell_bl;
966 cur_pos_max_cell_b = cur_pos_max_cell_bl;
972 cur_pos_min_cell_b = cur_pos_min_cell_br;
973 cur_pos_max_cell_b = cur_pos_max_cell_br;
983 bool l_contain = contain_cell(cur_pos_min_cell_bl, cur_pos_max_cell_bl);
984 bool r_contain = contain_cell(cur_pos_min_cell_br, cur_pos_max_cell_br);
994 u32 store_val = cur_id;
995 acc_new_node_id_to_old[item] = store_val;
999 new_tree_acc_pos_min_cell[item] = cur_pos_min_cell_bl;
1000 new_tree_acc_pos_max_cell[item] = cur_pos_max_cell_bl;
1003 }
else if (r_contain) {
1006 u32 store_val = cur_id;
1007 acc_new_node_id_to_old[item] = store_val;
1011 new_tree_acc_pos_min_cell[item] = cur_pos_min_cell_br;
1012 new_tree_acc_pos_max_cell[item] = cur_pos_max_cell_br;
1019 u32 store_val = cur_id;
1025 acc_new_node_id_to_old[item] = store_val;
1036 shamrock::sfc::MortonKernels<u_morton, vec3, dim>::sycl_irange_to_range(
1038 ret.tree_reduced_morton_codes.tree_leaf_count + ret.tree_struct.internal_cell_count,
1039 std::get<0>(ret.bounding_box),
1040 std::get<1>(ret.bounding_box),
1041 ret.tree_cell_ranges.buf_pos_min_cell,
1042 ret.tree_cell_ranges.buf_pos_max_cell,
1043 ret.tree_cell_ranges.buf_pos_min_cell_flt,
1044 ret.tree_cell_ranges.buf_pos_max_cell_flt);
1051 tree_struct.internal_cell_count,
1053 ret.tree_struct.internal_cell_count,
1055 tree_morton_codes.obj_cnt,
1061 std::move(new_node_id_to_old_v2),
1062 std::make_unique<sycl::buffer<u32>>(shamalgs::memory::vector_to_buf(
constexpr const char * uint
Specific internal energy u.
Header file describing a Node Instance.
sycl::queue & get_compute_queue(u32 id=0)
Utility to build morton codes for the radix tree.
float f32
Alias for float.
std::uint8_t u8
8 bit unsigned integer
std::uint32_t u32
32 bit unsigned integer
A buffer allocated in USM (Unified Shared Memory).
A SYCL queue associated with a device and a context.
sycl::event submit(Fct &&fct)
Submits a kernel to the SYCL queue.
Class to manage a list of SYCL events.
static TreeMortonCodes deserialize(shamalgs::SerializeHelper &serializer)
deserialize a TreeMortonCodes object Note : here since the initial buffer is a pow of 2 with traillin...
void print_buf(sycl::buffer< T > &buf, u32 len, u32 column_count, std::string_view fmt)
Print the content of a sycl::buffer.
namespace for basic c++ utilities
constexpr u32 group_count(u32 len, u32 group_size)
Calculates the number of groups based on the length and group size.
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...
ExcptTypes make_except_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Create an exception with a message and a location.
constexpr u32 u32_max
u32 max value
constexpr i32 i32_max
i32 max value
main include file for memory algorithms
void raw_ln(Types... var2)
Prints a log message with multiple arguments followed by a newline.
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.
header file to manage sycl