Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
MortonKernels.cpp
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
16#include "shambase/integer.hpp"
18#include "shambackends/math.hpp"
20
21template<class T>
23
24template<class morton_t, class pos_t, u32 dim>
26
27template<class morton_t, class pos_t, u32 dim>
29
30template<class morton_t, class _pos_t, u32 dim>
32
33namespace shamrock::sfc {
34
35 template<class T>
36 void details::sycl_fill_trailling_buffer(
37 sycl::queue &queue,
38 u32 morton_count,
39 u32 fill_count,
40 std::unique_ptr<sycl::buffer<T>> &buf_morton) {
41
42 shamlog_debug_sycl_ln("MortonKernels", "submit : ", __PRETTY_FUNCTION__);
43
44 if (fill_count - morton_count == 0) {
45 shamlog_debug_sycl_ln(
46 "MortonKernels", "sycl_fill_trailling_buffer skipping pow len 2 is ok");
47 return;
48 }
49
50 sycl::range<1> range_npart{fill_count - morton_count};
51
52 auto ker_fill_trailling_buf = [&](sycl::handler &cgh) {
53 sycl::accessor m{*buf_morton, cgh, sycl::write_only, sycl::no_init};
54
55 cgh.parallel_for<fill_trailling_buf<T>>(range_npart, [=](sycl::item<1> i) {
56 m[morton_count + i.get_id()] = MortonInfo<T>::err_code;
57 });
58 };
59
60 queue.submit(ker_fill_trailling_buf);
61 }
62
63 template void details::sycl_fill_trailling_buffer<u32>(
64 sycl::queue &queue,
65 u32 morton_count,
66 u32 fill_count,
67 std::unique_ptr<sycl::buffer<u32>> &buf_morton);
68
69 template void details::sycl_fill_trailling_buffer<u64>(
70 sycl::queue &queue,
71 u32 morton_count,
72 u32 fill_count,
73 std::unique_ptr<sycl::buffer<u64>> &buf_morton);
74
75 template<class morton_t, class _pos_t, u32 dim>
77 sycl::queue &queue,
78 u32 pos_count,
79 sycl::buffer<pos_t> &in_positions,
80 pos_t bounding_box_min,
81 pos_t bounding_box_max,
82 std::unique_ptr<sycl::buffer<morton_t>> &out_morton) {
83
84 shamlog_debug_sycl_ln("MortonKernels", "submit : ", __PRETTY_FUNCTION__);
85
86 sycl::range<1> range_cnt{pos_count};
87
88 queue.submit([&](sycl::handler &cgh) {
89 auto transf = get_transform(bounding_box_min, bounding_box_max);
90
91 sycl::accessor r{in_positions, cgh, sycl::read_only};
92 sycl::accessor m{*out_morton, cgh, sycl::write_only, sycl::no_init};
93
95 range_cnt, [=](sycl::item<1> item) {
96 int i = (int) item.get_id(0);
97
98 ipos_t mr = to_morton_grid(r[i], transf);
99 m[i] = Morton::icoord_to_morton(mr.x(), mr.y(), mr.z());
100 });
101 }
102
103 );
104 }
105
106 template<class morton_t, class _pos_t, u32 dim>
108 const sham::DeviceScheduler_ptr &dev_sched,
109 u32 pos_count,
110 sham::DeviceBuffer<pos_t> &in_positions,
111 pos_t bounding_box_min,
112 pos_t bounding_box_max,
113 std::unique_ptr<sycl::buffer<morton_t>> &out_morton) {
114
115 shamlog_debug_sycl_ln("MortonKernels", "submit : ", __PRETTY_FUNCTION__);
116
117 sycl::range<1> range_cnt{pos_count};
118
119 auto q = dev_sched->get_queue();
120
122 auto r = in_positions.get_read_access(el);
123
124 auto e = q.submit(el, [&](sycl::handler &cgh) {
125 auto transf = get_transform(bounding_box_min, bounding_box_max);
126
127 sycl::accessor m{*out_morton, cgh, sycl::write_only, sycl::no_init};
128
130 range_cnt, [=](sycl::item<1> item) {
131 int i = (int) item.get_id(0);
132
133 ipos_t mr = to_morton_grid(r[i], transf);
134 m[i] = Morton::icoord_to_morton(mr.x(), mr.y(), mr.z());
135 });
136 });
137
138 in_positions.complete_event_state(e);
139 }
140
141 template<class morton_t, class _pos_t, u32 dim>
142 void MortonKernels<morton_t, _pos_t, dim>::sycl_irange_to_range(
143 sycl::queue &queue,
144 u32 buf_len,
145 pos_t bounding_box_min,
146 pos_t bounding_box_max,
147 std::unique_ptr<sycl::buffer<ipos_t>> &buf_pos_min_cell,
148 std::unique_ptr<sycl::buffer<ipos_t>> &buf_pos_max_cell,
149 std::unique_ptr<sycl::buffer<pos_t>> &out_buf_pos_min_cell_flt,
150 std::unique_ptr<sycl::buffer<pos_t>> &out_buf_pos_max_cell_flt) {
151 sycl::range<1> range_cell{buf_len};
152
153 constexpr u32 group_size = 256;
154 u32 max_len = buf_len;
155 u32 group_cnt = shambase::group_count(buf_len, group_size);
156 group_cnt = group_cnt + (group_cnt % 4);
157 u32 corrected_len = group_cnt * group_size;
158
159 shamlog_debug_sycl_ln("MortonKernels", "submit : ", __PRETTY_FUNCTION__);
160
161 auto ker_convert_cell_ranges = [&, max_len](sycl::handler &cgh) {
162 auto transf = get_transform(bounding_box_min, bounding_box_max);
163
164 auto pos_min_cell = sycl::accessor{*buf_pos_min_cell, cgh, sycl::read_only};
165 auto pos_max_cell = sycl::accessor{*buf_pos_max_cell, cgh, sycl::read_only};
166
167 auto pos_min_cell_flt
168 = sycl::accessor{*out_buf_pos_min_cell_flt, cgh, sycl::write_only, sycl::no_init};
169 auto pos_max_cell_flt
170 = sycl::accessor{*out_buf_pos_max_cell_flt, cgh, sycl::write_only, sycl::no_init};
171
173 sycl::nd_range<1>{corrected_len, group_size}, [=](sycl::nd_item<1> id) {
174 u32 local_id = id.get_local_id(0);
175 u32 group_tile_id = id.get_group_linear_id();
176 u32 gid = group_tile_id * group_size + local_id;
177
178 if (gid >= max_len)
179 return;
180
181 pos_min_cell_flt[gid] = to_real_space(pos_min_cell[gid], transf);
182 pos_max_cell_flt[gid] = to_real_space(pos_max_cell[gid], transf);
183 });
184 };
185
186 queue.submit(ker_convert_cell_ranges);
187 }
188
189 template class MortonKernels<u32, f32_3, 3>;
190 template class MortonKernels<u64, f32_3, 3>;
191 template class MortonKernels<u32, f64_3, 3>;
192 template class MortonKernels<u64, f64_3, 3>;
193 template class MortonKernels<u32, u32_3, 3>;
194 template class MortonKernels<u64, u32_3, 3>;
195 template class MortonKernels<u32, u64_3, 3>;
196 template class MortonKernels<u64, u64_3, 3>;
197 template class MortonKernels<u32, i64_3, 3>;
198 template class MortonKernels<u64, i64_3, 3>;
199} // namespace shamrock::sfc
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
static void sycl_xyz_to_morton(sycl::queue &queue, u32 pos_count, sycl::buffer< pos_t > &in_positions, pos_t bounding_box_min, pos_t bounding_box_max, std::unique_ptr< sycl::buffer< morton_t > > &out_morton)
convert a buffer of 3d positions to morton codes
Define the fmt formatters for sycl::vec.
constexpr u32 group_count(u32 len, u32 group_size)
Calculates the number of groups based on the length and group size.
Definition integer.hpp:125