Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
reduction.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
18#include "shambase/floats.hpp"
24#include "shamalgs/memory.hpp"
25#include "shambackends/math.hpp"
26#include "shambackends/vec.hpp"
27
28namespace shamalgs::reduction {
29
30 template<class T>
31 T sum(sycl::queue &q, sycl::buffer<T> &buf1, u32 start_id, u32 end_id) {
32#ifdef SYCL2020_FEATURE_GROUP_REDUCTION
33 return details::GroupReduction<T, 32>::sum(q, buf1, start_id, end_id);
34#else
35 return details::FallbackReduction<T>::sum(q, buf1, start_id, end_id);
36#endif
37 }
38
39 template<class T>
40 T max(sycl::queue &q, sycl::buffer<T> &buf1, u32 start_id, u32 end_id) {
41#ifdef SYCL2020_FEATURE_GROUP_REDUCTION
42 return details::GroupReduction<T, 32>::max(q, buf1, start_id, end_id);
43#else
44 return details::FallbackReduction<T>::max(q, buf1, start_id, end_id);
45#endif
46 }
47
48 template<class T>
49 T min(sycl::queue &q, sycl::buffer<T> &buf1, u32 start_id, u32 end_id) {
50#ifdef SYCL2020_FEATURE_GROUP_REDUCTION
51 return details::GroupReduction<T, 32>::min(q, buf1, start_id, end_id);
52#else
53 return details::FallbackReduction<T>::min(q, buf1, start_id, end_id);
54#endif
55 }
56
57 bool is_all_true(sycl::buffer<u8> &buf, u32 cnt) {
58
59 // TODO do it on GPU pleeeaze
60
61 bool res = true;
62 {
63 sycl::host_accessor acc{buf, sycl::read_only};
64
65 for (u32 i = 0; i < cnt; i++) {
66 res = res && (acc[i] != 0);
67 }
68 }
69
70 return res;
71 }
72
73 template<class T>
74 bool has_nan(sycl::queue &q, sycl::buffer<T> &buf, u64 cnt) {
76 // res is filled with 1 if no nan 0 otherwise
77 sycl::buffer<u8> res(cnt);
78 q.submit([&](sycl::handler &cgh) {
79 sycl::accessor acc1{buf, cgh, sycl::read_only};
80
81 sycl::accessor out{res, cgh, sycl::write_only, sycl::no_init};
82
83 cgh.parallel_for(sycl::range{cnt}, [=](sycl::item<1> item) {
84 out[item] = !sham::has_nan(acc1[item]);
85 });
86 });
87
88 return !is_all_true(res, cnt);
89 } else {
90 return false;
91 }
92 }
93
94 template<class T>
95 bool has_inf(sycl::queue &q, sycl::buffer<T> &buf, u64 cnt) {
97 // res is filled with 1 if no inf 0 otherwise
98 sycl::buffer<u8> res(cnt);
99 q.submit([&](sycl::handler &cgh) {
100 sycl::accessor acc1{buf, cgh, sycl::read_only};
101
102 sycl::accessor out{res, cgh, sycl::write_only, sycl::no_init};
103
104 cgh.parallel_for(sycl::range{cnt}, [=](sycl::item<1> item) {
105 out[item] = !sham::has_inf(acc1[item]);
106 });
107 });
108
109 return !is_all_true(res, cnt);
110 } else {
111 return false;
112 }
113 }
114
115 template<class T>
116 bool has_nan_or_inf(sycl::queue &q, sycl::buffer<T> &buf, u64 cnt) {
118 // res is filled with 1 if no nan or inf 0 otherwise
119 sycl::buffer<u8> res(cnt);
120 q.submit([&](sycl::handler &cgh) {
121 sycl::accessor acc1{buf, cgh, sycl::read_only};
122
123 sycl::accessor out{res, cgh, sycl::write_only, sycl::no_init};
124
125 cgh.parallel_for(sycl::range{cnt}, [=](sycl::item<1> item) {
126 out[item] = !sham::has_nan_or_inf(acc1[item]);
127 });
128 });
129
130 return !is_all_true(res, cnt);
131 } else {
132 return false;
133 }
134 }
135
136#ifndef DOXYGEN
137 #define XMAC_TYPES \
138 X(f32) \
139 X(f32_2) \
140 X(f32_3) \
141 X(f32_4) \
142 X(f32_8) \
143 X(f32_16) \
144 X(f64) \
145 X(f64_2) \
146 X(f64_3) \
147 X(f64_4) \
148 X(f64_8) \
149 X(f64_16) \
150 X(u32) \
151 X(u64) \
152 X(i32) \
153 X(i64) \
154 X(u32_3) \
155 X(u64_3) \
156 X(i64_3) \
157 X(i32_3)
158
159 #define X(_arg_) \
160 template _arg_ sum(sycl::queue &q, sycl::buffer<_arg_> &buf1, u32 start_id, u32 end_id); \
161 template _arg_ max(sycl::queue &q, sycl::buffer<_arg_> &buf1, u32 start_id, u32 end_id); \
162 template _arg_ min(sycl::queue &q, sycl::buffer<_arg_> &buf1, u32 start_id, u32 end_id); \
163 template bool has_nan(sycl::queue &q, sycl::buffer<_arg_> &buf1, u64 cnt); \
164 template bool has_inf(sycl::queue &q, sycl::buffer<_arg_> &buf1, u64 cnt); \
165 template bool has_nan_or_inf(sycl::queue &q, sycl::buffer<_arg_> &buf1, u64 cnt);
166
167 XMAC_TYPES
168 #undef X
169#endif
170
171} // namespace shamalgs::reduction
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
bool is_all_true(sycl::buffer< T > &buf, u32 cnt)
Check if all elements in a sycl::buffer are non-zero.
main include file for memory algorithms