1#ifndef ARCH_DEVICE_HOST_H
2#define ARCH_DEVICE_HOST_H
5#define ARCH_LOOP_LAMBDA [=]
6#define ARCH_INNER_BODY2(i, j, aggregate) return [=](auto i, auto j, auto *aggregate)
7#define ARCH_INNER_BODY3(i, j, k, aggregate) return [=](auto i, auto j, auto k, auto *aggregate)
8#define ARCH_INNER_BODY4(i, j, k, l, aggregate) return [=](auto i, auto j, auto k, auto l, auto *aggregate)
44 inline static void free(
void* ptr) {
50 inline static void memcpy_h2d(T* dst, T* src,
size_t bytes) {}
54 inline static void memcpy_d2h(T* dst, T* src,
size_t bytes) {}
65 template <reduce_op Op, u
int NReductions, u
int NDim,
typename Lambda,
typename T>
69 #pragma omp parallel for reduction(+:sum[:n_redu_dynamic])
70 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
74 #pragma omp parallel for reduction(max:sum[:n_redu_dynamic])
75 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
79 #pragma omp parallel for reduction(min:sum[:n_redu_dynamic])
80 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
84 #pragma omp parallel for
85 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
89 printf(
"ERROR at %s:%d: Invalid reduction identifier \"Op\".", __FILE__, __LINE__);
94 template <reduce_op Op, uint NReductions, uint NDim, typename Lambda, typename T, typename = typename std::enable_if<std::is_void<typename std::invoke_result<Lambda, uint, uint, T*>::type>::value>::type>
98 #pragma omp parallel for collapse(2) reduction(+:sum[:n_redu_dynamic])
99 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
100 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
101 loop_body(idx0, idx1,
sum);
105 #pragma omp parallel for collapse(2) reduction(max:sum[:n_redu_dynamic])
106 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
107 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
108 loop_body(idx0, idx1,
sum);
112 #pragma omp parallel for collapse(2) reduction(min:sum[:n_redu_dynamic])
113 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
114 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
115 loop_body(idx0, idx1,
sum);
119 #pragma omp parallel for collapse(2)
120 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
121 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
122 loop_body(idx0, idx1,
sum);
126 printf(
"ERROR at %s:%d: Invalid reduction identifier \"Op\".", __FILE__, __LINE__);
131 template <reduce_op Op, uint NReductions, uint NDim, typename Lambda, typename T, typename = typename std::enable_if<!std::is_void<typename std::invoke_result<Lambda, uint, uint, T*>::type>::value>::type,
typename =
void>
135 #pragma omp parallel for reduction(+:sum[:n_redu_dynamic])
136 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
137 auto inner_loop = loop_body(idx1, idx1,
sum);
138 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
139 inner_loop(idx0, idx1,
sum);
143 #pragma omp parallel for reduction(max:sum[:n_redu_dynamic])
144 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
145 auto inner_loop = loop_body(idx1, idx1,
sum);
146 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
147 inner_loop(idx0, idx1,
sum);
151 #pragma omp parallel for reduction(min:sum[:n_redu_dynamic])
152 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
153 auto inner_loop = loop_body(idx1, idx1,
sum);
154 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
155 inner_loop(idx0, idx1,
sum);
159 #pragma omp parallel for
160 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
161 auto inner_loop = loop_body(idx1, idx1,
sum);
162 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
163 inner_loop(idx0, idx1,
sum);
167 printf(
"ERROR at %s:%d: Invalid reduction identifier \"Op\".", __FILE__, __LINE__);
172 template <reduce_op Op, uint NReductions, uint NDim, typename Lambda, typename T, typename = typename std::enable_if<std::is_void<typename std::invoke_result<Lambda, uint, uint, uint, T*>::type>::value>::type>
176 #pragma omp parallel for collapse(3) reduction(+:sum[:n_redu_dynamic])
177 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
178 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
179 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
180 loop_body(idx0, idx1, idx2,
sum);
185 #pragma omp parallel for collapse(3) reduction(max:sum[:n_redu_dynamic])
186 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
187 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
188 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
189 loop_body(idx0, idx1, idx2,
sum);
194 #pragma omp parallel for collapse(3) reduction(min:sum[:n_redu_dynamic])
195 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
196 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
197 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
198 loop_body(idx0, idx1, idx2,
sum);
203 #pragma omp parallel for collapse(3)
204 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
205 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
206 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
207 loop_body(idx0, idx1, idx2,
sum);
212 printf(
"ERROR at %s:%d: Invalid reduction identifier \"Op\".", __FILE__, __LINE__);
217 template <reduce_op Op, uint NReductions, uint NDim, typename Lambda, typename T, typename = typename std::enable_if<!std::is_void<typename std::invoke_result<Lambda, uint, uint, uint, T*>::type>::value>::type,
typename =
void>
221 #pragma omp parallel for reduction(+:sum[:n_redu_dynamic])
222 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
223 auto inner_loop = loop_body(idx2, idx2, idx2,
sum);
224 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
225 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
226 inner_loop(idx0, idx1, idx2,
sum);
231 #pragma omp parallel for reduction(max:sum[:n_redu_dynamic])
232 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
233 auto inner_loop = loop_body(idx2, idx2, idx2,
sum);
234 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
235 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
236 inner_loop(idx0, idx1, idx2,
sum);
241 #pragma omp parallel for reduction(min:sum[:n_redu_dynamic])
242 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
243 auto inner_loop = loop_body(idx2, idx2, idx2,
sum);
244 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
245 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
246 inner_loop(idx0, idx1, idx2,
sum);
251 #pragma omp parallel for
252 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
253 auto inner_loop = loop_body(idx2, idx2, idx2,
sum);
254 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
255 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
256 inner_loop(idx0, idx1, idx2,
sum);
261 printf(
"ERROR at %s:%d: Invalid reduction identifier \"Op\".", __FILE__, __LINE__);
266 template <reduce_op Op, uint NReductions, uint NDim, typename Lambda, typename T, typename = typename std::enable_if<std::is_void<typename std::invoke_result<Lambda, uint, uint, uint, uint, T*>::type>::value>::type>
270 #pragma omp parallel for collapse(4) reduction(+:sum[:n_redu_dynamic])
271 for (
uint idx3 = 0; idx3 < limits[3]; ++idx3) {
272 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
273 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
274 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
275 loop_body(idx0, idx1, idx2, idx3,
sum);
281 #pragma omp parallel for collapse(4) reduction(max:sum[:n_redu_dynamic])
282 for (
uint idx3 = 0; idx3 < limits[3]; ++idx3) {
283 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
284 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
285 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
286 loop_body(idx0, idx1, idx2, idx3,
sum);
292 #pragma omp parallel for collapse(4) reduction(min:sum[:n_redu_dynamic])
293 for (
uint idx3 = 0; idx3 < limits[3]; ++idx3) {
294 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
295 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
296 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
297 loop_body(idx0, idx1, idx2, idx3,
sum);
303 #pragma omp parallel for collapse(4)
304 for (
uint idx3 = 0; idx3 < limits[3]; ++idx3) {
305 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
306 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
307 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
308 loop_body(idx0, idx1, idx2, idx3,
sum);
314 printf(
"ERROR at %s:%d: Invalid reduction identifier \"Op\".", __FILE__, __LINE__);
319 template <reduce_op Op, uint NReductions, uint NDim, typename Lambda, typename T, typename = typename std::enable_if<!std::is_void<typename std::invoke_result<Lambda, uint, uint, uint, uint, T*>::type>::value>::type,
typename =
void>
323 #pragma omp parallel for reduction(+:sum[:n_redu_dynamic])
324 for (
uint idx3 = 0; idx3 < limits[3]; ++idx3) {
325 auto inner_loop = loop_body(idx3, idx3, idx3, idx3,
sum);
326 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
327 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
328 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
329 inner_loop(idx0, idx1, idx2, idx3,
sum);
335 #pragma omp parallel for reduction(max:sum[:n_redu_dynamic])
336 for (
uint idx3 = 0; idx3 < limits[3]; ++idx3) {
337 auto inner_loop = loop_body(idx3, idx3, idx3, idx3,
sum);
338 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
339 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
340 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
341 inner_loop(idx0, idx1, idx2, idx3,
sum);
347 #pragma omp parallel for reduction(min:sum[:n_redu_dynamic])
348 for (
uint idx3 = 0; idx3 < limits[3]; ++idx3) {
349 auto inner_loop = loop_body(idx3, idx3, idx3, idx3,
sum);
350 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
351 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
352 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
353 inner_loop(idx0, idx1, idx2, idx3,
sum);
359 #pragma omp parallel for
360 for (
uint idx3 = 0; idx3 < limits[3]; ++idx3) {
361 auto inner_loop = loop_body(idx3, idx3, idx3, idx3,
sum);
362 for (
uint idx2 = 0; idx2 < limits[2]; ++idx2) {
363 for (
uint idx1 = 0; idx1 < limits[1]; ++idx1) {
364 for (
uint idx0 = 0; idx0 < limits[0]; ++idx0) {
365 inner_loop(idx0, idx1, idx2, idx3,
sum);
371 printf(
"ERROR at %s:%d: Invalid reduction identifier \"Op\".", __FILE__, __LINE__);
void syncDeviceData(void)
__host__ __device__ T & operator[](uint i) const
buf(T *const _ptr, uint _bytes)
static __global__ void const T *__restrict__ T *__restrict__ const uint *__restrict__ const uint const uint n_redu_dynamic
static __forceinline__ void memcpy_d2h(T *dst, T *src, size_t bytes)
static __forceinline__ void parallel_reduce_driver(const uint(&limits)[NDim], Lambda loop_body, T *sum, const uint n_redu_dynamic)
static __forceinline__ void host_unregister(T *ptr)
__host__ static __forceinline__ void * allocate(size_t bytes)
static __forceinline__ void host_register(T *ptr, size_t bytes)
static __forceinline__ void memcpy_h2d(T *dst, T *src, size_t bytes)
__host__ static __forceinline__ void free(T *ptr)