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_wrapper (FabArray<FAB> const& fa, IntVect const& nghost, F&& f)
1142{
1143 amrex::ignore_unused(fa,nghost,f);
1144 amrex::Abort("ReduceLogicalOr: Launch Region is off. Device lambda cannot be called by host.");
1145 return false;
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 && numcomp == src.nComp() &&
1358 src.nComp() == dst.nComp() &&
1359 src.nGrowVect() == nghost && src.nGrowVect() == dst.nGrowVect() &&
1360 src.arena() == dst.arena() && src.hasEBFabFactory() == dst.hasEBFabFactory()) {
1361 explicit_swap = false;
1362 }
1363
1364 if (!explicit_swap) {
1365
1366 std::swap(dst, src);
1367
1368 } else {
1369#ifdef AMREX_USE_GPU
1370 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
1371 auto const& dstma = dst.arrays();
1372 auto const& srcma = src.arrays();
1373 ParallelFor(dst, nghost, numcomp,
1374 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
1375 {
1376 const auto tmp = dstma[box_no](i,j,k,n+dstcomp);
1377 dstma[box_no](i,j,k,n+dstcomp) = srcma[box_no](i,j,k,n+srccomp);
1378 srcma[box_no](i,j,k,n+srccomp) = tmp;
1379 });
1380 if (!Gpu::inNoSyncRegion()) {
1382 }
1383 } else
1384#endif
1385 {
1386#ifdef AMREX_USE_OMP
1387#pragma omp parallel if (Gpu::notInLaunchRegion())
1388#endif
1389 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
1390 {
1391 const Box& bx = mfi.growntilebox(nghost);
1392 if (bx.ok()) {
1393 auto sfab = src.array(mfi);
1394 auto dfab = dst.array(mfi);
1395 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
1396 {
1397 const auto tmp = dfab(i,j,k,n+dstcomp);
1398 dfab(i,j,k,n+dstcomp) = sfab(i,j,k,n+srccomp);
1399 sfab(i,j,k,n+srccomp) = tmp;
1400 });
1401 }
1402 }
1403 }
1404 }
1405}
1406
1408template <BaseFabType FAB>
1409void
1410Subtract (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
1411{
1412 Subtract(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
1413}
1414
1416template <BaseFabType FAB>
1417void
1418Subtract (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
1419{
1420#ifdef AMREX_USE_GPU
1421 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
1422 auto const& dstfa = dst.arrays();
1423 auto const& srcfa = src.const_arrays();
1424 ParallelFor(dst, nghost, numcomp,
1425 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
1426 {
1427 dstfa[box_no](i,j,k,n+dstcomp) -= srcfa[box_no](i,j,k,n+srccomp);
1428 });
1429 if (!Gpu::inNoSyncRegion()) {
1431 }
1432 } else
1433#endif
1434 {
1435#ifdef AMREX_USE_OMP
1436#pragma omp parallel if (Gpu::notInLaunchRegion())
1437#endif
1438 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
1439 {
1440 const Box& bx = mfi.growntilebox(nghost);
1441 if (bx.ok())
1442 {
1443 auto const srcFab = src.array(mfi);
1444 auto dstFab = dst.array(mfi);
1445 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
1446 {
1447 dstFab(i,j,k,n+dstcomp) -= srcFab(i,j,k,n+srccomp);
1448 });
1449 }
1450 }
1451 }
1452}
1453
1454
1456template <BaseFabType FAB>
1457void
1458Multiply (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
1459{
1460 Multiply(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
1461}
1462
1464template <BaseFabType FAB>
1465void
1466Multiply (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
1467{
1468#ifdef AMREX_USE_GPU
1469 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
1470 auto const& dstfa = dst.arrays();
1471 auto const& srcfa = src.const_arrays();
1472 ParallelFor(dst, nghost, numcomp,
1473 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
1474 {
1475 dstfa[box_no](i,j,k,n+dstcomp) *= srcfa[box_no](i,j,k,n+srccomp);
1476 });
1477 if (!Gpu::inNoSyncRegion()) {
1479 }
1480 } else
1481#endif
1482 {
1483#ifdef AMREX_USE_OMP
1484#pragma omp parallel if (Gpu::notInLaunchRegion())
1485#endif
1486 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
1487 {
1488 const Box& bx = mfi.growntilebox(nghost);
1489 if (bx.ok())
1490 {
1491 auto const srcFab = src.array(mfi);
1492 auto dstFab = dst.array(mfi);
1493 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
1494 {
1495 dstFab(i,j,k,n+dstcomp) *= srcFab(i,j,k,n+srccomp);
1496 });
1497 }
1498 }
1499 }
1500}
1501
1502
1504template <BaseFabType FAB>
1505void
1506Divide (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
1507{
1508 Divide(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
1509}
1510
1512template <BaseFabType FAB>
1513void
1514Divide (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
1515{
1516#ifdef AMREX_USE_GPU
1517 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
1518 auto const& dstfa = dst.arrays();
1519 auto const& srcfa = src.const_arrays();
1520 ParallelFor(dst, nghost, numcomp,
1521 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
1522 {
1523 dstfa[box_no](i,j,k,n+dstcomp) /= srcfa[box_no](i,j,k,n+srccomp);
1524 });
1525 if (!Gpu::inNoSyncRegion()) {
1527 }
1528 } else
1529#endif
1530 {
1531#ifdef AMREX_USE_OMP
1532#pragma omp parallel if (Gpu::notInLaunchRegion())
1533#endif
1534 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
1535 {
1536 const Box& bx = mfi.growntilebox(nghost);
1537 if (bx.ok())
1538 {
1539 auto const srcFab = src.array(mfi);
1540 auto dstFab = dst.array(mfi);
1541 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
1542 {
1543 dstFab(i,j,k,n+dstcomp) /= srcFab(i,j,k,n+srccomp);
1544 });
1545 }
1546 }
1547 }
1548}
1549
1551template <BaseFabType FAB>
1552void
1553Abs (FabArray<FAB>& fa, int icomp, int numcomp, int nghost)
1554{
1555 Abs(fa,icomp,numcomp,IntVect(nghost));
1556}
1557
1559template <BaseFabType FAB>
1560void
1561Abs (FabArray<FAB>& fa, int icomp, int numcomp, const IntVect& nghost)
1562{
1563#ifdef AMREX_USE_GPU
1564 if (Gpu::inLaunchRegion() && fa.isFusingCandidate()) {
1565 auto const& fabarr = fa.arrays();
1566 ParallelFor(fa, nghost, numcomp,
1567 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
1568 {
1569 fabarr[box_no](i,j,k,n+icomp) = std::abs(fabarr[box_no](i,j,k,n+icomp));
1570 });
1571 if (!Gpu::inNoSyncRegion()) {
1573 }
1574 } else
1575#endif
1576 {
1577#ifdef AMREX_USE_OMP
1578#pragma omp parallel if (Gpu::notInLaunchRegion())
1579#endif
1580 for (MFIter mfi(fa,TilingIfNotGPU()); mfi.isValid(); ++mfi)
1581 {
1582 const Box& bx = mfi.growntilebox(nghost);
1583 if (bx.ok())
1584 {
1585 auto const& fab = fa.array(mfi);
1586 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
1587 {
1588 fab(i,j,k,n+icomp) = std::abs(fab(i,j,k,n+icomp));
1589 });
1590 }
1591 }
1592 }
1593}
1594
1602template <BaseFabType FAB>
1603void
1604prefetchToHost (FabArray<FAB> const& fa, const bool synchronous = true)
1605{
1606#ifdef AMREX_USE_GPU
1607 if (fa.arena()->isManaged()) {
1608 for (MFIter mfi(fa, MFItInfo().SetDeviceSync(synchronous)); mfi.isValid(); ++mfi) {
1609 fa.prefetchToHost(mfi);
1610 }
1611 }
1612#else
1613 amrex::ignore_unused(fa,synchronous);
1614#endif
1615}
1616
1624template <BaseFabType FAB>
1625void
1626prefetchToDevice (FabArray<FAB> const& fa, const bool synchronous = true)
1627{
1628#ifdef AMREX_USE_GPU
1629 if (fa.arena()->isManaged()) {
1630 for (MFIter mfi(fa, MFItInfo().SetDeviceSync(synchronous)); mfi.isValid(); ++mfi) {
1631 fa.prefetchToDevice(mfi);
1632 }
1633 }
1634#else
1635 amrex::ignore_unused(fa,synchronous);
1636#endif
1637}
1638
1639
1646template <BaseFabType FAB, BaseFabType IFAB>
1647void
1648OverrideSync (FabArray<FAB> & fa, FabArray<IFAB> const& msk, const Periodicity& period)
1649{
1650 BL_PROFILE("OverrideSync()");
1651
1652 OverrideSync_nowait(fa, msk, period);
1654}
1655
1656
1658template <BaseFabType FAB, BaseFabType IFAB>
1659void
1661{
1662 BL_PROFILE("OverrideSync_nowait()");
1663 AMREX_ASSERT_WITH_MESSAGE(!fa.os_temp, "OverrideSync_nowait() called when already in progress.");
1664
1665 if (fa.ixType().cellCentered()) { return; }
1666
1667 const int ncomp = fa.nComp();
1668
1669#ifdef AMREX_USE_GPU
1670 if (Gpu::inLaunchRegion() && fa.isFusingCandidate()) {
1671 auto const& fabarr = fa.arrays();
1672 auto const& ifabarr = msk.const_arrays();
1673 ParallelFor(fa, IntVect(0), ncomp,
1674 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
1675 {
1676 if (!ifabarr[box_no](i,j,k)) { fabarr[box_no](i,j,k,n) = 0; }
1677 });
1678 if (!Gpu::inNoSyncRegion()) {
1680 }
1681 } else
1682#endif
1683 {
1684#ifdef AMREX_USE_OMP
1685#pragma omp parallel if (Gpu::notInLaunchRegion())
1686#endif
1687 for (MFIter mfi(fa,TilingIfNotGPU()); mfi.isValid(); ++mfi)
1688 {
1689 const Box& bx = mfi.tilebox();
1690 auto fab = fa.array(mfi);
1691 auto const ifab = msk.array(mfi);
1692 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
1693 {
1694 if (!ifab(i,j,k)) { fab(i,j,k,n) = 0; }
1695 });
1696 }
1697 }
1698
1699 fa.os_temp = std::make_unique< FabArray<FAB> > ( fa.boxArray(), fa.DistributionMap(),
1700 ncomp, 0,
1702 fa.Factory() );
1703 fa.os_temp->setVal(0);
1704 fa.os_temp->ParallelCopy_nowait(fa, period, FabArrayBase::ADD);
1705}
1706
1708template <BaseFabType FAB>
1709void
1711{
1712 BL_PROFILE("OverrideSync_finish()");
1713
1714 if (fa.ixType().cellCentered()) { return; }
1715
1716 fa.os_temp->ParallelCopy_finish();
1717 amrex::Copy(fa, *(fa.os_temp), 0, 0, fa.nComp(), 0);
1718
1719 fa.os_temp.reset();
1720}
1721
1723template <BaseFabType FAB>
1724void
1726 int scomp, int dcomp, int ncomp)
1727{
1728 AMREX_ASSERT(isMFIterSafe(dst, src));
1729 AMREX_ASSERT(dst.nGrowVect() == src.nGrowVect());
1730#ifdef AMREX_USE_GPU
1731 for (MFIter mfi(dst); mfi.isValid(); ++mfi) {
1732 void* pdst = dst[mfi].dataPtr(dcomp);
1733 void const* psrc = src[mfi].dataPtr(scomp);
1734 Gpu::dtoh_memcpy_async(pdst, psrc, dst[mfi].nBytes(mfi.fabbox(), ncomp));
1735 }
1736#else
1737 Copy(dst, src, scomp, dcomp, ncomp, dst.nGrowVect());
1738#endif
1739}
1740
1742template <BaseFabType FAB>
1743void
1745{
1746 dtoh_memcpy(dst, src, 0, 0, dst.nComp());
1747}
1748
1750template <BaseFabType FAB>
1751void
1753 int scomp, int dcomp, int ncomp)
1754{
1755 AMREX_ASSERT(isMFIterSafe(dst, src));
1756 AMREX_ASSERT(dst.nGrowVect() == src.nGrowVect());
1757#ifdef AMREX_USE_GPU
1758 for (MFIter mfi(dst); mfi.isValid(); ++mfi) {
1759 void* pdst = dst[mfi].dataPtr(dcomp);
1760 void const* psrc = src[mfi].dataPtr(scomp);
1761 Gpu::htod_memcpy_async(pdst, psrc, dst[mfi].nBytes(mfi.fabbox(), ncomp));
1762 }
1763#else
1764 Copy(dst, src, scomp, dcomp, ncomp, dst.nGrowVect());
1765#endif
1766}
1767
1769template <BaseFabType FAB>
1770void
1772{
1773 htod_memcpy(dst, src, 0, 0, dst.nComp());
1774}
1775
1783template <BaseFabType FAB>
1784IntVect
1785indexFromValue (FabArray<FAB> const& mf, int comp, IntVect const& nghost,
1786 typename FAB::value_type value)
1787{
1789
1790#ifdef AMREX_USE_GPU
1791 if (Gpu::inLaunchRegion())
1792 {
1793 constexpr int nofind = std::numeric_limits<int>::lowest();
1794 amrex::Gpu::Buffer<int> aa({0,AMREX_D_DECL(nofind,nofind,nofind)});
1795 int* p = aa.data();
1796 // This is a device ptr to 1+AMREX_SPACEDIM ints. The first is zero
1797 // and used as an atomic bool. The others hold the intvect and start
1798 // at the lowest int so that they stay TheMinVector if there is no
1799 // match.
1800 if (mf.isFusingCandidate()) {
1801 auto const& ma = mf.const_arrays();
1802 ParallelFor(mf, nghost, [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
1803 {
1804 int* flag = p;
1805 if (*flag == 0) {
1806 if (ma[box_no](i,j,k,comp) == value) {
1807 if (Gpu::Atomic::Exch(flag,1) == 0) {
1808 AMREX_D_TERM(p[1] = i;,
1809 p[2] = j;,
1810 p[3] = k;);
1811 }
1812 }
1813 }
1814 });
1815 } else {
1816 // The result is read on the host below, so the streams used by
1817 // MFIter must be synchronized even inside a NoSyncRegion.
1818 for (MFIter mfi(mf,MFItInfo().SetDeviceSync(true)); mfi.isValid(); ++mfi) {
1819 const Box& bx = amrex::grow(mfi.validbox(), nghost);
1820 auto const& arr = mf.const_array(mfi);
1821 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
1822 {
1823 int* flag = p;
1824 if (*flag == 0) {
1825 if (arr(i,j,k,comp) == value) {
1826 if (Gpu::Atomic::Exch(flag,1) == 0) {
1827 AMREX_D_TERM(p[1] = i;,
1828 p[2] = j;,
1829 p[3] = k;);
1830 }
1831 }
1832 }
1833 });
1834 }
1835 }
1836 int const* tmp = aa.copyToHost();
1837 AMREX_D_TERM(loc[0] = tmp[1];,
1838 loc[1] = tmp[2];,
1839 loc[2] = tmp[3];);
1840 }
1841 else
1842#endif
1843 {
1844 bool f = false;
1845#ifdef AMREX_USE_OMP
1846#pragma omp parallel
1847#endif
1848 {
1849 IntVect priv_loc = IntVect::TheMinVector();
1850 for (MFIter mfi(mf,true); mfi.isValid(); ++mfi)
1851 {
1852 const Box& bx = mfi.growntilebox(nghost);
1853 auto const& fab = mf.const_array(mfi);
1854 AMREX_LOOP_3D(bx, i, j, k,
1855 {
1856 if (fab(i,j,k,comp) == value) {
1857 priv_loc = IntVect(AMREX_D_DECL(i,j,k));
1858 }
1859 });
1860 }
1861
1862 if (priv_loc.allGT(IntVect::TheMinVector())) {
1863 bool old;
1864// we should be able to test on _OPENMP < 201107 for capture (version 3.1)
1865// but we must work around a bug in gcc < 4.9
1866// And, with NVHPC 21.9 to <23.1, we saw an ICE with the atomic capture (NV bug: #3390723)
1867#if defined(AMREX_USE_OMP) && defined(_OPENMP) && (_OPENMP < 201307 || (defined(__NVCOMPILER) && __NVCOMPILER_MAJOR__ < 23)) // OpenMP 4.0
1868#pragma omp critical (amrex_indexfromvalue)
1869#elif defined(AMREX_USE_OMP)
1870#pragma omp atomic capture
1871#endif
1872 {
1873 old = f;
1874 f = true;
1875 }
1876
1877 if (old == false) { loc = priv_loc; }
1878 }
1879 }
1880 }
1881
1882 return loc;
1883}
1884
1896template <BaseFabType FAB>
1897typename FAB::value_type
1898Dot (FabArray<FAB> const& x, int xcomp, FabArray<FAB> const& y, int ycomp, int ncomp,
1899 IntVect const& nghost, bool local = false)
1900{
1901 BL_ASSERT(x.boxArray() == y.boxArray());
1902 BL_ASSERT(x.DistributionMap() == y.DistributionMap());
1903 BL_ASSERT(x.nGrowVect().allGE(nghost) && y.nGrowVect().allGE(nghost));
1904
1905 BL_PROFILE("amrex::Dot()");
1906
1907 using T = typename FAB::value_type;
1908 auto sm = T(0.0);
1909#ifdef AMREX_USE_GPU
1910 if (Gpu::inLaunchRegion()) {
1911 auto const& xma = x.const_arrays();
1912 auto const& yma = y.const_arrays();
1913 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, x, nghost,
1914 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<T>
1915 {
1916 auto t = T(0.0);
1917 auto const& xfab = xma[box_no];
1918 auto const& yfab = yma[box_no];
1919 for (int n = 0; n < ncomp; ++n) {
1920 t += xfab(i,j,k,xcomp+n) * yfab(i,j,k,ycomp+n);
1921 }
1922 return t;
1923 });
1924 } else
1925#endif
1926 {
1927#ifdef AMREX_USE_OMP
1928#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
1929#endif
1930 for (MFIter mfi(x,true); mfi.isValid(); ++mfi)
1931 {
1932 Box const& bx = mfi.growntilebox(nghost);
1933 auto const& xfab = x.const_array(mfi);
1934 auto const& yfab = y.const_array(mfi);
1935 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
1936 {
1937 sm += xfab(i,j,k,xcomp+n) * yfab(i,j,k,ycomp+n);
1938 });
1939 }
1940 }
1941
1942 if (!local) {
1944 }
1945
1946 return sm;
1947}
1948
1958template <BaseFabType FAB>
1959typename FAB::value_type
1960Dot (FabArray<FAB> const& x, int xcomp, int ncomp, IntVect const& nghost, bool local = false)
1961{
1962 BL_ASSERT(x.nGrowVect().allGE(nghost));
1963
1964 BL_PROFILE("amrex::Dot()");
1965
1966 using T = typename FAB::value_type;
1967 auto sm = T(0.0);
1968#ifdef AMREX_USE_GPU
1969 if (Gpu::inLaunchRegion()) {
1970 auto const& xma = x.const_arrays();
1971 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, x, nghost,
1972 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<T>
1973 {
1974 auto t = T(0.0);
1975 auto const& xfab = xma[box_no];
1976 for (int n = 0; n < ncomp; ++n) {
1977 auto v = xfab(i,j,k,xcomp+n);
1978 t += v*v;
1979 }
1980 return t;
1981 });
1982 } else
1983#endif
1984 {
1985#ifdef AMREX_USE_OMP
1986#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
1987#endif
1988 for (MFIter mfi(x,true); mfi.isValid(); ++mfi)
1989 {
1990 Box const& bx = mfi.growntilebox(nghost);
1991 auto const& xfab = x.const_array(mfi);
1992 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
1993 {
1994 auto v = xfab(i,j,k,xcomp+n);
1995 sm += v*v;
1996 });
1997 }
1998 }
1999
2000 if (!local) {
2002 }
2003
2004 return sm;
2005}
2006
2026template <BaseFabType MFAB, BaseFabType FAB>
2027typename FAB::value_type
2028Dot (FabArray<MFAB> const& mask, FabArray<FAB> const& x, int xcomp,
2029 FabArray<FAB> const& y, int ycomp, int ncomp, IntVect const& nghost,
2030 bool local = false)
2031{
2032 BL_ASSERT(x.boxArray() == y.boxArray() && x.boxArray() == mask.boxArray());
2033 BL_ASSERT(x.DistributionMap() == y.DistributionMap() && x.DistributionMap() == mask.DistributionMap());
2034 BL_ASSERT(x.nGrowVect().allGE(nghost) && y.nGrowVect().allGE(nghost) &&
2035 mask.nGrowVect().allGE(nghost));
2036
2037 BL_PROFILE("amrex::Dot()");
2038
2039 using T = typename FAB::value_type;
2040 auto sm = T(0.0);
2041#ifdef AMREX_USE_GPU
2042 if (Gpu::inLaunchRegion()) {
2043 auto const& mma = mask.const_arrays();
2044 auto const& xma = x.const_arrays();
2045 auto const& yma = y.const_arrays();
2046 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, x, nghost,
2047 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<T>
2048 {
2049 auto t = T(0.0);
2050 auto m = T(mma[box_no](i,j,k));
2051 if (m != 0) {
2052 auto const& xfab = xma[box_no];
2053 auto const& yfab = yma[box_no];
2054 for (int n = 0; n < ncomp; ++n) {
2055 t += xfab(i,j,k,xcomp+n) * yfab(i,j,k,ycomp+n);
2056 }
2057 }
2058 return t*m;
2059 });
2060 } else
2061#endif
2062 {
2063#ifdef AMREX_USE_OMP
2064#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
2065#endif
2066 for (MFIter mfi(x,true); mfi.isValid(); ++mfi)
2067 {
2068 Box const& bx = mfi.growntilebox(nghost);
2069 auto const& mfab = mask.const_array(mfi);
2070 auto const& xfab = x.const_array(mfi);
2071 auto const& yfab = y.const_array(mfi);
2072 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
2073 {
2074 auto m = T(mfab(i,j,k));
2075 sm += m * xfab(i,j,k,xcomp+n) * yfab(i,j,k,ycomp+n);
2076 });
2077 }
2078 }
2079
2080 if (!local) {
2082 }
2083
2084 return sm;
2085}
2086
2101template <BaseFabType MFAB, BaseFabType FAB>
2102typename FAB::value_type
2103Dot (FabArray<MFAB> const& mask, FabArray<FAB> const& x, int xcomp, int ncomp,
2104 IntVect const& nghost, bool local = false)
2105{
2106 BL_ASSERT(x.boxArray() == mask.boxArray());
2107 BL_ASSERT(x.DistributionMap() == mask.DistributionMap());
2108 BL_ASSERT(x.nGrowVect().allGE(nghost) && mask.nGrowVect().allGE(nghost));
2109
2110 BL_PROFILE("amrex::Dot()");
2111
2112 using T = typename FAB::value_type;
2113 auto sm = T(0.0);
2114#ifdef AMREX_USE_GPU
2115 if (Gpu::inLaunchRegion()) {
2116 auto const& mma = mask.const_arrays();
2117 auto const& xma = x.const_arrays();
2118 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, x, nghost,
2119 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<T>
2120 {
2121 auto t = T(0.0);
2122 auto m = T(mma[box_no](i,j,k));
2123 if (m != 0) {
2124 auto const& xfab = xma[box_no];
2125 for (int n = 0; n < ncomp; ++n) {
2126 auto v = xfab(i,j,k,xcomp+n);
2127 t += v*v;
2128 }
2129 }
2130 return t*m;
2131 });
2132 } else
2133#endif
2134 {
2135#ifdef AMREX_USE_OMP
2136#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
2137#endif
2138 for (MFIter mfi(x,true); mfi.isValid(); ++mfi)
2139 {
2140 Box const& bx = mfi.growntilebox(nghost);
2141 auto const& mfab = mask.const_array(mfi);
2142 auto const& xfab = x.const_array(mfi);
2143 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
2144 {
2145 auto m = T(mfab(i,j,k));
2146 auto v = xfab(i,j,k,xcomp+n);
2147 sm += m*v*v;
2148 });
2149 }
2150 }
2151
2152 if (!local) {
2154 }
2155
2156 return sm;
2157}
2158
2160template <MultiFabLike MF>
2161void setVal (MF& dst, typename MF::value_type val)
2162{
2163 dst.setVal(val);
2164}
2165
2167template <MultiFabLike MF>
2168void setBndry (MF& dst, typename MF::value_type val, int scomp, int ncomp)
2169{
2170 dst.setBndry(val, scomp, ncomp);
2171}
2172
2174template <MultiFabLike MF>
2175void Scale (MF& dst, typename MF::value_type val, int scomp, int ncomp, int nghost)
2176{
2177 dst.mult(val, scomp, ncomp, nghost);
2178}
2179
2181template <MultiFabLike DMF, MultiFabLike SMF>
2182void LocalCopy (DMF& dst, SMF const& src, int scomp, int dcomp,
2183 int ncomp, IntVect const& nghost)
2184{
2185 amrex::Copy(dst, src, scomp, dcomp, ncomp, nghost);
2186}
2187
2189template <MultiFabLike MF>
2190void LocalAdd (MF& dst, MF const& src, int scomp, int dcomp,
2191 int ncomp, IntVect const& nghost)
2192{
2193 amrex::Add(dst, src, scomp, dcomp, ncomp, nghost);
2194}
2195
2197template <MultiFabLike MF>
2198void Saxpy (MF& dst, typename MF::value_type a, MF const& src, int scomp, int dcomp,
2199 int ncomp, IntVect const& nghost)
2200{
2201 MF::Saxpy(dst, a, src, scomp, dcomp, ncomp, nghost);
2202}
2203
2205template <MultiFabLike MF>
2206void Xpay (MF& dst, typename MF::value_type a, MF const& src, int scomp, int dcomp,
2207 int ncomp, IntVect const& nghost)
2208{
2209 MF::Xpay(dst, a, src, scomp, dcomp, ncomp, nghost);
2210}
2211
2213template <MultiFabLike MF>
2214void Saxpy_Xpay (MF& dst, typename MF::value_type a_saxpy, MF const& src_saxpy,
2215 typename MF::value_type a_xpay, MF const& src_xpay, int scomp, int dcomp,
2216 int ncomp, IntVect const& nghost)
2217{
2218 MF::Saxpy_Xpay(dst, a_saxpy, src_saxpy, a_xpay, src_xpay, scomp, dcomp, ncomp, nghost);
2219}
2220
2222template <MultiFabLike MF>
2223void Saxpy_Saxpy (MF& dst1, typename MF::value_type a1, MF const& src1,
2224 MF& dst2, typename MF::value_type a2, MF const& src2, int scomp, int dcomp,
2225 int ncomp, IntVect const& nghost)
2226{
2227 MF::Saxpy_Saxpy(dst1, a1, src1, dst2, a2, src2, scomp, dcomp, ncomp, nghost);
2228}
2229
2231template <MultiFabLike MF>
2232void Saypy_Saxpy (MF& dst1, typename MF::value_type a1,
2233 MF& dst2, typename MF::value_type a2, MF const& src, int scomp, int dcomp,
2234 int ncomp, IntVect const& nghost)
2235{
2236 MF::Saypy_Saxpy(dst1, a1, dst2, a2, src, scomp, dcomp, ncomp, nghost);
2237}
2238
2240template <MultiFabLike MF>
2241void LinComb (MF& dst,
2242 typename MF::value_type a, MF const& src_a, int acomp,
2243 typename MF::value_type b, MF const& src_b, int bcomp,
2244 int dcomp, int ncomp, IntVect const& nghost)
2245{
2246 MF::LinComb(dst, a, src_a, acomp, b, src_b, bcomp, dcomp, ncomp, nghost);
2247}
2248
2250template <MultiFabLike MF>
2251void ParallelCopy (MF& dst, MF const& src, int scomp, int dcomp, int ncomp,
2252 IntVect const& ng_src = IntVect(0),
2253 IntVect const& ng_dst = IntVect(0),
2254 Periodicity const& period = Periodicity::NonPeriodic())
2255{
2256 dst.ParallelCopy(src, scomp, dcomp, ncomp, ng_src, ng_dst, period);
2257}
2258
2260template <MultiFabLike MF>
2261[[nodiscard]] typename MF::value_type
2262norminf (MF const& mf, int scomp, int ncomp, IntVect const& nghost,
2263 bool local = false)
2264{
2265 return mf.norminf(scomp, ncomp, nghost, local);
2266}
2267
2269template <MultiFabLike MF, std::size_t N>
2270void setVal (Array<MF,N>& dst, typename MF::value_type val)
2271{
2272 for (auto& mf: dst) {
2273 mf.setVal(val);
2274 }
2275}
2276
2278template <MultiFabLike MF, std::size_t N>
2279void setBndry (Array<MF,N>& dst, typename MF::value_type val, int scomp, int ncomp)
2280{
2281 for (auto& mf : dst) {
2282 mf.setBndry(val, scomp, ncomp);
2283 }
2284}
2285
2287template <MultiFabLike MF, std::size_t N>
2288void Scale (Array<MF,N>& dst, typename MF::value_type val, int scomp, int ncomp,
2289 int nghost)
2290{
2291 for (auto& mf : dst) {
2292 mf.mult(val, scomp, ncomp, nghost);
2293 }
2294}
2295
2297template <MultiFabLike DMF, MultiFabLike SMF, std::size_t N>
2298void LocalCopy (Array<DMF,N>& dst, Array<SMF,N> const& src, int scomp, int dcomp,
2299 int ncomp, IntVect const& nghost)
2300{
2301 for (std::size_t i = 0; i < N; ++i) {
2302 amrex::Copy(dst[i], src[i], scomp, dcomp, ncomp, nghost);
2303 }
2304}
2305
2307template <MultiFabLike MF, std::size_t N>
2308void LocalAdd (Array<MF,N>& dst, Array<MF,N> const& src, int scomp, int dcomp,
2309 int ncomp, IntVect const& nghost)
2310{
2311 for (std::size_t i = 0; i < N; ++i) {
2312 amrex::Add(dst[i], src[i], scomp, dcomp, ncomp, nghost);
2313 }
2314}
2315
2317template <MultiFabLike MF, std::size_t N>
2318void Saxpy (Array<MF,N>& dst, typename MF::value_type a,
2319 Array<MF,N> const& src, int scomp, int dcomp, int ncomp,
2320 IntVect const& nghost)
2321{
2322 for (std::size_t i = 0; i < N; ++i) {
2323 MF::Saxpy(dst[i], a, src[i], scomp, dcomp, ncomp, nghost);
2324 }
2325}
2326
2328template <MultiFabLike MF, std::size_t N>
2329void Xpay (Array<MF,N>& dst, typename MF::value_type a,
2330 Array<MF,N> const& src, int scomp, int dcomp, int ncomp,
2331 IntVect const& nghost)
2332{
2333 for (std::size_t i = 0; i < N; ++i) {
2334 MF::Xpay(dst[i], a, src[i], scomp, dcomp, ncomp, nghost);
2335 }
2336}
2337
2339template <MultiFabLike MF, std::size_t N>
2341 typename MF::value_type a, Array<MF,N> const& src_a, int acomp,
2342 typename MF::value_type b, Array<MF,N> const& src_b, int bcomp,
2343 int dcomp, int ncomp, IntVect const& nghost)
2344{
2345 for (std::size_t i = 0; i < N; ++i) {
2346 MF::LinComb(dst[i], a, src_a[i], acomp, b, src_b[i], bcomp, dcomp, ncomp, nghost);
2347 }
2348}
2349
2351template <MultiFabLike MF, std::size_t N>
2352void ParallelCopy (Array<MF,N>& dst, Array<MF,N> const& src,
2353 int scomp, int dcomp, int ncomp,
2354 IntVect const& ng_src = IntVect(0),
2355 IntVect const& ng_dst = IntVect(0),
2356 Periodicity const& period = Periodicity::NonPeriodic())
2357{
2358 for (std::size_t i = 0; i < N; ++i) {
2359 dst[i].ParallelCopy(src[i], scomp, dcomp, ncomp, ng_src, ng_dst, period);
2360 }
2361}
2362
2364template <MultiFabLike MF, std::size_t N>
2365[[nodiscard]] typename MF::value_type
2366norminf (Array<MF,N> const& mf, int scomp, int ncomp, IntVect const& nghost,
2367 bool local = false)
2368{
2369 auto r = typename MF::value_type(0);
2370 for (std::size_t i = 0; i < N; ++i) {
2371 auto tmp = mf[i].norminf(scomp, ncomp, nghost, true);
2372 r = std::max(r,tmp);
2373 }
2374 if (!local) {
2376 }
2377 return r;
2378}
2379
2381template <MultiFabLike MF, std::size_t N>
2382requires (N > 0)
2383[[nodiscard]] int nComp (Array<MF,N> const& mf)
2384{
2385 return mf[0].nComp();
2386}
2387
2389template <MultiFabLike MF, std::size_t N>
2390requires (N > 0)
2391[[nodiscard]] IntVect nGrowVect (Array<MF,N> const& mf)
2392{
2393 return mf[0].nGrowVect();
2394}
2395
2397template <MultiFabLike MF, std::size_t N>
2398requires (N > 0)
2399[[nodiscard]] BoxArray const&
2401{
2402 return mf[0].boxArray();
2403}
2404
2406template <MultiFabLike MF, std::size_t N>
2407requires (N > 0)
2408[[nodiscard]] DistributionMapping const&
2410{
2411 return mf[0].DistributionMap();
2412}
2413
2421template <class FAB>
2422FabArray<BaseFab<int>>
2423OverlapMask (FabArray<FAB> const& fa, IntVect const& nghost, Periodicity const& period)
2424{
2425 BL_PROFILE("OverlapMask()");
2426
2427 const BoxArray& ba = fa.boxArray();
2428 const DistributionMapping& dm = fa.DistributionMap();
2429
2430 FabArray<BaseFab<int>> mask(ba, dm, 1, nghost);
2431 mask.setVal(1);
2432
2433 const std::vector<IntVect>& pshifts = period.shiftIntVect();
2434
2436
2437 bool run_on_gpu = Gpu::inLaunchRegion();
2438 amrex::ignore_unused(run_on_gpu, tags);
2439#ifdef AMREX_USE_OMP
2440#pragma omp parallel if (!run_on_gpu)
2441#endif
2442 {
2443 std::vector< std::pair<int,Box> > isects;
2444
2445 for (MFIter mfi(mask); mfi.isValid(); ++mfi)
2446 {
2447 const Box& bx = mask[mfi].box();
2448 auto const& arr = mask.array(mfi);
2449
2450 for (const auto& iv : pshifts)
2451 {
2452 ba.intersections(bx+iv, isects, false, nghost);
2453 for (const auto& is : isects)
2454 {
2455 Box const& b = is.second-iv;
2456 if (iv == 0 && b == bx) { continue; }
2457#ifdef AMREX_USE_GPU
2458 if (run_on_gpu) {
2459 tags.push_back(Array4BoxTag<int>{.dfab = arr, .dbox = b});
2460 } else
2461#endif
2462 {
2463 amrex::LoopConcurrentOnCpu(b, [=] (int i, int j, int k) noexcept
2464 {
2465 arr(i,j,k) += 1;
2466 });
2467 }
2468 }
2469 }
2470 }
2471 }
2472
2473#ifdef AMREX_USE_GPU
2474 amrex::ParallelFor(tags, 1,
2475 [=] AMREX_GPU_DEVICE (int i, int j, int k, int n, Array4BoxTag<int> const& tag) noexcept
2476 {
2477 Gpu::Atomic::AddNoRet(tag.dfab.ptr(i,j,k,n), 1);
2478 });
2479#endif
2480
2481 return mask;
2482}
2483
2484}
2485
2486#endif
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:562
#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:1132
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:681
std::vector< std::pair< int, Box > > intersections(const Box &bx) const
Return all intersections of bx with this BoxArray.
Definition AMReX_BoxArray.cpp:1202
__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:2713
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:3248
void setBndry(value_type val)
Set all values in the boundary region to val.
Definition AMReX_FabArray.H:2767
std::unique_ptr< FabArray< FAB > > os_temp
Definition AMReX_FabArray.H:1917
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:2985
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:104
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:176
Dynamically allocated vector for trivially copyable data.
Definition AMReX_PODVector.H:308
T * data() noexcept
Definition AMReX_PODVector.H:672
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
Arena * The_Async_Arena()
Definition AMReX_Arena.cpp:825
void Sum(Gpu::DeviceVector< T > &v, MPI_Comm comm)
Definition AMReX_GpuParallelReduce.H:37
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:1752
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:1660
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:2175
BoxArray const & boxArray(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.boxArray().
Definition AMReX_FabArrayBase.cpp:2870
DistributionMapping const & DistributionMap(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.DistributionMap().
Definition AMReX_FabArrayBase.cpp:2875
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:1898
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:2214
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:1626
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:2423
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:1604
bool isMFIterSafe(const FabArrayBase &x, const FabArrayBase &y)
Definition AMReX_MFIter.H:256
int nComp(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.nComp().
Definition AMReX_FabArrayBase.cpp:2860
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:2223
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:1785
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:2241
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:2251
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:2232
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:1458
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:1553
void OverrideSync_finish(FabArray< FAB > &fa)
Finish the current masked OverrideSync_nowait() operation.
Definition AMReX_FabArrayUtility.H:1710
void single_task(L &&f) noexcept
Definition AMReX_GpuLaunchFunctsC.H:1245
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:1725
IntVect nGrowVect(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.nGrowVect().
Definition AMReX_FabArrayBase.cpp:2865
void LocalCopy(DMF &dst, SMF const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst = src
Definition AMReX_FabArrayUtility.H:2182
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:2168
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:2262
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:2206
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:242
const int[]
Definition AMReX_BLProfiler.cpp:1665
void OverrideSync(FabArray< FAB > &fa, FabArray< IFAB > const &msk, const Periodicity &period)
Synchronize shared nodal values using an owner mask.
Definition AMReX_FabArrayUtility.H:1648
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:1506
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:1410
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:2198
void LocalAdd(MF &dst, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
dst += src
Definition AMReX_FabArrayUtility.H:2190
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:2161
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
MFInfo & SetArena(Arena *ar) noexcept
Select the Arena used for FAB storage.
Definition AMReX_FabArray.H:87
Definition AMReX_MFIter.H:20
Struct for holding types.
Definition AMReX_TypeList.H:13