Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
group_op.hpp
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
10#pragma once
11
18#include "shambackends/math.hpp"
19#include "shambackends/sycl.hpp"
20#include "shambackends/vec.hpp"
21#include <utility>
22
23namespace sham {
24
25#ifdef SYCL2020_FEATURE_GROUP_REDUCTION
37 template<class T, class Func, class... Args>
38 inline T map_vector(const T &in, Func &&f, Args... args) {
39
40 static constexpr u32 dim = shambase::VectorProperties<T>::dimension;
41
42 if constexpr (dim == 1) {
43 return f(in, std::forward<Args>(args)...);
44 } else if constexpr (dim == 2) {
45 return {f(in[0], std::forward<Args>(args)...), f(in[1], std::forward<Args>(args)...)};
46 } else if constexpr (dim == 3) {
47 return {
48 f(in[0], std::forward<Args>(args)...),
49 f(in[1], std::forward<Args>(args)...),
50 f(in[2], std::forward<Args>(args)...)};
51 } else if constexpr (dim == 4) {
52 return {
53 f(in[0], std::forward<Args>(args)...),
54 f(in[1], std::forward<Args>(args)...),
55 f(in[2], std::forward<Args>(args)...),
56 f(in[3], std::forward<Args>(args)...)};
57 } else if constexpr (dim == 8) {
58 return {
59 f(in[0], std::forward<Args>(args)...),
60 f(in[1], std::forward<Args>(args)...),
61 f(in[2], std::forward<Args>(args)...),
62 f(in[3], std::forward<Args>(args)...),
63 f(in[4], std::forward<Args>(args)...),
64 f(in[5], std::forward<Args>(args)...),
65 f(in[6], std::forward<Args>(args)...),
66 f(in[7], std::forward<Args>(args)...)};
67 } else if constexpr (dim == 16) {
68 return {
69 f(in[0], std::forward<Args>(args)...),
70 f(in[1], std::forward<Args>(args)...),
71 f(in[2], std::forward<Args>(args)...),
72 f(in[3], std::forward<Args>(args)...),
73 f(in[4], std::forward<Args>(args)...),
74 f(in[5], std::forward<Args>(args)...),
75 f(in[6], std::forward<Args>(args)...),
76 f(in[7], std::forward<Args>(args)...),
77 f(in[8], std::forward<Args>(args)...),
78 f(in[9], std::forward<Args>(args)...),
79 f(in[10], std::forward<Args>(args)...),
80 f(in[11], std::forward<Args>(args)...),
81 f(in[12], std::forward<Args>(args)...),
82 f(in[13], std::forward<Args>(args)...),
83 f(in[14], std::forward<Args>(args)...),
84 f(in[15], std::forward<Args>(args)...)};
85 } else {
86 static_assert(shambase::always_false_v<decltype(dim)>, "non-exhaustive visitor!");
87 }
88 }
89
90 // Note here
91 // Never ever capture the sycl::group<1> by reference
92 // This messes up the reduction and every component will be reduced by the same value
93 // I have no feaking idea why
94
103 template<class T>
104 inline T sum_over_group(const sycl::group<1> &g, const T &v) {
105 #ifdef SYCL_COMP_INTEL_LLVM
106 return sycl::reduce_over_group(g, v, sycl::plus<>());
107 #endif
108 #ifdef SYCL_COMP_ACPP
109 return map_vector(
110 v,
111 [](auto component, const sycl::group<1> &g) {
112 return sycl::reduce_over_group(g, component, sycl::plus<decltype(component)>{});
113 },
114 g);
115 #endif
116 }
117
126 template<class T>
127 inline T min_over_group(const sycl::group<1> &g, const T &v) {
128 #ifdef SYCL_COMP_INTEL_LLVM
129 return sycl::reduce_over_group(g, v, sycl::minimum<>());
130 #endif
131 #ifdef SYCL_COMP_ACPP
132 return map_vector(
133 v,
134 [](auto component, const sycl::group<1> &g) {
135 return sycl::reduce_over_group(g, component, sycl::minimum<decltype(component)>{});
136 },
137 g);
138 #endif
139 }
140
149 template<class T>
150 inline T max_over_group(const sycl::group<1> &g, const T &v) {
151 #ifdef SYCL_COMP_INTEL_LLVM
152 return sycl::reduce_over_group(g, v, sycl::maximum<>());
153 #endif
154 #ifdef SYCL_COMP_ACPP
155 return map_vector(
156 v,
157 [](auto component, const sycl::group<1> &g) {
158 return sycl::reduce_over_group(g, component, sycl::maximum<decltype(component)>{});
159 },
160 g);
161 #endif
162 }
163#endif
164
165} // namespace sham
std::uint32_t u32
32 bit unsigned integer
namespace for backends this one is named only sham since shambackends is too long to write
constexpr bool always_false_v
Helper variable template that is always false. Especially useful to perform static asserts based on t...