27template<
class u_morton,
class vec3>
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>
63 std::tuple<vec3, vec3> treebox,
64 const std::unique_ptr<sycl::buffer<vec3>> &pos_buf,
69template<
class u_morton,
class Tvec>
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));
145template<
class u_morton,
class vec3>
148 tree_cell_ranges.build1(queue, tree_reduced_morton_codes, tree_struct);
151template<
class morton_t,
class pos_t>
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>
163 shamlog_debug_sycl_ln(
"RadixTree",
"compute int boxes");
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];
237 logger::raw_ln(
"gid",gid);
238 logger::raw_ln(
"lid_0",lid_0);
239 logger::raw_ln(
"rid_0",rid_0);
240 logger::raw_ln(
"lfl_0",lfl_0);
241 logger::raw_ln(
"rfl_0",rfl_0);
242 logger::raw_ln(
"offset_leaf",offset_leaf);
243 logger::raw_ln(
"lid",lid);
244 logger::raw_ln(
"rid",rid);
245 logger::raw_ln(
"sz =", buf_cell_int_rad_buf->size());
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);
291 if (shamalgs::reduction::has_nan(
293 *buf_cell_int_rad_buf,
294 tree_struct.internal_cell_count + tree_reduced_morton_codes.tree_leaf_count)) {
296 *buf_cell_int_rad_buf,
297 tree_struct.internal_cell_count + tree_reduced_morton_codes.tree_leaf_count,
301 "the structure of the tree as issue in ids");
305 return std::move(buf_cell_interact_rad);
309std::string print_member(
const T &a);
312std::string print_member(
const u8 &a) {
317std::string print_member(
const u32 &a) {
321template<
class u_morton,
class vec3>
325 sycl::host_accessor acc{buf_field, sycl::read_only};
327 u32 total_count = tree_struct.internal_cell_count + tree_reduced_morton_codes.tree_leaf_count;
329 u32 offset_leaf = tree_struct.internal_cell_count;
331 sycl::host_accessor rchild_id{*tree_struct.buf_rchild_id};
332 sycl::host_accessor lchild_id{*tree_struct.buf_lchild_id};
333 sycl::host_accessor rchild_flag{*tree_struct.buf_rchild_flag};
334 sycl::host_accessor lchild_flag{*tree_struct.buf_lchild_flag};
337 auto printer = [&]() {
339 = [&](
u32 gid, std::string prefix,
bool is_left,
auto &step_ref) -> std::string {
340 std::string ret_val =
"";
346 std::string val =
" (" + print_member(acc[gid]) +
") ";
347 std::string val_empt = std::string(val.size(),
' ');
349 ret_val += (is_left ?
"╦══" :
"╚══");
352 if (gid < offset_leaf) {
353 u32 lid = lchild_id[gid] + offset_leaf * lchild_flag[gid];
354 u32 rid = rchild_id[gid] + offset_leaf * rchild_flag[gid];
357 lid, prefix + (is_left ?
"║ " + val_empt :
" " + val_empt), true, step_ref);
359 rid, prefix + (is_left ?
"║ " + val_empt :
" " + val_empt), false, step_ref);
367 logger::raw_ln(get_print_step(0,
"",
false, get_print_step));
385template<
class u_morton,
class vec3>
387 sycl::queue &queue, sycl::buffer<u8> &valid_node) {
389 u32 total_count = tree_struct.internal_cell_count + tree_reduced_morton_codes.tree_leaf_count;
390 sycl::range<1> range_tree{total_count};
401 sycl::buffer<u8> valid_node_new = sycl::buffer<u8>(total_count);
403 for (
u32 it = 0; it < tree_depth; it++) {
405 shamlog_debug_sycl_ln(
"Radixtree",
"cascading zeros step : ", it);
406 queue.submit([&](sycl::handler &cgh) {
407 sycl::accessor acc_valid_node_old{valid_node, cgh, sycl::read_only};
408 sycl::accessor acc_valid_node_new{
409 valid_node_new, cgh, sycl::write_only, sycl::no_init};
411 sycl::accessor acc_lchild_id{*tree_struct.buf_lchild_id, cgh, sycl::read_only};
412 sycl::accessor acc_rchild_id{*tree_struct.buf_rchild_id, cgh, sycl::read_only};
413 sycl::accessor acc_lchild_flag{
414 *tree_struct.buf_lchild_flag, cgh, sycl::read_only};
415 sycl::accessor acc_rchild_flag{
416 *tree_struct.buf_rchild_flag, cgh, sycl::read_only};
418 u32 leaf_offset = tree_struct.internal_cell_count;
421 sycl::range<1>(tree_struct.internal_cell_count), [=](sycl::item<1> item) {
422 u32 lid = acc_lchild_id[item] + leaf_offset * acc_lchild_flag[item];
423 u32 rid = acc_rchild_id[item] + leaf_offset * acc_rchild_flag[item];
425 u8 old_nid_falg = acc_valid_node_old[item];
427 if (item.get_linear_id() == 0) {
428 acc_valid_node_new[item] = old_nid_falg;
431 if (old_nid_falg == 0 || old_nid_falg == 2) {
432 acc_valid_node_new[lid] = 0;
433 acc_valid_node_new[rid] = 0;
435 u8 old_lid_falg = acc_valid_node_old[lid];
436 u8 old_rid_falg = acc_valid_node_old[rid];
438 if (old_lid_falg == 0) {
441 if (old_rid_falg == 0) {
445 acc_valid_node_new[lid] = old_lid_falg;
446 acc_valid_node_new[rid] = old_rid_falg;
451 std::swap(valid_node, valid_node_new);
461 sycl::buffer<u8> valid_tree_morton(tree_reduced_morton_codes.tree_leaf_count);
463 auto print_valid_morton = [&] {
464 shamlog_debug_sycl_ln(
"Radixtree",
"valid_tree_morton");
466 sycl::buffer<u32> print_map(total_count);
470 sycl::host_accessor acc{print_map};
471 sycl::host_accessor acc_leaf{valid_tree_morton};
473 for (
u32 i = 0; i < tree_reduced_morton_codes.tree_leaf_count; i++) {
474 acc[i + tree_struct.internal_cell_count] = acc_leaf[i];
477 for (
u32 i = 0; i < tree_struct.internal_cell_count; i++) {
478 acc[i] = acc_leaf[i];
482 print_tree_field(print_map);
487 queue.submit([&](sycl::handler &cgh) {
488 sycl::accessor acc_valid_tree_morton{
489 valid_tree_morton, cgh, sycl::write_only, sycl::no_init};
491 sycl::accessor acc_valid_node{valid_node, cgh, sycl::read_only};
493 u32 leaf_offset = tree_struct.internal_cell_count;
496 sycl::range<1>(tree_reduced_morton_codes.tree_leaf_count), [=](sycl::item<1> item) {
497 u8 leaf_val = acc_valid_node[item.get_linear_id() + leaf_offset];
499 if (item.get_linear_id() < leaf_offset) {
500 if (acc_valid_node[item] == 2) {
505 acc_valid_tree_morton[item] = leaf_val;
515 ret.bounding_box = bounding_box;
517 std::vector<u32> extract_id;
521 std::vector<u_morton> new_buf_morton;
522 std::vector<u32> new_buf_particle_index_map;
523 std::vector<u32> new_reduc_index_map;
525 u32 leaf_offset = tree_struct.internal_cell_count;
527 sycl::host_accessor cell_index_map{
528 *tree_reduced_morton_codes.buf_reduc_index_map, sycl::read_only};
529 sycl::host_accessor particle_index_map{
530 *tree_morton_codes.buf_particle_index_map, sycl::read_only};
532 sycl::host_accessor acc_valid_tree_morton{valid_tree_morton, sycl::read_only};
534 sycl::host_accessor acc_morton{*tree_morton_codes.buf_morton, sycl::read_only};
538 for (
u32 i = 0; i < tree_reduced_morton_codes.tree_leaf_count; i++) {
539 if (acc_valid_tree_morton[i] != 0) {
543 uint min_ids = cell_index_map[i];
544 uint max_ids = cell_index_map[i + 1];
546 new_reduc_index_map.push_back(cnt);
548 for (
unsigned int id_s = min_ids; id_s < max_ids; id_s++) {
551 uint id_b = particle_index_map[id_s];
555 extract_id.push_back(id_b);
556 new_buf_morton.push_back(acc_morton[id_b]);
557 new_buf_particle_index_map.push_back(cnt);
566 new_reduc_index_map.push_back(cnt);
568 std::vector<u_morton> new_morton_tree;
571 sycl::host_accessor acc_tree_morton{*tree_reduced_morton_codes.buf_tree_morton};
573 sycl::host_accessor acc_valid_tree_morton{valid_tree_morton, sycl::read_only};
575 for (
u32 i = 0; i < tree_reduced_morton_codes.tree_leaf_count; i++) {
576 if (acc_valid_tree_morton[i] != 0) {
577 new_morton_tree.push_back(acc_tree_morton[i]);
582 ret.tree_reduced_morton_codes.tree_leaf_count = new_morton_tree.size();
583 ret.tree_struct.internal_cell_count = ret.tree_reduced_morton_codes.tree_leaf_count - 1;
585 ret.tree_morton_codes.buf_morton
586 = std::make_unique<sycl::buffer<u_morton>>(new_buf_morton.size());
588 sycl::host_accessor acc{
589 *ret.tree_morton_codes.buf_morton, sycl::write_only, sycl::no_init};
590 for (
u32 i = 0; i < new_buf_morton.size(); i++) {
591 acc[i] = new_buf_morton[i];
595 ret.tree_morton_codes.buf_particle_index_map
596 = std::make_unique<sycl::buffer<u32>>(new_buf_particle_index_map.size());
598 sycl::host_accessor acc{
599 *ret.tree_morton_codes.buf_particle_index_map, sycl::write_only, sycl::no_init};
600 for (
u32 i = 0; i < new_buf_particle_index_map.size(); i++) {
601 acc[i] = new_buf_particle_index_map[i];
605 if (ret.tree_reduced_morton_codes.tree_leaf_count > 1) {
607 ret.tree_reduced_morton_codes.buf_reduc_index_map
608 = std::make_unique<sycl::buffer<u32>>(new_reduc_index_map.size());
610 sycl::host_accessor acc{
611 *ret.tree_reduced_morton_codes.buf_reduc_index_map,
614 for (
u32 i = 0; i < new_reduc_index_map.size(); i++) {
615 acc[i] = new_reduc_index_map[i];
619 ret.tree_reduced_morton_codes.buf_tree_morton
620 = std::make_unique<sycl::buffer<u_morton>>(new_morton_tree.size());
622 sycl::host_accessor acc{
623 *ret.tree_reduced_morton_codes.buf_tree_morton,
626 for (
u32 i = 0; i < new_morton_tree.size(); i++) {
627 acc[i] = new_morton_tree[i];
631 ret.tree_struct.build(
633 ret.tree_struct.internal_cell_count,
634 *ret.tree_reduced_morton_codes.buf_tree_morton);
641 ret.compute_cell_ibounding_box(queue);
642 ret.convert_bounding_box(queue);
645 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);
648 auto & new_node_id_to_old = new_node_id_to_old_naive;
652 sycl::host_accessor acc{* new_node_id_to_old, sycl::write_only, sycl::no_init};
653 for (
u32 i = 0 ; i < new_node_id_to_old->size(); i++) {
659 sycl::host_accessor acc_new_node_id_to_old {*new_node_id_to_old,sycl::write_only, sycl::no_init};
661 sycl::host_accessor new_tree_acc_pos_min_cell{*ret.buf_pos_min_cell,sycl::read_only};
662 sycl::host_accessor new_tree_acc_pos_max_cell{*ret.buf_pos_max_cell,sycl::read_only};
664 sycl::host_accessor old_tree_acc_pos_min_cell{*buf_pos_min_cell,sycl::read_only};
665 sycl::host_accessor old_tree_acc_pos_max_cell{*buf_pos_max_cell,sycl::read_only};
667 for(
u32 i = 0 ; i < ret.tree_leaf_count + ret.tree_internal_count; i++){
669 vec3i cur_pos_min_cell_a = new_tree_acc_pos_min_cell[i];
670 vec3i cur_pos_max_cell_a = new_tree_acc_pos_max_cell[i];
672 for(
u32 j = 0 ; j < tree_leaf_count + tree_internal_count; j++){
674 vec3i cur_pos_min_cell_b = old_tree_acc_pos_min_cell[j];
675 vec3i cur_pos_max_cell_b = old_tree_acc_pos_max_cell[j];
678 auto is_same_box = [&]() ->
bool {
680 (cur_pos_min_cell_a.x() == cur_pos_min_cell_b.x()) &&
681 (cur_pos_min_cell_a.y() == cur_pos_min_cell_b.y()) &&
682 (cur_pos_min_cell_a.z() == cur_pos_min_cell_b.z()) &&
683 (cur_pos_max_cell_a.x() == cur_pos_max_cell_b.x()) &&
684 (cur_pos_max_cell_a.y() == cur_pos_max_cell_b.y()) &&
685 (cur_pos_max_cell_a.z() == cur_pos_max_cell_b.z()) ;
692 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);
695 if(store_val >= tree_internal_count){
696 store_val -= tree_internal_count;
699 acc_new_node_id_to_old[i] = store_val;
709 ret.print_tree_field(*new_node_id_to_old_naive);
710 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);
713 auto & new_node_id_to_old = new_node_id_to_old_v1;
717 sycl::host_accessor acc{* new_node_id_to_old, sycl::write_only, sycl::no_init};
718 for (
u32 i = 0 ; i < new_node_id_to_old->size(); i++) {
724 sycl::host_accessor acc_new_node_id_to_old {*new_node_id_to_old,sycl::write_only, sycl::no_init};
726 sycl::host_accessor new_tree_acc_pos_min_cell{*ret.buf_pos_min_cell,sycl::read_only};
727 sycl::host_accessor new_tree_acc_pos_max_cell{*ret.buf_pos_max_cell,sycl::read_only};
729 sycl::host_accessor old_tree_acc_pos_min_cell{*buf_pos_min_cell,sycl::read_only};
730 sycl::host_accessor old_tree_acc_pos_max_cell{*buf_pos_max_cell,sycl::read_only};
732 sycl::host_accessor old_tree_lchild_id {*buf_lchild_id ,sycl::read_only};
733 sycl::host_accessor old_tree_rchild_id {*buf_rchild_id ,sycl::read_only};
734 sycl::host_accessor old_tree_lchild_flag {*buf_lchild_flag,sycl::read_only};
735 sycl::host_accessor old_tree_rchild_flag {*buf_rchild_flag,sycl::read_only};
737 u32 old_tree_leaf_offset = tree_internal_count;
740 for(
u32 i = 0 ; i < ret.tree_leaf_count + ret.tree_internal_count; i++){
744 vec3i cur_pos_min_cell_a = new_tree_acc_pos_min_cell[i];
745 vec3i cur_pos_max_cell_a = new_tree_acc_pos_max_cell[i];
748 vec3i cur_pos_min_cell_b = old_tree_acc_pos_min_cell[cur_id];
749 vec3i cur_pos_max_cell_b = old_tree_acc_pos_max_cell[cur_id];
755 auto is_same_box = [&]() ->
bool {
757 (cur_pos_min_cell_a.x() == cur_pos_min_cell_b.x()) &&
758 (cur_pos_min_cell_a.y() == cur_pos_min_cell_b.y()) &&
759 (cur_pos_min_cell_a.z() == cur_pos_min_cell_b.z()) &&
760 (cur_pos_max_cell_a.x() == cur_pos_max_cell_b.x()) &&
761 (cur_pos_max_cell_a.y() == cur_pos_max_cell_b.y()) &&
762 (cur_pos_max_cell_a.z() == cur_pos_max_cell_b.z()) ;
765 auto potential_cell = [&](vec3i other_min, vec3i other_max) ->
bool {
767 (cur_pos_min_cell_a.x() >= other_min.x()) &&
768 (cur_pos_min_cell_a.y() >= other_min.y()) &&
769 (cur_pos_min_cell_a.z() >= other_min.z()) &&
770 (cur_pos_max_cell_a.x() <= other_max.x()) &&
771 (cur_pos_max_cell_a.y() <= other_max.y()) &&
772 (cur_pos_max_cell_a.z() <= other_max.z()) ;
779 u32 store_val = cur_id;
781 if(store_val >= tree_internal_count){
782 store_val -= tree_internal_count;
785 acc_new_node_id_to_old[i] = store_val;
791 u32 lid = old_tree_lchild_id[cur_id] + old_tree_leaf_offset * old_tree_lchild_flag[cur_id];
792 u32 rid = old_tree_rchild_id[cur_id] + old_tree_leaf_offset * old_tree_rchild_flag[cur_id];
794 vec3i cur_pos_min_cell_bl = old_tree_acc_pos_min_cell[lid];
795 vec3i cur_pos_max_cell_bl = old_tree_acc_pos_max_cell[lid];
797 vec3i cur_pos_min_cell_br = old_tree_acc_pos_min_cell[rid];
798 vec3i cur_pos_max_cell_br = old_tree_acc_pos_max_cell[rid];
800 bool l_ok = potential_cell(cur_pos_min_cell_bl,cur_pos_max_cell_bl);
801 bool r_ok = potential_cell(cur_pos_min_cell_br,cur_pos_max_cell_br);
808 cur_pos_min_cell_b = cur_pos_min_cell_bl;
809 cur_pos_max_cell_b = cur_pos_max_cell_bl;
815 cur_pos_min_cell_b = cur_pos_min_cell_br;
816 cur_pos_max_cell_b = cur_pos_max_cell_br;
835 ret.print_tree_field(*new_node_id_to_old_v1);
839 std::unique_ptr<sycl::buffer<u32>> new_node_id_to_old_v2
840 = std::make_unique<sycl::buffer<u32>>(
841 ret.tree_reduced_morton_codes.tree_leaf_count
842 + ret.tree_struct.internal_cell_count);
845 auto &new_node_id_to_old = new_node_id_to_old_v2;
849 sycl::host_accessor acc{*new_node_id_to_old, sycl::write_only, sycl::no_init};
850 for (
u32 i = 0; i < new_node_id_to_old->size(); i++) {
856 sycl::accessor acc_new_node_id_to_old{
857 *new_node_id_to_old, cgh, sycl::write_only, sycl::no_init};
859 sycl::accessor new_tree_acc_pos_min_cell{
860 *ret.tree_cell_ranges.buf_pos_min_cell, cgh, sycl::read_write};
861 sycl::accessor new_tree_acc_pos_max_cell{
862 *ret.tree_cell_ranges.buf_pos_max_cell, cgh, sycl::read_write};
864 sycl::accessor old_tree_acc_pos_min_cell{
865 *tree_cell_ranges.buf_pos_min_cell, cgh, sycl::read_only};
866 sycl::accessor old_tree_acc_pos_max_cell{
867 *tree_cell_ranges.buf_pos_max_cell, cgh, sycl::read_only};
869 sycl::accessor old_tree_lchild_id{*tree_struct.buf_lchild_id, cgh, sycl::read_only};
870 sycl::accessor old_tree_rchild_id{*tree_struct.buf_rchild_id, cgh, sycl::read_only};
871 sycl::accessor old_tree_lchild_flag{
872 *tree_struct.buf_lchild_flag, cgh, sycl::read_only};
873 sycl::accessor old_tree_rchild_flag{
874 *tree_struct.buf_rchild_flag, cgh, sycl::read_only};
876 u32 old_tree_leaf_offset = tree_struct.internal_cell_count;
878 sycl::range<1> range_node = sycl::range<1>{
879 ret.tree_reduced_morton_codes.tree_leaf_count
880 + ret.tree_struct.internal_cell_count};
884 cgh.parallel_for(range_node, [=](sycl::item<1> item) {
887 ipos_t cur_pos_min_cell_a = new_tree_acc_pos_min_cell[item];
888 ipos_t cur_pos_max_cell_a = new_tree_acc_pos_max_cell[item];
891 ipos_t cur_pos_min_cell_b = old_tree_acc_pos_min_cell[cur_id];
892 ipos_t cur_pos_max_cell_b = old_tree_acc_pos_max_cell[cur_id];
899 auto is_same_box = [&]() ->
bool {
900 return (cur_pos_min_cell_a.x() == cur_pos_min_cell_b.x())
901 && (cur_pos_min_cell_a.y() == cur_pos_min_cell_b.y())
902 && (cur_pos_min_cell_a.z() == cur_pos_min_cell_b.z())
903 && (cur_pos_max_cell_a.x() == cur_pos_max_cell_b.x())
904 && (cur_pos_max_cell_a.y() == cur_pos_max_cell_b.y())
905 && (cur_pos_max_cell_a.z() == cur_pos_max_cell_b.z());
908 auto potential_cell = [&](ipos_t other_min, ipos_t other_max) ->
bool {
909 return (cur_pos_min_cell_a.x() >= other_min.x())
910 && (cur_pos_min_cell_a.y() >= other_min.y())
911 && (cur_pos_min_cell_a.z() >= other_min.z())
912 && (cur_pos_max_cell_a.x() <= other_max.x())
913 && (cur_pos_max_cell_a.y() <= other_max.y())
914 && (cur_pos_max_cell_a.z() <= other_max.z());
917 auto contain_cell = [&](ipos_t other_min, ipos_t other_max) ->
bool {
918 return (cur_pos_min_cell_a.x() <= other_min.x())
919 && (cur_pos_min_cell_a.y() <= other_min.y())
920 && (cur_pos_min_cell_a.z() <= other_min.z())
921 && (cur_pos_max_cell_a.x() >= other_max.x())
922 && (cur_pos_max_cell_a.y() >= other_max.y())
923 && (cur_pos_max_cell_a.z() >= other_max.z());
930 u32 store_val = cur_id;
936 acc_new_node_id_to_old[item] = store_val;
941 u32 lid = old_tree_lchild_id[cur_id]
942 + old_tree_leaf_offset * old_tree_lchild_flag[cur_id];
943 u32 rid = old_tree_rchild_id[cur_id]
944 + old_tree_leaf_offset * old_tree_rchild_flag[cur_id];
946 ipos_t cur_pos_min_cell_bl = old_tree_acc_pos_min_cell[lid];
947 ipos_t cur_pos_max_cell_bl = old_tree_acc_pos_max_cell[lid];
949 ipos_t cur_pos_min_cell_br = old_tree_acc_pos_min_cell[rid];
950 ipos_t cur_pos_max_cell_br = old_tree_acc_pos_max_cell[rid];
952 bool l_ok = potential_cell(cur_pos_min_cell_bl, cur_pos_max_cell_bl);
953 bool r_ok = potential_cell(cur_pos_min_cell_br, cur_pos_max_cell_br);
962 cur_pos_min_cell_b = cur_pos_min_cell_bl;
963 cur_pos_max_cell_b = cur_pos_max_cell_bl;
969 cur_pos_min_cell_b = cur_pos_min_cell_br;
970 cur_pos_max_cell_b = cur_pos_max_cell_br;
980 bool l_contain = contain_cell(cur_pos_min_cell_bl, cur_pos_max_cell_bl);
981 bool r_contain = contain_cell(cur_pos_min_cell_br, cur_pos_max_cell_br);
991 u32 store_val = cur_id;
992 acc_new_node_id_to_old[item] = store_val;
996 new_tree_acc_pos_min_cell[item] = cur_pos_min_cell_bl;
997 new_tree_acc_pos_max_cell[item] = cur_pos_max_cell_bl;
1000 }
else if (r_contain) {
1003 u32 store_val = cur_id;
1004 acc_new_node_id_to_old[item] = store_val;
1008 new_tree_acc_pos_min_cell[item] = cur_pos_min_cell_br;
1009 new_tree_acc_pos_max_cell[item] = cur_pos_max_cell_br;
1016 u32 store_val = cur_id;
1022 acc_new_node_id_to_old[item] = store_val;
1035 ret.tree_reduced_morton_codes.tree_leaf_count + ret.tree_struct.internal_cell_count,
1036 std::get<0>(ret.bounding_box),
1037 std::get<1>(ret.bounding_box),
1038 ret.tree_cell_ranges.buf_pos_min_cell,
1039 ret.tree_cell_ranges.buf_pos_max_cell,
1040 ret.tree_cell_ranges.buf_pos_min_cell_flt,
1041 ret.tree_cell_ranges.buf_pos_max_cell_flt);
1048 tree_struct.internal_cell_count,
1050 ret.tree_struct.internal_cell_count,
1052 tree_morton_codes.obj_cnt,
1058 std::move(new_node_id_to_old_v2),
1059 std::make_unique<sycl::buffer<u32>>(shamalgs::memory::vector_to_buf(
1060 shamsys::instance::get_compute_queue(), std::move(extract_id)))};
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.
DeviceQueue & get_queue(u32 id=0)
Get a reference to a DeviceQueue.
Class to manage a list of SYCL events.
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.
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
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...
constexpr u32 u32_max
u32 max value
constexpr i32 i32_max
i32 max value
main include file for memory algorithms
header file to manage sycl