Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_GpuLaunchFunctsG.H
Go to the documentation of this file.
1#ifndef AMREX_GPU_LAUNCH_FUNCTS_G_H_
2#define AMREX_GPU_LAUNCH_FUNCTS_G_H_
3#include <AMReX_Config.H>
4
5namespace amrex {
6
8namespace detail {
9
10 // call_f_scalar_handler
11
12 template <typename F, typename N>
14 auto call_f_scalar_handler (F const& f, N i, Gpu::Handler const&)
15 noexcept -> decltype(f(0))
16 {
17 return f(i);
18 }
19
20 template <typename F, typename N>
22 auto call_f_scalar_handler (F const& f, N i, Gpu::Handler const& handler)
23 noexcept -> decltype(f(0,Gpu::Handler{}))
24 {
25 return f(i, handler);
26 }
27
28 // call_f_intvect_inner
29
30 template <typename F, std::size_t...Ns, class...Args>
32 auto call_f_intvect_inner (std::index_sequence<Ns...>, F const& f, IntVectND<1> iv, Args...args)
33 noexcept -> decltype(f(0, 0, 0, args...))
34 {
35 return f(iv[0], 0, 0, args...);
36 }
37
38 template <typename F, std::size_t...Ns, class...Args>
40 auto call_f_intvect_inner (std::index_sequence<Ns...>, F const& f, IntVectND<2> iv, Args...args)
41 noexcept -> decltype(f(0, 0, 0, args...))
42 {
43 return f(iv[0], iv[1], 0, args...);
44 }
45
46 template <typename F, int dim, std::size_t...Ns, class...Args>
48 auto call_f_intvect_inner (std::index_sequence<Ns...>, F const& f, IntVectND<dim> iv, Args...args)
49 noexcept -> decltype(f(iv, args...))
50 {
51 return f(iv, args...);
52 }
53
54 template <typename F, int dim, std::size_t...Ns, class...Args>
56 auto call_f_intvect_inner (std::index_sequence<Ns...>, F const& f, IntVectND<dim> iv, Args...args)
57 noexcept -> decltype(f(iv[Ns]..., args...))
58 {
59 return f(iv[Ns]..., args...);
60 }
61
62 // call_f_intvect
63
64 template <typename F, int dim>
66 auto call_f_intvect (F const& f, IntVectND<dim> iv)
67 noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv))
68 {
69 return call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv);
70 }
71
72 // call_f_intvect_engine
73
74 template <typename F, int dim>
76 auto call_f_intvect_engine (F const& f, IntVectND<dim> iv, RandomEngine engine)
77 noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, engine))
78 {
79 return call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, engine);
80 }
81
82 // call_f_intvect_handler
83
84 template <typename F, int dim>
86 auto call_f_intvect_handler (F const& f, IntVectND<dim> iv, Gpu::Handler const&)
87 noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv))
88 {
89 return call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv);
90 }
91
92 template <typename F, int dim>
94 auto call_f_intvect_handler (F const& f, IntVectND<dim> iv, Gpu::Handler const& handler)
95 noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, Gpu::Handler{}))
96 {
97 return call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, handler);
98 }
99
100 // call_f_intvect_ncomp
101
102 template <typename F, typename T, int dim>
104 auto call_f_intvect_ncomp (F const& f, IntVectND<dim> iv, T ncomp)
105 noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, 0))
106 {
107 for (T n = 0; n < ncomp; ++n) {
108 call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, n);
109 }
110 }
111
112 // call_f_intvect_ncomp_engine
113
114 template <typename F, typename T, int dim>
116 auto call_f_intvect_ncomp_engine (F const& f, IntVectND<dim> iv, T ncomp, RandomEngine engine)
117 noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, 0, engine))
118 {
119 for (T n = 0; n < ncomp; ++n) {
120 call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, n, engine);
121 }
122 }
123
124 // call_f_intvect_ncomp_handler
125
126 template <typename F, typename T, int dim>
128 auto call_f_intvect_ncomp_handler (F const& f, IntVectND<dim> iv, T ncomp, Gpu::Handler const&)
129 noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, 0))
130 {
131 for (T n = 0; n < ncomp; ++n) {
132 call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, n);
133 }
134 }
135
136 template <typename F, typename T, int dim>
138 auto call_f_intvect_ncomp_handler (F const& f, IntVectND<dim> iv, T ncomp, Gpu::Handler const& handler)
139 noexcept -> decltype(call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, 0, Gpu::Handler{}))
140 {
141 for (T n = 0; n < ncomp; ++n) {
142 call_f_intvect_inner(std::make_index_sequence<dim>(), f, iv, n, handler);
143 }
144 }
145
146}
148
149#ifdef AMREX_USE_SYCL
150
151template <typename L>
152void single_task (gpuStream_t stream, L const& f)
153{
154 detail::SyclKernelDevPtr<L> skdp(f, stream);
155 L const* pf = skdp.template get<0>();
157
158 auto& q = *(stream.queue);
159 try {
160 q.submit([&] (sycl::handler& h) {
161 if constexpr (detail::is_big_kernel<L>()) {
162 h.single_task([=] () { (*pf)(); });
163 } else {
164 h.single_task(f);
165 }
166 });
167 } catch (sycl::exception const& ex) {
168 amrex::Abort(std::string("single_task: ")+ex.what()+"!!!!!");
169 }
170}
171
172template<typename L>
173void launch (int nblocks, int nthreads_per_block, std::size_t shared_mem_bytes,
174 gpuStream_t stream, L const& f)
175{
176 detail::SyclKernelDevPtr<L> skdp(f, stream);
177 L const* pf = skdp.template get<0>();
179
180 const auto nthreads_total = std::size_t(nthreads_per_block) * nblocks;
181 const std::size_t shared_mem_numull = (shared_mem_bytes+sizeof(unsigned long long)-1)
182 / sizeof(unsigned long long);
183 auto& q = *(stream.queue);
184 try {
185 q.submit([&] (sycl::handler& h) {
186 sycl::local_accessor<unsigned long long>
187 shared_data(sycl::range<1>(shared_mem_numull), h);
188 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
189 sycl::range<1>(nthreads_per_block)),
190 [=] (sycl::nd_item<1> item)
191 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
192 {
193 if constexpr (detail::is_big_kernel<L>()) {
194 (*pf)(Gpu::Handler{&item,shared_data.get_multi_ptr<sycl::access::decorated::yes>().get()});
195 } else {
196 f(Gpu::Handler{&item,shared_data.get_multi_ptr<sycl::access::decorated::yes>().get()});
197 }
198 });
199 });
200 } catch (sycl::exception const& ex) {
201 amrex::Abort(std::string("launch: ")+ex.what()+"!!!!!");
202 }
203}
204
205template<typename L>
206void launch (int nblocks, int nthreads_per_block, gpuStream_t stream, L const& f)
207{
208 detail::SyclKernelDevPtr<L> skdp(f, stream);
209 L const* pf = skdp.template get<0>();
211
212 const auto nthreads_total = std::size_t(nthreads_per_block) * nblocks;
213 auto& q = *(stream.queue);
214 try {
215 q.submit([&] (sycl::handler& h) {
216 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
217 sycl::range<1>(nthreads_per_block)),
218 [=] (sycl::nd_item<1> item)
219 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
220 {
221 if constexpr (detail::is_big_kernel<L>()) {
222 (*pf)(item);
223 } else {
224 f(item);
225 }
226 });
227 });
228 } catch (sycl::exception const& ex) {
229 amrex::Abort(std::string("launch: ")+ex.what()+"!!!!!");
230 }
231}
232
233template <int MT, typename L>
234void launch (int nblocks, std::size_t shared_mem_bytes, gpuStream_t stream,
235 L const& f)
236{
237 detail::SyclKernelDevPtr<L> skdp(f, stream);
238 L const* pf = skdp.template get<0>();
240
241 const auto nthreads_total = MT * std::size_t(nblocks);
242 const std::size_t shared_mem_numull = (shared_mem_bytes+sizeof(unsigned long long)-1)
243 / sizeof(unsigned long long);
244 auto& q = *(stream.queue);
245 try {
246 q.submit([&] (sycl::handler& h) {
247 sycl::local_accessor<unsigned long long>
248 shared_data(sycl::range<1>(shared_mem_numull), h);
249 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
250 sycl::range<1>(MT)),
251 [=] (sycl::nd_item<1> item)
252 [[sycl::reqd_work_group_size(MT)]]
253 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
254 {
255 if constexpr (detail::is_big_kernel<L>()) {
256 (*pf)(Gpu::Handler{&item,shared_data.get_multi_ptr<sycl::access::decorated::yes>().get()});
257 } else {
258 f(Gpu::Handler{&item,shared_data.get_multi_ptr<sycl::access::decorated::yes>().get()});
259 }
260 });
261 });
262 } catch (sycl::exception const& ex) {
263 amrex::Abort(std::string("launch: ")+ex.what()+"!!!!!");
264 }
265}
266
267template <int MT, typename L>
268void launch (int nblocks, gpuStream_t stream, L const& f)
269{
270 detail::SyclKernelDevPtr<L> skdp(f, stream);
271 L const* pf = skdp.template get<0>();
273
274 const auto nthreads_total = MT * std::size_t(nblocks);
275 auto& q = *(stream.queue);
276 try {
277 q.submit([&] (sycl::handler& h) {
278 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
279 sycl::range<1>(MT)),
280 [=] (sycl::nd_item<1> item)
281 [[sycl::reqd_work_group_size(MT)]]
282 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
283 {
284 if constexpr (detail::is_big_kernel<L>()) {
285 (*pf)(item);
286 } else {
287 f(item);
288 }
289 });
290 });
291 } catch (sycl::exception const& ex) {
292 amrex::Abort(std::string("launch: ")+ex.what()+"!!!!!");
293 }
294}
295
296template<int MT, typename T, typename L>
297void launch (T const& n, L const& f)
298{
299 if (amrex::isEmpty(n)) { return; }
300
301 detail::SyclKernelDevPtr<L> skdp(f, Gpu::gpuStream());
302 L const* pf = skdp.template get<0>();
304
305 const auto ec = Gpu::makeExecutionConfig<MT>(n);
306 const auto nthreads_per_block = ec.numThreads.x;
307 const auto nthreads_total = std::size_t(nthreads_per_block) * ec.numBlocks.x;
308 auto& q = Gpu::Device::streamQueue();
309 try {
310 q.submit([&] (sycl::handler& h) {
311 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
312 sycl::range<1>(nthreads_per_block)),
313 [=] (sycl::nd_item<1> item)
314 [[sycl::reqd_work_group_size(MT)]]
315 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
316 {
317 for (auto const i : Gpu::Range(n,item.get_global_id(0),item.get_global_range(0))) {
318 if constexpr (detail::is_big_kernel<L>()) {
319 (*pf)(i);
320 } else {
321 f(i);
322 }
323 }
324 });
325 });
326 } catch (sycl::exception const& ex) {
327 amrex::Abort(std::string("launch: ")+ex.what()+"!!!!!");
328 }
329}
330
331template <int MT, std::integral T, typename L>
332void ParallelFor (Gpu::KernelInfo const& info, T n, L const& f)
333{
334 if (amrex::isEmpty(n)) { return; }
335
336 detail::SyclKernelDevPtr<L> skdp(f, Gpu::gpuStream());
337 L const* pf = skdp.template get<0>();
339
340 const auto ec = Gpu::makeExecutionConfig<MT>(n);
341 const auto nthreads_per_block = ec.numThreads.x;
342 const auto nthreads_total = std::size_t(nthreads_per_block) * ec.numBlocks.x;
343 auto& q = Gpu::Device::streamQueue();
344 try {
345 if (info.hasReduction()) {
346 q.submit([&] (sycl::handler& h) {
347 sycl::local_accessor<unsigned long long>
348 shared_data(sycl::range<1>(std::max(Gpu::Device::warp_size,
349 MT/Gpu::Device::warp_size)), h);
350 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
351 sycl::range<1>(nthreads_per_block)),
352 [=] (sycl::nd_item<1> item)
353 [[sycl::reqd_work_group_size(MT)]]
354 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
355 {
356 for (std::size_t i = item.get_global_id(0), stride = item.get_global_range(0);
357 i < std::size_t(n); i += stride) {
358 int n_active_threads = amrex::min(std::size_t(n)-i+item.get_local_id(0),
359 item.get_local_range(0));
360 if constexpr (detail::is_big_kernel<L>()) {
361 detail::call_f_scalar_handler(*pf, T(i),
362 Gpu::Handler{&item, shared_data.get_multi_ptr<sycl::access::decorated::yes>().get(),
363 n_active_threads});
364 } else {
365 detail::call_f_scalar_handler(f, T(i),
366 Gpu::Handler{&item, shared_data.get_multi_ptr<sycl::access::decorated::yes>().get(),
367 n_active_threads});
368 }
369 }
370 });
371 });
372 } else {
373 q.submit([&] (sycl::handler& h) {
374 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
375 sycl::range<1>(nthreads_per_block)),
376 [=] (sycl::nd_item<1> item)
377 [[sycl::reqd_work_group_size(MT)]]
378 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
379 {
380 for (std::size_t i = item.get_global_id(0), stride = item.get_global_range(0);
381 i < std::size_t(n); i += stride) {
382 if constexpr (detail::is_big_kernel<L>()) {
383 detail::call_f_scalar_handler(*pf, T(i), Gpu::Handler{&item});
384 } else {
385 detail::call_f_scalar_handler(f, T(i), Gpu::Handler{&item});
386 }
387 }
388 });
389 });
390 }
391 } catch (sycl::exception const& ex) {
392 amrex::Abort(std::string("ParallelFor: ")+ex.what()+"!!!!!");
393 }
394}
395
396template <int MT, typename L, int dim>
397void ParallelFor (Gpu::KernelInfo const& info, BoxND<dim> const& box, L const& f)
398{
399 if (amrex::isEmpty(box)) { return; }
400
401 detail::SyclKernelDevPtr<L> skdp(f, Gpu::gpuStream());
402 L const* pf = skdp.template get<0>();
404
405 const BoxIndexerND<dim> indexer(box);
406 const auto ec = Gpu::makeExecutionConfig<MT>(box.numPts());
407 const auto nthreads_per_block = ec.numThreads.x;
408 const auto nthreads_total = std::size_t(nthreads_per_block) * ec.numBlocks.x;
409 auto& q = Gpu::Device::streamQueue();
410 try {
411 if (info.hasReduction()) {
412 q.submit([&] (sycl::handler& h) {
413 sycl::local_accessor<unsigned long long>
414 shared_data(sycl::range<1>(std::max(Gpu::Device::warp_size,
415 MT/Gpu::Device::warp_size)), h);
416 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
417 sycl::range<1>(nthreads_per_block)),
418 [=] (sycl::nd_item<1> item)
419 [[sycl::reqd_work_group_size(MT)]]
420 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
421 {
422 for (std::uint64_t icell = item.get_global_id(0), stride = item.get_global_range(0);
423 icell < indexer.numPts(); icell += stride) {
424 auto iv = indexer.intVect(icell);
425 int n_active_threads = amrex::min(indexer.numPts()-icell+std::uint64_t(item.get_local_id(0)),
426 std::uint64_t(item.get_local_range(0)));
427 if constexpr (detail::is_big_kernel<L>()) {
428 detail::call_f_intvect_handler(*pf,
429 iv, Gpu::Handler{&item,
430 shared_data.get_multi_ptr<sycl::access::decorated::yes>().get(),
431 n_active_threads});
432 } else {
433 detail::call_f_intvect_handler(f,
434 iv, Gpu::Handler{&item,
435 shared_data.get_multi_ptr<sycl::access::decorated::yes>().get(),
436 n_active_threads});
437 }
438 }
439 });
440 });
441 } else {
442 q.submit([&] (sycl::handler& h) {
443 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
444 sycl::range<1>(nthreads_per_block)),
445 [=] (sycl::nd_item<1> item)
446 [[sycl::reqd_work_group_size(MT)]]
447 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
448 {
449 for (std::uint64_t icell = item.get_global_id(0), stride = item.get_global_range(0);
450 icell < indexer.numPts(); icell += stride) {
451 auto iv = indexer.intVect(icell);
452 if constexpr (detail::is_big_kernel<L>()) {
453 detail::call_f_intvect_handler(*pf,iv,Gpu::Handler{&item});
454 } else {
455 detail::call_f_intvect_handler(f,iv,Gpu::Handler{&item});
456 }
457 }
458 });
459 });
460 }
461 } catch (sycl::exception const& ex) {
462 amrex::Abort(std::string("ParallelFor: ")+ex.what()+"!!!!!");
463 }
464}
465
466template <int MT, std::integral T, typename L, int dim>
467void ParallelFor (Gpu::KernelInfo const& info, BoxND<dim> const& box, T ncomp, L const& f)
468{
469 if (amrex::isEmpty(box)) { return; }
470
471 detail::SyclKernelDevPtr<L> skdp(f, Gpu::gpuStream());
472 L const* pf = skdp.template get<0>();
474
475 const BoxIndexerND<dim> indexer(box);
476 const auto ec = Gpu::makeExecutionConfig<MT>(box.numPts());
477 const auto nthreads_per_block = ec.numThreads.x;
478 const auto nthreads_total = std::size_t(nthreads_per_block) * ec.numBlocks.x;
479 auto& q = Gpu::Device::streamQueue();
480 try {
481 if (info.hasReduction()) {
482 q.submit([&] (sycl::handler& h) {
483 sycl::local_accessor<unsigned long long>
484 shared_data(sycl::range<1>(std::max(Gpu::Device::warp_size,
485 MT/Gpu::Device::warp_size)), h);
486 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
487 sycl::range<1>(nthreads_per_block)),
488 [=] (sycl::nd_item<1> item)
489 [[sycl::reqd_work_group_size(MT)]]
490 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
491 {
492 for (std::uint64_t icell = item.get_global_id(0), stride = item.get_global_range(0);
493 icell < indexer.numPts(); icell += stride) {
494 auto iv = indexer.intVect(icell);
495 int n_active_threads = amrex::min(indexer.numPts()-icell+std::uint64_t(item.get_local_id(0)),
496 std::uint64_t(item.get_local_range(0)));
497 if constexpr (detail::is_big_kernel<L>()) {
498 detail::call_f_intvect_ncomp_handler(*pf, iv, ncomp,
499 Gpu::Handler{&item, shared_data.get_multi_ptr<sycl::access::decorated::yes>().get(),
500 n_active_threads});
501 } else {
502 detail::call_f_intvect_ncomp_handler(f, iv, ncomp,
503 Gpu::Handler{&item, shared_data.get_multi_ptr<sycl::access::decorated::yes>().get(),
504 n_active_threads});
505 }
506 }
507 });
508 });
509 } else {
510 q.submit([&] (sycl::handler& h) {
511 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
512 sycl::range<1>(nthreads_per_block)),
513 [=] (sycl::nd_item<1> item)
514 [[sycl::reqd_work_group_size(MT)]]
515 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
516 {
517 for (std::uint64_t icell = item.get_global_id(0), stride = item.get_global_range(0);
518 icell < indexer.numPts(); icell += stride) {
519 auto iv = indexer.intVect(icell);
520 if constexpr (detail::is_big_kernel<L>()) {
521 detail::call_f_intvect_ncomp_handler(*pf,iv,ncomp,Gpu::Handler{&item});
522 } else {
523 detail::call_f_intvect_ncomp_handler(f,iv,ncomp,Gpu::Handler{&item});
524 }
525 }
526 });
527 });
528 }
529 } catch (sycl::exception const& ex) {
530 amrex::Abort(std::string("ParallelFor: ")+ex.what()+"!!!!!");
531 }
532}
533
534template <std::integral T, typename L>
535void ParallelForRNG (T n, L const& f)
536{
537 if (amrex::isEmpty(n)) { return; }
538
539 detail::SyclKernelDevPtr<L> skdp(f, Gpu::gpuStream());
540 L const* pf = skdp.template get<0>();
542
543 const auto ec = Gpu::ExecutionConfig(n);
544 const auto nthreads_per_block = ec.numThreads.x;
545 const auto nthreads_total = std::size_t(nthreads_per_block) * amrex::min(ec.numBlocks.x,Gpu::Device::maxBlocksPerLaunch());
546 auto& q = Gpu::Device::streamQueue();
547 auto& engdescr = *(getRandEngineDescriptor());
548 try {
549 q.submit([&] (sycl::handler& h) {
550 auto engine_acc = engdescr.get_access(h);
551 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
552 sycl::range<1>(nthreads_per_block)),
553 [=] (sycl::nd_item<1> item)
554 [[sycl::reqd_work_group_size(AMREX_GPU_MAX_THREADS)]]
555 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
556 {
557 auto const tid = item.get_global_id(0);
558 auto engine = engine_acc.load(tid);
559 RandomEngine rand_eng{&engine};
560 for (std::size_t i = tid, stride = item.get_global_range(0); i < std::size_t(n); i += stride) {
561 if constexpr (detail::is_big_kernel<L>()) {
562 (*pf)(T(i),rand_eng);
563 } else {
564 f(T(i),rand_eng);
565 }
566 }
567 engine_acc.store(engine, tid);
568 });
569 });
570 q.wait_and_throw(); // because next launch might be on a different queue
571 } catch (sycl::exception const& ex) {
572 amrex::Abort(std::string("ParallelFor: ")+ex.what()+"!!!!!");
573 }
574}
575
576template <typename L, int dim>
577void ParallelForRNG (BoxND<dim> const& box, L const& f)
578{
579 if (amrex::isEmpty(box)) { return; }
580
581 detail::SyclKernelDevPtr<L> skdp(f, Gpu::gpuStream());
582 L const* pf = skdp.template get<0>();
584
585 const BoxIndexerND<dim> indexer(box);
586 const auto ec = Gpu::ExecutionConfig(box.numPts());
587 const auto nthreads_per_block = ec.numThreads.x;
588 const auto nthreads_total = std::size_t(nthreads_per_block) * amrex::min(ec.numBlocks.x,Gpu::Device::maxBlocksPerLaunch());
589 auto& q = Gpu::Device::streamQueue();
590 auto& engdescr = *(getRandEngineDescriptor());
591 try {
592 q.submit([&] (sycl::handler& h) {
593 auto engine_acc = engdescr.get_access(h);
594 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
595 sycl::range<1>(nthreads_per_block)),
596 [=] (sycl::nd_item<1> item)
597 [[sycl::reqd_work_group_size(AMREX_GPU_MAX_THREADS)]]
598 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
599 {
600 auto const tid = item.get_global_id(0);
601 auto engine = engine_acc.load(tid);
602 RandomEngine rand_eng{&engine};
603 for (std::uint64_t icell = tid, stride = item.get_global_range(0);
604 icell < indexer.numPts(); icell += stride) {
605 auto iv = indexer.intVect(icell);
606 if constexpr (detail::is_big_kernel<L>()) {
607 detail::call_f_intvect_engine(*pf,iv,rand_eng);
608 } else {
609 detail::call_f_intvect_engine(f,iv,rand_eng);
610 }
611 }
612 engine_acc.store(engine, tid);
613 });
614 });
615 q.wait_and_throw(); // because next launch might be on a different queue
616 } catch (sycl::exception const& ex) {
617 amrex::Abort(std::string("ParallelFor: ")+ex.what()+"!!!!!");
618 }
619}
620
621template <std::integral T, typename L, int dim>
622void ParallelForRNG (BoxND<dim> const& box, T ncomp, L const& f)
623{
624 if (amrex::isEmpty(box)) { return; }
625
626 detail::SyclKernelDevPtr<L> skdp(f, Gpu::gpuStream());
627 L const* pf = skdp.template get<0>();
629
630 const BoxIndexerND<dim> indexer(box);
631 const auto ec = Gpu::ExecutionConfig(box.numPts());
632 const auto nthreads_per_block = ec.numThreads.x;
633 const auto nthreads_total = std::size_t(nthreads_per_block) * amrex::min(ec.numBlocks.x,Gpu::Device::maxBlocksPerLaunch());
634 auto& q = Gpu::Device::streamQueue();
635 auto& engdescr = *(getRandEngineDescriptor());
636 try {
637 q.submit([&] (sycl::handler& h) {
638 auto engine_acc = engdescr.get_access(h);
639 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
640 sycl::range<1>(nthreads_per_block)),
641 [=] (sycl::nd_item<1> item)
642 [[sycl::reqd_work_group_size(AMREX_GPU_MAX_THREADS)]]
643 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
644 {
645 auto const tid = item.get_global_id(0);
646 auto engine = engine_acc.load(tid);
647 RandomEngine rand_eng{&engine};
648 for (std::uint64_t icell = tid, stride = item.get_global_range(0);
649 icell < indexer.numPts(); icell += stride) {
650 auto iv = indexer.intVect(icell);
651 if constexpr (detail::is_big_kernel<L>()) {
652 detail::call_f_intvect_ncomp_engine(*pf,iv,ncomp,rand_eng);
653 } else {
654 detail::call_f_intvect_ncomp_engine(f,iv,ncomp,rand_eng);
655 }
656 }
657 engine_acc.store(engine, tid);
658 });
659 });
660 q.wait_and_throw(); // because next launch might be on a different queue
661 } catch (sycl::exception const& ex) {
662 amrex::Abort(std::string("ParallelFor: ")+ex.what()+"!!!!!");
663 }
664}
665
666template <int MT, typename L1, typename L2, int dim>
667void ParallelFor (Gpu::KernelInfo const& /*info*/, BoxND<dim> const& box1, BoxND<dim> const& box2, L1 const& f1, L2 const& f2)
668{
669 if (amrex::isEmpty(box1) && amrex::isEmpty(box2)) { return; }
670
671 detail::SyclKernelDevPtr<L1,L2> skdp(f1, f2, Gpu::gpuStream());
672 L1 const* pf1 = skdp.template get<0>();
673 L2 const* pf2 = skdp.template get<1>();
674 amrex::ignore_unused(pf1,pf2);
675
676 const BoxIndexerND<dim> indexer1(box1);
677 const BoxIndexerND<dim> indexer2(box2);
678 const auto ec = Gpu::makeExecutionConfig<MT>(std::max(box1.numPts(), box2.numPts()));
679 const auto nthreads_per_block = ec.numThreads.x;
680 const auto nthreads_total = std::size_t(nthreads_per_block) * ec.numBlocks.x;
681 auto& q = Gpu::Device::streamQueue();
682 try {
683 q.submit([&] (sycl::handler& h) {
684 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
685 sycl::range<1>(nthreads_per_block)),
686 [=] (sycl::nd_item<1> item)
687 [[sycl::reqd_work_group_size(MT)]]
688 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
689 {
690 auto const ncells = std::max(indexer1.numPts(), indexer2.numPts());
691 for (std::uint64_t icell = item.get_global_id(0), stride = item.get_global_range(0);
692 icell < ncells; icell += stride) {
693 if (icell < indexer1.numPts()) {
694 auto iv = indexer1.intVect(icell);
695 if constexpr (detail::is_big_kernel<L1,L2>()) {
696 detail::call_f_intvect(*pf1,iv);
697 } else {
698 detail::call_f_intvect(f1,iv);
699 }
700 }
701 if (icell < indexer2.numPts()) {
702 auto iv = indexer2.intVect(icell);
703 if constexpr (detail::is_big_kernel<L1,L2>()) {
704 detail::call_f_intvect(*pf2,iv);
705 } else {
706 detail::call_f_intvect(f2,iv);
707 }
708 }
709 }
710 });
711 });
712 } catch (sycl::exception const& ex) {
713 amrex::Abort(std::string("ParallelFor: ")+ex.what()+"!!!!!");
714 }
715}
716
717template <int MT, typename L1, typename L2, typename L3, int dim>
718void ParallelFor (Gpu::KernelInfo const& /*info*/,
719 BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
720 L1 const& f1, L2 const& f2, L3 const& f3)
721{
722 if (amrex::isEmpty(box1) && amrex::isEmpty(box2) && amrex::isEmpty(box3)) { return; }
723
724 detail::SyclKernelDevPtr<L1,L2,L3> skdp(f1, f2, f3, Gpu::gpuStream());
725 L1 const* pf1 = skdp.template get<0>();
726 L2 const* pf2 = skdp.template get<1>();
727 L3 const* pf3 = skdp.template get<2>();
728 amrex::ignore_unused(pf1,pf2,pf3);
729
730 const BoxIndexerND<dim> indexer1(box1);
731 const BoxIndexerND<dim> indexer2(box2);
732 const BoxIndexerND<dim> indexer3(box3);
733 const auto ec = Gpu::makeExecutionConfig<MT>(std::max({box1.numPts(),box2.numPts(),box3.numPts()}));
734 const auto nthreads_per_block = ec.numThreads.x;
735 const auto nthreads_total = std::size_t(nthreads_per_block) * ec.numBlocks.x;
736 auto& q = Gpu::Device::streamQueue();
737 try {
738 q.submit([&] (sycl::handler& h) {
739 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
740 sycl::range<1>(nthreads_per_block)),
741 [=] (sycl::nd_item<1> item)
742 [[sycl::reqd_work_group_size(MT)]]
743 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
744 {
745 auto const ncells = amrex::max(indexer1.numPts(), indexer2.numPts(), indexer3.numPts());
746 for (std::uint64_t icell = item.get_global_id(0), stride = item.get_global_range(0);
747 icell < ncells; icell += stride) {
748 if (icell < indexer1.numPts()) {
749 auto iv = indexer1.intVect(icell);
750 if constexpr (detail::is_big_kernel<L1,L2,L3>()) {
751 detail::call_f_intvect(*pf1,iv);
752 } else {
753 detail::call_f_intvect(f1,iv);
754 }
755 }
756 if (icell < indexer2.numPts()) {
757 auto iv = indexer2.intVect(icell);
758 if constexpr (detail::is_big_kernel<L1,L2,L3>()) {
759 detail::call_f_intvect(*pf2,iv);
760 } else {
761 detail::call_f_intvect(f2,iv);
762 }
763 }
764 if (icell < indexer3.numPts()) {
765 auto iv = indexer3.intVect(icell);
766 if constexpr (detail::is_big_kernel<L1,L2,L3>()) {
767 detail::call_f_intvect(*pf3,iv);
768 } else {
769 detail::call_f_intvect(f3,iv);
770 }
771 }
772 }
773 });
774 });
775 } catch (sycl::exception const& ex) {
776 amrex::Abort(std::string("ParallelFor: ")+ex.what()+"!!!!!");
777 }
778}
779
780template <int MT, std::integral T1, std::integral T2, typename L1, typename L2, int dim>
781void ParallelFor (Gpu::KernelInfo const& /*info*/,
782 BoxND<dim> const& box1, T1 ncomp1, L1 const& f1,
783 BoxND<dim> const& box2, T2 ncomp2, L2 const& f2)
784{
785 if (amrex::isEmpty(box1) && amrex::isEmpty(box2)) { return; }
786
787 detail::SyclKernelDevPtr<L1,L2> skdp(f1, f2, Gpu::gpuStream());
788 L1 const* pf1 = skdp.template get<0>();
789 L2 const* pf2 = skdp.template get<1>();
790 amrex::ignore_unused(pf1,pf2);
791
792 const BoxIndexerND<dim> indexer1(box1);
793 const BoxIndexerND<dim> indexer2(box2);
794 const auto ec = Gpu::makeExecutionConfig<MT>(std::max(box1.numPts(),box2.numPts()));
795 const auto nthreads_per_block = ec.numThreads.x;
796 const auto nthreads_total = std::size_t(nthreads_per_block) * ec.numBlocks.x;
797 auto& q = Gpu::Device::streamQueue();
798 try {
799 q.submit([&] (sycl::handler& h) {
800 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
801 sycl::range<1>(nthreads_per_block)),
802 [=] (sycl::nd_item<1> item)
803 [[sycl::reqd_work_group_size(MT)]]
804 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
805 {
806 auto const ncells = std::max(indexer1.numPts(), indexer2.numPts());
807 for (std::uint64_t icell = item.get_global_id(0), stride = item.get_global_range(0);
808 icell < ncells; icell += stride) {
809 if (icell < indexer1.numPts()) {
810 auto iv = indexer1.intVect(icell);
811 if constexpr (detail::is_big_kernel<L1,L2>()) {
812 detail::call_f_intvect_ncomp(*pf1,iv,ncomp1);
813 } else {
814 detail::call_f_intvect_ncomp(f1,iv,ncomp1);
815 }
816 }
817 if (icell < indexer2.numPts()) {
818 auto iv = indexer2.intVect(icell);
819 if constexpr (detail::is_big_kernel<L1,L2>()) {
820 detail::call_f_intvect_ncomp(*pf2,iv,ncomp2);
821 } else {
822 detail::call_f_intvect_ncomp(f2,iv,ncomp2);
823 }
824 }
825 }
826 });
827 });
828 } catch (sycl::exception const& ex) {
829 amrex::Abort(std::string("ParallelFor: ")+ex.what()+"!!!!!");
830 }
831}
832
833template <int MT, std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
834void ParallelFor (Gpu::KernelInfo const& /*info*/,
835 BoxND<dim> const& box1, T1 ncomp1, L1 const& f1,
836 BoxND<dim> const& box2, T2 ncomp2, L2 const& f2,
837 BoxND<dim> const& box3, T3 ncomp3, L3 const& f3)
838{
839 if (amrex::isEmpty(box1) && amrex::isEmpty(box2) && amrex::isEmpty(box3)) { return; }
840
841 detail::SyclKernelDevPtr<L1,L2,L3> skdp(f1, f2, f3, Gpu::gpuStream());
842 L1 const* pf1 = skdp.template get<0>();
843 L2 const* pf2 = skdp.template get<1>();
844 L3 const* pf3 = skdp.template get<2>();
845 amrex::ignore_unused(pf1,pf2,pf3);
846
847 const BoxIndexerND<dim> indexer1(box1);
848 const BoxIndexerND<dim> indexer2(box2);
849 const BoxIndexerND<dim> indexer3(box3);
850 const auto ec = Gpu::makeExecutionConfig<MT>(std::max({box1.numPts(),box2.numPts(),box3.numPts()}));
851 const auto nthreads_per_block = ec.numThreads.x;
852 const auto nthreads_total = std::size_t(nthreads_per_block) * ec.numBlocks.x;
853 auto& q = Gpu::Device::streamQueue();
854 try {
855 q.submit([&] (sycl::handler& h) {
856 h.parallel_for(sycl::nd_range<1>(sycl::range<1>(nthreads_total),
857 sycl::range<1>(nthreads_per_block)),
858 [=] (sycl::nd_item<1> item)
859 [[sycl::reqd_work_group_size(MT)]]
860 [[sycl::reqd_sub_group_size(Gpu::Device::warp_size)]]
861 {
862 auto const ncells = amrex::max(indexer1.numPts(), indexer2.numPts(), indexer3.numPts());
863 for (std::uint64_t icell = item.get_global_id(0), stride = item.get_global_range(0);
864 icell < ncells; icell += stride) {
865 if (icell < indexer1.numPts()) {
866 auto iv = indexer1.intVect(icell);
867 if constexpr (detail::is_big_kernel<L1,L2,L3>()) {
868 detail::call_f_intvect_ncomp(*pf1,iv,ncomp1);
869 } else {
870 detail::call_f_intvect_ncomp(f1,iv,ncomp1);
871 }
872 }
873 if (icell < indexer2.numPts()) {
874 auto iv = indexer2.intVect(icell);
875 if constexpr (detail::is_big_kernel<L1,L2,L3>()) {
876 detail::call_f_intvect_ncomp(*pf2,iv,ncomp2);
877 } else {
878 detail::call_f_intvect_ncomp(f2,iv,ncomp2);
879 }
880 }
881 if (icell < indexer3.numPts()) {
882 auto iv = indexer3.intVect(icell);
883 if constexpr (detail::is_big_kernel<L1,L2,L3>()) {
884 detail::call_f_intvect_ncomp(*pf3,iv,ncomp3);
885 } else {
886 detail::call_f_intvect_ncomp(f3,iv,ncomp3);
887 }
888 }
889 }
890 });
891 });
892 } catch (sycl::exception const& ex) {
893 amrex::Abort(std::string("ParallelFor: ")+ex.what()+"!!!!!");
894 }
895}
896
897#else
898// CUDA or HIP
899
900template <typename L>
901void single_task (gpuStream_t stream, L const& f)
902{
903 AMREX_LAUNCH_KERNEL(Gpu::Device::warp_size, 1, 1, 0, stream, f);
905}
906
907template <int MT, typename L>
908void launch (int nblocks, std::size_t shared_mem_bytes, gpuStream_t stream,
909 L const& f)
910{
911 AMREX_LAUNCH_KERNEL(MT, nblocks, MT, shared_mem_bytes, stream, f);
913}
914
915template <int MT, typename L>
916void launch (int nblocks, gpuStream_t stream, L const& f)
917{
918 AMREX_LAUNCH_KERNEL(MT, nblocks, MT, 0, stream, f);
920}
921
922template<typename L>
923void launch (int nblocks, int nthreads_per_block, std::size_t shared_mem_bytes,
924 gpuStream_t stream, L const& f)
925{
926 AMREX_LAUNCH_KERNEL_NOBOUND(nblocks, nthreads_per_block, shared_mem_bytes, stream, f);
928}
929
930template<typename L>
931void launch (int nblocks, int nthreads_per_block, gpuStream_t stream, L&& f) noexcept
932{
933 launch(nblocks, nthreads_per_block, 0, stream, std::forward<L>(f));
934}
935
936template<int MT, std::integral T, typename L>
937void launch (T const& n, L const& f)
938{
939 static_assert(sizeof(T) >= 2);
940 if (amrex::isEmpty(n)) { return; }
941 const auto& nec = Gpu::makeNExecutionConfigs<MT>(n);
942 for (auto const& ec : nec) {
943 const T start_idx = T(ec.start_idx);
944 const T nleft = n - start_idx;
945 AMREX_LAUNCH_KERNEL(MT, ec.nblocks, MT, 0, Gpu::gpuStream(),
946 [=] AMREX_GPU_DEVICE () noexcept {
947 auto tid = std::uint64_t(MT)*blockIdx.x+threadIdx.x;
948 if (tid < std::uint64_t(nleft)) {
949 f(T(tid)+start_idx);
950 }
951 });
952 }
954}
955
956template<int MT, int dim, typename L>
957void launch (BoxND<dim> const& box, L const& f)
958{
959 if (box.isEmpty()) { return; }
960 const auto& nec = Gpu::makeNExecutionConfigs<MT>(box);
961 const BoxIndexerND<dim> indexer(box);
962 const auto type = box.ixType();
963 for (auto const& ec : nec) {
964 const auto start_idx = std::uint64_t(ec.start_idx);
965 AMREX_LAUNCH_KERNEL(MT, ec.nblocks, MT, 0, Gpu::gpuStream(),
966 [=] AMREX_GPU_DEVICE () noexcept {
967 auto icell = std::uint64_t(MT)*blockIdx.x+threadIdx.x + start_idx;
968 if (icell < indexer.numPts()) {
969 auto iv = indexer.intVect(icell);
970 f(BoxND<dim>(iv,iv,type));
971 }
972 });
973 }
975}
976
981template <int MT, std::integral T, typename L>
982requires (MaybeDeviceRunnable<L>::value)
983void
984ParallelFor (Gpu::KernelInfo const&, T n, L const& f)
985{
986 static_assert(sizeof(T) >= 2);
987 if (amrex::isEmpty(n)) { return; }
988 const auto& nec = Gpu::makeNExecutionConfigs<MT>(n);
989 for (auto const& ec : nec) {
990 const T start_idx = T(ec.start_idx);
991 const T nleft = n - start_idx;
992 AMREX_LAUNCH_KERNEL(MT, ec.nblocks, MT, 0, Gpu::gpuStream(),
993 [=] AMREX_GPU_DEVICE () noexcept {
994 auto tid = std::uint64_t(MT)*blockIdx.x+threadIdx.x;
995 if (tid < std::uint64_t(nleft)) {
996 detail::call_f_scalar_handler(f, T(tid)+start_idx,
997 Gpu::Handler(amrex::min((std::uint64_t(nleft)-tid+(std::uint64_t)threadIdx.x),
998 (std::uint64_t)MT)));
999 }
1000 });
1001 }
1003}
1004
1009template <int MT, typename L, int dim>
1010requires (MaybeDeviceRunnable<L>::value)
1011void
1012ParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box, L const& f)
1013{
1014 if (amrex::isEmpty(box)) { return; }
1015 const BoxIndexerND<dim> indexer(box);
1016 const auto& nec = Gpu::makeNExecutionConfigs<MT>(box);
1017 for (auto const& ec : nec) {
1018 const auto start_idx = std::uint64_t(ec.start_idx);
1019 AMREX_LAUNCH_KERNEL(MT, ec.nblocks, MT, 0, Gpu::gpuStream(),
1020 [=] AMREX_GPU_DEVICE () noexcept {
1021 auto icell = std::uint64_t(MT)*blockIdx.x+threadIdx.x + start_idx;
1022 if (icell < indexer.numPts()) {
1023 auto iv = indexer.intVect(icell);
1024 detail::call_f_intvect_handler(f, iv,
1025 Gpu::Handler(amrex::min((indexer.numPts()-icell+(std::uint64_t)threadIdx.x),
1026 (std::uint64_t)MT)));
1027 }
1028 });
1029 }
1031}
1032
1037template <int MT, std::integral T, typename L, int dim>
1038requires (MaybeDeviceRunnable<L>::value)
1039void
1040ParallelFor (Gpu::KernelInfo const&, BoxND<dim> const& box, T ncomp, L const& f)
1041{
1042 if (amrex::isEmpty(box)) { return; }
1043 const BoxIndexerND<dim> indexer(box);
1044 const auto& nec = Gpu::makeNExecutionConfigs<MT>(box);
1045 for (auto const& ec : nec) {
1046 const auto start_idx = std::uint64_t(ec.start_idx);
1047 AMREX_LAUNCH_KERNEL(MT, ec.nblocks, MT, 0, Gpu::gpuStream(),
1048 [=] AMREX_GPU_DEVICE () noexcept {
1049 auto icell = std::uint64_t(MT)*blockIdx.x+threadIdx.x + start_idx;
1050 if (icell < indexer.numPts()) {
1051 auto iv = indexer.intVect(icell);
1052 detail::call_f_intvect_ncomp_handler(f, iv, ncomp,
1053 Gpu::Handler(amrex::min((indexer.numPts()-icell+(std::uint64_t)threadIdx.x),
1054 (std::uint64_t)MT)));
1055 }
1056 });
1057 }
1059}
1060
1066template <std::integral T, typename L>
1067requires (MaybeDeviceRunnable<L>::value)
1068void
1069ParallelForRNG (T n, L const& f)
1070{
1071 if (amrex::isEmpty(n)) { return; }
1072 randState_t* rand_state = getRandState();
1073 const auto ec = Gpu::ExecutionConfig(n);
1074 AMREX_LAUNCH_KERNEL(AMREX_GPU_MAX_THREADS,
1076 ec.numThreads, 0, Gpu::gpuStream(),
1077 [=] AMREX_GPU_DEVICE () noexcept {
1078 Long tid = Long(AMREX_GPU_MAX_THREADS)*blockIdx.x+threadIdx.x;
1079 RandomEngine engine{&(rand_state[tid])};
1080 for (Long i = tid, stride = Long(AMREX_GPU_MAX_THREADS)*gridDim.x; i < Long(n); i += stride) {
1081 f(T(i),engine);
1082 }
1083 });
1084 Gpu::streamSynchronize(); // To avoid multiple streams using RNG
1086}
1087
1093template <typename L, int dim>
1094requires (MaybeDeviceRunnable<L>::value)
1095void
1096ParallelForRNG (BoxND<dim> const& box, L const& f)
1097{
1098 if (amrex::isEmpty(box)) { return; }
1099 randState_t* rand_state = getRandState();
1100 const BoxIndexerND<dim> indexer(box);
1101 const auto ec = Gpu::ExecutionConfig(box.numPts());
1102 AMREX_LAUNCH_KERNEL(AMREX_GPU_MAX_THREADS,
1104 ec.numThreads, 0, Gpu::gpuStream(),
1105 [=] AMREX_GPU_DEVICE () noexcept {
1106 auto const tid = std::uint64_t(AMREX_GPU_MAX_THREADS)*blockIdx.x+threadIdx.x;
1107 RandomEngine engine{&(rand_state[tid])};
1108 for (std::uint64_t icell = tid, stride = std::uint64_t(AMREX_GPU_MAX_THREADS)*gridDim.x; icell < indexer.numPts(); icell += stride) {
1109 auto iv = indexer.intVect(icell);
1110 detail::call_f_intvect_engine(f, iv, engine);
1111 }
1112 });
1113 Gpu::streamSynchronize(); // To avoid multiple streams using RNG
1115}
1116
1122template <std::integral T, typename L, int dim>
1123requires (MaybeDeviceRunnable<L>::value)
1124void
1125ParallelForRNG (BoxND<dim> const& box, T ncomp, L const& f)
1126{
1127 if (amrex::isEmpty(box)) { return; }
1128 randState_t* rand_state = getRandState();
1129 const BoxIndexerND<dim> indexer(box);
1130 const auto ec = Gpu::ExecutionConfig(box.numPts());
1131 AMREX_LAUNCH_KERNEL(AMREX_GPU_MAX_THREADS,
1133 ec.numThreads, 0, Gpu::gpuStream(),
1134 [=] AMREX_GPU_DEVICE () noexcept {
1135 auto const tid = std::uint64_t(AMREX_GPU_MAX_THREADS)*blockIdx.x+threadIdx.x;
1136 RandomEngine engine{&(rand_state[tid])};
1137 for (std::uint64_t icell = tid, stride = std::uint64_t(AMREX_GPU_MAX_THREADS)*gridDim.x; icell < indexer.numPts(); icell += stride) {
1138 auto iv = indexer.intVect(icell);
1139 detail::call_f_intvect_ncomp_engine(f, iv, ncomp, engine);
1140 }
1141 });
1142 Gpu::streamSynchronize(); // To avoid multiple streams using RNG
1144}
1145
1150template <int MT, typename L1, typename L2, int dim>
1151requires (MaybeDeviceRunnable<L1>::value && MaybeDeviceRunnable<L2>::value)
1152void
1154 BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2)
1155{
1156 if (amrex::isEmpty(box1) && amrex::isEmpty(box2)) { return; }
1157 const BoxIndexerND<dim> indexer1(box1);
1158 const BoxIndexerND<dim> indexer2(box2);
1159 const auto ec = Gpu::makeExecutionConfig<MT>(std::max(box1.numPts(),box2.numPts()));
1160 AMREX_LAUNCH_KERNEL(MT, ec.numBlocks, ec.numThreads, 0, Gpu::gpuStream(),
1161 [=] AMREX_GPU_DEVICE () noexcept {
1162 auto const ncells = std::max(indexer1.numPts(), indexer2.numPts());
1163 for (std::uint64_t icell = std::uint64_t(MT)*blockIdx.x+threadIdx.x, stride = std::uint64_t(MT)*gridDim.x;
1164 icell < ncells; icell += stride) {
1165 if (icell < indexer1.numPts()) {
1166 auto iv = indexer1.intVect(icell);
1167 detail::call_f_intvect(f1, iv);
1168 }
1169 if (icell < indexer2.numPts()) {
1170 auto iv = indexer2.intVect(icell);
1171 detail::call_f_intvect(f2, iv);
1172 }
1173 }
1174 });
1176}
1177
1182template <int MT, typename L1, typename L2, typename L3, int dim>
1183requires (MaybeDeviceRunnable<L1>::value && MaybeDeviceRunnable<L2>::value &&
1184 MaybeDeviceRunnable<L3>::value)
1185void
1187 BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1188 L1&& f1, L2&& f2, L3&& f3)
1189{
1190 if (amrex::isEmpty(box1) && amrex::isEmpty(box2) && amrex::isEmpty(box3)) { return; }
1191 const BoxIndexerND<dim> indexer1(box1);
1192 const BoxIndexerND<dim> indexer2(box2);
1193 const BoxIndexerND<dim> indexer3(box3);
1194 const auto ec = Gpu::makeExecutionConfig<MT>(std::max({box1.numPts(),box2.numPts(),box3.numPts()}));
1195 AMREX_LAUNCH_KERNEL(MT, ec.numBlocks, ec.numThreads, 0, Gpu::gpuStream(),
1196 [=] AMREX_GPU_DEVICE () noexcept {
1197 auto const ncells = std::max({indexer1.numPts(), indexer2.numPts(), indexer3.numPts()});
1198 for (std::uint64_t icell = std::uint64_t(MT)*blockIdx.x+threadIdx.x, stride = std::uint64_t(MT)*gridDim.x;
1199 icell < ncells; icell += stride) {
1200 if (icell < indexer1.numPts()) {
1201 auto iv = indexer1.intVect(icell);
1202 detail::call_f_intvect(f1, iv);
1203 }
1204 if (icell < indexer2.numPts()) {
1205 auto iv = indexer2.intVect(icell);
1206 detail::call_f_intvect(f2, iv);
1207 }
1208 if (icell < indexer3.numPts()) {
1209 auto iv = indexer3.intVect(icell);
1210 detail::call_f_intvect(f3, iv);
1211 }
1212 }
1213 });
1215}
1216
1221template <int MT, std::integral T1, std::integral T2, typename L1, typename L2, int dim>
1222requires (MaybeDeviceRunnable<L1>::value && MaybeDeviceRunnable<L2>::value)
1223void
1225 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1226 BoxND<dim> const& box2, T2 ncomp2, L2&& f2)
1227{
1228 if (amrex::isEmpty(box1) && amrex::isEmpty(box2)) { return; }
1229 const BoxIndexerND<dim> indexer1(box1);
1230 const BoxIndexerND<dim> indexer2(box2);
1231 const auto ec = Gpu::makeExecutionConfig<MT>(std::max(box1.numPts(),box2.numPts()));
1232 AMREX_LAUNCH_KERNEL(MT, ec.numBlocks, ec.numThreads, 0, Gpu::gpuStream(),
1233 [=] AMREX_GPU_DEVICE () noexcept {
1234 auto const ncells = std::max(indexer1.numPts(), indexer2.numPts());
1235 for (std::uint64_t icell = std::uint64_t(MT)*blockIdx.x+threadIdx.x, stride = std::uint64_t(MT)*gridDim.x;
1236 icell < ncells; icell += stride) {
1237 if (icell < indexer1.numPts()) {
1238 auto iv = indexer1.intVect(icell);
1239 detail::call_f_intvect_ncomp(f1, iv, ncomp1);
1240 }
1241 if (icell < indexer2.numPts()) {
1242 auto iv = indexer2.intVect(icell);
1243 detail::call_f_intvect_ncomp(f2, iv, ncomp2);
1244 }
1245 }
1246 });
1248}
1249
1254template <int MT, std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
1255requires (MaybeDeviceRunnable<L1>::value && MaybeDeviceRunnable<L2>::value &&
1256 MaybeDeviceRunnable<L3>::value)
1257void
1259 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1260 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
1261 BoxND<dim> const& box3, T3 ncomp3, L3&& f3)
1262{
1263 if (amrex::isEmpty(box1) && amrex::isEmpty(box2) && amrex::isEmpty(box3)) { return; }
1264 const BoxIndexerND<dim> indexer1(box1);
1265 const BoxIndexerND<dim> indexer2(box2);
1266 const BoxIndexerND<dim> indexer3(box3);
1267 const auto ec = Gpu::makeExecutionConfig<MT>(std::max({box1.numPts(),box2.numPts(),box3.numPts()}));
1268 AMREX_LAUNCH_KERNEL(MT, ec.numBlocks, ec.numThreads, 0, Gpu::gpuStream(),
1269 [=] AMREX_GPU_DEVICE () noexcept {
1270 auto const ncells = std::max({indexer1.numPts(), indexer2.numPts(), indexer3.numPts()});
1271 for (std::uint64_t icell = std::uint64_t(MT)*blockIdx.x+threadIdx.x, stride = std::uint64_t(MT)*gridDim.x;
1272 icell < ncells; icell += stride) {
1273 if (icell < indexer1.numPts()) {
1274 auto iv = indexer1.intVect(icell);
1275 detail::call_f_intvect_ncomp(f1, iv, ncomp1);
1276 }
1277 if (icell < indexer2.numPts()) {
1278 auto iv = indexer2.intVect(icell);
1279 detail::call_f_intvect_ncomp(f2, iv, ncomp2);
1280 }
1281 if (icell < indexer3.numPts()) {
1282 auto iv = indexer3.intVect(icell);
1283 detail::call_f_intvect_ncomp(f3, iv, ncomp3);
1284 }
1285 }
1286 });
1288}
1289
1290#endif
1291
1292template <typename L>
1293void single_task (L&& f) noexcept
1294{
1295 single_task(Gpu::gpuStream(), std::forward<L>(f));
1296}
1297
1298template<typename T, typename L>
1299void launch (T const& n, L&& f) noexcept
1300{
1301 launch<AMREX_GPU_MAX_THREADS>(n, std::forward<L>(f));
1302}
1303
1308template <std::integral T, typename L>
1309requires (MaybeDeviceRunnable<L>::value)
1310void
1311ParallelFor (Gpu::KernelInfo const& info, T n, L&& f) noexcept
1312{
1313 ParallelFor<AMREX_GPU_MAX_THREADS>(info, n, std::forward<L>(f));
1314}
1315
1320template <typename L, int dim>
1321requires (MaybeDeviceRunnable<L>::value)
1322void
1323ParallelFor (Gpu::KernelInfo const& info, BoxND<dim> const& box, L&& f) noexcept
1324{
1325 ParallelFor<AMREX_GPU_MAX_THREADS>(info, box, std::forward<L>(f));
1326}
1327
1332template <std::integral T, typename L, int dim>
1333requires (MaybeDeviceRunnable<L>::value)
1334void
1335ParallelFor (Gpu::KernelInfo const& info, BoxND<dim> const& box, T ncomp, L&& f) noexcept
1336{
1337 ParallelFor<AMREX_GPU_MAX_THREADS>(info, box, ncomp, std::forward<L>(f));
1338}
1339
1344template <typename L1, typename L2, int dim>
1345requires (MaybeDeviceRunnable<L1>::value && MaybeDeviceRunnable<L2>::value)
1346void
1348 BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
1349{
1350 ParallelFor<AMREX_GPU_MAX_THREADS>(info, box1, box2, std::forward<L1>(f1),
1351 std::forward<L2>(f2));
1352}
1353
1358template <typename L1, typename L2, typename L3, int dim>
1359requires (MaybeDeviceRunnable<L1>::value && MaybeDeviceRunnable<L2>::value &&
1360 MaybeDeviceRunnable<L3>::value)
1361void
1363 BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1364 L1&& f1, L2&& f2, L3&& f3) noexcept
1365{
1366 ParallelFor<AMREX_GPU_MAX_THREADS>(info, box1, box2, box3, std::forward<L1>(f1),
1367 std::forward<L2>(f2), std::forward<L3>(f3));
1368}
1369
1374template <std::integral T1, std::integral T2, typename L1, typename L2, int dim>
1375requires (MaybeDeviceRunnable<L1>::value && MaybeDeviceRunnable<L2>::value)
1376void
1378 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1379 BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
1380{
1381 ParallelFor<AMREX_GPU_MAX_THREADS>(info, box1, ncomp1, std::forward<L1>(f1),
1382 box2, ncomp2, std::forward<L2>(f2));
1383}
1384
1389template <std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
1390requires (MaybeDeviceRunnable<L1>::value && MaybeDeviceRunnable<L2>::value &&
1391 MaybeDeviceRunnable<L3>::value)
1392void
1394 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1395 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
1396 BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
1397{
1398 ParallelFor<AMREX_GPU_MAX_THREADS>(info, box1, ncomp1, std::forward<L1>(f1),
1399 box2, ncomp2, std::forward<L2>(f2),
1400 box3, ncomp3, std::forward<L3>(f3));
1401}
1402
1403template <std::integral T, typename L>
1404void For (Gpu::KernelInfo const& info, T n, L&& f) noexcept
1405{
1406 ParallelFor<AMREX_GPU_MAX_THREADS>(info, n,std::forward<L>(f));
1407}
1408
1409template <int MT, std::integral T, typename L>
1410void For (Gpu::KernelInfo const& info, T n, L&& f) noexcept
1411{
1412 ParallelFor<MT>(info, n,std::forward<L>(f));
1413}
1414
1415template <typename L, int dim>
1416void For (Gpu::KernelInfo const& info, BoxND<dim> const& box, L&& f) noexcept
1417{
1418 ParallelFor<AMREX_GPU_MAX_THREADS>(info, box,std::forward<L>(f));
1419}
1420
1421template <int MT, typename L, int dim>
1422void For (Gpu::KernelInfo const& info, BoxND<dim> const& box, L&& f) noexcept
1423{
1424 ParallelFor<MT>(info, box,std::forward<L>(f));
1425}
1426
1427template <std::integral T, typename L, int dim>
1428void For (Gpu::KernelInfo const& info, BoxND<dim> const& box, T ncomp, L&& f) noexcept
1429{
1430 ParallelFor<AMREX_GPU_MAX_THREADS>(info,box,ncomp,std::forward<L>(f));
1431}
1432
1433template <int MT, std::integral T, typename L, int dim>
1434void For (Gpu::KernelInfo const& info, BoxND<dim> const& box, T ncomp, L&& f) noexcept
1435{
1436 ParallelFor<MT>(info,box,ncomp,std::forward<L>(f));
1437}
1438
1439template <typename L1, typename L2, int dim>
1440void For (Gpu::KernelInfo const& info,
1441 BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
1442{
1443 ParallelFor<AMREX_GPU_MAX_THREADS>(info,box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
1444}
1445
1446template <int MT, typename L1, typename L2, int dim>
1447void For (Gpu::KernelInfo const& info,
1448 BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
1449{
1450 ParallelFor<MT>(info,box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
1451}
1452
1453template <typename L1, typename L2, typename L3, int dim>
1454void For (Gpu::KernelInfo const& info,
1455 BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1456 L1&& f1, L2&& f2, L3&& f3) noexcept
1457{
1458 ParallelFor<AMREX_GPU_MAX_THREADS>(info,box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
1459}
1460
1461template <int MT, typename L1, typename L2, typename L3, int dim>
1462void For (Gpu::KernelInfo const& info,
1463 BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1464 L1&& f1, L2&& f2, L3&& f3) noexcept
1465{
1466 ParallelFor<MT>(info,box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
1467}
1468
1469template <std::integral T1, std::integral T2, typename L1, typename L2, int dim>
1470void For (Gpu::KernelInfo const& info,
1471 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1472 BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
1473{
1474 ParallelFor<AMREX_GPU_MAX_THREADS>(info,box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
1475}
1476
1477template <int MT, std::integral T1, std::integral T2, typename L1, typename L2, int dim>
1478void For (Gpu::KernelInfo const& info,
1479 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1480 BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
1481{
1482 ParallelFor<MT>(info,box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
1483}
1484
1485template <std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
1486void For (Gpu::KernelInfo const& info,
1487 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1488 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
1489 BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
1490{
1491 ParallelFor<AMREX_GPU_MAX_THREADS>(info,
1492 box1,ncomp1,std::forward<L1>(f1),
1493 box2,ncomp2,std::forward<L2>(f2),
1494 box3,ncomp3,std::forward<L3>(f3));
1495}
1496
1497template <int MT, std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
1498void For (Gpu::KernelInfo const& info,
1499 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1500 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
1501 BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
1502{
1503 ParallelFor<MT>(info,
1504 box1,ncomp1,std::forward<L1>(f1),
1505 box2,ncomp2,std::forward<L2>(f2),
1506 box3,ncomp3,std::forward<L3>(f3));
1507}
1508
1513template <std::integral T, typename L>
1514void ParallelFor (T n, L&& f) noexcept
1515{
1516 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{}, n, std::forward<L>(f));
1517}
1518
1523template <int MT, std::integral T, typename L>
1524void ParallelFor (T n, L&& f) noexcept
1525{
1526 ParallelFor<MT>(Gpu::KernelInfo{}, n, std::forward<L>(f));
1527}
1528
1533template <typename L, int dim>
1534void ParallelFor (BoxND<dim> const& box, L&& f) noexcept
1535{
1536 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{}, box, std::forward<L>(f));
1537}
1538
1543template <int MT, typename L, int dim>
1544void ParallelFor (BoxND<dim> const& box, L&& f) noexcept
1545{
1546 ParallelFor<MT>(Gpu::KernelInfo{}, box, std::forward<L>(f));
1547}
1548
1553template <std::integral T, typename L, int dim>
1554void ParallelFor (BoxND<dim> const& box, T ncomp, L&& f) noexcept
1555{
1556 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},box,ncomp,std::forward<L>(f));
1557}
1558
1563template <int MT, std::integral T, typename L, int dim>
1564void ParallelFor (BoxND<dim> const& box, T ncomp, L&& f) noexcept
1565{
1566 ParallelFor<MT>(Gpu::KernelInfo{},box,ncomp,std::forward<L>(f));
1567}
1568
1573template <typename L1, typename L2, int dim>
1574void ParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
1575{
1576 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
1577}
1578
1583template <int MT, typename L1, typename L2, int dim>
1584void ParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
1585{
1586 ParallelFor<MT>(Gpu::KernelInfo{},box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
1587}
1588
1593template <typename L1, typename L2, typename L3, int dim>
1594void ParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1595 L1&& f1, L2&& f2, L3&& f3) noexcept
1596{
1597 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
1598}
1599
1604template <int MT, typename L1, typename L2, typename L3, int dim>
1605void ParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1606 L1&& f1, L2&& f2, L3&& f3) noexcept
1607{
1608 ParallelFor<MT>(Gpu::KernelInfo{},box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
1609}
1610
1615template <std::integral T1, std::integral T2, typename L1, typename L2, int dim>
1616void ParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1617 BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
1618{
1619 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
1620}
1621
1626template <int MT, std::integral T1, std::integral T2, typename L1, typename L2, int dim>
1627void ParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1628 BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
1629{
1630 ParallelFor<MT>(Gpu::KernelInfo{},box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
1631}
1632
1637template <std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
1638void ParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1639 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
1640 BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
1641{
1642 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},
1643 box1,ncomp1,std::forward<L1>(f1),
1644 box2,ncomp2,std::forward<L2>(f2),
1645 box3,ncomp3,std::forward<L3>(f3));
1646}
1647
1652template <int MT, std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
1653void ParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1654 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
1655 BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
1656{
1657 ParallelFor<MT>(Gpu::KernelInfo{},
1658 box1,ncomp1,std::forward<L1>(f1),
1659 box2,ncomp2,std::forward<L2>(f2),
1660 box3,ncomp3,std::forward<L3>(f3));
1661}
1662
1663template <std::integral T, typename L>
1664void For (T n, L&& f) noexcept
1665{
1666 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{}, n,std::forward<L>(f));
1667}
1668
1669template <int MT, std::integral T, typename L>
1670void For (T n, L&& f) noexcept
1671{
1672 ParallelFor<MT>(Gpu::KernelInfo{}, n,std::forward<L>(f));
1673}
1674
1675template <typename L, int dim>
1676void For (BoxND<dim> const& box, L&& f) noexcept
1677{
1678 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{}, box,std::forward<L>(f));
1679}
1680
1681template <int MT, typename L, int dim>
1682void For (BoxND<dim> const& box, L&& f) noexcept
1683{
1684 ParallelFor<MT>(Gpu::KernelInfo{}, box,std::forward<L>(f));
1685}
1686
1687template <std::integral T, typename L, int dim>
1688void For (BoxND<dim> const& box, T ncomp, L&& f) noexcept
1689{
1690 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},box,ncomp,std::forward<L>(f));
1691}
1692
1693template <int MT, std::integral T, typename L, int dim>
1694void For (BoxND<dim> const& box, T ncomp, L&& f) noexcept
1695{
1696 ParallelFor<MT>(Gpu::KernelInfo{},box,ncomp,std::forward<L>(f));
1697}
1698
1699template <typename L1, typename L2, int dim>
1700void For (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
1701{
1702 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
1703}
1704
1705template <int MT, typename L1, typename L2, int dim>
1706void For (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
1707{
1708 ParallelFor<MT>(Gpu::KernelInfo{},box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
1709}
1710
1711template <typename L1, typename L2, typename L3, int dim>
1712void For (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1713 L1&& f1, L2&& f2, L3&& f3) noexcept
1714{
1715 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
1716}
1717
1718template <int MT, typename L1, typename L2, typename L3, int dim>
1719void For (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1720 L1&& f1, L2&& f2, L3&& f3) noexcept
1721{
1722 ParallelFor<MT>(Gpu::KernelInfo{},box1,box2,box3,std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
1723}
1724
1725template <std::integral T1, std::integral T2, typename L1, typename L2, int dim>
1726void For (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1727 BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
1728{
1729 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
1730}
1731
1732template <int MT, std::integral T1, std::integral T2, typename L1, typename L2, int dim>
1733void For (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1734 BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
1735{
1736 ParallelFor<MT>(Gpu::KernelInfo{},box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
1737}
1738
1739template <std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
1740void For (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1741 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
1742 BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
1743{
1744 ParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},
1745 box1,ncomp1,std::forward<L1>(f1),
1746 box2,ncomp2,std::forward<L2>(f2),
1747 box3,ncomp3,std::forward<L3>(f3));
1748}
1749
1750template <int MT, std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
1751void For (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1752 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
1753 BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
1754{
1755 ParallelFor<MT>(Gpu::KernelInfo{},
1756 box1,ncomp1,std::forward<L1>(f1),
1757 box2,ncomp2,std::forward<L2>(f2),
1758 box3,ncomp3,std::forward<L3>(f3));
1759}
1760
1761template <std::integral T, typename L>
1762requires (MaybeHostDeviceRunnable<L>::value)
1763void
1765{
1766 if (Gpu::inLaunchRegion()) {
1767 ParallelFor<AMREX_GPU_MAX_THREADS>(info,n,std::forward<L>(f));
1768 } else {
1769#ifdef AMREX_USE_SYCL
1770 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
1771#else
1773 for (T i = 0; i < n; ++i) { f(i); }
1774#endif
1775 }
1776}
1777
1778template <int MT, std::integral T, typename L>
1779requires (MaybeHostDeviceRunnable<L>::value)
1780void
1782{
1783 if (Gpu::inLaunchRegion()) {
1784 ParallelFor<MT>(info,n,std::forward<L>(f));
1785 } else {
1786#ifdef AMREX_USE_SYCL
1787 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
1788#else
1790 for (T i = 0; i < n; ++i) { f(i); }
1791#endif
1792 }
1793}
1794
1795template <std::integral T, typename L>
1796requires (MaybeHostDeviceRunnable<L>::value)
1797void
1798HostDeviceParallelFor (T n, L&& f) noexcept
1799{
1800 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{}, n, std::forward<L>(f));
1801}
1802
1803template <int MT, std::integral T, typename L>
1804requires (MaybeHostDeviceRunnable<L>::value)
1805void
1806HostDeviceParallelFor (T n, L&& f) noexcept
1807{
1808 HostDeviceParallelFor<MT>(Gpu::KernelInfo{}, n, std::forward<L>(f));
1809}
1810
1811template <typename L, int dim>
1812requires (MaybeHostDeviceRunnable<L>::value)
1813void
1814HostDeviceParallelFor (Gpu::KernelInfo const& info, BoxND<dim> const& box, L&& f)
1815{
1816 if (Gpu::inLaunchRegion()) {
1817 ParallelFor<AMREX_GPU_MAX_THREADS>(info, box,std::forward<L>(f));
1818 } else {
1819#ifdef AMREX_USE_SYCL
1820 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
1821#else
1822 LoopConcurrentOnCpu(box,std::forward<L>(f));
1823#endif
1824 }
1825}
1826
1827template <int MT, typename L, int dim>
1828requires (MaybeHostDeviceRunnable<L>::value)
1829void
1830HostDeviceParallelFor (Gpu::KernelInfo const& info, BoxND<dim> const& box, L&& f)
1831{
1832 if (Gpu::inLaunchRegion()) {
1833 ParallelFor<MT>(info, box,std::forward<L>(f));
1834 } else {
1835#ifdef AMREX_USE_SYCL
1836 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
1837#else
1838 LoopConcurrentOnCpu(box,std::forward<L>(f));
1839#endif
1840 }
1841}
1842
1843template <std::integral T, typename L, int dim>
1844requires (MaybeHostDeviceRunnable<L>::value)
1845void
1846HostDeviceParallelFor (Gpu::KernelInfo const& info, BoxND<dim> const& box, T ncomp, L&& f)
1847{
1848 if (Gpu::inLaunchRegion()) {
1849 ParallelFor<AMREX_GPU_MAX_THREADS>(info, box,ncomp,std::forward<L>(f));
1850 } else {
1851#ifdef AMREX_USE_SYCL
1852 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
1853#else
1854 LoopConcurrentOnCpu(box,ncomp,std::forward<L>(f));
1855#endif
1856 }
1857}
1858
1859template <int MT, std::integral T, typename L, int dim>
1860requires (MaybeHostDeviceRunnable<L>::value)
1861void
1862HostDeviceParallelFor (Gpu::KernelInfo const& info, BoxND<dim> const& box, T ncomp, L&& f)
1863{
1864 if (Gpu::inLaunchRegion()) {
1865 ParallelFor<MT>(info, box,ncomp,std::forward<L>(f));
1866 } else {
1867#ifdef AMREX_USE_SYCL
1868 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
1869#else
1870 LoopConcurrentOnCpu(box,ncomp,std::forward<L>(f));
1871#endif
1872 }
1873}
1874
1875template <typename L1, typename L2, int dim>
1876requires (MaybeHostDeviceRunnable<L1>::value && MaybeHostDeviceRunnable<L2>::value)
1877void
1879 BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2)
1880{
1881 if (Gpu::inLaunchRegion()) {
1882 ParallelFor<AMREX_GPU_MAX_THREADS>(info,box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
1883 } else {
1884#ifdef AMREX_USE_SYCL
1885 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
1886#else
1887 LoopConcurrentOnCpu(box1,std::forward<L1>(f1));
1888 LoopConcurrentOnCpu(box2,std::forward<L2>(f2));
1889#endif
1890 }
1891}
1892
1893template <int MT, typename L1, typename L2, int dim>
1894requires (MaybeHostDeviceRunnable<L1>::value && MaybeHostDeviceRunnable<L2>::value)
1895void
1897 BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2)
1898{
1899 if (Gpu::inLaunchRegion()) {
1900 ParallelFor<MT>(info,box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
1901 } else {
1902#ifdef AMREX_USE_SYCL
1903 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
1904#else
1905 LoopConcurrentOnCpu(box1,std::forward<L1>(f1));
1906 LoopConcurrentOnCpu(box2,std::forward<L2>(f2));
1907#endif
1908 }
1909}
1910
1911template <typename L1, typename L2, typename L3, int dim>
1912requires (MaybeHostDeviceRunnable<L1>::value && MaybeHostDeviceRunnable<L2>::value &&
1913 MaybeHostDeviceRunnable<L3>::value)
1914void
1916 BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1917 L1&& f1, L2&& f2, L3&& f3)
1918{
1919 if (Gpu::inLaunchRegion()) {
1920 ParallelFor<AMREX_GPU_MAX_THREADS>(info,box1,box2,box3,
1921 std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
1922 } else {
1923#ifdef AMREX_USE_SYCL
1924 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
1925#else
1926 LoopConcurrentOnCpu(box1,std::forward<L1>(f1));
1927 LoopConcurrentOnCpu(box2,std::forward<L2>(f2));
1928 LoopConcurrentOnCpu(box3,std::forward<L3>(f3));
1929#endif
1930 }
1931}
1932
1933template <int MT, typename L1, typename L2, typename L3, int dim>
1934requires (MaybeHostDeviceRunnable<L1>::value && MaybeHostDeviceRunnable<L2>::value &&
1935 MaybeHostDeviceRunnable<L3>::value)
1936void
1938 BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
1939 L1&& f1, L2&& f2, L3&& f3)
1940{
1941 if (Gpu::inLaunchRegion()) {
1942 ParallelFor<MT>(info,box1,box2,box3,
1943 std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
1944 } else {
1945#ifdef AMREX_USE_SYCL
1946 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
1947#else
1948 LoopConcurrentOnCpu(box1,std::forward<L1>(f1));
1949 LoopConcurrentOnCpu(box2,std::forward<L2>(f2));
1950 LoopConcurrentOnCpu(box3,std::forward<L3>(f3));
1951#endif
1952 }
1953}
1954
1955template <std::integral T1, std::integral T2, typename L1, typename L2, int dim>
1956requires (MaybeHostDeviceRunnable<L1>::value && MaybeHostDeviceRunnable<L2>::value)
1957void
1959 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1960 BoxND<dim> const& box2, T2 ncomp2, L2&& f2)
1961{
1962 if (Gpu::inLaunchRegion()) {
1963 ParallelFor<AMREX_GPU_MAX_THREADS>(info,box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
1964 } else {
1965#ifdef AMREX_USE_SYCL
1966 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
1967#else
1968 LoopConcurrentOnCpu(box1,ncomp1,std::forward<L1>(f1));
1969 LoopConcurrentOnCpu(box2,ncomp2,std::forward<L2>(f2));
1970#endif
1971 }
1972}
1973
1974template <int MT, std::integral T1, std::integral T2, typename L1, typename L2, int dim>
1975requires (MaybeHostDeviceRunnable<L1>::value && MaybeHostDeviceRunnable<L2>::value)
1976void
1978 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1979 BoxND<dim> const& box2, T2 ncomp2, L2&& f2)
1980{
1981 if (Gpu::inLaunchRegion()) {
1982 ParallelFor<MT>(info,box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
1983 } else {
1984#ifdef AMREX_USE_SYCL
1985 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
1986#else
1987 LoopConcurrentOnCpu(box1,ncomp1,std::forward<L1>(f1));
1988 LoopConcurrentOnCpu(box2,ncomp2,std::forward<L2>(f2));
1989#endif
1990 }
1991}
1992
1993template <std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
1994requires (MaybeHostDeviceRunnable<L1>::value && MaybeHostDeviceRunnable<L2>::value &&
1995 MaybeHostDeviceRunnable<L3>::value)
1996void
1998 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
1999 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
2000 BoxND<dim> const& box3, T3 ncomp3, L3&& f3)
2001{
2002 if (Gpu::inLaunchRegion()) {
2003 ParallelFor<AMREX_GPU_MAX_THREADS>(info,
2004 box1,ncomp1,std::forward<L1>(f1),
2005 box2,ncomp2,std::forward<L2>(f2),
2006 box3,ncomp3,std::forward<L3>(f3));
2007 } else {
2008#ifdef AMREX_USE_SYCL
2009 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
2010#else
2011 LoopConcurrentOnCpu(box1,ncomp1,std::forward<L1>(f1));
2012 LoopConcurrentOnCpu(box2,ncomp2,std::forward<L2>(f2));
2013 LoopConcurrentOnCpu(box3,ncomp3,std::forward<L3>(f3));
2014#endif
2015 }
2016}
2017
2018template <int MT, std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
2019requires (MaybeHostDeviceRunnable<L1>::value && MaybeHostDeviceRunnable<L2>::value &&
2020 MaybeHostDeviceRunnable<L3>::value)
2021void
2023 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
2024 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
2025 BoxND<dim> const& box3, T3 ncomp3, L3&& f3)
2026{
2027 if (Gpu::inLaunchRegion()) {
2028 ParallelFor<MT>(info,
2029 box1,ncomp1,std::forward<L1>(f1),
2030 box2,ncomp2,std::forward<L2>(f2),
2031 box3,ncomp3,std::forward<L3>(f3));
2032 } else {
2033#ifdef AMREX_USE_SYCL
2034 amrex::Abort("amrex:: HOST_DEVICE disabled for Intel. It takes too long to compile");
2035#else
2036 LoopConcurrentOnCpu(box1,ncomp1,std::forward<L1>(f1));
2037 LoopConcurrentOnCpu(box2,ncomp2,std::forward<L2>(f2));
2038 LoopConcurrentOnCpu(box3,ncomp3,std::forward<L3>(f3));
2039#endif
2040 }
2041}
2042
2043template <std::integral T, typename L>
2044void HostDeviceFor (Gpu::KernelInfo const& info, T n, L&& f) noexcept
2045{
2046 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(info,n,std::forward<L>(f));
2047}
2048
2049template <int MT, std::integral T, typename L>
2050void HostDeviceFor (Gpu::KernelInfo const& info, T n, L&& f) noexcept
2051{
2052 HostDeviceParallelFor<MT>(info,n,std::forward<L>(f));
2053}
2054
2055template <typename L, int dim>
2056void HostDeviceFor (Gpu::KernelInfo const& info, BoxND<dim> const& box, L&& f) noexcept
2057{
2058 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(info,box,std::forward<L>(f));
2059}
2060
2061template <int MT, typename L, int dim>
2062void HostDeviceFor (Gpu::KernelInfo const& info, BoxND<dim> const& box, L&& f) noexcept
2063{
2064 HostDeviceParallelFor<MT>(info,box,std::forward<L>(f));
2065}
2066
2067template <std::integral T, typename L, int dim>
2068void HostDeviceFor (Gpu::KernelInfo const& info, BoxND<dim> const& box, T ncomp, L&& f) noexcept
2069{
2070 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(info,box,ncomp,std::forward<L>(f));
2071}
2072
2073template <int MT, std::integral T, typename L, int dim>
2074void HostDeviceFor (Gpu::KernelInfo const& info, BoxND<dim> const& box, T ncomp, L&& f) noexcept
2075{
2076 HostDeviceParallelFor<MT>(info,box,ncomp,std::forward<L>(f));
2077}
2078
2079template <typename L1, typename L2, int dim>
2080void HostDeviceFor (Gpu::KernelInfo const& info,
2081 BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
2082{
2083 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(info,box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
2084}
2085
2086template <int MT, typename L1, typename L2, int dim>
2087void HostDeviceFor (Gpu::KernelInfo const& info,
2088 BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
2089{
2090 HostDeviceParallelFor<MT>(info,box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
2091}
2092
2093template <typename L1, typename L2, typename L3, int dim>
2094void HostDeviceFor (Gpu::KernelInfo const& info,
2095 BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
2096 L1&& f1, L2&& f2, L3&& f3) noexcept
2097{
2098 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(info, box1,box2,box3,
2099 std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
2100}
2101
2102template <int MT, typename L1, typename L2, typename L3, int dim>
2103void HostDeviceFor (Gpu::KernelInfo const& info,
2104 BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
2105 L1&& f1, L2&& f2, L3&& f3) noexcept
2106{
2107 HostDeviceParallelFor<MT>(info, box1,box2,box3,
2108 std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
2109}
2110
2111template <std::integral T1, std::integral T2, typename L1, typename L2, int dim>
2112void HostDeviceFor (Gpu::KernelInfo const& info,
2113 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
2114 BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
2115{
2116 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(info,box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
2117}
2118
2119template <int MT, std::integral T1, std::integral T2, typename L1, typename L2, int dim>
2120void HostDeviceFor (Gpu::KernelInfo const& info,
2121 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
2122 BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
2123{
2124 HostDeviceParallelFor<MT>(info,box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
2125}
2126
2127template <std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
2128void HostDeviceFor (Gpu::KernelInfo const& info,
2129 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
2130 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
2131 BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
2132{
2133 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(info,
2134 box1,ncomp1,std::forward<L1>(f1),
2135 box2,ncomp2,std::forward<L2>(f2),
2136 box3,ncomp3,std::forward<L3>(f3));
2137}
2138
2139template <int MT, std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
2140void HostDeviceFor (Gpu::KernelInfo const& info,
2141 BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
2142 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
2143 BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
2144{
2145 HostDeviceParallelFor<MT>(info,
2146 box1,ncomp1,std::forward<L1>(f1),
2147 box2,ncomp2,std::forward<L2>(f2),
2148 box3,ncomp3,std::forward<L3>(f3));
2149}
2150
2151template <std::integral T, typename L>
2152void HostDeviceParallelFor (T n, L&& f) noexcept
2153{
2154 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},n,std::forward<L>(f));
2155}
2156
2157template <int MT, std::integral T, typename L>
2158void HostDeviceParallelFor (T n, L&& f) noexcept
2159{
2160 HostDeviceParallelFor<MT>(Gpu::KernelInfo{},n,std::forward<L>(f));
2161}
2162
2163template <typename L, int dim>
2164void HostDeviceParallelFor (BoxND<dim> const& box, L&& f) noexcept
2165{
2166 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},box,std::forward<L>(f));
2167}
2168
2169template <int MT, typename L, int dim>
2170void HostDeviceParallelFor (BoxND<dim> const& box, L&& f) noexcept
2171{
2172 HostDeviceParallelFor<MT>(Gpu::KernelInfo{},box,std::forward<L>(f));
2173}
2174
2175template <std::integral T, typename L, int dim>
2176void HostDeviceParallelFor (BoxND<dim> const& box, T ncomp, L&& f) noexcept
2177{
2178 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},box,ncomp,std::forward<L>(f));
2179}
2180
2181template <int MT, std::integral T, typename L, int dim>
2182void HostDeviceParallelFor (BoxND<dim> const& box, T ncomp, L&& f) noexcept
2183{
2184 HostDeviceParallelFor<MT>(Gpu::KernelInfo{},box,ncomp,std::forward<L>(f));
2185}
2186
2187template <typename L1, typename L2, int dim>
2188void HostDeviceParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
2189{
2190 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
2191}
2192
2193template <int MT, typename L1, typename L2, int dim>
2194void HostDeviceParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, L1&& f1, L2&& f2) noexcept
2195{
2196 HostDeviceParallelFor<MT>(Gpu::KernelInfo{},box1,box2,std::forward<L1>(f1),std::forward<L2>(f2));
2197}
2198
2199template <typename L1, typename L2, typename L3, int dim>
2200void HostDeviceParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
2201 L1&& f1, L2&& f2, L3&& f3) noexcept
2202{
2203 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{}, box1,box2,box3,
2204 std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
2205}
2206
2207template <int MT, typename L1, typename L2, typename L3, int dim>
2208void HostDeviceParallelFor (BoxND<dim> const& box1, BoxND<dim> const& box2, BoxND<dim> const& box3,
2209 L1&& f1, L2&& f2, L3&& f3) noexcept
2210{
2211 HostDeviceParallelFor<MT>(Gpu::KernelInfo{}, box1,box2,box3,
2212 std::forward<L1>(f1),std::forward<L2>(f2),std::forward<L3>(f3));
2213}
2214
2215template <std::integral T1, std::integral T2, typename L1, typename L2, int dim>
2216void HostDeviceParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
2217 BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
2218{
2219 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
2220}
2221
2222template <int MT, std::integral T1, std::integral T2, typename L1, typename L2, int dim>
2223void HostDeviceParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
2224 BoxND<dim> const& box2, T2 ncomp2, L2&& f2) noexcept
2225{
2226 HostDeviceParallelFor<MT>(Gpu::KernelInfo{},box1,ncomp1,std::forward<L1>(f1),box2,ncomp2,std::forward<L2>(f2));
2227}
2228
2229template <std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
2230void HostDeviceParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
2231 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
2232 BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
2233{
2234 HostDeviceParallelFor<AMREX_GPU_MAX_THREADS>(Gpu::KernelInfo{},
2235 box1,ncomp1,std::forward<L1>(f1),
2236 box2,ncomp2,std::forward<L2>(f2),
2237 box3,ncomp3,std::forward<L3>(f3));
2238}
2239
2240template <int MT, std::integral T1, std::integral T2, std::integral T3, typename L1, typename L2, typename L3, int dim>
2241void HostDeviceParallelFor (BoxND<dim> const& box1, T1 ncomp1, L1&& f1,
2242 BoxND<dim> const& box2, T2 ncomp2, L2&& f2,
2243 BoxND<dim> const& box3, T3 ncomp3, L3&& f3) noexcept
2244{
2245 HostDeviceParallelFor<MT>(Gpu::KernelInfo{},
2246 box1,ncomp1,std::forward<L1>(f1),
2247 box2,ncomp2,std::forward<L2>(f2),
2248 box3,ncomp3,std::forward<L3>(f3));
2249}
2250
2251}
2252
2253#endif
#define AMREX_PRAGMA_SIMD
Definition AMReX_Extension.H:85
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:124
#define AMREX_GPU_ERROR_CHECK()
Definition AMReX_GpuError.H:151
#define AMREX_LAUNCH_KERNEL(MT, blocks, threads, sharedMem, stream,...)
Definition AMReX_GpuLaunch.H:37
#define AMREX_LAUNCH_KERNEL_NOBOUND(blocks, threads, sharedMem, stream,...)
Definition AMReX_GpuLaunch.H:39
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
A Rectangular Domain on an Integer Lattice.
Definition AMReX_Box.H:54
__host__ __device__ bool isEmpty() const noexcept
Checks if it is an empty BoxND.
Definition AMReX_Box.H:223
__host__ __device__ Long numPts() const noexcept
Return the number of points contained in the BoxND.
Definition AMReX_Box.H:385
__host__ __device__ IndexTypeND< dim > ixType() const noexcept
Return the indexing type.
Definition AMReX_Box.H:148
static unsigned int maxBlocksPerLaunch() noexcept
Definition AMReX_GpuDevice.H:239
static constexpr int warp_size
Definition AMReX_GpuDevice.H:236
Definition AMReX_GpuKernelInfo.H:8
amrex_long Long
Definition AMReX_INT.H:30
__host__ __device__ constexpr const T & min(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:31
__host__ __device__ constexpr const T & max(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:53
__host__ __device__ range_detail::range_impl< T > Range(T const &b) noexcept
Definition AMReX_GpuRange.H:128
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:310
bool inLaunchRegion() noexcept
Definition AMReX_GpuControl.H:88
gpuStream_t gpuStream() noexcept
Definition AMReX_GpuDevice.H:291
Definition AMReX_Amr.cpp:50
__host__ __device__ void ignore_unused(const Ts &...)
No-op helper that marks variables as intentionally unused.
Definition AMReX.H:259
void HostDeviceParallelFor(T n, L &&f) noexcept
Definition AMReX_GpuLaunchFunctsC.H:732
void For(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:400
cudaStream_t gpuStream_t
Definition AMReX_GpuControl.H:79
randState_t * getRandState()
Definition AMReX_RandomEngine.H:65
void launch(T const &n, L const &f) noexcept
Definition AMReX_GpuLaunchFunctsC.H:122
void ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:202
void HostDeviceFor(T n, L &&f) noexcept
Definition AMReX_GpuLaunchFunctsC.H:835
bool isEmpty(T n) noexcept
Definition AMReX_GpuRange.H:15
void single_task(L &&f) noexcept
Definition AMReX_GpuLaunchFunctsC.H:1245
AMREX_ATTRIBUTE_FLATTEN_FOR void ParallelForRNG(T n, L const &f) noexcept
Definition AMReX_GpuLaunchFunctsC.H:1157
curandState_t randState_t
Definition AMReX_RandomEngine.H:58
void LoopConcurrentOnCpu(Dim3 lo, Dim3 hi, F const &f) noexcept
Definition AMReX_Loop.H:388
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:242
__host__ __device__ constexpr int get(IntVectND< dim > const &iv) noexcept
Get I'th element of IntVectND<dim>
Definition AMReX_IntVect.H:1338
Utility that maps flattened point indices back to IntVectND coordinates.
Definition AMReX_Box.H:2494
__host__ __device__ IntVectND< dim > intVect(std::uint64_t icell) const
Convert flattened point index icell to its IntVectND coordinate.
Definition AMReX_Box.H:2517
__host__ __device__ std::uint64_t numPts() const
Return the number of points covered by the indexed box.
Definition AMReX_Box.H:2552
Definition AMReX_GpuLaunch.H:121
Definition AMReX_GpuTypes.H:88
Definition AMReX_RandomEngine.H:72