Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
sort_by_key_pow2_len.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
24#include "shamcomm/logs.hpp"
25
27
30 enum class MaxStencilSize : u32 {
31 // Size2 = 2,
32 // Size4 = 4,
33 // Size8 = 8,
34 Size16 = 16,
35 Size32 = 32,
36 };
37
39 struct BitonicSort {
40 static constexpr std::string_view variant_type_name = "bitonic_sort";
41 MaxStencilSize stencil_size = MaxStencilSize::Size16;
42
44 static std::vector<BitonicSort> variant_custom_defaults() {
45 return {
46 // BitonicSort{MaxStencilSize::Size8},
47 BitonicSort{MaxStencilSize::Size16},
48 BitonicSort{MaxStencilSize::Size32},
49 };
50 }
51 };
52
54 struct StdSort {
55 static constexpr std::string_view variant_type_name = "std_sort";
56 };
57
58} // namespace shamalgs::primitives::impl
59
60template<>
62 static nlohmann::json to_json(const shamalgs::primitives::impl::BitonicSort &p) {
63 return {{"stencil_size", static_cast<u32>(p.stencil_size)}};
64 }
65 static shamalgs::primitives::impl::BitonicSort from_json(const nlohmann::json &j) {
67 if (j.contains("stencil_size")) {
68 p.stencil_size = static_cast<shamalgs::primitives::impl::MaxStencilSize>(
69 j.at("stencil_size").get<u32>());
70 }
71 return p;
72 }
73};
74
75namespace shamalgs::primitives {
76
77 template<class Tkey, class Tval>
79 sycl::queue &q, sycl::buffer<Tkey> &buf_key, sycl::buffer<Tval> &buf_values, u32 len) {
80
81 if (!shambase::is_pow_of_two(len)) {
83 "Length must be a power of 2");
84 }
85
86 if (len < 5e3) {
87 shamalgs::algorithm::details::sort_by_key_bitonic_fallback(q, buf_key, buf_values, len);
88 } else {
89 shamalgs::algorithm::details::sort_by_key_bitonic_updated<Tkey, Tval, 16>(
90 q, buf_key, buf_values, len);
91 }
92 }
93
95 namespace impl {
96
98 [](const sham::DeviceScheduler_ptr &, auto &self) {
99 self.set(BitonicSort{});
100 }};
101
104 return sort_by_key_pow2_len_impl.get_default_config_list();
105 }
106
109 return sort_by_key_pow2_len_impl.get_current_config();
110 }
111
113 bool is_impl_set_sort_by_key_pow2_len() { return sort_by_key_pow2_len_impl.is_set(); }
114
116 void set_impl_sort_by_key_pow2_len(const std::string &impl) {
117 shamlog_info_ln(
118 "algs", "setting sort by key (pow2 len) implementation to impl :", impl);
119 sort_by_key_pow2_len_impl.set(impl);
120 }
121
123 void autoselect_impl_sort_by_key_pow2_len(const sham::DeviceScheduler_ptr &dev_sched) {
124 sort_by_key_pow2_len_impl.autoselect(dev_sched);
125 shamlog_info_ln(
126 "algs",
127 "defaulting sort by key (pow2 len) implementation to impl :",
129 }
130
133 template<class Tkey, class Tval>
135 const sham::DeviceScheduler_ptr &sched,
137 sham::DeviceBuffer<Tval> &buf_values,
138 u32 len,
139 MaxStencilSize stencil_size) {
140
141 switch (stencil_size) {
142 // case MaxStencilSize::Size2:
143 // shamalgs::algorithm::details::sort_by_key_bitonic_updated_usm<Tkey, Tval, 2>(
144 // sched, buf_key, buf_values, len);
145 // return;
146 // case MaxStencilSize::Size4:
147 // shamalgs::algorithm::details::sort_by_key_bitonic_updated_usm<Tkey, Tval, 4>(
148 // sched, buf_key, buf_values, len);
149 // return;
150 // case MaxStencilSize::Size8:
151 // shamalgs::algorithm::details::sort_by_key_bitonic_updated_usm<Tkey, Tval, 8>(
152 // sched, buf_key, buf_values, len);
153 // return;
154 case MaxStencilSize::Size16:
155 shamalgs::algorithm::details::sort_by_key_bitonic_updated_usm<Tkey, Tval, 16>(
156 sched, buf_key, buf_values, len);
157 return;
158 case MaxStencilSize::Size32:
159 shamalgs::algorithm::details::sort_by_key_bitonic_updated_usm<Tkey, Tval, 32>(
160 sched, buf_key, buf_values, len);
161 return;
162 }
163
164 throw shambase::make_except_with_loc<std::invalid_argument>("invalid MaxStencilSize");
165 }
166
167 } // namespace impl
168
169 template<class Tkey, class Tval>
171 const sham::DeviceScheduler_ptr &sched,
173 sham::DeviceBuffer<Tval> &buf_values,
174 u32 len) {
175
176 if (!shambase::is_pow_of_two(len)) {
178 "Length must be a power of 2");
179 }
180
181 if (!impl::sort_by_key_pow2_len_impl.is_set()) {
183 }
184
185 std::visit(
187 [&](impl::BitonicSort cfg) {
189 sched, buf_key, buf_values, len, cfg.stencil_size);
190 },
191 [&](impl::StdSort) {
192 device::details::sort_by_keys_std_sort(buf_key, buf_values, len);
193 },
194 },
195 impl::sort_by_key_pow2_len_impl.get());
196 }
197
198 template void sort_by_key_pow2_len(
199 sycl::queue &q, sycl::buffer<u32> &buf_key, sycl::buffer<u32> &buf_values, u32 len);
200
201 template void sort_by_key_pow2_len(
202 sycl::queue &q, sycl::buffer<u64> &buf_key, sycl::buffer<u32> &buf_values, u32 len);
203
204 template void sort_by_key_pow2_len(
205 const sham::DeviceScheduler_ptr &sched,
207 sham::DeviceBuffer<u32> &buf_values,
208 u32 len);
209
210 template void sort_by_key_pow2_len(
211 const sham::DeviceScheduler_ptr &sched,
213 sham::DeviceBuffer<u32> &buf_values,
214 u32 len);
215
216 template void sort_by_key_pow2_len(
217 const sham::DeviceScheduler_ptr &sched,
219 sham::DeviceBuffer<f64> &buf_values,
220 u32 len);
221
222 template void sort_by_key_pow2_len(
223 const sham::DeviceScheduler_ptr &sched,
225 sham::DeviceBuffer<f32> &buf_values,
226 u32 len);
227
228} // namespace shamalgs::primitives
Generic std::variant-based implementation selector.
std::uint32_t u32
32 bit unsigned integer
main include file for the shamalgs algorithms
A buffer allocated in USM (Unified Shared Memory).
Drop-in replacement for the hand-rolled "global variable + enum + name mapping.
This header file contains utility functions related to exception handling in the code.
namespace to control implementation behavior
void sort_by_key_pow2_len_bitonic_dispatch(const sham::DeviceScheduler_ptr &sched, sham::DeviceBuffer< Tkey > &buf_key, sham::DeviceBuffer< Tval > &buf_values, u32 len, MaxStencilSize stencil_size)
std::vector< std::string > get_default_impl_list_sort_by_key_pow2_len()
Get list of available sort by key pow2 len implementations, as config json strings.
void autoselect_impl_sort_by_key_pow2_len(const sham::DeviceScheduler_ptr &dev_sched)
Select the default implementation for sort by key pow2 len.
std::string get_current_impl_sort_by_key_pow2_len()
Get the current implementation for sort by key pow2 len, as a config json string.
bool is_impl_set_sort_by_key_pow2_len()
Check if an implementation has been selected for sort by key pow2 len.
void set_impl_sort_by_key_pow2_len(const std::string &impl)
Set the implementation for sort by key pow2 len, from a config json string.
namespace for primitive algorithm (e.g. sort, scan, reductions, ...)
void sort_by_key_pow2_len(sycl::queue &q, sycl::buffer< Tkey > &buf_key, sycl::buffer< Tval > &buf_values, u32 len)
Sort key-value pairs using sycl::buffers (power-of-2 optimized).
namespace to contain everything implemented by shamalgs
Definition algorithm.hpp:21
constexpr bool is_pow_of_two(T v) noexcept
determine if v is a power of two and check if v==0 Source : https://graphics.stanford....
Definition integer.hpp:49
ExcptTypes make_except_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Create an exception with a message and a location.
Sort by keys algorithms.
std::sort based sort by keys implementation, shared by the sort by keys primitives
void sort_by_keys_std_sort(sham::DeviceBuffer< Tkey > &buf_key, sham::DeviceBuffer< Tval > &buf_values, u32 len)
Copy both buffers to host, std::sort the zipped key/value pairs, and copy back.
Customization point controlling how an alternative's fields (if any) are serialized to / parsed from ...
static Alt from_json(const nlohmann::json &)
Parse the alternative's fields back (default: no fields, ignored).
static nlohmann::json to_json(const Alt &)
Serialize the alternative's fields (default: no fields, empty object).
Bitonic sort, updated USM kernel (see bitonicSort_updated_usm.hpp).
static std::vector< BitonicSort > variant_custom_defaults()
Expose the stencil sizes worth benchmarking as separate default implementations.
Copy the buffers to host, std::sort the zipped key/value pairs, and copy back.
Build an overload set out of several callables, for use with std::visit.