Block-Structured AMR Software Framework
AMReX_GpuLaunchFunctsC.H
Go to the documentation of this file.
1 #ifndef AMREX_GPU_LAUNCH_FUNCTS_C_H_
2 #define AMREX_GPU_LAUNCH_FUNCTS_C_H_
3 #include <AMReX_Config.H>
4 
5 namespace amrex {
6 
7 namespace detail {
8 
9  // call_f_scalar_handler
10 
11  template <typename F, typename N>
13  auto call_f_scalar_handler (F const& f, N i)
14  noexcept -> decltype(f(0))
15  {
16  f(i);
17  }
18 
19  template <typename F, typename N>
21  auto call_f_scalar_handler (F const& f, N i)
22  noexcept -> decltype(f(0,Gpu::Handler{}))
23  {
24  f(i, Gpu::Handler{});
25  }
26 
27  // call_f_intvect_inner
28 
29  template <typename F, std::size_t...Ns, class...Args>
31  auto call_f_intvect_inner (std::index_sequence<Ns...>, F const& f, IntVectND<1> iv, Args...args)
32  noexcept -> decltype(f(0, 0, 0, args...))
33  {
34  f(iv[0], 0, 0, args...);
35  }
36 
37  template <typename F, std::size_t...Ns, class...Args>
39  auto call_f_intvect_inner (std::index_sequence<Ns...>, F const& f, IntVectND<2> iv, Args...args)
40  noexcept -> decltype(f(0, 0, 0, args...))
41  {
42  f(iv[0], iv[1], 0, args...);
43  }
44 
45  template <typename F, int dim, std::size_t...Ns, class...Args>
47  auto call_f_intvect_inner (std::index_sequence<Ns...>, F const& f, IntVectND<dim> iv, Args...args)
48  noexcept -> decltype(f(iv, args...))
49  {
50  f(iv, args...);
51  }
52 
53  template <typename F, int dim, std::size_t...Ns, class...Args>
55  auto call_f_intvect_inner (std::index_sequence<Ns...>, F const& f, IntVectND<dim> iv, Args...args)
56  noexcept -> decltype(f(iv[Ns]..., args...))
57  {
58  f(iv[Ns]..., args...);
59  }
60 
61  // call_f_intvect_engine
62 
63  template <typename F, int dim>
65  auto call_f_intvect_engine (F const& f, IntVectND<dim> iv, RandomEngine engine)
66  noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, engine))
67  {
68  call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, engine);
69  }
70 
71  // call_f_intvect_handler
72 
73  template <typename F, int dim>
76  noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv))
77  {
78  call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv);
79  }
80 
81  template <typename F, int dim>
83  auto call_f_intvect_handler (F const& f, IntVectND<dim> iv)
84  noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, Gpu::Handler{}))
85  {
86  call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, Gpu::Handler{});
87  }
88 
89  // call_f_intvect_ncomp_engine
90 
91  template <typename F, typename T, int dim>
93  auto call_f_intvect_ncomp_engine (F const& f, IntVectND<dim> iv, T n, RandomEngine engine)
94  noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, n, engine))
95  {
96  call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, n, engine);
97  }
98 
99  // call_f_intvect_ncomp_handler
100 
101  template <typename F, typename T, int dim>
104  noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, n))
105  {
106  call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, n);
107  }
108 
109  template <typename F, typename T, int dim>
111  auto call_f_intvect_ncomp_handler (F const& f, IntVectND<dim> iv, T n)
112  noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, n, Gpu::Handler{}))
113  {
114  call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, n, Gpu::Handler{});
115  }
116 
117 }
118 
119 template<typename T, typename L>
120 void launch (T const& n, L&& f) noexcept
121 {
122  std::forward<L>(f)(n);
123 }
124 
125 template<int MT, typename T, typename L>
126 void launch (T const& n, L&& f) noexcept
127 {
129  std::forward<L>(f)(n);
130 }
131 
132 template <typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
134 void For (T n, L const& f) noexcept
135 {
136  for (T i = 0; i < n; ++i) {
138  }
139 }
140 
141 template <int MT, typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
142 void For (T n, L&& f) noexcept
143 {
145  For(n, std::forward<L>(f));
146 }
147 
148 template <typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
149 void For (Gpu::KernelInfo const&, T n, L&& f) noexcept
150 {
151  For(n, std::forward<L>(f));
152 }
153 
154 template <int MT, typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
155 void For (Gpu::KernelInfo const&, T n, L&& f) noexcept
156 {
158  For(n, std::forward<L>(f));
159 }
160 
161 template <typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
163 void ParallelFor (T n, L const& f) noexcept
164 {
166  for (T i = 0; i < n; ++i) {
168  }
169 }
170 
171 template <int MT, typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
172 void ParallelFor (T n, L&& f) noexcept
173 {
175  ParallelFor(n, std::forward<L>(f));
176 }
177 
178 template <typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
179 void ParallelFor (Gpu::KernelInfo const&, T n, L&& f) noexcept
180 {
181  ParallelFor(n, std::forward<L>(f));
182 }
183 
184 template <int MT, typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
185 void ParallelFor (Gpu::KernelInfo const&, T n, L&& f) noexcept
186 {
188  ParallelFor(n, std::forward<L>(f));
189 }
190 
191 namespace detail {
192 
193 template <int idim, typename L, int dim>
195 void For_impND (L const& f, IntVectND<dim> const lo, IntVectND<dim> const hi, IntVectND<dim> iv) noexcept
196 {
197  if constexpr (idim == 1) {
198  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
200  }
201  } else if constexpr (idim == 2) {
202  for (int i1 = lo[1], h1 = hi[1]; i1 <= h1; ++i1) { iv[1] = i1;
203  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
205  }}
206  } else if constexpr (idim == 3) {
207  for (int i2 = lo[2], h2 = hi[2]; i2 <= h2; ++i2) { iv[2] = i2;
208  for (int i1 = lo[1], h1 = hi[1]; i1 <= h1; ++i1) { iv[1] = i1;
209  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
211  }}}
212  } else {
213  for (int id = lo[idim-1], hd = hi[idim-1]; id <= hd; ++id) { iv[idim-1] = id;
214  For_impND<idim-1>(f, lo, hi, iv);
215  }
216  }
217 }
218 
219 }
220 
221 template <typename L, int dim>
223 void For (BoxND<dim> const& box, L const& f) noexcept
224 {
225  const auto lo = amrex::lbound_iv(box);
226  const auto hi = amrex::ubound_iv(box);
227  IntVectND<dim> iv;
228  detail::For_impND<dim>(f, lo, hi, iv);
229 }
230 
231 template <int MT, typename L, int dim>
232 void For (BoxND<dim> const& box, L&& f) noexcept
233 {
235  For(box, std::forward<L>(f));
236 }
237 
238 template <typename L, int dim>
239 void For (Gpu::KernelInfo const&, BoxND<dim> const& box, L&& f) noexcept
240 {
241  For(box, std::forward<L>(f));
242 }
243 
244 template <int MT, typename L, int dim>
245 void For (Gpu::KernelInfo const&, BoxND<dim> const& box, L&& f) noexcept
246 {
248  For(box, std::forward<L>(f));
249 }
250 
251 namespace detail {
252 
253 template <int idim, typename L, int dim>
255 void ParallelFor_impND (L const& f, IntVectND<dim> const lo, IntVectND<dim> const hi, IntVectND<dim> iv) noexcept
256 {
257  if constexpr (idim == 1) {
259  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
261  }
262  } else if constexpr (idim == 2) {
263  for (int i1 = lo[1], h1 = hi[1]; i1 <= h1; ++i1) { iv[1] = i1;
265  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
267  }}
268  } else if constexpr (idim == 3) {
269  for (int i2 = lo[2], h2 = hi[2]; i2 <= h2; ++i2) { iv[2] = i2;
270  for (int i1 = lo[1], h1 = hi[1]; i1 <= h1; ++i1) { iv[1] = i1;
272  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
274  }}}
275  } else {
276  for (int id = lo[idim-1], hd = hi[idim-1]; id <= hd; ++id) { iv[idim-1] = id;
277  ParallelFor_impND<idim-1>(f, lo, hi, iv);
278  }
279  }
280 }
281 
282 }
283 
284 template <typename L, int dim>
286 void ParallelFor (BoxND<dim> const& box, L const& f) noexcept
287 {
288  const auto lo = amrex::lbound_iv(box);
289  const auto hi = amrex::ubound_iv(box);
290  IntVectND<dim> iv;
291  detail::ParallelFor_impND<dim>(f, lo, hi, iv);
292 }
293 
294 template <int MT, typename L, int dim>
295 void ParallelFor (BoxND<dim> const& box, L&& f) noexcept
296 {
298  ParallelFor(box, std::forward<L>(f));
299 }
300 
301 template <typename L, int dim>
302 void ParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box, L&& f) noexcept
303 {
304  ParallelFor(box, std::forward<L>(f));
305 }
306 
307 template <int MT, typename L, int dim>
308 void ParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box, L&& f) noexcept
309 {
311  ParallelFor(box, std::forward<L>(f));
312 }
313 
314 namespace detail {
315 
316 template <int idim, typename L, typename T, int dim>
318 void For_impND (L const& f, IntVectND<dim> const lo, IntVectND<dim> const hi, IntVectND<dim> iv, T n) noexcept
319 {
320  if constexpr (idim == 1) {
321  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
323  }
324  } else if constexpr (idim == 2) {
325  for (int i1 = lo[1], h1 = hi[1]; i1 <= h1; ++i1) { iv[1] = i1;
326  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
328  }}
329  } else if constexpr (idim == 3) {
330  for (int i2 = lo[2], h2 = hi[2]; i2 <= h2; ++i2) { iv[2] = i2;
331  for (int i1 = lo[1], h1 = hi[1]; i1 <= h1; ++i1) { iv[1] = i1;
332  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
334  }}}
335  } else {
336  for (int id = lo[idim-1], hd = hi[idim-1]; id <= hd; ++id) { iv[idim-1] = id;
337  For_impND<idim-1>(f, lo, hi, iv, n);
338  }
339  }
340 }
341 
342 }
343 
344 template <typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
346 void For (BoxND<dim> const& box, T ncomp, L const& f) noexcept
347 {
348  const auto lo = amrex::lbound_iv(box);
349  const auto hi = amrex::ubound_iv(box);
350  IntVectND<dim> iv;
351  for (T n = 0; n < ncomp; ++n) {
352  detail::For_impND<dim>(f, lo, hi, iv, n);
353  }
354 }
355 
356 template <int MT, typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
357 void For (BoxND<dim> const& box, T ncomp, L&& f) noexcept
358 {
360  For(box, ncomp, std::forward<L>(f));
361 }
362 
363 template <typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
364 void For (Gpu::KernelInfo const&, BoxND<dim> const& box, T ncomp, L&& f) noexcept
365 {
366  For(box, ncomp, std::forward<L>(f));
367 }
368 
369 template <int MT, typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
370 void For (Gpu::KernelInfo const&, BoxND<dim> const& box, T ncomp, L&& f) noexcept
371 {
373  For(box, ncomp, std::forward<L>(f));
374 }
375 
376 namespace detail {
377 
378 template <int idim, typename L, typename T, int dim>
380 void ParallelFor_impND (L const& f, IntVectND<dim> const lo, IntVectND<dim> const hi, IntVectND<dim> iv, T n) noexcept
381 {
382  if constexpr (idim == 1) {
384  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
386  }
387  } else if constexpr (idim == 2) {
388  for (int i1 = lo[1], h1 = hi[1]; i1 <= h1; ++i1) { iv[1] = i1;
390  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
392  }}
393  } else if constexpr (idim == 3) {
394  for (int i2 = lo[2], h2 = hi[2]; i2 <= h2; ++i2) { iv[2] = i2;
395  for (int i1 = lo[1], h1 = hi[1]; i1 <= h1; ++i1) { iv[1] = i1;
397  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
399  }}}
400  } else {
401  for (int id = lo[idim-1], hd = hi[idim-1]; id <= hd; ++id) { iv[idim-1] = id;
402  ParallelFor_impND<idim-1>(f, lo, hi, iv, n);
403  }
404  }
405 }
406 
407 }
408 
409 template <typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
411 void ParallelFor (BoxND<dim> const& box, T ncomp, L const& f) noexcept
412 {
413  const auto lo = amrex::lbound_iv(box);
414  const auto hi = amrex::ubound_iv(box);
415  IntVectND<dim> iv;
416  for (T n = 0; n < ncomp; ++n) {
417  detail::ParallelFor_impND<dim>(f, lo, hi, iv, n);
418  }
419 }
420 
421 template <int MT, typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
422 void ParallelFor (BoxND<dim> const& box, T ncomp, L&& f) noexcept
423 {
425  ParallelFor(box, ncomp, std::forward<L>(f));
426 }
427 
428 template <typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
429 void ParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box, T ncomp, L&& f) noexcept
430 {
431  ParallelFor(box, ncomp, std::forward<L>(f));
432 }
433 
434 template <int MT, typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
435 void ParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box, T ncomp, L&& f) noexcept
436 {
438  ParallelFor(box, ncomp, std::forward<L>(f));
439 }
440 
441 template <typename L1, typename L2, int dim>
442 void For (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
443 {
444  For(box1, std::forward<L1>(f1));
445  For(box2, std::forward<L2>(f2));
446 }
447 
448 template <int MT, typename L1, typename L2, int dim>
449 void For (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
450 {
452  For(box1, std::forward<L1>(f1));
453  For(box2, std::forward<L2>(f2));
454 }
455 
456 template <typename L1, typename L2, int dim>
457 void For (Gpu::KernelInfo const&, BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
458 {
459  For (box1, box2, std::forward<L1>(f1), std::forward<L2>(f2));
460 }
461 
462 template <int MT, typename L1, typename L2, int dim>
463 void For (Gpu::KernelInfo const&, BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
464 {
466  For (box1, box2, std::forward<L1>(f1), std::forward<L2>(f2));
467 }
468 
469 template <typename L1, typename L2, typename L3, int dim>
470 void For (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3, L1&& f1, L2&& f2, L3&& f3) noexcept
471 {
472  For(box1, std::forward<L1>(f1));
473  For(box2, std::forward<L2>(f2));
474  For(box3, std::forward<L3>(f3));
475 }
476 
477 template <int MT, typename L1, typename L2, typename L3, int dim>
478 void For (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3, L1&& f1, L2&& f2, L3&& f3) noexcept
479 {
481  For(box1, std::forward<L1>(f1));
482  For(box2, std::forward<L2>(f2));
483  For(box3, std::forward<L3>(f3));
484 }
485 
486 template <typename L1, typename L2, typename L3, int dim>
487 void For (Gpu::KernelInfo const&, BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3, L1&& f1, L2&& f2, L3&& f3) noexcept
488 {
489  For(box1, box2, box3, std::forward<L1>(f1), std::forward<L2>(f2), std::forward<L3>(f3));
490 }
491 
492 template <int MT, typename L1, typename L2, typename L3, int dim>
493 void For (Gpu::KernelInfo const&, BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3, L1&& f1, L2&& f2, L3&& f3) noexcept
494 {
496  For(box1, box2, box3, std::forward<L1>(f1), std::forward<L2>(f2), std::forward<L3>(f3));
497 }
498 
499 template <typename T1, typename T2, typename L1, typename L2, int dim,
500  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
501  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
502 void For (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
503  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
504 {
505  For(box1, ncomp1, std::forward<L1>(f1));
506  For(box2, ncomp2, std::forward<L2>(f2));
507 }
508 
509 template <int MT, typename T1, typename T2, typename L1, typename L2, int dim,
510  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
511  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
512 void For (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
513  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
514 {
516  For(box1, ncomp1, std::forward<L1>(f1));
517  For(box2, ncomp2, std::forward<L2>(f2));
518 }
519 
520 template <typename T1, typename T2, typename L1, typename L2, int dim,
521  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
522  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
523 void For (Gpu::KernelInfo const&,
524  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
525  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
526 {
527  For(box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
528 }
529 
530 template <int MT, typename T1, typename T2, typename L1, typename L2, int dim,
531  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
532  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
533 void For (Gpu::KernelInfo const&,
534  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
535  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
536 {
538  For(box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
539 }
540 
541 template <typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
542  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
543  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
544  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
545 void For (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
546  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
547  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
548 {
549  For(box1, ncomp1, std::forward<L1>(f1));
550  For(box2, ncomp2, std::forward<L2>(f2));
551  For(box3, ncomp3, std::forward<L3>(f3));
552 }
553 
554 template <int MT, typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
555  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
556  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
557  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
558 void For (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
559  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
560  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
561 {
563  For(box1, ncomp1, std::forward<L1>(f1));
564  For(box2, ncomp2, std::forward<L2>(f2));
565  For(box3, ncomp3, std::forward<L3>(f3));
566 }
567 
568 template <typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
569  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
570  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
571  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
572 void For (Gpu::KernelInfo const&,
573  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
574  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
575  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
576 {
577  For(box1,ncomp1,std::forward<L1>(f1),
578  box2,ncomp2,std::forward<L2>(f2),
579  box3,ncomp3,std::forward<L3>(f3));
580 }
581 
582 template <int MT, typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
583  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
584  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
585  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
586 void For (Gpu::KernelInfo const&,
587  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
588  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
589  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
590 {
592  For(box1,ncomp1,std::forward<L1>(f1),
593  box2,ncomp2,std::forward<L2>(f2),
594  box3,ncomp3,std::forward<L3>(f3));
595 }
596 
597 template <typename L1, typename L2, int dim>
598 void ParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
599 {
600  ParallelFor(box1, std::forward<L1>(f1));
601  ParallelFor(box2, std::forward<L2>(f2));
602 }
603 
604 template <int MT, typename L1, typename L2, int dim>
605 void ParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
606 {
608  ParallelFor(box1, std::forward<L1>(f1));
609  ParallelFor(box2, std::forward<L2>(f2));
610 }
611 
612 template <typename L1, typename L2, int dim>
613 void ParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
614 {
615  ParallelFor(box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
616 }
617 
618 template <int MT, typename L1, typename L2, int dim>
619 void ParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
620 {
622  ParallelFor(box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
623 }
624 
625 template <typename L1, typename L2, typename L3, int dim>
626 void ParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3, L1&& f1, L2&& f2, L3&& f3) noexcept
627 {
628  ParallelFor(box1, std::forward<L1>(f1));
629  ParallelFor(box2, std::forward<L2>(f2));
630  ParallelFor(box3, std::forward<L3>(f3));
631 }
632 
633 template <int MT, typename L1, typename L2, typename L3, int dim>
634 void ParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3, L1&& f1, L2&& f2, L3&& f3) noexcept
635 {
637  ParallelFor(box1, std::forward<L1>(f1));
638  ParallelFor(box2, std::forward<L2>(f2));
639  ParallelFor(box3, std::forward<L3>(f3));
640 }
641 
642 template <typename L1, typename L2, typename L3, int dim>
643 void ParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3, L1&& f1, L2&& f2, L3&& f3) noexcept
644 {
645  ParallelFor(box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
646 }
647 
648 template <int MT, typename L1, typename L2, typename L3, int dim>
649 void ParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3, L1&& f1, L2&& f2, L3&& f3) noexcept
650 {
652  ParallelFor(box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
653 }
654 
655 template <typename T1, typename T2, typename L1, typename L2, int dim,
656  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
657  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
658 void ParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
659  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
660 {
661  ParallelFor(box1, ncomp1, std::forward<L1>(f1));
662  ParallelFor(box2, ncomp2, std::forward<L2>(f2));
663 }
664 
665 template <int MT, typename T1, typename T2, typename L1, typename L2, int dim,
666  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
667  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
668 void ParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
669  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
670 {
672  ParallelFor(box1, ncomp1, std::forward<L1>(f1));
673  ParallelFor(box2, ncomp2, std::forward<L2>(f2));
674 }
675 
676 template <typename T1, typename T2, typename L1, typename L2, int dim,
677  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
678  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
680  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
681  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
682 {
683  ParallelFor(box1,ncomp1,std::forward<L1>(f1),
684  box2,ncomp2,std::forward<L2>(f2));
685 }
686 
687 template <int MT, typename T1, typename T2, typename L1, typename L2, int dim,
688  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
689  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
691  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
692  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
693 {
695  ParallelFor(box1,ncomp1,std::forward<L1>(f1),
696  box2,ncomp2,std::forward<L2>(f2));
697 }
698 
699 template <typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
700  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
701  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
702  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
703 void ParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
704  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
705  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
706 {
707  ParallelFor(box1, ncomp1, std::forward<L1>(f1));
708  ParallelFor(box2, ncomp2, std::forward<L2>(f2));
709  ParallelFor(box3, ncomp3, std::forward<L3>(f3));
710 }
711 
712 template <int MT, typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
713  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
714  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
715  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
716 void ParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
717  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
718  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
719 {
721  ParallelFor(box1, ncomp1, std::forward<L1>(f1));
722  ParallelFor(box2, ncomp2, std::forward<L2>(f2));
723  ParallelFor(box3, ncomp3, std::forward<L3>(f3));
724 }
725 
726 template <typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
727  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
728  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
729  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
731  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
732  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
733  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
734 {
735  ParallelFor(box1, ncomp1, std::forward<L1>(f1),
736  box2, ncomp2, std::forward<L2>(f2),
737  box3, ncomp3, std::forward<L3>(f3));
738 }
739 
740 template <int MT, typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
741  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
742  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
743  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
745  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
746  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
747  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
748 {
750  ParallelFor(box1, ncomp1, std::forward<L1>(f1),
751  box2, ncomp2, std::forward<L2>(f2),
752  box3, ncomp3, std::forward<L3>(f3));
753 }
754 
755 template <typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
756 void HostDeviceParallelFor (T n, L&& f) noexcept
757 {
758  ParallelFor(n,std::forward<L>(f));
759 }
760 
761 template <int MT, typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
762 void HostDeviceParallelFor (T n, L&& f) noexcept
763 {
765  ParallelFor(n,std::forward<L>(f));
766 }
767 
768 template <typename L, int dim>
769 void HostDeviceParallelFor (BoxND<dim> const& box, L&& f) noexcept
770 {
771  ParallelFor(box,std::forward<L>(f));
772 }
773 
774 template <int MT, typename L, int dim>
775 void HostDeviceParallelFor (BoxND<dim> const& box, L&& f) noexcept
776 {
778  ParallelFor(box,std::forward<L>(f));
779 }
780 
781 template <typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
782 void HostDeviceParallelFor (BoxND<dim> const& box, T ncomp, L&& f) noexcept
783 {
784  ParallelFor(box,ncomp,std::forward<L>(f));
785 }
786 
787 template <int MT, typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
788 void HostDeviceParallelFor (BoxND<dim> const& box, T ncomp, L&& f) noexcept
789 {
791  ParallelFor(box,ncomp,std::forward<L>(f));
792 }
793 
794 template <typename L1, typename L2, int dim>
795 void HostDeviceParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
796 {
797  ParallelFor(box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
798 }
799 
800 template <int MT, typename L1, typename L2, int dim>
801 void HostDeviceParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
802 {
804  ParallelFor(box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
805 }
806 
807 template <typename L1, typename L2, typename L3, int dim>
808 void HostDeviceParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
809  L1&& f1, L2&& f2, L3&& f3) noexcept
810 {
811  ParallelFor(box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
812 }
813 
814 template <int MT, typename L1, typename L2, typename L3, int dim>
815 void HostDeviceParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
816  L1&& f1, L2&& f2, L3&& f3) noexcept
817 {
819  ParallelFor(box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
820 }
821 
822 template <typename T1, typename T2, typename L1, typename L2, int dim,
823  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
824  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
825 void HostDeviceParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
826  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
827 {
828  ParallelFor(box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
829 }
830 
831 template <int MT, typename T1, typename T2, typename L1, typename L2, int dim,
832  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
833  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
834 void HostDeviceParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
835  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
836 {
838  ParallelFor(box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
839 }
840 
841 template <typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
842  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
843  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
844  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
845 void HostDeviceParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
846  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
847  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
848 {
849  ParallelFor(box1,ncomp1,std::forward<L1>(f1),
850  box2,ncomp2,std::forward<L2>(f2),
851  box3,ncomp3,std::forward<L3>(f3));
852 }
853 
854 template <int MT, typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
855  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
856  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
857  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
858 void HostDeviceParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
859  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
860  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
861 {
863  ParallelFor(box1,ncomp1,std::forward<L1>(f1),
864  box2,ncomp2,std::forward<L2>(f2),
865  box3,ncomp3,std::forward<L3>(f3));
866 }
867 
868 template <typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
869 void HostDeviceFor (T n, L&& f) noexcept
870 {
871  For(n,std::forward<L>(f));
872 }
873 
874 template <int MT, typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
875 void HostDeviceFor (T n, L&& f) noexcept
876 {
878  For(n,std::forward<L>(f));
879 }
880 
881 template <typename L, int dim>
882 void HostDeviceFor (BoxND<dim> const& box, L&& f) noexcept
883 {
884  For(box,std::forward<L>(f));
885 }
886 
887 template <int MT, typename L, int dim>
888 void HostDeviceFor (BoxND<dim> const& box, L&& f) noexcept
889 {
891  For(box,std::forward<L>(f));
892 }
893 
894 template <typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
895 void HostDeviceFor (BoxND<dim> const& box, T ncomp, L&& f) noexcept
896 {
897  For(box,ncomp,std::forward<L>(f));
898 }
899 
900 template <int MT, typename T, int dim, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
901 void HostDeviceFor (BoxND<dim> const& box, T ncomp, L&& f) noexcept
902 {
904  For(box,ncomp,std::forward<L>(f));
905 }
906 
907 template <typename L1, typename L2, int dim>
908 void HostDeviceFor (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
909 {
910  For(box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
911 }
912 
913 template <int MT, typename L1, typename L2, int dim>
914 void HostDeviceFor (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
915 {
917  For(box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
918 }
919 
920 template <typename L1, typename L2, typename L3, int dim>
921 void HostDeviceFor (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
922  L1&& f1, L2&& f2, L3&& f3) noexcept
923 {
924  For(box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
925 }
926 
927 template <int MT, typename L1, typename L2, typename L3, int dim>
928 void HostDeviceFor (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
929  L1&& f1, L2&& f2, L3&& f3) noexcept
930 {
932  For(box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
933 }
934 
935 template <typename T1, typename T2, typename L1, typename L2, int dim,
936  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
937  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
938 void HostDeviceFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
939  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
940 {
941  For(box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
942 }
943 
944 template <int MT, typename T1, typename T2, typename L1, typename L2, int dim,
945  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
946  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
947 void HostDeviceFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
948  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
949 {
951  For(box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
952 }
953 
954 template <typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
955  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
956  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
957  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
958 void HostDeviceFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
959  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
960  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
961 {
962  For(box1,ncomp1,std::forward<L1>(f1),
963  box2,ncomp2,std::forward<L2>(f2),
964  box3,ncomp3,std::forward<L3>(f3));
965 }
966 
967 template <int MT, typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
968  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
969  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
970  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
971 void HostDeviceFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
972  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
973  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
974 {
976  For(box1,ncomp1,std::forward<L1>(f1),
977  box2,ncomp2,std::forward<L2>(f2),
978  box3,ncomp3,std::forward<L3>(f3));
979 }
980 
981 template <typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
982 void HostDeviceParallelFor (Gpu::KernelInfo const&, T n, L&& f) noexcept
983 {
984  ParallelFor(n,std::forward<L>(f));
985 }
986 
987 template <int MT, typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
988 void HostDeviceParallelFor (Gpu::KernelInfo const&, T n, L&& f) noexcept
989 {
991  ParallelFor(n,std::forward<L>(f));
992 }
993 
994 template <typename L, int dim>
995 void HostDeviceParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box, L&& f) noexcept
996 {
997  ParallelFor(box,std::forward<L>(f));
998 }
999 
1000 template <int MT, typename L, int dim>
1001 void HostDeviceParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box, L&& f) noexcept
1002 {
1004  ParallelFor(box,std::forward<L>(f));
1005 }
1006 
1007 template <typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
1008 void HostDeviceParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box, T ncomp, L&& f) noexcept
1009 {
1010  ParallelFor(box,ncomp,std::forward<L>(f));
1011 }
1012 
1013 template <int MT, typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
1014 void HostDeviceParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box, T ncomp, L&& f) noexcept
1015 {
1017  ParallelFor(box,ncomp,std::forward<L>(f));
1018 }
1019 
1020 template <typename L1, typename L2, int dim>
1021 void HostDeviceParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
1022 {
1023  ParallelFor(box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
1024 }
1025 
1026 template <int MT, typename L1, typename L2, int dim>
1027 void HostDeviceParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
1028 {
1030  ParallelFor(box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
1031 }
1032 
1033 template <typename L1, typename L2, typename L3, int dim>
1035  BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1036  L1&& f1, L2&& f2, L3&& f3) noexcept
1037 {
1038  ParallelFor(box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
1039 }
1040 
1041 template <int MT, typename L1, typename L2, typename L3, int dim>
1043  BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1044  L1&& f1, L2&& f2, L3&& f3) noexcept
1045 {
1047  ParallelFor(box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
1048 }
1049 
1050 template <typename T1, typename T2, typename L1, typename L2, int dim,
1051  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
1052  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
1054  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1055  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
1056 {
1057  ParallelFor(box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
1058 }
1059 
1060 template <int MT, typename T1, typename T2, typename L1, typename L2, int dim,
1061  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
1062  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
1064  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1065  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
1066 {
1068  ParallelFor(box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
1069 }
1070 
1071 template <typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
1072  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
1073  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
1074  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
1076  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1077  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
1078  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
1079 {
1080  ParallelFor(box1,ncomp1,std::forward<L1>(f1),
1081  box2,ncomp2,std::forward<L2>(f2),
1082  box3,ncomp3,std::forward<L3>(f3));
1083 }
1084 
1085 template <int MT, typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
1086  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
1087  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
1088  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
1090  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1091  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
1092  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
1093 {
1095  ParallelFor(box1,ncomp1,std::forward<L1>(f1),
1096  box2,ncomp2,std::forward<L2>(f2),
1097  box3,ncomp3,std::forward<L3>(f3));
1098 }
1099 
1100 template <typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
1101 void HostDeviceFor (Gpu::KernelInfo const&, T n, L&& f) noexcept
1102 {
1103  For(n,std::forward<L>(f));
1104 }
1105 
1106 template <int MT, typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
1107 void HostDeviceFor (Gpu::KernelInfo const&, T n, L&& f) noexcept
1108 {
1110  For(n,std::forward<L>(f));
1111 }
1112 
1113 template <typename L, int dim>
1114 void HostDeviceFor (Gpu::KernelInfo const&, BoxND<dim> const& box, L&& f) noexcept
1115 {
1116  For(box,std::forward<L>(f));
1117 }
1118 
1119 template <int MT, typename L, int dim>
1120 void HostDeviceFor (Gpu::KernelInfo const&, BoxND<dim> const& box, L&& f) noexcept
1121 {
1123  For(box,std::forward<L>(f));
1124 }
1125 
1126 template <typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
1127 void HostDeviceFor (Gpu::KernelInfo const&, BoxND<dim> const& box, T ncomp, L&& f) noexcept
1128 {
1129  For(box,ncomp,std::forward<L>(f));
1130 }
1131 
1132 template <int MT, typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
1133 void HostDeviceFor (Gpu::KernelInfo const&, BoxND<dim> const& box, T ncomp, L&& f) noexcept
1134 {
1136  For(box,ncomp,std::forward<L>(f));
1137 }
1138 
1139 template <typename L1, typename L2, int dim>
1140 void HostDeviceFor (Gpu::KernelInfo const&, BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
1141 {
1142  For(box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
1143 }
1144 
1145 template <int MT, typename L1, typename L2, int dim>
1146 void HostDeviceFor (Gpu::KernelInfo const&, BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
1147 {
1149  For(box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
1150 }
1151 
1152 template <typename L1, typename L2, typename L3, int dim>
1154  BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1155  L1&& f1, L2&& f2, L3&& f3) noexcept
1156 {
1157  For(box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
1158 }
1159 
1160 template <int MT, typename L1, typename L2, typename L3, int dim>
1162  BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1163  L1&& f1, L2&& f2, L3&& f3) noexcept
1164 {
1166  For(box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
1167 }
1168 
1169 template <typename T1, typename T2, typename L1, typename L2, int dim,
1170  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
1171  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
1173  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1174  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
1175 {
1176  For(box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
1177 }
1178 
1179 template <int MT, typename T1, typename T2, typename L1, typename L2, int dim,
1180  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
1181  typename M2=std::enable_if_t<std::is_integral_v<T2>> >
1183  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1184  BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
1185 {
1187  For(box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
1188 }
1189 
1190 template <typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
1191  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
1192  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
1193  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
1195  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1196  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
1197  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
1198 {
1199  For(box1,ncomp1,std::forward<L1>(f1),
1200  box2,ncomp2,std::forward<L2>(f2),
1201  box3,ncomp3,std::forward<L3>(f3));
1202 }
1203 
1204 template <int MT, typename T1, typename T2, typename T3, typename L1, typename L2, typename L3, int dim,
1205  typename M1=std::enable_if_t<std::is_integral_v<T1>>,
1206  typename M2=std::enable_if_t<std::is_integral_v<T2>>,
1207  typename M3=std::enable_if_t<std::is_integral_v<T3>> >
1209  BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1210  BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
1211  BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
1212 {
1214  For(box1,ncomp1,std::forward<L1>(f1),
1215  box2,ncomp2,std::forward<L2>(f2),
1216  box3,ncomp3,std::forward<L3>(f3));
1217 }
1218 
1219 template <typename T, typename L, typename M=std::enable_if_t<std::is_integral_v<T>> >
1221 void ParallelForRNG (T n, L const& f) noexcept
1222 {
1223  for (T i = 0; i < n; ++i) {
1224  f(i,RandomEngine{});
1225  }
1226 }
1227 
1228 namespace detail {
1229 
1230 template <int idim, typename L, int dim>
1232 void ParallelForRNG_impND (L const& f, IntVectND<dim> const lo, IntVectND<dim> const hi, IntVectND<dim> iv) noexcept
1233 {
1234  if constexpr (idim == 1) {
1235  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
1237  }
1238  } else if constexpr (idim == 2) {
1239  for (int i1 = lo[1], h1 = hi[1]; i1 <= h1; ++i1) { iv[1] = i1;
1240  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
1242  }}
1243  } else if constexpr (idim == 3) {
1244  for (int i2 = lo[2], h2 = hi[2]; i2 <= h2; ++i2) { iv[2] = i2;
1245  for (int i1 = lo[1], h1 = hi[1]; i1 <= h1; ++i1) { iv[1] = i1;
1246  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
1248  }}}
1249  } else {
1250  for (int id = lo[idim-1], hd = hi[idim-1]; id <= hd; ++id) { iv[idim-1] = id;
1251  ParallelForRNG_impND<idim-1>(f, lo, hi, iv);
1252  }
1253  }
1254 }
1255 
1256 template <int idim, typename L, typename T, int dim>
1258 void ParallelForRNG_impND (L const& f, IntVectND<dim> const lo, IntVectND<dim> const hi, IntVectND<dim> iv, T n) noexcept
1259 {
1260  if constexpr (idim == 1) {
1261  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
1263  }
1264  } else if constexpr (idim == 2) {
1265  for (int i1 = lo[1], h1 = hi[1]; i1 <= h1; ++i1) { iv[1] = i1;
1266  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
1268  }}
1269  } else if constexpr (idim == 3) {
1270  for (int i2 = lo[2], h2 = hi[2]; i2 <= h2; ++i2) { iv[2] = i2;
1271  for (int i1 = lo[1], h1 = hi[1]; i1 <= h1; ++i1) { iv[1] = i1;
1272  for (int i0 = lo[0], h0 = hi[0]; i0 <= h0; ++i0) { iv[0] = i0;
1274  }}}
1275  } else {
1276  for (int id = lo[idim-1], hd = hi[idim-1]; id <= hd; ++id) { iv[idim-1] = id;
1277  ParallelForRNG_impND<idim-1>(f, lo, hi, iv, n);
1278  }
1279  }
1280 }
1281 
1282 }
1283 
1284 template <typename L, int dim>
1286 void ParallelForRNG (BoxND<dim> const& box, L const& f) noexcept
1287 {
1288  const auto lo = amrex::lbound_iv(box);
1289  const auto hi = amrex::ubound_iv(box);
1290  IntVectND<dim> iv;
1291  detail::ParallelForRNG_impND<dim>(f, lo, hi, iv);
1292 }
1293 
1294 template <typename T, typename L, int dim, typename M=std::enable_if_t<std::is_integral_v<T>> >
1296 void ParallelForRNG (BoxND<dim> const& box, T ncomp, L const& f) noexcept
1297 {
1298  const auto lo = amrex::lbound_iv(box);
1299  const auto hi = amrex::ubound_iv(box);
1300  IntVectND<dim> iv;
1301  for (T n = 0; n < ncomp; ++n) {
1302  detail::ParallelForRNG_impND<dim>(f, lo, hi, iv, n);
1303  }
1304 }
1305 
1306 template <typename L>
1307 void single_task (L&& f) noexcept
1308 {
1309  std::forward<L>(f)();
1310 }
1311 
1312 }
1313 
1314 #endif
#define AMREX_PRAGMA_SIMD
Definition: AMReX_Extension.H:80
#define AMREX_FORCE_INLINE
Definition: AMReX_Extension.H:119
#define AMREX_ATTRIBUTE_FLATTEN_FOR
Definition: AMReX_Extension.H:151
A Rectangular Domain on an Integer Lattice.
Definition: AMReX_Box.H:43
Definition: AMReX_GpuKernelInfo.H:8
Definition: AMReX_IntVect.H:48
static int f(amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data)
Definition: AMReX_SundialsIntegrator.H:44
AMREX_FORCE_INLINE auto call_f_intvect_handler(F const &f, IntVectND< dim > iv) noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence< dim >(), f, iv))
Definition: AMReX_GpuLaunchFunctsC.H:75
AMREX_FORCE_INLINE auto call_f_intvect_ncomp_handler(F const &f, IntVectND< dim > iv, T n) noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence< dim >(), f, iv, n))
Definition: AMReX_GpuLaunchFunctsC.H:103
AMREX_FORCE_INLINE void For_impND(L const &f, IntVectND< dim > const lo, IntVectND< dim > const hi, IntVectND< dim > iv) noexcept
Definition: AMReX_GpuLaunchFunctsC.H:195
AMREX_FORCE_INLINE auto call_f_scalar_handler(F const &f, N i) noexcept -> decltype(f(0))
Definition: AMReX_GpuLaunchFunctsC.H:13
AMREX_FORCE_INLINE void ParallelForRNG_impND(L const &f, IntVectND< dim > const lo, IntVectND< dim > const hi, IntVectND< dim > iv) noexcept
Definition: AMReX_GpuLaunchFunctsC.H:1232
AMREX_FORCE_INLINE void ParallelFor_impND(L const &f, IntVectND< dim > const lo, IntVectND< dim > const hi, IntVectND< dim > iv) noexcept
Definition: AMReX_GpuLaunchFunctsC.H:255
AMREX_FORCE_INLINE auto call_f_intvect_engine(F const &f, IntVectND< dim > iv, RandomEngine engine) noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence< dim >(), f, iv, engine))
Definition: AMReX_GpuLaunchFunctsC.H:65
AMREX_FORCE_INLINE auto call_f_intvect_ncomp_engine(F const &f, IntVectND< dim > iv, T n, RandomEngine engine) noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence< dim >(), f, iv, n, engine))
Definition: AMReX_GpuLaunchFunctsC.H:93
AMREX_FORCE_INLINE auto call_f_intvect_inner(std::index_sequence< Ns... >, F const &f, IntVectND< 1 > iv, Args...args) noexcept -> decltype(f(0, 0, 0, args...))
Definition: AMReX_GpuLaunchFunctsC.H:31
Definition: AMReX_Amr.cpp:49
std::enable_if_t< std::is_integral_v< T > > ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition: AMReX_CTOParallelForImpl.H:200
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE IntVectND< dim > ubound_iv(BoxND< dim > const &box) noexcept
Definition: AMReX_Box.H:1789
void launch(T const &n, L &&f) noexcept
Definition: AMReX_GpuLaunchFunctsC.H:120
void HostDeviceFor(T n, L &&f) noexcept
Definition: AMReX_GpuLaunchFunctsC.H:869
void HostDeviceParallelFor(T n, L &&f) noexcept
Definition: AMReX_GpuLaunchFunctsC.H:756
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition: AMReX.H:111
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE IntVectND< dim > lbound_iv(BoxND< dim > const &box) noexcept
Definition: AMReX_Box.H:1780
void single_task(L &&f) noexcept
Definition: AMReX_GpuLaunchFunctsC.H:1307
AMREX_ATTRIBUTE_FLATTEN_FOR void For(T n, L const &f) noexcept
Definition: AMReX_GpuLaunchFunctsC.H:134
AMREX_ATTRIBUTE_FLATTEN_FOR void ParallelForRNG(T n, L const &f) noexcept
Definition: AMReX_GpuLaunchFunctsC.H:1221
Definition: AMReX_FabArrayCommI.H:841
Definition: AMReX_GpuTypes.H:86
Definition: AMReX_RandomEngine.H:57