32 template<
class Tkey,
class Tval>
37 Tkey *__restrict__ keys, Tval *__restrict__ vals,
u32 a,
u32 b) {
44 bool swap = key_b < key_a;
46 keys[a] = (swap) ? key_b : key_a;
47 keys[b] = (swap) ? key_a : key_b;
48 vals[a] = (swap) ? val_b : val_a;
49 vals[b] = (swap) ? val_a : val_b;
76 Tkey *__restrict__ keys,
77 Tval *__restrict__ vals,
85 u64 x = j0 + ((t >> log_k) << (log_k + 1)) + (t & (k - 1));
90 if ((x >> log_2p) != ((x + k) >> log_2p)) {
98 template<
class Tkey,
class Tval>
100 const sham::DeviceScheduler_ptr &sched,
115 u64 n_threads = (n + 1) / 2;
119 for (
u32 log_p = 0; (
u64(1) << log_p) < n; log_p++) {
120 for (
i32 log_k =
i32(log_p); log_k >= 0; log_k--) {
123 u64 j0 = (log_k ==
i32(log_p)) ? 0 : k;
124 u32 log_2p = log_p + 1;
132 [=](
u64 gid, Tkey *keys, Tval *vals) {
133 B::merge_step(keys, vals, n, k, j0, lk, log_2p, gid);
139 template<
class Tkey,
class Tval>
141 std::vector<Tkey> &keys, std::vector<Tval> &values) {
143 if (keys.size() != values.size()) {
145 "the keys and the values must have the same length");
158 i32 n =
static_cast<i32>(keys.size());
159 for (
i32 p = 1; p < n; p <<= 1) {
160 for (
i32 k = p; k >= 1; k >>= 1) {
161 for (
i32 j = k % p; j <= n - 1 - k; j += 2 * k) {
162 i32 imax = std::min(k - 1, n - j - k - 1);
163 for (
i32 i = 0; i <= imax; ++i) {
165 i32 idx2 = i + j + k;
166 if ((idx1 / (2 * p)) == (idx2 / (2 * p))) {
167 if (keys[idx2] < keys[idx1]) {
168 std::swap(keys[idx1], keys[idx2]);
169 std::swap(values[idx1], values[idx2]);
178 template void sort_by_key_batcher_odd_even<u32, u32>(
179 const sham::DeviceScheduler_ptr &sched,
184 template void sort_by_key_batcher_odd_even<u64, u32>(
185 const sham::DeviceScheduler_ptr &sched,
190 template void sort_by_key_batcher_odd_even<f32, f32>(
191 const sham::DeviceScheduler_ptr &sched,
196 template void sort_by_key_batcher_odd_even<f64, f64>(
197 const sham::DeviceScheduler_ptr &sched,
202 template void sort_by_key_batcher_odd_even<f32, u32>(
203 const sham::DeviceScheduler_ptr &sched,
208 template void sort_by_key_batcher_odd_even<f64, u32>(
209 const sham::DeviceScheduler_ptr &sched,
214 template void sort_by_key_batcher_odd_even_host_reference<u32, u32>(
215 std::vector<u32> &keys, std::vector<u32> &values);
217 template void sort_by_key_batcher_odd_even_host_reference<u64, u32>(
218 std::vector<u64> &keys, std::vector<u32> &values);
220 template void sort_by_key_batcher_odd_even_host_reference<f32, f32>(
221 std::vector<f32> &keys, std::vector<f32> &values);
223 template void sort_by_key_batcher_odd_even_host_reference<f32, u32>(
224 std::vector<f32> &keys, std::vector<u32> &values);
226 template void sort_by_key_batcher_odd_even_host_reference<f64, u32>(
227 std::vector<f64> &keys, std::vector<u32> &values);
229 template void sort_by_key_batcher_odd_even_host_reference<f64, f64>(
230 std::vector<f64> &keys, std::vector<f64> &values);
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
std::int32_t i32
32 bit integer
Batcher odd-even mergesort, native for any length.
A buffer allocated in USM (Unified Shared Memory).
This header file contains utility functions related to exception handling in the code.
void kernel_call_u64(sham::DeviceQueue &q, RefIn in, RefOut in_out, u64 n, Functor &&func, SourceLocation &&callsite=SourceLocation{})
u64 indexed variant of kernel_call
namespace to store algorithms implemented by shamalgs
void sort_by_key_batcher_odd_even_host_reference(std::vector< Tkey > &keys, std::vector< Tval > &values)
Host reference of sort_by_key_batcher_odd_even.
void sort_by_key_batcher_odd_even(const sham::DeviceScheduler_ptr &sched, sham::DeviceBuffer< Tkey > &buf_key, sham::DeviceBuffer< Tval > &buf_values, u32 len)
Sort key-value pairs of any length using a Batcher odd-even merge network.
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
A class that references multiple buffers or similar objects.
Device side primitives of the odd-even merge network.
static void compare_exchange(Tkey *__restrict__ keys, Tval *__restrict__ vals, u32 a, u32 b)
Ascending branchless compare-exchange of the pair (a, b), with a < b.
static void merge_step(Tkey *__restrict__ keys, Tval *__restrict__ vals, u64 len, u64 k, u64 j0, u32 log_k, u32 log_2p, u64 t)
Work of a single thread within the (p, k) stage of the network.