Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
KarrasTreeTraverser.hpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
10#pragma once
11
21#include <vector>
22
23namespace shamtree {
24
29 struct KarrasTreeTraverser;
30
32 struct KarrasTreeTraverserHost;
33
35 struct KarrasTreeTraverserAccessed;
36
37} // namespace shamtree
38
40 const u32 *lchild_id;
41 const u32 *rchild_id;
42 const u8 *lchild_flag;
43 const u8 *rchild_flag;
44 u32 offset_leaf;
45
52 inline u32 get_left_child(u32 id) const {
53 return lchild_id[id] + offset_leaf * u32(lchild_flag[id]);
54 }
55
62 inline u32 get_right_child(u32 id) const {
63 return rchild_id[id] + offset_leaf * u32(rchild_flag[id]);
64 }
65
67 inline bool is_id_leaf(u32 id) const { return id >= offset_leaf; }
68
70 template<u32 tree_depth, class Functor1, class Functor2, class Functor3>
72 u32 root_node,
73 Functor1 &&traverse_condition,
74 Functor2 &&on_found_leaf,
75 Functor3 &&on_excluded_node) const {
76
77 static constexpr u32 _nindex = 4294967295;
78
79 // Init the stack state
80 std::array<u32, tree_depth> id_stack;
81
82 u32 stack_cursor = tree_depth - 1;
83 id_stack[stack_cursor] = root_node;
84
85 // until the stack is empty
86 while (stack_cursor < tree_depth) {
87
88 // Pop the top of the stack
89 u32 current_node_id = id_stack[stack_cursor];
90 id_stack[stack_cursor] = _nindex;
91 stack_cursor++;
92
93 // check iteraction creteria
94 bool cur_id_valid = traverse_condition(current_node_id);
95
96 if (cur_id_valid) { // leaf or cell satisfies the criteria
97
98 if (is_id_leaf(current_node_id)) { // I found a leaf !!!!!
99
100 on_found_leaf(current_node_id);
101
102 } else { // it can interact & not leaf => stack
103
104 u32 lid = get_left_child(current_node_id);
105 u32 rid = get_right_child(current_node_id);
106
107 id_stack[stack_cursor - 1] = rid;
108 stack_cursor--;
109
110 id_stack[stack_cursor - 1] = lid;
111 stack_cursor--;
112 }
113 } else {
114 // This does not satisfy the criteria => excluded case (gravity for ex.)
115 on_excluded_node(current_node_id);
116 }
117 }
118 }
119
121 template<u32 tree_depth, class Functor1, class Functor2, class Functor3>
123 Functor1 &&traverse_condition,
124 Functor2 &&on_found_leaf,
125 Functor3 &&on_excluded_node) const {
126
127 // On a Karras tree, the root is always 0
128 u32 root_node = 0;
129
130 stack_based_traversal<tree_depth>(
131 root_node,
132 std::forward<Functor1>(traverse_condition),
133 std::forward<Functor2>(on_found_leaf),
134 std::forward<Functor3>(on_excluded_node));
135 }
136};
137
167
169
170 std::vector<u32> buf_lchild_id;
171 std::vector<u32> buf_rchild_id;
172 std::vector<u8> buf_lchild_flag;
173 std::vector<u8> buf_rchild_flag;
175
179 buf_lchild_id.data(),
180 buf_rchild_id.data(),
181 buf_lchild_flag.data(),
182 buf_rchild_flag.data(),
184 }
185};
std::uint8_t u8
8 bit unsigned integer
std::uint32_t u32
32 bit unsigned integer
A buffer allocated in USM (Unified Shared Memory)
void complete_event_state(sycl::event e) const
Complete the event state of the buffer.
const T * get_read_access(sham::EventList &depends_list, SourceLocation src_loc=SourceLocation{}) const
Get a read-only pointer to the buffer's data.
Class to manage a list of SYCL events.
Definition EventList.hpp:31
void stack_based_traversal(u32 root_node, Functor1 &&traverse_condition, Functor2 &&on_found_leaf, Functor3 &&on_excluded_node) const
stack based tree traversal
bool is_id_leaf(u32 id) const
is the given id a leaf (Note that if there is no internal cell every node is a leaf)
void stack_based_traversal(Functor1 &&traverse_condition, Functor2 &&on_found_leaf, Functor3 &&on_excluded_node) const
stack based tree traversal
u32 get_left_child(u32 id) const
Retrieves the left child node identifier for a given node ID.
u32 get_right_child(u32 id) const
Retrieves the right child node identifier for a given node ID.
std::vector< u32 > buf_rchild_id
ref to right child id buffer
std::vector< u32 > buf_lchild_id
ref to left child id buffer
u32 offset_leaf
how many internal nodes before the first leaf ?
std::vector< u8 > buf_lchild_flag
ref to left child flag buffer
KarrasTreeTraverserAccessed get_read_access() const
get read only accessor
std::vector< u8 > buf_rchild_flag
ref to right child flag buffer
Utility struct to traverse a Karras Radix Tree.
bool is_root_leaf() const
is the root a leaf ?
const sham::DeviceBuffer< u8 > & buf_lchild_flag
ref to left child flag buffer
u32 offset_leaf
how many internal nodes before the first leaf ?
const sham::DeviceBuffer< u8 > & buf_rchild_flag
ref to right child flag buffer
KarrasTreeTraverserAccessed get_read_access(sham::EventList &deps) const
get read only accessor
const sham::DeviceBuffer< u32 > & buf_rchild_id
ref to right child id buffer
void complete_event_state(sycl::event e) const
complete the buffer states with the resulting event
const sham::DeviceBuffer< u32 > & buf_lchild_id
ref to left child id buffer