Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
pyShamalgs.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
15
17#include "shambase/time.hpp"
26#include "shamalgs/random.hpp"
30#include "shamcomm/logs.hpp"
32#include <pybind11/complex.h>
33#include <utility>
34
36 auto &m = root_module;
37
38 py::module shamalgs_module = m.def_submodule("algs", "algorithmic library");
39
40 py::class_<std::mt19937>(shamalgs_module, "rng");
41
42 py::class_<shamalgs::impl_param>(shamalgs_module, "impl_param")
43 .def(py::init([]() {
44 return shamalgs::impl_param{.impl_name = "", .params = ""};
45 }))
46 .def_readwrite(
47 "impl_name",
48 &shamalgs::impl_param::impl_name,
49 py::return_value_policy::reference_internal)
50 .def_readwrite(
51 "params", &shamalgs::impl_param::params, py::return_value_policy::reference_internal)
52 .def(
53 "__str__",
54 [](const shamalgs::impl_param &impl_param) {
55 return shambase::format(
56 "impl_param(impl_name=\"{}\", params=\"{}\")",
57 impl_param.impl_name,
58 impl_param.params);
59 })
60 .def("__repr__", [](const shamalgs::impl_param &impl_param) {
61 return shambase::format(
62 "impl_param(impl_name=\"{}\", params=\"{}\")",
63 impl_param.impl_name,
64 impl_param.params);
65 });
66
67 shamalgs_module.def("gen_seed", [](u64 seed) {
68 return std::mt19937(seed);
69 });
70
71 shamalgs_module.def("mock_gaussian", [](std::mt19937 &eng) {
72 return shamalgs::random::mock_gaussian<f64>(eng);
73 });
74 shamalgs_module.def("mock_gaussian_f64_2", [](std::mt19937 &eng) {
75 return shamalgs::random::mock_gaussian_multidim<f64_2>(eng);
76 });
77 shamalgs_module.def("mock_gaussian_f64_3", [](std::mt19937 &eng) {
78 return shamalgs::random::mock_gaussian_multidim<f64_3>(eng);
79 });
80 shamalgs_module.def("mock_unit_vector_f64_3", [](std::mt19937 &eng) {
81 return shamalgs::random::mock_unit_vector<f64_3>(eng);
82 });
83
84 shamalgs_module.def("mock_buffer_f64", [](u64 seed, u32 len, f64 min_bound, f64 max_bound) {
85 return shamalgs::random::mock_buffer_usm<f64>(
86 shamsys::instance::get_compute_scheduler_ptr(), seed, len, min_bound, max_bound);
87 });
88 shamalgs_module.def("mock_buffer_u8", [](u64 seed, u32 len, u8 min_bound, u8 max_bound) {
89 return shamalgs::random::mock_buffer_usm<u8>(
90 shamsys::instance::get_compute_scheduler_ptr(), seed, len, min_bound, max_bound);
91 });
92 shamalgs_module.def("mock_buffer_u32", [](u64 seed, u32 len, u32 min_bound, u32 max_bound) {
93 return shamalgs::random::mock_buffer_usm<u32>(
94 shamsys::instance::get_compute_scheduler_ptr(), seed, len, min_bound, max_bound);
95 });
96 shamalgs_module.def(
97 "mock_buffer_f64_2", [](u64 seed, u32 len, f64_2 min_bound, f64_2 max_bound) {
98 return shamalgs::random::mock_buffer_usm<f64_2>(
99 shamsys::instance::get_compute_scheduler_ptr(), seed, len, min_bound, max_bound);
100 });
101 shamalgs_module.def(
102 "mock_buffer_f64_3", [](u64 seed, u32 len, f64_3 min_bound, f64_3 max_bound) {
103 return shamalgs::random::mock_buffer_usm<f64_3>(
104 shamsys::instance::get_compute_scheduler_ptr(), seed, len, min_bound, max_bound);
105 });
106
107 { // is_all_true
108
109 shamalgs_module.def("is_all_true", [](sham::DeviceBuffer<u8> &buf, u32 len) {
110 return shamalgs::primitives::is_all_true(buf, len);
111 });
112
113 shamalgs_module.def("benchmark_is_all_true", [](sham::DeviceBuffer<u8> &buf, u32 len) {
114 buf.synchronize();
115 shambase::Timer timer;
116 timer.start();
117 bool result = shamalgs::primitives::is_all_true(buf, len);
118 buf.synchronize();
119 timer.stop();
120 return timer.elapsed_sec();
121 });
122
123 shamalgs_module.def(
124 "set_impl_is_all_true", [](const std::string &impl, const std::string &param = "") {
126 });
127
128 shamalgs_module.def("get_current_impl_is_all_true", []() {
130 });
131
132 shamalgs_module.def("get_default_impl_list_is_all_true", []() {
134 });
135 }
136
137 { // reductions
138 shamalgs_module.def("sum", [](sham::DeviceBuffer<f64> &buf, u32 start_id, u32 end_id) {
140 shamsys::instance::get_compute_scheduler_ptr(), buf, start_id, end_id);
141 });
142
143 shamalgs_module.def("benchmark_reduction_sum", [](sham::DeviceBuffer<f64> &buf, u32 len) {
144 buf.synchronize();
145 shambase::Timer timer;
146 timer.start();
148 shamsys::instance::get_compute_scheduler_ptr(), buf, 0, len);
149 timer.stop();
150 return timer.elapsed_sec();
151 });
152
153 shamalgs_module.def("benchmark_reduction_sum", [](sham::DeviceBuffer<f32> &buf, u32 len) {
154 buf.synchronize();
155 shambase::Timer timer;
156 timer.start();
158 shamsys::instance::get_compute_scheduler_ptr(), buf, 0, len);
159 timer.stop();
160 return timer.elapsed_sec();
161 });
162
163 shamalgs_module.def(
164 "set_impl_reduction", [](const std::string &impl, const std::string &param = "") {
166 });
167
168 shamalgs_module.def("get_current_impl_reduction", []() {
170 });
171
172 shamalgs_module.def("get_default_impl_list_reduction", []() {
174 });
175 }
176
177 { // scan_exclusive_sum_in_place
178
179 shamalgs_module.def(
180 "scan_exclusive_sum_in_place", [](sham::DeviceBuffer<u32> &buf, u32 len) {
182 });
183
184 shamalgs_module.def(
185 "benchmark_scan_exclusive_sum_in_place", [](sham::DeviceBuffer<u32> &buf, u32 len) {
186 buf.synchronize();
187 shambase::Timer timer;
188 timer.start();
190 buf.synchronize();
191 timer.stop();
192 return timer.elapsed_sec();
193 });
194
195 shamalgs_module.def(
196 "set_impl_scan_exclusive_sum_in_place",
197 [](const std::string &impl, const std::string &param = "") {
199 });
200
201 shamalgs_module.def("get_current_impl_scan_exclusive_sum_in_place", []() {
203 });
204
205 shamalgs_module.def("get_default_impl_list_scan_exclusive_sum_in_place", []() {
207 });
208 }
209
210 { // segmented_sort_in_place
211 shamalgs_module.def(
212 "segmented_sort_in_place",
213 [](sham::DeviceBuffer<u32> &buf, const sham::DeviceBuffer<u32> &offsets) {
214 shamalgs::primitives::segmented_sort_in_place(buf, offsets);
215 });
216
217 shamalgs_module.def(
218 "benchmark_segmented_sort_in_place",
219 [](sham::DeviceBuffer<u32> &buf, const sham::DeviceBuffer<u32> &offsets) {
220 auto buf_copy = buf.copy();
221 auto offsets_copy = offsets.copy();
222
223 buf_copy.synchronize();
224 offsets_copy.synchronize();
225
226 shambase::Timer timer;
227 timer.start();
228
229 shamalgs::primitives::segmented_sort_in_place(buf_copy, offsets_copy);
230 buf_copy.synchronize();
231 offsets_copy.synchronize();
232
233 timer.stop();
234 return timer.elapsed_sec();
235 });
236
237 shamalgs_module.def(
238 "set_impl_segmented_sort_in_place",
239 [](const std::string &impl, const std::string &param = "") {
241 });
242
243 shamalgs_module.def("get_current_impl_segmented_sort_in_place", []() {
245 });
246
247 shamalgs_module.def("get_default_impl_list_segmented_sort_in_place", []() {
249 });
250 }
251
252 py::class_<shamalgs::primitives::ImplControl>(shamalgs_module, "ImplControl")
253 .def(
254 "get_alg_name",
255 [](shamalgs::primitives::ImplControl &impl_control) {
256 return impl_control.get_alg_name();
257 })
258 .def(
259 "was_configured",
260 [](shamalgs::primitives::ImplControl &impl_control) {
261 return impl_control.was_configured(shamsys::instance::get_compute_scheduler_ptr());
262 })
263 .def(
264 "get_config",
265 [](shamalgs::primitives::ImplControl &impl_control) {
266 return impl_control.get_config(shamsys::instance::get_compute_scheduler_ptr());
267 })
268 .def(
269 "set_config",
270 [](shamalgs::primitives::ImplControl &impl_control, const std::string &config) {
271 impl_control.set_config(shamsys::instance::get_compute_scheduler_ptr(), config);
272 })
273 .def(
274 "get_default_config",
275 [](shamalgs::primitives::ImplControl &impl_control) {
276 return impl_control.get_default_config(
277 shamsys::instance::get_compute_scheduler_ptr());
278 })
279 .def("get_avail_configs", [](shamalgs::primitives::ImplControl &impl_control) {
280 return impl_control.get_avail_configs(shamsys::instance::get_compute_scheduler_ptr());
281 });
282
283 shamalgs_module.def(
284 "compute_histogram_impl",
286 return shamalgs::primitives::impl::compute_histogram_impl_control;
287 },
288 py::return_value_policy::reference);
289
290 shamalgs_module.def(
291 "compute_histogram_basic_f64",
292 [](sham::DeviceBuffer<f64> &bin_edge_inf,
293 sham::DeviceBuffer<f64> &bin_edge_sup,
294 sham::DeviceBuffer<f64> &positions) {
295 return shamalgs::primitives::compute_histogram_basic<f64>(
296 shamsys::instance::get_compute_scheduler_ptr(),
297 bin_edge_inf,
298 bin_edge_sup,
299 positions);
300 });
301 shamalgs_module.def(
302 "compute_histogram_basic_f32",
303 [](sham::DeviceBuffer<f32> &bin_edge_inf,
304 sham::DeviceBuffer<f32> &bin_edge_sup,
305 sham::DeviceBuffer<f32> &positions) {
306 return shamalgs::primitives::compute_histogram_basic<f32>(
307 shamsys::instance::get_compute_scheduler_ptr(),
308 bin_edge_inf,
309 bin_edge_sup,
310 positions);
311 });
312
313 shamalgs_module.def(
314 "benchmark_compute_histogram_basic_f64",
315 [](sham::DeviceBuffer<f64> &bin_edge_inf,
316 sham::DeviceBuffer<f64> &bin_edge_sup,
317 sham::DeviceBuffer<f64> &positions) {
318 bin_edge_inf.synchronize();
319 bin_edge_sup.synchronize();
320 positions.synchronize();
321
322 auto run = [&]() {
323 auto result = shamalgs::primitives::compute_histogram_basic<f64>(
324 shamsys::instance::get_compute_scheduler_ptr(),
325 bin_edge_inf,
326 bin_edge_sup,
327 positions);
328 result.synchronize();
329 };
330
331 run();
332
333 return shambase::timeitfor(run);
334 });
335 shamalgs_module.def(
336 "benchmark_compute_histogram_basic_f32",
337 [](sham::DeviceBuffer<f32> &bin_edge_inf,
338 sham::DeviceBuffer<f32> &bin_edge_sup,
339 sham::DeviceBuffer<f32> &positions) {
340 bin_edge_inf.synchronize();
341 bin_edge_sup.synchronize();
342 positions.synchronize();
343
344 auto run = [&]() {
345 auto result = shamalgs::primitives::compute_histogram_basic<f32>(
346 shamsys::instance::get_compute_scheduler_ptr(),
347 bin_edge_inf,
348 bin_edge_sup,
349 positions);
350 result.synchronize();
351 };
352
353 run();
354
355 return shambase::timeitfor(run);
356 });
357
358 shamalgs_module.def(
359 "string_histogram",
360 [](const std::vector<std::string> &inputs, std::string delimiter, bool hash_based) {
361 return shamalgs::collective::string_histogram(inputs, std::move(delimiter), hash_based);
362 },
363 py::arg("inputs"),
364 py::arg("delimiter") = "\n",
365 py::arg("hash_based") = false);
366
367 shamalgs_module.def(
368 "all_string_histogram",
369 [](const std::vector<std::string> &inputs, std::string delimiter, bool hash_based) {
371 inputs, std::move(delimiter), hash_based);
372 },
373 py::arg("inputs"),
374 py::arg("delimiter") = "\n",
375 py::arg("hash_based") = false);
376}
Header file describing a Node Instance.
double f64
Alias for double.
float f32
Alias for float.
std::uint8_t u8
8 bit unsigned integer
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
A buffer allocated in USM (Unified Shared Memory).
void synchronize() const
Wait for all the events associated with the buffer to be completed.
DeviceBuffer< T, target > copy() const
Copy the current buffer.
Class Timer measures the time elapsed since the timer was started.
Definition Timer.hpp:36
f64 elapsed_sec() const
Converts the stored nanosecond time to a floating point representation in seconds.
Definition Timer.hpp:88
void start()
Starts the timer.
Definition Timer.hpp:51
void stop()
Stops the timer and stores the elapsed time in nanoseconds.
Definition Timer.hpp:65
Boolean reduction algorithm for checking if all elements are non-zero.
std::vector< shamalgs::impl_param > get_default_impl_list_segmented_sort_in_place()
Get list of available segmented sort in place implementations.
void set_impl_reduction(const std::string &impl, const std::string &param="")
Set the implementation for reduction.
Definition reduction.cpp:99
std::vector< shamalgs::impl_param > get_default_impl_list_reduction()
Get list of available reduction implementations.
Definition reduction.cpp:84
std::vector< shamalgs::impl_param > get_default_impl_list_scan_exclusive_sum_in_place()
Get list of available scan_exclusive_sum_in_place implementations.
void set_impl_segmented_sort_in_place(const std::string &impl, const std::string &param="")
Set the implementation for segmented sort in place.
void set_impl_is_all_true(const std::string &impl, const std::string &param="")
Set the implementation for is_all_true.
shamalgs::impl_param get_current_impl_scan_exclusive_sum_in_place()
Get the current implementation for scan_exclusive_sum_in_place.
shamalgs::impl_param get_current_impl_segmented_sort_in_place()
Get the current implementation for segmented sort in place.
shamalgs::impl_param get_current_impl_reduction()
Get the current implementation for reduction.
Definition reduction.cpp:95
void set_impl_scan_exclusive_sum_in_place(const std::string &impl, const std::string &param="")
Set the implementation for scan_exclusive_sum_in_place.
std::vector< shamalgs::impl_param > get_default_impl_list_is_all_true()
Get list of available is_all_true implementations.
shamalgs::impl_param get_current_impl_is_all_true()
Get the current implementation for is_all_true.
T sum(const sham::DeviceScheduler_ptr &sched, const sham::DeviceBuffer< T > &buf1, u32 start_id, u32 end_id)
Compute the sum of elements in a device buffer within a specified range.
bool is_all_true(sycl::buffer< T > &buf, u32 cnt)
Check if all elements in a sycl::buffer are non-zero.
void scan_exclusive_sum_in_place(sham::DeviceBuffer< T > &buf1, u32 len)
Compute exclusive prefix sum in-place on a device buffer.
f64 timeitfor(Func &&f, f64 max_duration=1)
Measures the average time it takes to execute a function until a maximum duration is reached.
Definition time.hpp:105
Pybind11 include and definitions.
#define ON_PYTHON_INIT
Register a Python module init function using static initialization.
In-place exclusive scan (prefix sum) algorithm for device buffers.
MPI string gather / allgather helpers (declarations; implementations in shamalgs/src/collective/gathe...
std::unordered_map< std::string, int > string_histogram(const std::vector< std::string > &inputs, std::string delimiter, bool hash_based)
Constructs a histogram from a vector of strings, counting occurrences of each unique string.
std::unordered_map< std::string, int > all_string_histogram(const std::vector< std::string > &inputs, std::string delimiter, bool hash_based)
same as string_histogram but with result return on every rank