Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_FabArrayUtility.H
Go to the documentation of this file.
1#ifndef AMREX_FABARRAY_UTILITY_H_
2#define AMREX_FABARRAY_UTILITY_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_Concepts.H>
6#include <AMReX_FabArray.H>
7#include <AMReX_LayoutData.H>
8#include <AMReX_Print.H>
9#include <AMReX_ParReduce.H>
10#include <limits>
11
17namespace amrex {
18
31template <BaseFabType FAB, class F>
32typename FAB::value_type
33ReduceSum (FabArray<FAB> const& fa, int nghost, F&& f)
34{
35 return ReduceSum(fa, IntVect(nghost), std::forward<F>(f));
36}
37
39namespace fudetail {
40template <BaseFabType FAB, class F>
41typename FAB::value_type
42ReduceSum_host (FabArray<FAB> const& fa, IntVect const& nghost, F const& f)
43{
44 using value_type = typename FAB::value_type;
45 value_type sm = 0;
46
47#ifdef AMREX_USE_OMP
48#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
49#endif
50 for (MFIter mfi(fa,true); mfi.isValid(); ++mfi)
51 {
52 const Box& bx = mfi.growntilebox(nghost);
53 auto const& arr = fa.const_array(mfi);
54 sm += f(bx, arr);
55 }
56
57 return sm;
58}
59}
61
62#ifdef AMREX_USE_GPU
64namespace fudetail {
65template <class OP, BaseFabType FAB, class F>
66std::conditional_t<std::is_same_v<OP,ReduceOpLogicalAnd> ||
67 std::is_same_v<OP,ReduceOpLogicalOr>,
68 int, typename FAB::value_type>
69ReduceMF (FabArray<FAB> const& fa, IntVect const& nghost, F const& f)
70{
71 using T = std::conditional_t<std::is_same_v<OP,ReduceOpLogicalAnd> ||
72 std::is_same_v<OP,ReduceOpLogicalOr>,
73 int, typename FAB::value_type>;
74 auto typ = fa.ixType();
75 auto const& ma = fa.const_arrays();
76 return ParReduce(TypeList<OP>{}, TypeList<T>{}, fa, nghost,
77 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<T>
78 {
79 return { static_cast<T>(f(amrex::makeSingleCellBox(i,j,k,typ), ma[box_no])) };
80 });
81}
82
83template <class OP, BaseFabType FAB1, BaseFabType FAB2, class F>
84std::conditional_t<std::is_same_v<OP,ReduceOpLogicalAnd> ||
85 std::is_same_v<OP,ReduceOpLogicalOr>,
86 int, typename FAB1::value_type>
87ReduceMF (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2, IntVect const& nghost, F const& f)
88{
89 using T = std::conditional_t<std::is_same_v<OP,ReduceOpLogicalAnd> ||
90 std::is_same_v<OP,ReduceOpLogicalOr>,
91 int, typename FAB1::value_type>;
92 auto typ = fa1.ixType();
93 auto const& ma1 = fa1.const_arrays();
94 auto const& ma2 = fa2.const_arrays();
95 return ParReduce(TypeList<OP>{}, TypeList<T>{}, fa1, nghost,
96 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<T>
97 {
98 return { static_cast<T>(f(amrex::makeSingleCellBox(i,j,k,typ),
99 ma1[box_no], ma2[box_no])) };
100 });
101}
102
103template <class OP, BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
104std::conditional_t<std::is_same_v<OP,ReduceOpLogicalAnd> ||
105 std::is_same_v<OP,ReduceOpLogicalOr>,
106 int, typename FAB1::value_type>
107ReduceMF (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
108 FabArray<FAB3> const& fa3, IntVect const& nghost, F const& f)
109{
110 using T = std::conditional_t<std::is_same_v<OP,ReduceOpLogicalAnd> ||
111 std::is_same_v<OP,ReduceOpLogicalOr>,
112 int, typename FAB1::value_type>;
113 auto typ = fa1.ixType();
114 auto const& ma1 = fa1.const_arrays();
115 auto const& ma2 = fa2.const_arrays();
116 auto const& ma3 = fa3.const_arrays();
117 return ParReduce(TypeList<OP>{}, TypeList<T>{}, fa1, nghost,
118 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<T>
119 {
120 return { static_cast<T>(f(amrex::makeSingleCellBox(i,j,k,typ),
121 ma1[box_no], ma2[box_no], ma3[box_no])) };
122 });
123}
124
125template <BaseFabType FAB, class F>
127typename FAB::value_type ReduceSum_host_wrapper (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
128{
129 return ReduceSum_host(fa,nghost,std::forward<F>(f));
130}
131
132template <BaseFabType FAB, class F>
134typename FAB::value_type ReduceSum_host_wrapper (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
135{
136 amrex::ignore_unused(fa,nghost,f);
137 amrex::Abort("ReduceSum: Launch Region is off. Device lambda cannot be called by host.");
138 return 0;
139}
140}
142
151template <BaseFabType FAB, class F>
152typename FAB::value_type
153ReduceSum (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
154{
155 if (Gpu::inLaunchRegion()) {
156 return fudetail::ReduceMF<ReduceOpSum>(fa, nghost, std::forward<F>(f));
157 } else {
158 return fudetail::ReduceSum_host_wrapper(fa, nghost, std::forward<F>(f));
159 }
160}
161#else
170template <BaseFabType FAB, class F>
171typename FAB::value_type
172ReduceSum (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
173{
174 return fudetail::ReduceSum_host(fa, nghost, std::forward<F>(f));
175}
176#endif
177
186template <BaseFabType FAB1, BaseFabType FAB2, class F>
187typename FAB1::value_type
189 int nghost, F&& f)
190{
191 return ReduceSum(fa1, fa2, IntVect(nghost), std::forward<F>(f));
192}
193
195namespace fudetail {
196template <BaseFabType FAB1, BaseFabType FAB2, class F>
197typename FAB1::value_type
198ReduceSum_host (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
199 IntVect const& nghost, F const& f)
200{
201 using value_type = typename FAB1::value_type;
202 value_type sm = 0;
203
204#ifdef AMREX_USE_OMP
205#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
206#endif
207 for (MFIter mfi(fa1,true); mfi.isValid(); ++mfi)
208 {
209 const Box& bx = mfi.growntilebox(nghost);
210 const auto& arr1 = fa1.const_array(mfi);
211 const auto& arr2 = fa2.const_array(mfi);
212 sm += f(bx, arr1, arr2);
213 }
214
215 return sm;
216}
217}
219
220#ifdef AMREX_USE_GPU
222namespace fudetail {
223template <BaseFabType FAB1, BaseFabType FAB2, class F>
225typename FAB1::value_type ReduceSum_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
226 IntVect const& nghost, F&& f)
227{
228 return ReduceSum_host(fa1,fa2,nghost,std::forward<F>(f));
229}
230
231template <BaseFabType FAB1, BaseFabType FAB2, class F>
233typename FAB1::value_type ReduceSum_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
234 IntVect const& nghost, F&& f)
235{
236 amrex::ignore_unused(fa1,fa2,nghost,f);
237 amrex::Abort("ReduceSum: Launch Region is off. Device lambda cannot be called by host.");
238 return 0;
239}
240}
242
251template <BaseFabType FAB1, BaseFabType FAB2, class F>
252typename FAB1::value_type
254 IntVect const& nghost, F&& f)
255{
256 if (Gpu::inLaunchRegion()) {
257 return fudetail::ReduceMF<ReduceOpSum>(fa1,fa2,nghost,std::forward<F>(f));
258 } else {
259 return fudetail::ReduceSum_host_wrapper(fa1,fa2,nghost, std::forward<F>(f));
260 }
261}
262#else
271template <BaseFabType FAB1, BaseFabType FAB2, class F>
272typename FAB1::value_type
273ReduceSum (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
274 IntVect const& nghost, F&& f)
275{
276 return fudetail::ReduceSum_host(fa1,fa2,nghost,std::forward<F>(f));
277}
278#endif
279
289template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
290typename FAB1::value_type
291ReduceSum (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2, FabArray<FAB3> const& fa3,
292 int nghost, F&& f)
293{
294 return ReduceSum(fa1, fa2, fa3, IntVect(nghost), std::forward<F>(f));
295}
296
298namespace fudetail {
299template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
300typename FAB1::value_type
301ReduceSum_host (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
302 FabArray<FAB3> const& fa3, IntVect const& nghost, F const& f)
303{
304 using value_type = typename FAB1::value_type;
305 value_type sm = 0;
306
307#ifdef AMREX_USE_OMP
308#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
309#endif
310 for (MFIter mfi(fa1,true); mfi.isValid(); ++mfi)
311 {
312 const Box& bx = mfi.growntilebox(nghost);
313 const auto& arr1 = fa1.const_array(mfi);
314 const auto& arr2 = fa2.const_array(mfi);
315 const auto& arr3 = fa3.const_array(mfi);
316 sm += f(bx, arr1, arr2, arr3);
317 }
318
319 return sm;
320}
321}
323
324#ifdef AMREX_USE_GPU
326namespace fudetail {
327template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
329typename FAB1::value_type ReduceSum_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
330 FabArray<FAB3> const& fa3, IntVect const& nghost, F&& f)
331{
332 return fudetail::ReduceSum_host(fa1,fa2,fa3,nghost,std::forward<F>(f));
333}
334
335template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
337typename FAB1::value_type ReduceSum_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
338 FabArray<FAB3> const& fa3, IntVect const& nghost, F&& f)
339{
340 amrex::ignore_unused(fa1,fa2,fa3,nghost,f);
341 amrex::Abort("ReduceSum: Launch Region is off. Device lambda cannot be called by host.");
342 return 0;
343}
344}
346
356template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
357typename FAB1::value_type
359 FabArray<FAB3> const& fa3, IntVect const& nghost, F&& f)
360{
361 if (Gpu::inLaunchRegion()) {
362 return fudetail::ReduceMF<ReduceOpSum>(fa1,fa2,fa3,nghost,std::forward<F>(f));
363 } else {
364 return fudetail::ReduceSum_host_wrapper(fa1,fa2,fa3,nghost,std::forward<F>(f));
365 }
366}
367#else
377template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
378typename FAB1::value_type
379ReduceSum (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
380 FabArray<FAB3> const& fa3, IntVect const& nghost, F&& f)
381{
382 return fudetail::ReduceSum_host(fa1,fa2,fa3,nghost,std::forward<F>(f));
383}
384#endif
385
397template <BaseFabType FAB, class F>
398typename FAB::value_type
399ReduceMin (FabArray<FAB> const& fa, int nghost, F&& f)
400{
401 return ReduceMin(fa, IntVect(nghost), std::forward<F>(f));
402}
403
405namespace fudetail {
406template <BaseFabType FAB, class F>
407typename FAB::value_type
408ReduceMin_host (FabArray<FAB> const& fa, IntVect const& nghost, F const& f)
409{
410 using value_type = typename FAB::value_type;
411 value_type r = std::numeric_limits<value_type>::max();
412
413#ifdef AMREX_USE_OMP
414#pragma omp parallel reduction(min:r)
415#endif
416 for (MFIter mfi(fa,true); mfi.isValid(); ++mfi)
417 {
418 const Box& bx = mfi.growntilebox(nghost);
419 const auto& arr = fa.const_array(mfi);
420 r = std::min(r, f(bx, arr));
421 }
422 return r;
423}
424}
426
427#ifdef AMREX_USE_GPU
429namespace fudetail {
430template <BaseFabType FAB, class F>
432typename FAB::value_type ReduceMin_host_wrapper (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
433{
434 return ReduceMin_host(fa,nghost,std::forward<F>(f));
435}
436
437template <BaseFabType FAB, class F>
439typename FAB::value_type ReduceMin_host_wrapper (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
440{
441 amrex::ignore_unused(fa,nghost,f);
442 amrex::Abort("ReduceMin: Launch Region is off. Device lambda cannot be called by host.");
443 return 0;
444}
445}
447
455template <BaseFabType FAB, class F>
456typename FAB::value_type
457ReduceMin (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
458{
459 if (Gpu::inLaunchRegion()) {
460 return fudetail::ReduceMF<ReduceOpMin>(fa, nghost, std::forward<F>(f));
461 } else {
462 return fudetail::ReduceMin_host_wrapper(fa, nghost, std::forward<F>(f));
463 }
464}
465#else
473template <BaseFabType FAB, class F>
474typename FAB::value_type
475ReduceMin (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
476{
477 return fudetail::ReduceMin_host(fa, nghost, std::forward<F>(f));
478}
479#endif
480
489template <BaseFabType FAB1, BaseFabType FAB2, class F>
490typename FAB1::value_type
491ReduceMin (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2, int nghost, F&& f)
492{
493 return ReduceMin(fa1, fa2, IntVect(nghost), std::forward<F>(f));
494}
495
497namespace fudetail {
498template <BaseFabType FAB1, BaseFabType FAB2, class F>
499typename FAB1::value_type
500ReduceMin_host (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
501 IntVect const& nghost, F const& f)
502{
503 using value_type = typename FAB1::value_type;
504 value_type r = std::numeric_limits<value_type>::max();
505
506#ifdef AMREX_USE_OMP
507#pragma omp parallel reduction(min:r)
508#endif
509 for (MFIter mfi(fa1,true); mfi.isValid(); ++mfi)
510 {
511 const Box& bx = mfi.growntilebox(nghost);
512 const auto& arr1 = fa1.const_array(mfi);
513 const auto& arr2 = fa2.const_array(mfi);
514 r = std::min(r, f(bx, arr1, arr2));
515 }
516
517 return r;
518}
519}
521
522#ifdef AMREX_USE_GPU
524namespace fudetail {
525template <BaseFabType FAB1, BaseFabType FAB2, class F>
527typename FAB1::value_type ReduceMin_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
528 IntVect const& nghost, F&& f)
529{
530 return fudetail::ReduceMin_host(fa1,fa2,nghost,std::forward<F>(f));
531}
532
533template <BaseFabType FAB1, BaseFabType FAB2, class F>
535typename FAB1::value_type ReduceMin_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
536 IntVect const& nghost, F&& f)
537{
538 amrex::ignore_unused(fa1,fa2,nghost,f);
539 amrex::Abort("ReduceMin: Launch Region is off. Device lambda cannot be called by host.");
540 return 0;
541}
542}
544
553template <BaseFabType FAB1, BaseFabType FAB2, class F>
554typename FAB1::value_type
556 IntVect const& nghost, F&& f)
557{
558 if (Gpu::inLaunchRegion()) {
559 return fudetail::ReduceMF<ReduceOpMin>(fa1,fa2,nghost,std::forward<F>(f));
560 } else {
561 return fudetail::ReduceMin_host_wrapper(fa1,fa2,nghost,std::forward<F>(f));
562 }
563}
564#else
568template <BaseFabType FAB1, BaseFabType FAB2, class F>
569typename FAB1::value_type
570ReduceMin (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
571 IntVect const& nghost, F&& f)
572{
573 return fudetail::ReduceMin_host(fa1,fa2,nghost,std::forward<F>(f));
574}
575#endif
576
580template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
581typename FAB1::value_type
582ReduceMin (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2, FabArray<FAB3> const& fa3,
583 int nghost, F&& f)
584{
585 return ReduceMin(fa1, fa2, fa3, IntVect(nghost), std::forward<F>(f));
586}
587
589namespace fudetail {
590template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
591typename FAB1::value_type
592ReduceMin_host (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
593 FabArray<FAB3> const& fa3, IntVect const& nghost, F const& f)
594{
595 using value_type = typename FAB1::value_type;
596 value_type r = std::numeric_limits<value_type>::max();
597
598#ifdef AMREX_USE_OMP
599#pragma omp parallel reduction(min:r)
600#endif
601 for (MFIter mfi(fa1,true); mfi.isValid(); ++mfi)
602 {
603 const Box& bx = mfi.growntilebox(nghost);
604 const auto& arr1 = fa1.const_array(mfi);
605 const auto& arr2 = fa2.const_array(mfi);
606 const auto& arr3 = fa3.const_array(mfi);
607 r = std::min(r, f(bx, arr1, arr2, arr3));
608 }
609
610 return r;
611}
612}
614
615#ifdef AMREX_USE_GPU
617namespace fudetail {
618template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
620typename FAB1::value_type ReduceMin_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
621 FabArray<FAB3> const& fa3, IntVect const& nghost, F&& f)
622{
623 return fudetail::ReduceMin_host(fa1,fa2,fa3,nghost,std::forward<F>(f));
624}
625
626template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
628typename FAB1::value_type ReduceMin_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
629 FabArray<FAB3> const& fa3, IntVect const& nghost, F&& f)
630{
631 amrex::ignore_unused(fa1,fa2,fa3,nghost,f);
632 amrex::Abort("ReduceMin: Launch Region is off. Device lambda cannot be called by host.");
633 return 0;
634}
635}
637
641template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
642typename FAB1::value_type
644 FabArray<FAB3> const& fa3, IntVect const& nghost, F&& f)
645{
646 if (Gpu::inLaunchRegion()) {
647 return fudetail::ReduceMF<ReduceOpMin>(fa1,fa2,fa3,nghost,std::forward<F>(f));
648 } else {
649 return fudetail::ReduceMin_host_wrapper(fa1,fa2,fa3,nghost,std::forward<F>(f));
650 }
651}
652#else
656template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
657typename FAB1::value_type
658ReduceMin (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
659 FabArray<FAB3> const& fa3, IntVect const& nghost, F&& f)
660{
661 return fudetail::ReduceMin_host(fa1,fa2,fa3,nghost,std::forward<F>(f));
662}
663#endif
664
672template <BaseFabType FAB, class F>
673typename FAB::value_type
674ReduceMax (FabArray<FAB> const& fa, int nghost, F&& f)
675{
676 return ReduceMax(fa, IntVect(nghost), std::forward<F>(f));
677}
678
680namespace fudetail {
681template <BaseFabType FAB, class F>
682typename FAB::value_type
683ReduceMax_host (FabArray<FAB> const& fa, IntVect const& nghost, F const& f)
684{
685 using value_type = typename FAB::value_type;
686 value_type r = std::numeric_limits<value_type>::lowest();
687
688#ifdef AMREX_USE_OMP
689#pragma omp parallel reduction(max:r)
690#endif
691 for (MFIter mfi(fa,true); mfi.isValid(); ++mfi)
692 {
693 const Box& bx = mfi.growntilebox(nghost);
694 const auto& arr = fa.const_array(mfi);
695 r = std::max(r, f(bx, arr));
696 }
697
698 return r;
699}
700}
702
703#ifdef AMREX_USE_GPU
705namespace fudetail {
706template <BaseFabType FAB, class F>
708typename FAB::value_type ReduceMax_host_wrapper (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
709{
710 return ReduceMax_host(fa,nghost,std::forward<F>(f));
711}
712
713template <BaseFabType FAB, class F>
715typename FAB::value_type ReduceMax_host_wrapper (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
716{
717 amrex::ignore_unused(fa,nghost,f);
718 amrex::Abort("ReduceMax: Launch Region is off. Device lambda cannot be called by host.");
719 return 0;
720}
721}
723
727template <BaseFabType FAB, class F>
728typename FAB::value_type
729ReduceMax (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
730{
731 if (Gpu::inLaunchRegion()) {
732 return fudetail::ReduceMF<ReduceOpMax>(fa,nghost,std::forward<F>(f));
733 } else {
734 return fudetail::ReduceMax_host_wrapper(fa,nghost,std::forward<F>(f));
735 }
736}
737#else
741template <BaseFabType FAB, class F>
742typename FAB::value_type
743ReduceMax (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
744{
745 return fudetail::ReduceMax_host(fa,nghost,std::forward<F>(f));
746}
747#endif
748
752template <BaseFabType FAB1, BaseFabType FAB2, class F>
753typename FAB1::value_type
754ReduceMax (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2, int nghost, F&& f)
755{
756 return ReduceMax(fa1, fa2, IntVect(nghost), std::forward<F>(f));
757}
758
760namespace fudetail {
761template <BaseFabType FAB1, BaseFabType FAB2, class F>
762typename FAB1::value_type
763ReduceMax_host (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
764 IntVect const& nghost, F const& f)
765{
766 using value_type = typename FAB1::value_type;
767 value_type r = std::numeric_limits<value_type>::lowest();
768
769#ifdef AMREX_USE_OMP
770#pragma omp parallel reduction(max:r)
771#endif
772 for (MFIter mfi(fa1,true); mfi.isValid(); ++mfi)
773 {
774 const Box& bx = mfi.growntilebox(nghost);
775 const auto& arr1 = fa1.const_array(mfi);
776 const auto& arr2 = fa2.const_array(mfi);
777 r = std::max(r, f(bx, arr1, arr2));
778 }
779
780 return r;
781}
782}
784
785#ifdef AMREX_USE_GPU
787namespace fudetail {
788template <BaseFabType FAB1, BaseFabType FAB2, class F>
790typename FAB1::value_type ReduceMax_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
791 IntVect const& nghost, F&& f)
792{
793 return ReduceMax_host(fa1,fa2,nghost,std::forward<F>(f));
794}
795
796template <BaseFabType FAB1, BaseFabType FAB2, class F>
798typename FAB1::value_type ReduceMax_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
799 IntVect const& nghost, F&& f)
800{
801 amrex::ignore_unused(fa1,fa2,nghost,f);
802 amrex::Abort("ReduceMax: Launch Region is off. Device lambda cannot be called by host.");
803 return 0;
804}
805}
807
811template <BaseFabType FAB1, BaseFabType FAB2, class F>
812typename FAB1::value_type
814 IntVect const& nghost, F&& f)
815{
816 if (Gpu::inLaunchRegion()) {
817 return fudetail::ReduceMF<ReduceOpMax>(fa1,fa2,nghost,std::forward<F>(f));
818 } else {
819 return fudetail::ReduceMax_host_wrapper(fa1,fa2,nghost,std::forward<F>(f));
820 }
821}
822#else
826template <BaseFabType FAB1, BaseFabType FAB2, class F>
827typename FAB1::value_type
828ReduceMax (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
829 IntVect const& nghost, F&& f)
830{
831 return fudetail::ReduceMax_host(fa1,fa2,nghost,std::forward<F>(f));
832}
833#endif
834
838template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
839typename FAB1::value_type
840ReduceMax (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2, FabArray<FAB3> const& fa3,
841 int nghost, F&& f)
842{
843 return ReduceMax(fa1, fa2, fa3, IntVect(nghost), std::forward<F>(f));
844}
845
847namespace fudetail {
848template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
849typename FAB1::value_type
850ReduceMax_host (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
851 FabArray<FAB3> const& fa3, IntVect const& nghost, F const& f)
852{
853 using value_type = typename FAB1::value_type;
854 value_type r = std::numeric_limits<value_type>::lowest();
855
856#ifdef AMREX_USE_OMP
857#pragma omp parallel reduction(max:r)
858#endif
859 for (MFIter mfi(fa1,true); mfi.isValid(); ++mfi)
860 {
861 const Box& bx = mfi.growntilebox(nghost);
862 const auto& arr1 = fa1.const_array(mfi);
863 const auto& arr2 = fa2.const_array(mfi);
864 const auto& arr3 = fa3.const_array(mfi);
865 r = std::max(r, f(bx, arr1, arr2, arr3));
866 }
867
868 return r;
869}
870}
872
873#ifdef AMREX_USE_GPU
875namespace fudetail {
876template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
878typename FAB1::value_type ReduceMax_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
879 FabArray<FAB3> const& fa3, IntVect const& nghost, F&& f)
880{
881 return fudetail::ReduceMax_host(fa1,fa2,fa3,nghost,std::forward<F>(f));
882}
883
884template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
886typename FAB1::value_type ReduceMax_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
887 FabArray<FAB3> const& fa3, IntVect const& nghost, F&& f)
888{
889 amrex::ignore_unused(fa1,fa2,fa3,nghost,f);
890 amrex::Abort("ReduceMax: Launch Region is off. Device lambda cannot be called by host.");
891 return 0;
892}
893}
895
899template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
900typename FAB1::value_type
902 FabArray<FAB3> const& fa3, IntVect const& nghost, F&& f)
903{
904 if (Gpu::inLaunchRegion()) {
905 return fudetail::ReduceMF<ReduceOpMax>(fa1,fa2,fa3,nghost,std::forward<F>(f));
906 } else {
907 return fudetail::ReduceMax_host_wrapper(fa1,fa2,fa3,nghost,std::forward<F>(f));
908 }
909}
910#else
914template <BaseFabType FAB1, BaseFabType FAB2, BaseFabType FAB3, class F>
915typename FAB1::value_type
916ReduceMax (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
917 FabArray<FAB3> const& fa3, IntVect const& nghost, F&& f)
918{
919 return fudetail::ReduceMax_host(fa1,fa2,fa3,nghost,std::forward<F>(f));
920}
921#endif
922
930template <BaseFabType FAB, class F>
931bool
932ReduceLogicalAnd (FabArray<FAB> const& fa, int nghost, F&& f)
933{
934 return ReduceLogicalAnd(fa, IntVect(nghost), std::forward<F>(f));
935}
936
938namespace fudetail {
939template <BaseFabType FAB, class F>
940bool
941ReduceLogicalAnd_host (FabArray<FAB> const& fa, IntVect const& nghost, F const& f)
942{
943 int r = true;
944
945#ifdef AMREX_USE_OMP
946#pragma omp parallel reduction(&&:r)
947#endif
948 for (MFIter mfi(fa,true); mfi.isValid(); ++mfi)
949 {
950 const Box& bx = mfi.growntilebox(nghost);
951 const auto& arr = fa.const_array(mfi);
952 r = r && f(bx, arr);
953 }
954
955 return r;
956}
957}
959
960#ifdef AMREX_USE_GPU
962namespace fudetail {
963template <BaseFabType FAB, class F>
965bool ReduceLogicalAnd_host_wrapper (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
966{
967 return ReduceLogicalAnd_host(fa,nghost,std::forward<F>(f));
968}
969
970template <BaseFabType FAB, class F>
972bool ReduceLogicalAnd_host_wrapper (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
973{
974 amrex::ignore_unused(fa,nghost,f);
975 amrex::Abort("ReduceLogicalAnd: Launch Region is off. Device lambda cannot be called by host.");
976 return false;
977}
978}
980
984template <BaseFabType FAB, class F>
985bool
986ReduceLogicalAnd (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
987{
988 if (Gpu::inLaunchRegion()) {
989 return fudetail::ReduceMF<ReduceOpLogicalAnd>(fa,nghost,std::forward<F>(f));
990 } else {
991 return fudetail::ReduceLogicalAnd_host_wrapper(fa,nghost,std::forward<F>(f));
992 }
993}
994#else
998template <BaseFabType FAB, class F>
999bool
1000ReduceLogicalAnd (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
1001{
1002 return fudetail::ReduceLogicalAnd_host(fa,nghost,std::forward<F>(f));
1003}
1004#endif
1005
1009template <BaseFabType FAB1, BaseFabType FAB2, class F>
1010bool
1012 int nghost, F&& f)
1013{
1014 return ReduceLogicalAnd(fa1, fa2, IntVect(nghost), std::forward<F>(f));
1015}
1016
1018namespace fudetail {
1019template <BaseFabType FAB1, BaseFabType FAB2, class F>
1020bool
1021ReduceLogicalAnd_host (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
1022 IntVect const& nghost, F const& f)
1023{
1024 int r = true;
1025
1026#ifdef AMREX_USE_OMP
1027#pragma omp parallel reduction(&&:r)
1028#endif
1029 for (MFIter mfi(fa1,true); mfi.isValid(); ++mfi)
1030 {
1031 const Box& bx = mfi.growntilebox(nghost);
1032 const auto& arr1 = fa1.const_array(mfi);
1033 const auto& arr2 = fa2.const_array(mfi);
1034 r = r && f(bx, arr1, arr2);
1035 }
1036
1037 return r;
1038}
1039}
1041
1042#ifdef AMREX_USE_GPU
1044namespace fudetail {
1045template <BaseFabType FAB1, BaseFabType FAB2, class F>
1047bool ReduceLogicalAnd_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
1048 IntVect const& nghost, F&& f)
1049{
1050 return ReduceLogicalAnd_host(fa1,fa2,nghost,std::forward<F>(f));
1051}
1052
1053template <BaseFabType FAB1, BaseFabType FAB2, class F>
1055bool ReduceLogicalAnd_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
1056 IntVect const& nghost, F&& f)
1057{
1058 amrex::ignore_unused(fa1,fa2,nghost,f);
1059 amrex::Abort("ReduceLogicalAnd: Luanch Region is off. Device lambda cannot be called by host.");
1060 return false;
1061}
1062}
1064
1068template <BaseFabType FAB1, BaseFabType FAB2, class F>
1069bool
1071 IntVect const& nghost, F&& f)
1072{
1073 if (Gpu::inLaunchRegion()) {
1074 return fudetail::ReduceMF<ReduceOpLogicalAnd>(fa1,fa2,nghost,std::forward<F>(f));
1075 } else {
1076 return fudetail::ReduceLogicalAnd_host_wrapper(fa1,fa2,nghost,std::forward<F>(f));
1077 }
1078}
1079#else
1083template <BaseFabType FAB1, BaseFabType FAB2, class F>
1084bool
1085ReduceLogicalAnd (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
1086 IntVect const& nghost, F&& f)
1087{
1088 return fudetail::ReduceLogicalAnd_host(fa1,fa2,nghost,std::forward<F>(f));
1089}
1090#endif
1091
1099template <BaseFabType FAB, class F>
1100bool
1101ReduceLogicalOr (FabArray<FAB> const& fa, int nghost, F&& f)
1102{
1103 return ReduceLogicalOr(fa, IntVect(nghost), std::forward<F>(f));
1104}
1105
1107namespace fudetail {
1108template <BaseFabType FAB, class F>
1109bool
1110ReduceLogicalOr_host (FabArray<FAB> const& fa, IntVect const& nghost, F const& f)
1111{
1112 int r = false;
1113
1114#ifdef AMREX_USE_OMP
1115#pragma omp parallel reduction(||:r)
1116#endif
1117 for (MFIter mfi(fa,true); mfi.isValid(); ++mfi)
1118 {
1119 const Box& bx = mfi.growntilebox(nghost);
1120 const auto& arr = fa.const_array(mfi);
1121 r = r || f(bx, arr);
1122 }
1123
1124 return r;
1125}
1126}
1128
1129#ifdef AMREX_USE_GPU
1131namespace fudetail {
1132template <BaseFabType FAB, class F>
1134bool ReduceLogicalOr_host_wrapper (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
1135{
1136 return ReduceLogicalOr_host(fa,nghost,std::forward<F>(f));
1137}
1138
1139template <BaseFabType FAB, class F>
1141bool ReduceLogicalOr_host (FabArray<FAB> const& fa, IntVect const& nghost, F&& /*f*/)
1142{
1143 amrex::ignore_unused(fa,nghost);
1144 amrex::Abort("ReduceLogicalOr: Launch Region is off. Device lambda cannot be called by host.");
1145 return 0;
1146}
1147}
1149
1153template <BaseFabType FAB, class F>
1154bool
1155ReduceLogicalOr (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
1156{
1157 if (Gpu::inLaunchRegion()) {
1158 return fudetail::ReduceMF<ReduceOpLogicalOr>(fa,nghost,std::forward<F>(f));
1159 } else {
1160 return fudetail::ReduceLogicalOr_host_wrapper(fa,nghost,std::forward<F>(f));
1161 }
1162}
1163#else
1167template <BaseFabType FAB, class F>
1168bool
1169ReduceLogicalOr (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
1170{
1171 return fudetail::ReduceLogicalOr_host(fa,nghost,std::forward<F>(f));
1172}
1173#endif
1174
1178template <BaseFabType FAB1, BaseFabType FAB2, class F>
1179bool
1181 int nghost, F&& f)
1182{
1183 return ReduceLogicalOr(fa1, fa2, IntVect(nghost), std::forward<F>(f));
1184}
1185
1187namespace fudetail {
1188template <BaseFabType FAB1, BaseFabType FAB2, class F>
1189bool
1190ReduceLogicalOr_host (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
1191 IntVect const& nghost, F const& f)
1192{
1193 int r = false;
1194
1195#ifdef AMREX_USE_OMP
1196#pragma omp parallel reduction(||:r)
1197#endif
1198 for (MFIter mfi(fa1,true); mfi.isValid(); ++mfi)
1199 {
1200 const Box& bx = mfi.growntilebox(nghost);
1201 const auto& arr1 = fa1.const_array(mfi);
1202 const auto& arr2 = fa2.const_array(mfi);
1203 r = r || f(bx, arr1, arr2);
1204 }
1205
1206 return r;
1207}
1208}
1210
1211#ifdef AMREX_USE_GPU
1213namespace fudetail {
1214template <BaseFabType FAB1, BaseFabType FAB2, class F>
1216bool ReduceLogicalOr_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
1217 IntVect const& nghost, F&& f)
1218{
1219 return fudetail::ReduceLogicalOr_host(fa1,fa2,nghost,std::forward<F>(f));
1220}
1221
1222template <BaseFabType FAB1, BaseFabType FAB2, class F>
1224bool ReduceLogicalOr_host_wrapper (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
1225 IntVect const& nghost, F&& f)
1226{
1227 amrex::ignore_unused(fa1,fa2,nghost,f);
1228 amrex::Abort("ReeuceLogicalOr: Launch Region is off. Device lambda cannot be called by host.");
1229 return false;
1230}
1231}
1233
1237template <BaseFabType FAB1, BaseFabType FAB2, class F>
1238bool
1240 IntVect const& nghost, F&& f)
1241{
1242 if (Gpu::inLaunchRegion()) {
1243 return fudetail::ReduceMF<ReduceOpLogicalOr>(fa1,fa2,nghost,std::forward<F>(f));
1244 } else {
1245 return fudetail::ReduceLogicalOr_host_wrapper(fa1,fa2,nghost,std::forward<F>(f));
1246 }
1247}
1248#else
1252template <BaseFabType FAB1, BaseFabType FAB2, class F>
1253bool
1254ReduceLogicalOr (FabArray<FAB1> const& fa1, FabArray<FAB2> const& fa2,
1255 IntVect const& nghost, F&& f)
1256{
1257 return fudetail::ReduceLogicalOr_host(fa1,fa2,nghost,std::forward<F>(f));
1258}
1259#endif
1260
1269template <BaseFabType FAB>
1270void
1271printCell (FabArray<FAB> const& mf, const IntVect& cell, int comp = -1,
1272 const IntVect& ng = IntVect::TheZeroVector())
1273{
1274 for (MFIter mfi(mf); mfi.isValid(); ++mfi)
1275 {
1276 const Box& bx = amrex::grow(mfi.validbox(), ng);
1277 if (bx.contains(cell)) {
1278 int n = (comp >= 0) ? 1 : mf.nComp();
1279 auto const& fab = mf.const_array(mfi);
1281 auto* dp = pv.data();
1282 auto f = [=] AMREX_GPU_HOST_DEVICE ()
1283 {
1284 if (comp >= 0) {
1285 *dp = fab(cell, comp);
1286 } else {
1287 for (int i = 0; i < n; ++i) {
1288 dp[i] = fab(cell,i);
1289 }
1290 }
1291 };
1292
1293#ifdef AMREX_USE_GPU
1294 if (mf.arena()->isManaged() || mf.arena()->isDevice()) {
1297 } else
1298#endif
1299 {
1300 f();
1301 }
1302
1303 if (comp >= 0) {
1304 amrex::AllPrint().SetPrecision(17) << " At cell " << cell << " in Box " << bx
1305 << ": " << *dp << '\n';
1306 } else {
1307 std::ostringstream ss;
1308 ss.precision(17);
1309 for (int i = 0; i < n-1; ++i)
1310 {
1311 ss << dp[i] << ", ";
1312 }
1313 ss << dp[n-1];
1314 amrex::AllPrint() << " At cell " << cell << " in Box " << bx
1315 << ": " << ss.view() << '\n';
1316 }
1317 }
1318 }
1319}
1320
1331template <BaseFabType FAB>
1332void
1333Swap (FabArray<FAB>& dst, FabArray<FAB>& src, int srccomp, int dstcomp, int numcomp, int nghost)
1334{
1335 Swap(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
1336}
1337
1348template <BaseFabType FAB>
1349void
1350Swap (FabArray<FAB>& dst, FabArray<FAB>& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
1351{
1352 // We can take a shortcut and do a std::swap if we're swapping all of the data
1353 // and they are allocated in the same Arena.
1354
1355 bool explicit_swap = true;
1356
1357 if (srccomp == dstcomp && dstcomp == 0 && src.nComp() == dst.nComp() &&
1358 src.nGrowVect() == nghost && src.nGrowVect() == dst.nGrowVect() &&
1359 src.arena() == dst.arena() && src.hasEBFabFactory() == dst.hasEBFabFactory()) {
1360 explicit_swap = false;
1361 }
1362
1363 if (!explicit_swap) {
1364
1365 std::swap(dst, src);
1366
1367 } else {
1368#ifdef AMREX_USE_GPU
1369 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
1370 auto const& dstma = dst.arrays();
1371 auto const& srcma = src.arrays();
1372 ParallelFor(dst, nghost, numcomp,
1373 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
1374 {
1375 const auto tmp = dstma[box_no](i,j,k,n+dstcomp);
1376 dstma[box_no](i,j,k,n+dstcomp) = srcma[box_no](i,j,k,n+srccomp);
1377 srcma[box_no](i,j,k,n+srccomp) = tmp;
1378 });
1379 if (!Gpu::inNoSyncRegion()) {
1381 }
1382 } else
1383#endif
1384 {
1385#ifdef AMREX_USE_OMP
1386#pragma omp parallel if (Gpu::notInLaunchRegion())
1387#endif
1388 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
1389 {
1390 const Box& bx = mfi.growntilebox(nghost);
1391 if (bx.ok()) {
1392 auto sfab = src.array(mfi);
1393 auto dfab = dst.array(mfi);
1394 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
1395 {
1396 const auto tmp = dfab(i,j,k,n+dstcomp);
1397 dfab(i,j,k,n+dstcomp) = sfab(i,j,k,n+srccomp);
1398 sfab(i,j,k,n+srccomp) = tmp;
1399 });
1400 }
1401 }
1402 }
1403 }
1404}
1405
1407template <BaseFabType FAB>
1408void
1409Subtract (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
1410{
1411 Subtract(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
1412}
1413
1415template <BaseFabType FAB>
1416void
1417Subtract (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
1418{
1419#ifdef AMREX_USE_GPU
1420 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
1421 auto const& dstfa = dst.arrays();
1422 auto const& srcfa = src.const_arrays();
1423 ParallelFor(dst, nghost, numcomp,
1424 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
1425 {
1426 dstfa[box_no](i,j,k,n+dstcomp) -= srcfa[box_no](i,j,k,n+srccomp);
1427 });
1428 if (!Gpu::inNoSyncRegion()) {
1430 }
1431 } else
1432#endif
1433 {
1434#ifdef AMREX_USE_OMP
1435#pragma omp parallel if (Gpu::notInLaunchRegion())
1436#endif
1437 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
1438 {
1439 const Box& bx = mfi.growntilebox(nghost);
1440 if (bx.ok())
1441 {
1442 auto const srcFab = src.array(mfi);
1443 auto dstFab = dst.array(mfi);
1444 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
1445 {
1446 dstFab(i,j,k,n+dstcomp) -= srcFab(i,j,k,n+srccomp);
1447 });
1448 }
1449 }
1450 }
1451}
1452
1453
1455template <BaseFabType FAB>
1456void
1457Multiply (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
1458{
1459 Multiply(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
1460}
1461
1463template <BaseFabType FAB>
1464void
1465Multiply (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
1466{
1467#ifdef AMREX_USE_GPU
1468 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
1469 auto const& dstfa = dst.arrays();
1470 auto const& srcfa = src.const_arrays();
1471 ParallelFor(dst, nghost, numcomp,
1472 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
1473 {
1474 dstfa[box_no](i,j,k,n+dstcomp) *= srcfa[box_no](i,j,k,n+srccomp);
1475 });
1476 if (!Gpu::inNoSyncRegion()) {
1478 }
1479 } else
1480#endif
1481 {
1482#ifdef AMREX_USE_OMP
1483#pragma omp parallel if (Gpu::notInLaunchRegion())
1484#endif
1485 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
1486 {
1487 const Box& bx = mfi.growntilebox(nghost);
1488 if (bx.ok())
1489 {
1490 auto const srcFab = src.array(mfi);
1491 auto dstFab = dst.array(mfi);
1492 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
1493 {
1494 dstFab(i,j,k,n+dstcomp) *= srcFab(i,j,k,n+srccomp);
1495 });
1496 }
1497 }
1498 }
1499}
1500
1501
1503template <BaseFabType FAB>
1504void
1505Divide (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
1506{
1507 Divide(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
1508}
1509
1511template <BaseFabType FAB>
1512void
1513Divide (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
1514{
1515#ifdef AMREX_USE_GPU
1516 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
1517 auto const& dstfa = dst.arrays();
1518 auto const& srcfa = src.const_arrays();
1519 ParallelFor(dst, nghost, numcomp,
1520 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
1521 {
1522 dstfa[box_no](i,j,k,n+dstcomp) /= srcfa[box_no](i,j,k,n+srccomp);
1523 });
1524 if (!Gpu::inNoSyncRegion()) {
1526 }
1527 } else
1528#endif
1529 {
1530#ifdef AMREX_USE_OMP
1531#pragma omp parallel if (Gpu::notInLaunchRegion())
1532#endif
1533 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
1534 {
1535 const Box& bx = mfi.growntilebox(nghost);
1536 if (bx.ok())
1537 {
1538 auto const srcFab = src.array(mfi);
1539 auto dstFab = dst.array(mfi);
1540 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
1541 {
1542 dstFab(i,j,k,n+dstcomp) /= srcFab(i,j,k,n+srccomp);
1543 });
1544 }
1545 }
1546 }
1547}
1548
1550template <BaseFabType FAB>
1551void
1552Abs (FabArray<FAB>& fa, int icomp, int numcomp, int nghost)
1553{
1554 Abs(fa,icomp,numcomp,IntVect(nghost));
1555}
1556
1558template <BaseFabType FAB>
1559void
1560Abs (FabArray<FAB>& fa, int icomp, int numcomp, const IntVect& nghost)
1561{
1562#ifdef AMREX_USE_GPU
1563 if (Gpu::inLaunchRegion() && fa.isFusingCandidate()) {
1564 auto const& fabarr = fa.arrays();
1565 ParallelFor(fa, nghost, numcomp,
1566 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
1567 {
1568 fabarr[box_no](i,j,k,n+icomp) = std::abs(fabarr[box_no](i,j,k,n+icomp));
1569 });
1570 if (!Gpu::inNoSyncRegion()) {
1572 }
1573 } else
1574#endif
1575 {
1576#ifdef AMREX_USE_OMP
1577#pragma omp parallel if (Gpu::notInLaunchRegion())
1578#endif
1579 for (MFIter mfi(fa,TilingIfNotGPU()); mfi.isValid(); ++mfi)
1580 {
1581 const Box& bx = mfi.growntilebox(nghost);
1582 if (bx.ok())
1583 {
1584 auto const& fab = fa.array(mfi);
1585 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
1586 {
1587 fab(i,j,k,n+icomp) = std::abs(fab(i,j,k,n+icomp));
1588 });
1589 }
1590 }
1591 }
1592}
1593
1601template <BaseFabType FAB>
1602void
1603prefetchToHost (FabArray<FAB> const& fa, const bool synchronous = true)
1604{
1605#ifdef AMREX_USE_GPU
1606 if (fa.arena()->isManaged()) {
1607 for (MFIter mfi(fa, MFItInfo().SetDeviceSync(synchronous)); mfi.isValid(); ++mfi) {
1608 fa.prefetchToHost(mfi);
1609 }
1610 }
1611#else
1612 amrex::ignore_unused(fa,synchronous);
1613#endif
1614}
1615
1623template <BaseFabType FAB>
1624void
1625prefetchToDevice (FabArray<FAB> const& fa, const bool synchronous = true)
1626{
1627#ifdef AMREX_USE_GPU
1628 if (fa.arena()->isManaged()) {
1629 for (MFIter mfi(fa, MFItInfo().SetDeviceSync(synchronous)); mfi.isValid(); ++mfi) {
1630 fa.prefetchToDevice(mfi);
1631 }
1632 }
1633#else
1634 amrex::ignore_unused(fa,synchronous);
1635#endif
1636}
1637
1638
1645template <BaseFabType FAB, BaseFabType IFAB>
1646void
1647OverrideSync (FabArray<FAB> & fa, FabArray<IFAB> const& msk, const Periodicity& period)
1648{
1649 BL_PROFILE("OverrideSync()");
1650
1651 OverrideSync_nowait(fa, msk, period);
1653}
1654
1655
1657template <BaseFabType FAB, BaseFabType IFAB>
1658void
1660{
1661 BL_PROFILE("OverrideSync_nowait()");
1662 AMREX_ASSERT_WITH_MESSAGE(!fa.os_temp, "OverrideSync_nowait() called when already in progress.");
1663
1664 if (fa.ixType().cellCentered()) { return; }
1665
1666 const int ncomp = fa.nComp();
1667
1668#ifdef AMREX_USE_GPU
1669 if (Gpu::inLaunchRegion() && fa.isFusingCandidate()) {
1670 auto const& fabarr = fa.arrays();
1671 auto const& ifabarr = msk.const_arrays();
1672 ParallelFor(fa, IntVect(0), ncomp,
1673 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
1674 {
1675 if (!ifabarr[box_no](i,j,k)) { fabarr[box_no](i,j,k,n) = 0; }
1676 });
1677 if (!Gpu::inNoSyncRegion()) {
1679 }
1680 } else
1681#endif
1682 {
1683#ifdef AMREX_USE_OMP
1684#pragma omp parallel if (Gpu::notInLaunchRegion())
1685#endif
1686 for (MFIter mfi(fa,TilingIfNotGPU()); mfi.isValid(); ++mfi)
1687 {
1688 const Box& bx = mfi.tilebox();
1689 auto fab = fa.array(mfi);
1690 auto const ifab = msk.array(mfi);
1691 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
1692 {
1693 if (!ifab(i,j,k)) { fab(i,j,k,n) = 0; }
1694 });
1695 }
1696 }
1697
1698 fa.os_temp = std::make_unique< FabArray<FAB> > ( fa.boxArray(), fa.DistributionMap(),
1699 ncomp, 0, MFInfo(), fa.Factory() );
1700 fa.os_temp->setVal(0);
1701 fa.os_temp->ParallelCopy_nowait(fa, period, FabArrayBase::ADD);
1702}
1703
1705template <BaseFabType FAB>
1706void
1708{
1709 BL_PROFILE("OverrideSync_finish()");
1710
1711 if (fa.ixType().cellCentered()) { return; }
1712
1713 fa.os_temp->ParallelCopy_finish();
1714 amrex::Copy(fa, *(fa.os_temp), 0, 0, fa.nComp(), 0);
1715
1716 fa.os_temp.reset();
1717}
1718
1720template <BaseFabType FAB>
1721void
1723 int scomp, int dcomp, int ncomp)
1724{
1725 AMREX_ASSERT(isMFIterSafe(dst, src));
1726 AMREX_ASSERT(dst.nGrowVect() == src.nGrowVect());
1727#ifdef AMREX_USE_GPU
1728 for (MFIter mfi(dst); mfi.isValid(); ++mfi) {
1729 void* pdst = dst[mfi].dataPtr(dcomp);
1730 void const* psrc = src[mfi].dataPtr(scomp);
1731 Gpu::dtoh_memcpy_async(pdst, psrc, dst[mfi].nBytes(mfi.fabbox(), ncomp));
1732 }
1733#else
1734 Copy(dst, src, scomp, dcomp, ncomp, dst.nGrowVect());
1735#endif
1736}
1737
1739template <BaseFabType FAB>
1740void
1742{
1743 dtoh_memcpy(dst, src, 0, 0, dst.nComp());
1744}
1745
1747template <BaseFabType FAB>
1748void
1750 int scomp, int dcomp, int ncomp)
1751{
1752 AMREX_ASSERT(isMFIterSafe(dst, src));
1753 AMREX_ASSERT(dst.nGrowVect() == src.nGrowVect());
1754#ifdef AMREX_USE_GPU
1755 for (MFIter mfi(dst); mfi.isValid(); ++mfi) {
1756 void* pdst = dst[mfi].dataPtr(dcomp);
1757 void const* psrc = src[mfi].dataPtr(scomp);
1758 Gpu::htod_memcpy_async(pdst, psrc, dst[mfi].nBytes(mfi.fabbox(), ncomp));
1759 }
1760#else
1761 Copy(dst, src, scomp, dcomp, ncomp, dst.nGrowVect());
1762#endif
1763}
1764
1766template <BaseFabType FAB>
1767void
1769{
1770 htod_memcpy(dst, src, 0, 0, dst.nComp());
1771}
1772
1781template <BaseFabType FAB>
1782IntVect
1783indexFromValue (FabArray<FAB> const& mf, int comp, IntVect const& nghost,
1784 typename FAB::value_type value)
1785{
1786 IntVect loc;
1787
1788#ifdef AMREX_USE_GPU
1789 if (Gpu::inLaunchRegion())
1790 {
1792 int* p = aa.data();
1793 // This is a device ptr to 1+AMREX_SPACEDIM int zeros.
1794 // The first is used as an atomic bool and the others for intvect.
1795 if (mf.isFusingCandidate()) {
1796 auto const& ma = mf.const_arrays();
1797 ParallelFor(mf, nghost, [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
1798 {
1799 int* flag = p;
1800 if (*flag == 0) {
1801 if (ma[box_no](i,j,k,comp) == value) {
1802 if (Gpu::Atomic::Exch(flag,1) == 0) {
1803 AMREX_D_TERM(p[1] = i;,
1804 p[2] = j;,
1805 p[3] = k;);
1806 }
1807 }
1808 }
1809 });
1810 } else {
1811 for (MFIter mfi(mf,MFItInfo().SetDeviceSync(false)); mfi.isValid(); ++mfi) {
1812 const Box& bx = amrex::grow(mfi.validbox(), nghost);
1813 auto const& arr = mf.const_array(mfi);
1814 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
1815 {
1816 int* flag = p;
1817 if (*flag == 0) {
1818 if (arr(i,j,k,comp) == value) {
1819 if (Gpu::Atomic::Exch(flag,1) == 0) {
1820 AMREX_D_TERM(p[1] = i;,
1821 p[2] = j;,
1822 p[3] = k;);
1823 }
1824 }
1825 }
1826 });
1827 }
1828 }
1829 int const* tmp = aa.copyToHost();
1830 AMREX_D_TERM(loc[0] = tmp[1];,
1831 loc[1] = tmp[2];,
1832 loc[2] = tmp[3];);
1833 }
1834 else
1835#endif
1836 {
1837 bool f = false;
1838#ifdef AMREX_USE_OMP
1839#pragma omp parallel
1840#endif
1841 {
1842 IntVect priv_loc = IntVect::TheMinVector();
1843 for (MFIter mfi(mf,true); mfi.isValid(); ++mfi)
1844 {
1845 const Box& bx = mfi.growntilebox(nghost);
1846 auto const& fab = mf.const_array(mfi);
1847 AMREX_LOOP_3D(bx, i, j, k,
1848 {
1849 if (fab(i,j,k,comp) == value) {
1850 priv_loc = IntVect(AMREX_D_DECL(i,j,k));
1851 }
1852 });
1853 }
1854
1855 if (priv_loc.allGT(IntVect::TheMinVector())) {
1856 bool old;
1857// we should be able to test on _OPENMP < 201107 for capture (version 3.1)
1858// but we must work around a bug in gcc < 4.9
1859// And, with NVHPC 21.9 to <23.1, we saw an ICE with the atomic capture (NV bug: #3390723)
1860#if defined(AMREX_USE_OMP) && defined(_OPENMP) && (_OPENMP < 201307 || (defined(__NVCOMPILER) && __NVCOMPILER_MAJOR__ < 23)) // OpenMP 4.0
1861#pragma omp critical (amrex_indexfromvalue)
1862#elif defined(AMREX_USE_OMP)
1863#pragma omp atomic capture
1864#endif
1865 {
1866 old = f;
1867 f = true;
1868 }
1869
1870 if (old == false) { loc = priv_loc; }
1871 }
1872 }
1873 }
1874
1875 return loc;
1876}
1877
1889template <BaseFabType FAB>
1890typename FAB::value_type
1891Dot (FabArray<FAB> const& x, int xcomp, FabArray<FAB> const& y, int ycomp, int ncomp,
1892 IntVect const& nghost, bool local = false)
1893{
1894 BL_ASSERT(x.boxArray() == y.boxArray());
1895 BL_ASSERT(x.DistributionMap() == y.DistributionMap());
1896 BL_ASSERT(x.nGrowVect().allGE(nghost) && y.nGrowVect().allGE(nghost));
1897
1898 BL_PROFILE("amrex::Dot()");
1899
1900 using T = typename FAB::value_type;
1901 auto sm = T(0.0);
1902#ifdef AMREX_USE_GPU
1903 if (Gpu::inLaunchRegion()) {
1904 auto const& xma = x.const_arrays();
1905 auto const& yma = y.const_arrays();
1906 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, x, nghost,
1907 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<T>
1908 {
1909 auto t = T(0.0);
1910 auto const& xfab = xma[box_no];
1911 auto const& yfab = yma[box_no];
1912 for (int n = 0; n < ncomp; ++n) {
1913 t += xfab(i,j,k,xcomp+n) * yfab(i,j,k,ycomp+n);
1914 }
1915 return t;
1916 });
1917 } else
1918#endif
1919 {
1920#ifdef AMREX_USE_OMP
1921#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
1922#endif
1923 for (MFIter mfi(x,true); mfi.isValid(); ++mfi)
1924 {
1925 Box const& bx = mfi.growntilebox(nghost);
1926 auto const& xfab = x.const_array(mfi);
1927 auto const& yfab = y.const_array(mfi);
1928 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
1929 {
1930 sm += xfab(i,j,k,xcomp+n) * yfab(i,j,k,ycomp+n);
1931 });
1932 }
1933 }
1934
1935 if (!local) {
1937 }
1938
1939 return sm;
1940}
1941
1951template <BaseFabType FAB>
1952typename FAB::value_type
1953Dot (FabArray<FAB> const& x, int xcomp, int ncomp, IntVect const& nghost, bool local = false)
1954{
1955 BL_ASSERT(x.nGrowVect().allGE(nghost));
1956
1957 BL_PROFILE("amrex::Dot()");
1958
1959 using T = typename FAB::value_type;
1960 auto sm = T(0.0);
1961#ifdef AMREX_USE_GPU
1962 if (Gpu::inLaunchRegion()) {
1963 auto const& xma = x.const_arrays();
1964 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, x, nghost,
1965 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<T>
1966 {
1967 auto t = T(0.0);
1968 auto const& xfab = xma[box_no];
1969 for (int n = 0; n < ncomp; ++n) {
1970 auto v = xfab(i,j,k,xcomp+n);
1971 t += v*v;
1972 }
1973 return t;
1974 });
1975 } else
1976#endif
1977 {
1978#ifdef AMREX_USE_OMP
1979#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
1980#endif
1981 for (MFIter mfi(x,true); mfi.isValid(); ++mfi)
1982 {
1983 Box const& bx = mfi.growntilebox(nghost);
1984 auto const& xfab = x.const_array(mfi);
1985 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
1986 {
1987 auto v = xfab(i,j,k,xcomp+n);
1988 sm += v*v;
1989 });
1990 }
1991 }
1992
1993 if (!local) {
1995 }
1996
1997 return sm;
1998}
1999
2012template <BaseFabType IFAB, BaseFabType FAB>
2013typename FAB::value_type
2014Dot (FabArray<IFAB> const& mask, FabArray<FAB> const& x, int xcomp,
2015 FabArray<FAB> const& y, int ycomp, int ncomp, IntVect const& nghost,
2016 bool local = false)
2017{
2018 BL_ASSERT(x.boxArray() == y.boxArray() && x.boxArray() == mask.boxArray());
2019 BL_ASSERT(x.DistributionMap() == y.DistributionMap() && x.DistributionMap() == mask.DistributionMap());
2020 BL_ASSERT(x.nGrowVect().allGE(nghost) && y.nGrowVect().allGE(nghost) &&
2021 mask.nGrowVect().allGE(nghost));
2022
2023 BL_PROFILE("amrex::Dot()");
2024
2025 using T = typename FAB::value_type;
2026 auto sm = T(0.0);
2027#ifdef AMREX_USE_GPU
2028 if (Gpu::inLaunchRegion()) {
2029 auto const& mma = mask.const_arrays();
2030 auto const& xma = x.const_arrays();
2031 auto const& yma = y.const_arrays();
2032 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, x, nghost,
2033 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<T>
2034 {
2035 auto t = T(0.0);
2036 auto m = T(mma[box_no](i,j,k));
2037 if (m != 0) {
2038 auto const& xfab = xma[box_no];
2039 auto const& yfab = yma[box_no];
2040 for (int n = 0; n < ncomp; ++n) {
2041 t += xfab(i,j,k,xcomp+n) * yfab(i,j,k,ycomp+n);
2042 }
2043 }
2044 return t*m;
2045 });
2046 } else
2047#endif
2048 {
2049#ifdef AMREX_USE_OMP
2050#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
2051#endif
2052 for (MFIter mfi(x,true); mfi.isValid(); ++mfi)
2053 {
2054 Box const& bx = mfi.growntilebox(nghost);
2055 auto const& mfab = mask.const_array(mfi);
2056 auto const& xfab = x.const_array(mfi);
2057 auto const& yfab = y.const_array(mfi);
2058 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
2059 {
2060 auto m = T(mfab(i,j,k));
2061 sm += m * xfab(i,j,k,xcomp+n) * yfab(i,j,k,ycomp+n);
2062 });
2063 }
2064 }
2065
2066 if (!local) {
2068 }
2069
2070 return sm;
2071}
2072
2083template <BaseFabType IFAB, BaseFabType FAB>
2084typename FAB::value_type
2085Dot (FabArray<IFAB> const& mask, FabArray<FAB> const& x, int xcomp, int ncomp,
2086 IntVect const& nghost, bool local = false)
2087{
2088 BL_ASSERT(x.boxArray() == mask.boxArray());
2089 BL_ASSERT(x.DistributionMap() == mask.DistributionMap());
2090 BL_ASSERT(x.nGrowVect().allGE(nghost) && mask.nGrowVect().allGE(nghost));
2091
2092 BL_PROFILE("amrex::Dot()");
2093
2094 using T = typename FAB::value_type;
2095 auto sm = T(0.0);
2096#ifdef AMREX_USE_GPU
2097 if (Gpu::inLaunchRegion()) {
2098 auto const& mma = mask.const_arrays();
2099 auto const& xma = x.const_arrays();
2100 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, x, nghost,
2101 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<T>
2102 {
2103 auto t = T(0.0);
2104 auto m = T(mma[box_no](i,j,k));
2105 if (m != 0) {
2106 auto const& xfab = xma[box_no];
2107 for (int n = 0; n < ncomp; ++n) {
2108 auto v = xfab(i,j,k,xcomp+n);
2109 t += v*v;
2110 }
2111 }
2112 return t*m;
2113 });
2114 } else
2115#endif
2116 {
2117#ifdef AMREX_USE_OMP
2118#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
2119#endif
2120 for (MFIter mfi(x,true); mfi.isValid(); ++mfi)
2121 {
2122 Box const& bx = mfi.growntilebox(nghost);
2123 auto const& mfab = mask.const_array(mfi);
2124 auto const& xfab = x.const_array(mfi);
2125 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
2126 {
2127 auto m = T(mfab(i,j,k));
2128 auto v = xfab(i,j,k,xcomp+n);
2129 sm += m*v*v;
2130 });
2131 }
2132 }
2133
2134 if (!local) {
2136 }
2137
2138 return sm;
2139}
2140
2142template <MultiFabLike MF>
2143void setVal (MF& dst, typename MF::value_type val)
2144{
2145 dst.setVal(val);
2146}
2147
2149template <MultiFabLike MF>
2150void setBndry (MF& dst, typename MF::value_type val, int scomp, int ncomp)
2151{
2152 dst.setBndry(val, scomp, ncomp);
2153}
2154
2156template <MultiFabLike MF>
2157void Scale (MF& dst, typename MF::value_type val, int scomp, int ncomp, int nghost)
2158{
2159 dst.mult(val, scomp, ncomp, nghost);
2160}
2161
2163template <MultiFabLike DMF, MultiFabLike SMF>
2164void LocalCopy (DMF& dst, SMF const& src, int scomp, int dcomp,
2165 int ncomp, IntVect const& nghost)
2166{
2167 amrex::Copy(dst, src, scomp, dcomp, ncomp, nghost);
2168}
2169
2171template <MultiFabLike MF>
2172void LocalAdd (MF& dst, MF const& src, int scomp, int dcomp,
2173 int ncomp, IntVect const& nghost)
2174{
2175 amrex::Add(dst, src, scomp, dcomp, ncomp, nghost);
2176}
2177
2179template <MultiFabLike MF>
2180void Saxpy (MF& dst, typename MF::value_type a, MF const& src, int scomp, int dcomp,
2181 int ncomp, IntVect const& nghost)
2182{
2183 MF::Saxpy(dst, a, src, scomp, dcomp, ncomp, nghost);
2184}
2185
2187template <MultiFabLike MF>
2188void Xpay (MF& dst, typename MF::value_type a, MF const& src, int scomp, int dcomp,
2189 int ncomp, IntVect const& nghost)
2190{
2191 MF::Xpay(dst, a, src, scomp, dcomp, ncomp, nghost);
2192}
2193
2195template <MultiFabLike MF>
2196void Saxpy_Xpay (MF& dst, typename MF::value_type a_saxpy, MF const& src_saxpy,
2197 typename MF::value_type a_xpay, MF const& src_xpay, int scomp, int dcomp,
2198 int ncomp, IntVect const& nghost)
2199{
2200 MF::Saxpy_Xpay(dst, a_saxpy, src_saxpy, a_xpay, src_xpay, scomp, dcomp, ncomp, nghost);
2201}
2202
2204template <MultiFabLike MF>
2205void Saxpy_Saxpy (MF& dst1, typename MF::value_type a1, MF const& src1,
2206 MF& dst2, typename MF::value_type a2, MF const& src2, int scomp, int dcomp,
2207 int ncomp, IntVect const& nghost)
2208{
2209 MF::Saxpy_Saxpy(dst1, a1, src1, dst2, a2, src2, scomp, dcomp, ncomp, nghost);
2210}
2211
2213template <MultiFabLike MF>
2214void Saypy_Saxpy (MF& dst1, typename MF::value_type a1,
2215 MF& dst2, typename MF::value_type a2, MF const& src, int scomp, int dcomp,
2216 int ncomp, IntVect const& nghost)
2217{
2218 MF::Saypy_Saxpy(dst1, a1, dst2, a2, src, scomp, dcomp, ncomp, nghost);
2219}
2220
2222template <MultiFabLike MF>
2223void LinComb (MF& dst,
2224 typename MF::value_type a, MF const& src_a, int acomp,
2225 typename MF::value_type b, MF const& src_b, int bcomp,
2226 int dcomp, int ncomp, IntVect const& nghost)
2227{
2228 MF::LinComb(dst, a, src_a, acomp, b, src_b, bcomp, dcomp, ncomp, nghost);
2229}
2230
2232template <MultiFabLike MF>
2233void ParallelCopy (MF& dst, MF const& src, int scomp, int dcomp, int ncomp,
2234 IntVect const& ng_src = IntVect(0),
2235 IntVect const& ng_dst = IntVect(0),
2236 Periodicity const& period = Periodicity::NonPeriodic())
2237{
2238 dst.ParallelCopy(src, scomp, dcomp, ncomp, ng_src, ng_dst, period);
2239}
2240
2242template <MultiFabLike MF>
2243[[nodiscard]] typename MF::value_type
2244norminf (MF const& mf, int scomp, int ncomp, IntVect const& nghost,
2245 bool local = false)
2246{
2247 return mf.norminf(scomp, ncomp, nghost, local);
2248}
2249
2251template <MultiFabLike MF, std::size_t N>
2252void setVal (Array<MF,N>& dst, typename MF::value_type val)
2253{
2254 for (auto& mf: dst) {
2255 mf.setVal(val);
2256 }
2257}
2258
2260template <MultiFabLike MF, std::size_t N>
2261void setBndry (Array<MF,N>& dst, typename MF::value_type val, int scomp, int ncomp)
2262{
2263 for (auto& mf : dst) {
2264 mf.setBndry(val, scomp, ncomp);
2265 }
2266}
2267
2269template <MultiFabLike MF, std::size_t N>
2270void Scale (Array<MF,N>& dst, typename MF::value_type val, int scomp, int ncomp,
2271 int nghost)
2272{
2273 for (auto& mf : dst) {
2274 mf.mult(val, scomp, ncomp, nghost);
2275 }
2276}
2277
2279template <MultiFabLike DMF, MultiFabLike SMF, std::size_t N>
2280void LocalCopy (Array<DMF,N>& dst, Array<SMF,N> const& src, int scomp, int dcomp,
2281 int ncomp, IntVect const& nghost)
2282{
2283 for (std::size_t i = 0; i < N; ++i) {
2284 amrex::Copy(dst[i], src[i], scomp, dcomp, ncomp, nghost);
2285 }
2286}
2287
2289template <MultiFabLike MF, std::size_t N>
2290void LocalAdd (Array<MF,N>& dst, Array<MF,N> const& src, int scomp, int dcomp,
2291 int ncomp, IntVect const& nghost)
2292{
2293 for (std::size_t i = 0; i < N; ++i) {
2294 amrex::Add(dst[i], src[i], scomp, dcomp, ncomp, nghost);
2295 }
2296}
2297
2299template <MultiFabLike MF, std::size_t N>
2300void Saxpy (Array<MF,N>& dst, typename MF::value_type a,
2301 Array<MF,N> const& src, int scomp, int dcomp, int ncomp,
2302 IntVect const& nghost)
2303{
2304 for (std::size_t i = 0; i < N; ++i) {
2305 MF::Saxpy(dst[i], a, src[i], scomp, dcomp, ncomp, nghost);
2306 }
2307}
2308
2310template <MultiFabLike MF, std::size_t N>
2311void Xpay (Array<MF,N>& dst, typename MF::value_type a,
2312 Array<MF,N> const& src, int scomp, int dcomp, int ncomp,
2313 IntVect const& nghost)
2314{
2315 for (std::size_t i = 0; i < N; ++i) {
2316 MF::Xpay(dst[i], a, src[i], scomp, dcomp, ncomp, nghost);
2317 }
2318}
2319
2321template <MultiFabLike MF, std::size_t N>
2323 typename MF::value_type a, Array<MF,N> const& src_a, int acomp,
2324 typename MF::value_type b, Array<MF,N> const& src_b, int bcomp,
2325 int dcomp, int ncomp, IntVect const& nghost)
2326{
2327 for (std::size_t i = 0; i < N; ++i) {
2328 MF::LinComb(dst[i], a, src_a[i], acomp, b, src_b[i], bcomp, dcomp, ncomp, nghost);
2329 }
2330}
2331
2333template <MultiFabLike MF, std::size_t N>
2334void ParallelCopy (Array<MF,N>& dst, Array<MF,N> const& src,
2335 int scomp, int dcomp, int ncomp,
2336 IntVect const& ng_src = IntVect(0),
2337 IntVect const& ng_dst = IntVect(0),
2338 Periodicity const& period = Periodicity::NonPeriodic())
2339{
2340 for (std::size_t i = 0; i < N; ++i) {
2341 dst[i].ParallelCopy(src[i], scomp, dcomp, ncomp, ng_src, ng_dst, period);
2342 }
2343}
2344
2346template <MultiFabLike MF, std::size_t N>
2347[[nodiscard]] typename MF::value_type
2348norminf (Array<MF,N> const& mf, int scomp, int ncomp, IntVect const& nghost,
2349 bool local = false)
2350{
2351 auto r = typename MF::value_type(0);
2352 for (std::size_t i = 0; i < N; ++i) {
2353 auto tmp = mf[i].norminf(scomp, ncomp, nghost, true);
2354 r = std::max(r,tmp);
2355 }
2356 if (!local) {
2358 }
2359 return r;
2360}
2361
2363template <MultiFabLike MF, std::size_t N>
2364requires (N > 0)
2365[[nodiscard]] int nComp (Array<MF,N> const& mf)
2366{
2367 return mf[0].nComp();
2368}
2369
2371template <MultiFabLike MF, std::size_t N>
2372requires (N > 0)
2373[[nodiscard]] IntVect nGrowVect (Array<MF,N> const& mf)
2374{
2375 return mf[0].nGrowVect();
2376}
2377
2379template <MultiFabLike MF, std::size_t N>
2380requires (N > 0)
2381[[nodiscard]] BoxArray const&
2383{
2384 return mf[0].boxArray();
2385}
2386
2388template <MultiFabLike MF, std::size_t N>
2389requires (N > 0)
2390[[nodiscard]] DistributionMapping const&
2392{
2393 return mf[0].DistributionMap();
2394}
2395
2403template <class FAB>
2404FabArray<BaseFab<int>>
2405OverlapMask (FabArray<FAB> const& fa, IntVect const& nghost, Periodicity const& period)
2406{
2407 BL_PROFILE("OverlapMask()");
2408
2409 const BoxArray& ba = fa.boxArray();
2410 const DistributionMapping& dm = fa.DistributionMap();
2411
2412 FabArray<BaseFab<int>> mask(ba, dm, 1, nghost);
2413 mask.setVal(1);
2414
2415 const std::vector<IntVect>& pshifts = period.shiftIntVect();
2416
2418
2419 bool run_on_gpu = Gpu::inLaunchRegion();
2420 amrex::ignore_unused(run_on_gpu, tags);
2421#ifdef AMREX_USE_OMP
2422#pragma omp parallel if (!run_on_gpu)
2423#endif
2424 {
2425 std::vector< std::pair<int,Box> > isects;
2426
2427 for (MFIter mfi(mask); mfi.isValid(); ++mfi)
2428 {
2429 const Box& bx = mask[mfi].box();
2430 auto const& arr = mask.array(mfi);
2431
2432 for (const auto& iv : pshifts)
2433 {
2434 ba.intersections(bx+iv, isects, false, nghost);
2435 for (const auto& is : isects)
2436 {
2437 Box const& b = is.second-iv;
2438 if (iv == 0 && b == bx) { continue; }
2439#ifdef AMREX_USE_GPU
2440 if (run_on_gpu) {
2441 tags.push_back(Array4BoxTag<int>{.dfab = arr, .dbox = b});
2442 } else
2443#endif
2444 {
2445 amrex::LoopConcurrentOnCpu(b, [=] (int i, int j, int k) noexcept
2446 {
2447 arr(i,j,k) += 1;
2448 });
2449 }
2450 }
2451 }
2452 }
2453 }
2454
2455#ifdef AMREX_USE_GPU
2456 amrex::ParallelFor(tags, 1,
2457 [=] AMREX_GPU_DEVICE (int i, int j, int k, int n, Array4BoxTag<int> const& tag) noexcept
2458 {
2459 Gpu::Atomic::AddNoRet(tag.dfab.ptr(i,j,k,n), 1);
2460 });
2461#endif
2462
2463 return mask;
2464}
2465
2466}
2467
2468#endif
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#define BL_ASSERT(EX)
Definition AMReX_BLassert.H:39
#define AMREX_ASSERT_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:37
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
Distributed container of FAB objects plus copy and fill utilities.
#define AMREX_HOST_DEVICE_PARALLEL_FOR_4D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:111
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
Real * pdst
Definition AMReX_HypreMLABecLap.cpp:1130
Array4< int const > mask
Definition AMReX_InterpFaceRegister.cpp:93
#define AMREX_LOOP_3D(bx, i, j, k, block)
Definition AMReX_Loop.nolint.H:4
#define AMREX_LOOP_4D(bx, ncomp, i, j, k, n, block)
Definition AMReX_Loop.nolint.H:16
#define AMREX_D_TERM(a, b, c)
Definition AMReX_SPACE.H:172
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
Print on all processors of the default communicator.
Definition AMReX_Print.H:113
virtual bool isManaged() const
Check whether it is managed GPU memory.
Definition AMReX_Arena.cpp:88
virtual bool isDevice() const
Check whether it is non-managed GPU device memory.
Definition AMReX_Arena.cpp:100
Reference-counted collection of Boxes.
Definition AMReX_BoxArray.H:676
std::vector< std::pair< int, Box > > intersections(const Box &bx) const
Return all intersections of bx with this BoxArray.
Definition AMReX_BoxArray.cpp:1186
__host__ __device__ bool contains(const IntVectND< dim > &p) const noexcept
Return true if argument is contained within BoxND.
Definition AMReX_Box.H:233
__host__ __device__ bool ok() const noexcept
Return true if high bounds are >= low bounds and the index type is valid.
Definition AMReX_Box.H:229
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:51
IntVect nGrowVect() const noexcept
Definition AMReX_FabArrayBase.H:85
bool isFusingCandidate() const noexcept
Is this a good candidate for kernel fusing?
Definition AMReX_FabArrayBase.cpp:2705
IndexType ixType() const noexcept
Return index type.
Definition AMReX_FabArrayBase.H:91
const DistributionMapping & DistributionMap() const noexcept
Return constant reference to associated DistributionMapping.
Definition AMReX_FabArrayBase.H:135
@ ADD
Definition AMReX_FabArrayBase.H:411
int nComp() const noexcept
Return number of variables (aka components) associated with each point.
Definition AMReX_FabArrayBase.H:88
const BoxArray & boxArray() const noexcept
Return a constant reference to the BoxArray that defines the valid region associated with this FabArr...
Definition AMReX_FabArrayBase.H:100
An Array of FortranArrayBox(FAB)-like Objects.
Definition AMReX_FabArray.H:356
void mult(value_type val, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:3213
void setBndry(value_type val)
Set all values in the boundary region to val.
Definition AMReX_FabArray.H:2732
std::unique_ptr< FabArray< FAB > > os_temp
Definition AMReX_FabArray.H:1906
const FabFactory< FAB > & Factory() const noexcept
Factory used to create FAB instances for this FabArray.
Definition AMReX_FabArray.H:471
void prefetchToHost(const MFIter &mfi) const noexcept
Request that the FAB selected by iterator mfi be prefetched to host memory, where supported.
Definition AMReX_FabArray.H:592
MultiArray4< typename FabArray< FAB >::value_type > arrays() noexcept
Build, if needed, and return mutable Array4 views for local FABs.
Definition AMReX_FabArray.H:713
void prefetchToDevice(const MFIter &mfi) const noexcept
Request that the FAB selected by iterator mfi be prefetched to device memory, where supported.
Definition AMReX_FabArray.H:608
Arena * arena() const noexcept
Arena configured for allocations by this FabArray.
Definition AMReX_FabArray.H:480
MultiArray4< typename FabArray< FAB >::value_type const > const_arrays() const noexcept
Read-only convenience wrapper equivalent to arrays() const.
Definition AMReX_FabArray.H:731
void setVal(value_type val)
Set all components in the entire region of each FAB to val.
Definition AMReX_FabArray.H:2950
Array4< typename FabArray< FAB >::value_type const > array(const MFIter &mfi) const noexcept
Read-only Array4 view for the FAB referenced by iterator mfi.
Definition AMReX_FabArray.H:621
bool hasEBFabFactory() const noexcept
Return whether this FabArray uses an EBFArrayBoxFactory.
Definition AMReX_FabArray.H:493
Array4< typename FabArray< FAB >::value_type const > const_array(const MFIter &mfi) const noexcept
Synonym for array(const MFIter&) that highlights read-only semantics.
Definition AMReX_FabArray.H:649
GPU-compatible tuple.
Definition AMReX_Tuple.H:98
Definition AMReX_GpuBuffer.H:24
T const * data() const noexcept
Definition AMReX_GpuBuffer.H:51
__host__ __device__ bool cellCentered() const noexcept
True if the IndexTypeND is CELL based in all directions.
Definition AMReX_IndexType.H:102
__host__ __device__ constexpr bool allGT(const IntVectND< dim > &rhs) const noexcept
Returns true if this is greater than argument for all components. NOTE: This is NOT a strict weak ord...
Definition AMReX_IntVect.H:517
__host__ static __device__ constexpr IntVectND< dim > TheZeroVector() noexcept
This static member function returns a reference to a constant IntVectND object, all of whose dim argu...
Definition AMReX_IntVect.H:771
__host__ static __device__ constexpr IntVectND< dim > TheMinVector() noexcept
Definition AMReX_IntVect.H:819
Iterator for looping ever tiles and boxes of amrex::FabArray based containers.
Definition AMReX_MFIter.H:88
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:172
Dynamically allocated vector for trivially copyable data.
Definition AMReX_PODVector.H:308
T * data() noexcept
Definition AMReX_PODVector.H:666
This provides length of period for periodic domains. 0 means it is not periodic in that direction....
Definition AMReX_Periodicity.H:17
static const Periodicity & NonPeriodic() noexcept
Definition AMReX_Periodicity.cpp:52
std::vector< IntVect > shiftIntVect(IntVect const &nghost=IntVect(0)) const
Definition AMReX_Periodicity.cpp:8
Print & SetPrecision(int p)
Definition AMReX_Print.H:86
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:29
__host__ __device__ BoxND< dim > makeSingleCellBox(int i, int j, int k, IndexTypeND< dim > typ=IndexTypeND< dim >::TheCellType())
Create a single-cell box at coordinates (i,j,k).
Definition AMReX_Box.H:2458
__host__ __device__ BoxND< dim > grow(const BoxND< dim > &b, int i) noexcept
Return a copy of b grown uniformly by i cells in every direction.
Definition AMReX_Box.H:1326
std::array< T, N > Array
Definition AMReX_Array.H:31
void Sum(Gpu::DeviceVector< T > &v, MPI_Comm comm)
Definition AMReX_GpuParallelReduce.H:34
void Max(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:133
__host__ __device__ void Swap(T &t1, T &t2) noexcept
Definition AMReX_Algorithm.H:108
__host__ __device__ AMREX_FORCE_INLINE T Exch(T *address, T val) noexcept
Definition AMReX_GpuAtomic.H:487
__host__ __device__ AMREX_FORCE_INLINE void AddNoRet(T *sum, T value) noexcept
Definition AMReX_GpuAtomic.H:283
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:310
void dtoh_memcpy_async(void *p_h, const void *p_d, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:435
bool inLaunchRegion() noexcept
Definition AMReX_GpuControl.H:88
bool inNoSyncRegion() noexcept
Definition AMReX_GpuControl.H:148
void htod_memcpy_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:421
MPI_Comm CommunicatorSub() noexcept
sub-communicator for current frame
Definition AMReX_ParallelContext.H:70
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 Copy(FabArray< DFAB > &dst, FabArray< SFAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Definition AMReX_FabArray.H:192
void htod_memcpy(FabArray< FAB > &dst, FabArray< FAB > const &src, int scomp, int dcomp, int ncomp)
Copy selected components of each local FAB, ghost cells included, host-to-device.
Definition AMReX_FabArrayUtility.H:1749
void OverrideSync_nowait(FabArray< FAB > &fa, FabArray< IFAB > const &msk, const Periodicity &period)
Start the masked OverrideSync operation; call OverrideSync_finish() to complete it.
Definition AMReX_FabArrayUtility.H:1659
void Add(FabArray< FAB > &dst, FabArray< FAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Definition AMReX_FabArray.H:251
ReduceData< Ts... >::Type ParReduce(TypeList< Ops... > operation_list, TypeList< Ts... > type_list, FabArray< FAB > const &fa, IntVect const &nghost, F &&f)
Parallel reduce for MultiFab/FabArray. The reduce result is local and it's the user's responsibility ...
Definition AMReX_ParReduce.H:48
void Scale(MF &dst, typename MF::value_type val, int scomp, int ncomp, int nghost)
dst *= val
Definition AMReX_FabArrayUtility.H:2157
BoxArray const & boxArray(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.boxArray().
Definition AMReX_FabArrayBase.cpp:2862
DistributionMapping const & DistributionMap(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.DistributionMap().
Definition AMReX_FabArrayBase.cpp:2867
FAB::value_type Dot(FabArray< FAB > const &x, int xcomp, FabArray< FAB > const &y, int ycomp, int ncomp, IntVect const &nghost, bool local=false)
Compute dot products of two FabArrays.
Definition AMReX_FabArrayUtility.H:1891
void Saxpy_Xpay(MF &dst, typename MF::value_type a_saxpy, MF const &src_saxpy, typename MF::value_type a_xpay, MF const &src_xpay, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst += a_saxpy * src_saxpy followed by dst = src_xpay + a_xpay * dst
Definition AMReX_FabArrayUtility.H:2196
void prefetchToDevice(FabArray< FAB > const &fa, const bool synchronous=true)
Request that managed-memory FAB data be prefetched to the device, where supported.
Definition AMReX_FabArrayUtility.H:1625
FAB::value_type ReduceMin(FabArray< FAB > const &fa, int nghost, F &&f)
Compute the rank-local minimum of a functor, including nghost cells.
Definition AMReX_FabArrayUtility.H:399
void ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:202
FabArray< BaseFab< int > > OverlapMask(FabArray< FAB > const &fa, IntVect const &nghost, Periodicity const &period)
Return the number of overlapping grown FAB regions at each point.
Definition AMReX_FabArrayUtility.H:2405
void prefetchToHost(FabArray< FAB > const &fa, const bool synchronous=true)
Request that managed-memory FAB data be prefetched to the host, where supported.
Definition AMReX_FabArrayUtility.H:1603
bool isMFIterSafe(const FabArrayBase &x, const FabArrayBase &y)
Definition AMReX_MFIter.H:252
int nComp(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.nComp().
Definition AMReX_FabArrayBase.cpp:2852
void Saxpy_Saxpy(MF &dst1, typename MF::value_type a1, MF const &src1, MF &dst2, typename MF::value_type a2, MF const &src2, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst1 += a1 * src1 followed by dst2 += a2 * src2
Definition AMReX_FabArrayUtility.H:2205
IntVect indexFromValue(FabArray< FAB > const &mf, int comp, IntVect const &nghost, typename FAB::value_type value)
Return the index of an arbitrary cell at which component comp equals value.
Definition AMReX_FabArrayUtility.H:1783
void LinComb(MF &dst, typename MF::value_type a, MF const &src_a, int acomp, typename MF::value_type b, MF const &src_b, int bcomp, int dcomp, int ncomp, IntVect const &nghost)
dst = a*src_a + b*src_b
Definition AMReX_FabArrayUtility.H:2223
void ParallelCopy(MF &dst, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &ng_src=IntVect(0), IntVect const &ng_dst=IntVect(0), Periodicity const &period=Periodicity::NonPeriodic())
dst = src w/ MPI communication
Definition AMReX_FabArrayUtility.H:2233
void Saypy_Saxpy(MF &dst1, typename MF::value_type a1, MF &dst2, typename MF::value_type a2, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst1 += a1 * dst2 followed by dst2 += a2 * src
Definition AMReX_FabArrayUtility.H:2214
void Multiply(FabArray< FAB > &dst, FabArray< FAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Apply dst(dstcomp+n) *= src(srccomp+n) using a uniform ghost width.
Definition AMReX_FabArrayUtility.H:1457
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
void Abs(FabArray< FAB > &fa, int icomp, int numcomp, int nghost)
Replace selected components by their absolute values using a uniform ghost width.
Definition AMReX_FabArrayUtility.H:1552
void OverrideSync_finish(FabArray< FAB > &fa)
Finish the current masked OverrideSync_nowait() operation.
Definition AMReX_FabArrayUtility.H:1707
void single_task(L &&f) noexcept
Definition AMReX_GpuLaunchFunctsC.H:1239
void dtoh_memcpy(FabArray< FAB > &dst, FabArray< FAB > const &src, int scomp, int dcomp, int ncomp)
Copy selected components of each local FAB, ghost cells included, device-to-host.
Definition AMReX_FabArrayUtility.H:1722
IntVect nGrowVect(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.nGrowVect().
Definition AMReX_FabArrayBase.cpp:2857
void LocalCopy(DMF &dst, SMF const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst = src
Definition AMReX_FabArrayUtility.H:2164
bool TilingIfNotGPU() noexcept
Definition AMReX_MFIter.H:12
void setBndry(MF &dst, typename MF::value_type val, int scomp, int ncomp)
dst = val in ghost cells.
Definition AMReX_FabArrayUtility.H:2150
void printCell(FabArray< FAB > const &mf, const IntVect &cell, int comp=-1, const IntVect &ng=IntVect::TheZeroVector())
Print the value(s) stored at a specific cell of a FabArray.
Definition AMReX_FabArrayUtility.H:1271
MF::value_type norminf(MF const &mf, int scomp, int ncomp, IntVect const &nghost, bool local=false)
Return the infinity norm, with an MPI maximum unless local is true.
Definition AMReX_FabArrayUtility.H:2244
bool ReduceLogicalOr(FabArray< FAB > const &fa, int nghost, F &&f)
Return the logical OR of predicate results over locally owned data.
Definition AMReX_FabArrayUtility.H:1101
void LoopConcurrentOnCpu(Dim3 lo, Dim3 hi, F const &f) noexcept
Definition AMReX_Loop.H:388
void Xpay(MF &dst, typename MF::value_type a, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst = src + a * dst
Definition AMReX_FabArrayUtility.H:2188
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:241
const int[]
Definition AMReX_BLProfiler.cpp:1664
void OverrideSync(FabArray< FAB > &fa, FabArray< IFAB > const &msk, const Periodicity &period)
Synchronize shared nodal values using an owner mask.
Definition AMReX_FabArrayUtility.H:1647
void Divide(FabArray< FAB > &dst, FabArray< FAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Apply dst(dstcomp+n) /= src(srccomp+n) using a uniform ghost width.
Definition AMReX_FabArrayUtility.H:1505
bool ReduceLogicalAnd(FabArray< FAB > const &fa, int nghost, F &&f)
Return the logical AND of predicate results over locally owned data.
Definition AMReX_FabArrayUtility.H:932
FAB::value_type ReduceMax(FabArray< FAB > const &fa, int nghost, F &&f)
Compute the rank-local maximum of a functor, including nghost cells.
Definition AMReX_FabArrayUtility.H:674
void Subtract(FabArray< FAB > &dst, FabArray< FAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Apply dst(dstcomp+n) -= src(srccomp+n) using a uniform ghost width.
Definition AMReX_FabArrayUtility.H:1409
void Saxpy(MF &dst, typename MF::value_type a, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst += a * src
Definition AMReX_FabArrayUtility.H:2180
void LocalAdd(MF &dst, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst += src
Definition AMReX_FabArrayUtility.H:2172
FAB::value_type ReduceSum(FabArray< FAB > const &fa, int nghost, F &&f)
Sum a user-defined quantity over locally owned data, including nghost cells.
Definition AMReX_FabArrayUtility.H:33
void setVal(MF &dst, typename MF::value_type val)
dst = val
Definition AMReX_FabArrayUtility.H:2143
Definition AMReX_TagParallelFor.H:58
Array4< T > dfab
Definition AMReX_TagParallelFor.H:59
Definition AMReX_TypeTraits.H:94
FabArray memory allocation information.
Definition AMReX_FabArray.H:73
Definition AMReX_MFIter.H:20
Struct for holding types.
Definition AMReX_TypeList.H:13