34template<
class fp_prec_vec>
35class SerialPatchTree {
43 std::unique_ptr<sycl::buffer<PtNode>> serial_tree_buf;
44 std::unique_ptr<sycl::buffer<u64>> linked_patch_ids_buf;
46 inline void attach_buf() {
47 if (
bool(serial_tree_buf))
49 "serial_tree_buf is already allocated");
50 if (
bool(linked_patch_ids_buf))
52 "linked_patch_ids_buf is already allocated");
55 = std::make_unique<sycl::buffer<PtNode>>(serial_tree.data(), serial_tree.size());
57 = std::make_unique<sycl::buffer<u64>>(linked_patch_ids.data(), linked_patch_ids.size());
60 inline void detach_buf() {
61 if (!
bool(serial_tree_buf))
63 "serial_tree_buf wasn't allocated");
64 if (!
bool(linked_patch_ids_buf))
66 "linked_patch_ids_buf wasn't allocated");
68 serial_tree_buf.reset();
69 linked_patch_ids_buf.reset();
75 std::vector<PtNode> serial_tree;
76 std::vector<u64> linked_patch_ids;
77 std::vector<u64> roots_ids;
79 void build_from_patch_tree(
83 inline void print_status() {
85 for (PtNode n : serial_tree) {
103 inline SerialPatchTree(
106 build_from_patch_tree(ptree, box_transform);
109 template<
class Acc1,
class Acc2>
110 inline void host_for_each_leafs_internal(
111 std::function<
bool(
u64, PtNode pnode)> interact_cd,
112 std::function<
void(
u64, PtNode)> found_case,
116 std::stack<u64> id_stack;
118 for (
u64 root : roots_ids) {
122 while (!id_stack.empty()) {
123 u64 cur_id = id_stack.top();
125 PtNode cur_p = tree[cur_id];
127 bool interact = interact_cd(cur_id, cur_p);
130 u64 linked_id = lpid[cur_id];
132 found_case(linked_id, cur_p);
134 id_stack.push(cur_p.childs_id[0]);
135 id_stack.push(cur_p.childs_id[1]);
136 id_stack.push(cur_p.childs_id[2]);
137 id_stack.push(cur_p.childs_id[3]);
138 id_stack.push(cur_p.childs_id[4]);
139 id_stack.push(cur_p.childs_id[5]);
140 id_stack.push(cur_p.childs_id[6]);
141 id_stack.push(cur_p.childs_id[7]);
147 inline void host_for_each_leafs(
148 std::function<
bool(
u64, PtNode pnode)> interact_cd,
149 std::function<
void(
u64, PtNode)> found_case) {
155 host_for_each_leafs_internal(interact_cd, found_case, tree, lpid);
174 sched.
patch_tree, sched.get_patch_transform<fp_prec_vec>());
177 template<
class T,
class Func>
178 inline shamrock::patch::PatchtreeField<T> make_patch_tree_field(
179 PatchScheduler &sched,
181 shamrock::patch::PatchField<T> pfield,
183 shamrock::patch::PatchtreeField<T> ptfield;
187 sycl::host_accessor lpid{
189 sycl::host_accessor tree_field{
195 tree_field[idx] = (lpid[idx] !=
u64_max) ? pfield.get(lpid[idx]) : T();
202 for (
u32 level = 0; level < end_loop; level++) {
203 queue.submit([&](sycl::handler &cgh) {
208 cgh.parallel_for(range, [=](sycl::item<1> item) {
209 u64 i = (
u64) item.get_id(0);
211 std::array<u64, 8> n = tree[i].childs_id;
215 f[n[0]], f[n[1]], f[n[2]], f[n[3]], f[n[4]], f[n[5]], f[n[6]], f[n[7]]);
223 inline void dump_dat() {
225 std::cout << idx <<
" (" << serial_tree[idx].childs_id[0] <<
", "
226 << serial_tree[idx].childs_id[1] <<
", " << serial_tree[idx].childs_id[2]
227 <<
", " << serial_tree[idx].childs_id[3] <<
", "
228 << serial_tree[idx].childs_id[4] <<
", " << serial_tree[idx].childs_id[5]
229 <<
", " << serial_tree[idx].childs_id[6] <<
", "
230 << serial_tree[idx].childs_id[7] <<
")";
232 std::cout <<
" (" << serial_tree[idx].box_min.x() <<
", "
233 << serial_tree[idx].box_min.y() <<
", " << serial_tree[idx].box_min.z()
236 std::cout <<
" (" << serial_tree[idx].box_max.x() <<
", "
237 << serial_tree[idx].box_max.y() <<
", " << serial_tree[idx].box_max.z()
240 std::cout <<
" = " << linked_patch_ids[idx];
242 std::cout << std::endl;
246 sycl::buffer<u64> compute_patch_owner(
247 sham::DeviceScheduler_ptr dev_sched,
248 sham::DeviceBuffer<fp_prec_vec> &position_buffer,
253sycl::buffer<u64> SerialPatchTree<vec>::compute_patch_owner(
255 sycl::buffer<u64> new_owned_id(len);
257 using namespace shamrock::patch;
261 auto &q = dev_sched->get_queue();
266 auto e = q.submit(depends_list, [&](sycl::handler &cgh) {
268 sycl::accessor linked_node_id{
270 sycl::accessor roots_id{roots, cgh, sycl::read_only};
271 sycl::accessor new_id{new_owned_id, cgh, sycl::write_only, sycl::no_init};
273 u32 root_cnt = roots_id.size();
274 auto max_lev = get_level_count();
278 cgh.parallel_for(sycl::range(len), [=](sycl::item<1> item) {
279 u32 i = (
u32) item.get_id(0);
283 u64 current_node = 0;
286 for (
u32 iroot = 0; iroot < root_cnt; iroot++) {
287 u32 root_id = roots_id[iroot];
288 PtNode root_node = tnode[root_id];
291 current_node = root_id;
298 for (
u32 step = 0; step < max_lev + 1; step++) {
299 PtNode cur_node = tnode[current_node];
301 if (cur_node.childs_id[0] !=
u64_max) {
305 tnode[cur_node.childs_id[0]].box_min,
306 tnode[cur_node.childs_id[0]].box_max)) {
307 current_node = cur_node.childs_id[0];
311 tnode[cur_node.childs_id[1]].box_min,
312 tnode[cur_node.childs_id[1]].box_max)) {
313 current_node = cur_node.childs_id[1];
317 tnode[cur_node.childs_id[2]].box_min,
318 tnode[cur_node.childs_id[2]].box_max)) {
319 current_node = cur_node.childs_id[2];
323 tnode[cur_node.childs_id[3]].box_min,
324 tnode[cur_node.childs_id[3]].box_max)) {
325 current_node = cur_node.childs_id[3];
329 tnode[cur_node.childs_id[4]].box_min,
330 tnode[cur_node.childs_id[4]].box_max)) {
331 current_node = cur_node.childs_id[4];
335 tnode[cur_node.childs_id[5]].box_min,
336 tnode[cur_node.childs_id[5]].box_max)) {
337 current_node = cur_node.childs_id[5];
341 tnode[cur_node.childs_id[6]].box_min,
342 tnode[cur_node.childs_id[6]].box_max)) {
343 current_node = cur_node.childs_id[6];
347 tnode[cur_node.childs_id[7]].box_min,
348 tnode[cur_node.childs_id[7]].box_max)) {
349 current_node = cur_node.childs_id[7];
354 result_node = linked_node_id[current_node];
359 new_id[i] = result_node;
constexpr const char * xyz
Position field (3D coordinates).
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
PatchTree patch_tree
handle the tree structure of the patches
SchedulerPatchList patch_list
handle the list of the patches of the scheduler
std::unordered_map< u64, u64 > id_patch_to_global_idx
id_patch_to_global_idx[patch_id] = index in global patch list
const u32 & get_level_count()
accesor to the number of level in the tree
u32 get_element_count()
accesor to the number of element in the tree
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.
Patch Tree : Tree structure organisation for an abstract list of patches Nb : this tree is compatible...
sycl::buffer< T > vec_to_buf(const std::vector< T > &buf)
Convert a std::vector to a sycl::buffer.
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.
i32 world_rank()
Gives the rank of the current process in the MPI communicator.
constexpr u64 u64_max
u64 max value
void raw_ln(Types... var2)
Prints a log message with multiple arguments followed by a newline.
This file contains the definition for the stacktrace related functionality.
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.
static bool is_in_patch_converted(sycl::vec< T, 3 > val, sycl::vec< T, 3 > min_val, sycl::vec< T, 3 > max_val)
check if particle is in the asked range, given the output of @convert_coord
header file to manage sycl