Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_FabArray.H
Go to the documentation of this file.
1
2#ifndef BL_FABARRAY_H
3#define BL_FABARRAY_H
4#include <AMReX_Config.H>
5
6#include <AMReX_BLassert.H>
7#include <AMReX_Array.H>
8#include <AMReX_Vector.H>
9#include <AMReX_Box.H>
10#include <AMReX.H>
11#include <AMReX_BoxArray.H>
12#include <AMReX_BoxDomain.H>
13#include <AMReX_FabFactory.H>
15#include <AMReX_Geometry.H>
16#include <AMReX_GpuComplex.H>
18#include <AMReX_Utility.H>
19#include <AMReX_ccse-mpi.H>
20#include <AMReX_BLProfiler.H>
21#include <AMReX_Periodicity.H>
22#include <AMReX_Print.H>
23#include <AMReX_FabArrayBase.H>
24#include <AMReX_MFIter.H>
25#include <AMReX_MakeType.H>
26#include <AMReX_TypeTraits.H>
27#include <AMReX_LayoutData.H>
28#include <AMReX_BaseFab.H>
30#include <AMReX_MFParallelFor.H>
32#include <AMReX_ParReduce.H>
33
34#include <AMReX_Gpu.H>
35
36#ifdef AMREX_USE_EB
37#include <AMReX_EBFabFactory.H>
38#endif
39
40#ifdef AMREX_USE_OMP
41#include <omp.h>
42#endif
43
44#include <algorithm>
45#include <cstring>
46#include <iterator>
47#include <limits>
48#include <map>
49#include <memory>
50#include <utility>
51#include <set>
52#include <string>
53#include <vector>
54
55
56namespace amrex {
57
58template <typename T, std::enable_if_t<!IsBaseFab<T>::value,int> = 0>
59Long nBytesOwned (T const&) noexcept { return 0; }
60
61template <typename T>
62Long nBytesOwned (BaseFab<T> const& fab) noexcept { return fab.nBytesOwned(); }
63
67struct MFInfo {
68 // alloc: allocate memory or not
69 bool alloc = true;
71 Arena* arena = nullptr;
73
74 MFInfo& SetAlloc (bool a) noexcept { alloc = a; return *this; }
75
76 MFInfo& SetAllocSingleChunk (bool a) noexcept { alloc_single_chunk = a; return *this; }
77
78 MFInfo& SetArena (Arena* ar) noexcept { arena = ar; return *this; }
79
80 MFInfo& SetTag () noexcept { return *this; }
81
82 MFInfo& SetTag (const char* t) noexcept {
83 tags.emplace_back(t);
84 return *this;
85 }
86
87 MFInfo& SetTag (const std::string& t) noexcept {
88 tags.emplace_back(t);
89 return *this;
90 }
91
92 template <typename T, typename... Ts>
93 MFInfo& SetTag (T&& t, Ts&&... ts) noexcept {
94 tags.emplace_back(std::forward<T>(t));
95 return SetTag(std::forward<Ts>(ts)...);
96 }
97};
98
100 using pointer = char*;
101 void operator()(pointer p) const noexcept {
102 The_Comms_Arena()->free(p);
103 }
104};
105using TheFaArenaPointer = std::unique_ptr<char, TheFaArenaDeleter>;
106
107// Data used in non-blocking fill boundary.
108template <class FAB>
130
131// Data used in non-blocking parallel copy.
132template <class FAB>
152
153template <typename T>
155{
157 Array4<T> const& operator[] (int li) const noexcept {
158 AMREX_IF_ON_DEVICE((return dp[li];))
159 AMREX_IF_ON_HOST((return hp[li];))
160 }
161
163 explicit operator bool() const noexcept {
164 AMREX_IF_ON_DEVICE((return dp != nullptr;))
165 AMREX_IF_ON_HOST((return hp != nullptr;))
166 }
167
168#ifdef AMREX_USE_GPU
169 Array4<T> const* AMREX_RESTRICT dp = nullptr;
170#endif
171 Array4<T> const* AMREX_RESTRICT hp = nullptr;
172};
173
174template <class FAB> class FabArray;
175
176template <class DFAB, class SFAB,
177 std::enable_if_t<std::conjunction_v<
179 std::is_convertible<typename SFAB::value_type,
180 typename DFAB::value_type>>, int> BAR = 0>
181void
182Copy (FabArray<DFAB>& dst, FabArray<SFAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
183{
184 Copy(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
185}
186
187template <class DFAB, class SFAB,
188 std::enable_if_t<std::conjunction_v<
189 IsBaseFab<DFAB>, IsBaseFab<SFAB>,
190 std::is_convertible<typename SFAB::value_type,
191 typename DFAB::value_type>>, int> BAR = 0>
192void
193Copy (FabArray<DFAB>& dst, FabArray<SFAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
194{
195 BL_PROFILE("amrex::Copy()");
196
197 using DT = typename DFAB::value_type;
198
199 if (dst.local_size() == 0) { return; }
200
201 // avoid self copy
202 if constexpr (std::is_same_v<typename SFAB::value_type, typename DFAB::value_type>) {
203 if (dst.atLocalIdx(0).dataPtr(dstcomp) == src.atLocalIdx(0).dataPtr(srccomp)) {
204 return;
205 }
206 }
207
208#ifdef AMREX_USE_GPU
209 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
210 auto const& srcarr = src.const_arrays();
211 auto const& dstarr = dst.arrays();
212 ParallelFor(dst, nghost, numcomp,
213 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
214 {
215 dstarr[box_no](i,j,k,dstcomp+n) = DT(srcarr[box_no](i,j,k,srccomp+n));
216 });
217 if (!Gpu::inNoSyncRegion()) {
219 }
220 } else
221#endif
222 {
223#ifdef AMREX_USE_OMP
224#pragma omp parallel if (Gpu::notInLaunchRegion())
225#endif
226 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
227 {
228 const Box& bx = mfi.growntilebox(nghost);
229 if (bx.ok())
230 {
231 auto const& srcFab = src.const_array(mfi);
232 auto const& dstFab = dst.array(mfi);
233 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
234 {
235 dstFab(i,j,k,dstcomp+n) = DT(srcFab(i,j,k,srccomp+n));
236 });
237 }
238 }
239 }
240}
241
242template <class FAB,
243 class bar = std::enable_if_t<IsBaseFab<FAB>::value> >
244void
245Add (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
246{
247 Add(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
248}
249
250template <class FAB,
251 class bar = std::enable_if_t<IsBaseFab<FAB>::value> >
252void
253Add (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
254{
255 BL_PROFILE("amrex::Add()");
256
257#ifdef AMREX_USE_GPU
258 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
259 auto const& dstfa = dst.arrays();
260 auto const& srcfa = src.const_arrays();
261 ParallelFor(dst, nghost, numcomp,
262 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
263 {
264 dstfa[box_no](i,j,k,n+dstcomp) += srcfa[box_no](i,j,k,n+srccomp);
265 });
266 if (!Gpu::inNoSyncRegion()) {
268 }
269 } else
270#endif
271 {
272#ifdef AMREX_USE_OMP
273#pragma omp parallel if (Gpu::notInLaunchRegion())
274#endif
275 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
276 {
277 const Box& bx = mfi.growntilebox(nghost);
278 if (bx.ok())
279 {
280 auto const srcFab = src.array(mfi);
281 auto dstFab = dst.array(mfi);
282 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
283 {
284 dstFab(i,j,k,n+dstcomp) += srcFab(i,j,k,n+srccomp);
285 });
286 }
287 }
288 }
289}
290
347template <class FAB>
349 :
350 public FabArrayBase
351{
352public:
353
354 struct FABType {
355 using value_type = FAB;
356 };
357
358 /*
359 * if FAB is a BaseFab or its child, value_type = FAB::value_type
360 * else value_type = FAB;
361 */
362 using value_type = typename std::conditional_t<IsBaseFab<FAB>::value, FAB, FABType>::value_type;
363
364 using fab_type = FAB;
365
366 //
368 FabArray () noexcept;
369
377 explicit FabArray (Arena* a) noexcept;
378
384 FabArray (const BoxArray& bxs,
385 const DistributionMapping& dm,
386 int nvar,
387 int ngrow,
388#ifdef AMREX_STRICT_MODE
389 const MFInfo& info,
390 const FabFactory<FAB>& factory);
391#else
392 const MFInfo& info = MFInfo(),
393 const FabFactory<FAB>& factory = DefaultFabFactory<FAB>());
394#endif
395
396 FabArray (const BoxArray& bxs,
397 const DistributionMapping& dm,
398 int nvar,
399 const IntVect& ngrow,
400#ifdef AMREX_STRICT_MODE
401 const MFInfo& info,
402 const FabFactory<FAB>& factory);
403#else
404 const MFInfo& info = MFInfo(),
405 const FabFactory<FAB>& factory = DefaultFabFactory<FAB>());
406#endif
407
408 FabArray (const FabArray<FAB>& rhs, MakeType maketype, int scomp, int ncomp);
409
412
413 FabArray (FabArray<FAB>&& rhs) noexcept;
415
416 FabArray (const FabArray<FAB>& rhs) = delete;
418
425 void define (const BoxArray& bxs,
426 const DistributionMapping& dm,
427 int nvar,
428 int ngrow,
429#ifdef AMREX_STRICT_MODE
430 const MFInfo& info,
431 const FabFactory<FAB>& factory);
432#else
433 const MFInfo& info = MFInfo(),
434 const FabFactory<FAB>& factory = DefaultFabFactory<FAB>());
435#endif
436
437 void define (const BoxArray& bxs,
438 const DistributionMapping& dm,
439 int nvar,
440 const IntVect& ngrow,
441#ifdef AMREX_STRICT_MODE
442 const MFInfo& info,
443 const FabFactory<FAB>& factory);
444#else
445 const MFInfo& info = MFInfo(),
446 const FabFactory<FAB>& factory = DefaultFabFactory<FAB>());
447#endif
448
449 const FabFactory<FAB>& Factory () const noexcept { return *m_factory; }
450
451 // Provides access to the Arena this FabArray was build with.
452 Arena* arena () const noexcept { return m_dallocator.arena(); }
453
454 const Vector<std::string>& tags () const noexcept { return m_tags; }
455
456 bool hasEBFabFactory () const noexcept {
457#ifdef AMREX_USE_EB
458 const auto *const f = dynamic_cast<EBFArrayBoxFactory const*>(m_factory.get());
459 return (f != nullptr);
460#else
461 return false;
462#endif
463 }
464
467 [[nodiscard]] value_type* singleChunkPtr () noexcept {
468 return m_single_chunk_arena ? (value_type*)m_single_chunk_arena->data() : nullptr;
469 }
470
473 [[nodiscard]] value_type const* singleChunkPtr () const noexcept {
474 return m_single_chunk_arena ? (value_type const*)m_single_chunk_arena->data() : nullptr;
475 }
476
479 [[nodiscard]] std::size_t singleChunkSize () const noexcept { return m_single_chunk_size; }
480
481 bool isAllRegular () const noexcept {
482#ifdef AMREX_USE_EB
483 const auto *const f = dynamic_cast<EBFArrayBoxFactory const*>(m_factory.get());
484 if (f) {
485 return f->isAllRegular();
486 } else {
487 return true;
488 }
489#else
490 return true;
491#endif
492 }
493
503 bool ok () const;
504
512 bool isDefined () const;
513
515 const FAB& operator[] (const MFIter& mfi) const noexcept { return *(this->fabPtr(mfi)); }
516
518 const FAB& get (const MFIter& mfi) const noexcept { return *(this->fabPtr(mfi)); }
519
521 FAB& operator[] (const MFIter& mfi) noexcept { return *(this->fabPtr(mfi)); }
522
524 FAB& get (const MFIter& mfi) noexcept { return *(this->fabPtr(mfi)); }
525
527 const FAB& operator[] (int K) const noexcept { return *(this->fabPtr(K)); }
528
530 const FAB& get (int K) const noexcept { return *(this->fabPtr(K)); }
531
533 FAB& operator[] (int K) noexcept { return *(this->fabPtr(K)); }
534
536 FAB& get (int K) noexcept { return *(this->fabPtr(K)); }
537
539 FAB& atLocalIdx (int L) noexcept { return *m_fabs_v[L]; }
540 const FAB& atLocalIdx (int L) const noexcept { return *m_fabs_v[L]; }
541
543 FAB * fabPtr (const MFIter& mfi) noexcept;
544 FAB const* fabPtr (const MFIter& mfi) const noexcept;
545 FAB * fabPtr (int K) noexcept; // Here K is global index
546 FAB const* fabPtr (int K) const noexcept;
547
548 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
549 void prefetchToHost (const MFIter& mfi) const noexcept
550 {
551#ifdef AMREX_USE_CUDA
552 this->fabPtr(mfi)->prefetchToHost();
553#else
555#endif
556 }
557
558 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
559 void prefetchToDevice (const MFIter& mfi) const noexcept
560 {
561#ifdef AMREX_USE_CUDA
562 this->fabPtr(mfi)->prefetchToDevice();
563#else
565#endif
566 }
567
568 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
569 Array4<typename FabArray<FAB>::value_type const> array (const MFIter& mfi) const noexcept
570 {
571 return fabPtr(mfi)->const_array();
572 }
573
574 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
576 {
577 return fabPtr(mfi)->array();
578 }
579
580 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
582 {
583 return fabPtr(K)->const_array();
584 }
585
586 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
588 {
589 return fabPtr(K)->array();
590 }
591
592 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
594 {
595 return fabPtr(mfi)->const_array();
596 }
597
598 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
600 {
601 return fabPtr(K)->const_array();
602 }
603
604 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
605 Array4<typename FabArray<FAB>::value_type const> array (const MFIter& mfi, int start_comp) const noexcept
606 {
607 return fabPtr(mfi)->const_array(start_comp);
608 }
609
610 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
611 Array4<typename FabArray<FAB>::value_type> array (const MFIter& mfi, int start_comp) noexcept
612 {
613 return fabPtr(mfi)->array(start_comp);
614 }
615
616 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
617 Array4<typename FabArray<FAB>::value_type const> array (int K, int start_comp) const noexcept
618 {
619 return fabPtr(K)->const_array(start_comp);
620 }
621
622 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
623 Array4<typename FabArray<FAB>::value_type> array (int K, int start_comp) noexcept
624 {
625 return fabPtr(K)->array(start_comp);
626 }
627
628 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
629 Array4<typename FabArray<FAB>::value_type const> const_array (const MFIter& mfi, int start_comp) const noexcept
630 {
631 return fabPtr(mfi)->const_array(start_comp);
632 }
633
634 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
635 Array4<typename FabArray<FAB>::value_type const> const_array (int K, int start_comp) const noexcept
636 {
637 return fabPtr(K)->const_array(start_comp);
638 }
639
640 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
642 {
643 build_arrays();
644 return m_arrays;
645 }
646
647 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
649 {
650 build_arrays();
651 return m_const_arrays;
652 }
653
654 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
656 {
657 build_arrays();
658 return m_const_arrays;
659 }
660
662 void setFab (int boxno, std::unique_ptr<FAB> elem);
663
665 template <class F=FAB, std::enable_if_t<std::is_move_constructible_v<F>,int> = 0>
666 void setFab (int boxno, FAB&& elem);
667
669 void setFab (const MFIter&mfi, std::unique_ptr<FAB> elem);
670
672 template <class F=FAB, std::enable_if_t<std::is_move_constructible_v<F>,int> = 0>
673 void setFab (const MFIter&mfi, FAB&& elem);
674
677 FAB* release (int K);
678
681 FAB* release (const MFIter& mfi);
682
684 void clear ();
685
700 template <typename SFAB, typename DFAB = FAB,
701 std::enable_if_t<std::conjunction_v<
703 std::is_convertible<typename SFAB::value_type,
704 typename DFAB::value_type>>, int> = 0>
705 void LocalCopy (FabArray<SFAB> const& src, int scomp, int dcomp, int ncomp,
706 IntVect const& nghost);
707
720 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
721 void LocalAdd (FabArray<FAB> const& src, int scomp, int dcomp, int ncomp,
722 IntVect const& nghost);
723
725 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
726 void setVal (value_type val);
727
729 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
731
737 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
739 int comp,
740 int ncomp,
741 int nghost = 0);
742
743 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
745 int comp,
746 int ncomp,
747 const IntVect& nghost);
748
755 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
757 const Box& region,
758 int comp,
759 int ncomp,
760 int nghost = 0);
761
762 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
764 const Box& region,
765 int comp,
766 int ncomp,
767 const IntVect& nghost);
772 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
773 void setVal (value_type val, int nghost);
774
775 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
776 void setVal (value_type val, const IntVect& nghost);
777
783 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
784 void setVal (value_type val, const Box& region, int nghost);
785
786 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
787 void setVal (value_type val, const Box& region, const IntVect& nghost);
788
789 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
790 void abs (int comp, int ncomp, int nghost = 0);
791
792 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
793 void abs (int comp, int ncomp, const IntVect& nghost);
794
795 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
796 void plus (value_type val, int comp, int num_comp, int nghost = 0);
797
798 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
799 void plus (value_type val, const Box& region, int comp, int num_comp, int nghost = 0);
800
801 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
802 void mult (value_type val, int comp, int num_comp, int nghost = 0);
803
804 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
805 void mult (value_type val, const Box& region, int comp, int num_comp, int nghost = 0);
806
807 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
808 void invert (value_type numerator, int comp, int num_comp, int nghost = 0);
809
810 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
811 void invert (value_type numerator, const Box& region, int comp, int num_comp, int nghost = 0);
812
814 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
816
818 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
819 void setBndry (value_type val, int strt_comp, int ncomp);
820
822 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
823 void setDomainBndry (value_type val, const Geometry& geom);
824
826 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
827 void setDomainBndry (value_type val, int strt_comp, int ncomp, const Geometry& geom);
828
830 template <typename I, class F=FAB, std::enable_if_t<IsBaseFab<F>::value && std::is_integral_v<I> && (sizeof(I) >= sizeof(Long)), int> = 0>
831 void capacityOfFabs (LayoutData<I>& mem) const;
832
842 template <typename F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
843 typename F::value_type
844 sum (int comp, IntVect const& nghost, bool local = false) const;
845
852 void ParallelAdd (const FabArray<FAB>& src,
853 const Periodicity& period = Periodicity::NonPeriodic())
854 { ParallelCopy(src,period,FabArray::ADD); }
855 void ParallelCopy (const FabArray<FAB>& src,
856 const Periodicity& period = Periodicity::NonPeriodic(),
858 { ParallelCopy(src,0,0,nComp(),0,0,period,op); }
859
860 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
861 void copy (const FabArray<FAB>& src,
862 const Periodicity& period = Periodicity::NonPeriodic(),
864 { ParallelCopy(src,period,op); }
865
867 const Periodicity& period = Periodicity::NonPeriodic())
868 { ParallelCopy_nowait(src,period,FabArray::ADD); }
870 const Periodicity& period = Periodicity::NonPeriodic(),
872 { ParallelCopy_nowait(src,0,0,nComp(),0,0,period,op); }
873
882 void ParallelAdd (const FabArray<FAB>& src,
883 int src_comp,
884 int dest_comp,
885 int num_comp,
886 const Periodicity& period = Periodicity::NonPeriodic())
887 { ParallelCopy(src,src_comp,dest_comp,num_comp, period, FabArrayBase::ADD); }
888 void ParallelCopy (const FabArray<FAB>& src,
889 int src_comp,
890 int dest_comp,
891 int num_comp,
892 const Periodicity& period = Periodicity::NonPeriodic(),
894 { ParallelCopy(src,src_comp,dest_comp,num_comp,0,0,period,op); }
895
896 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
897 void copy (const FabArray<FAB>& src,
898 int src_comp,
899 int dest_comp,
900 int num_comp,
901 const Periodicity& period = Periodicity::NonPeriodic(),
903 { ParallelCopy(src,src_comp,dest_comp,num_comp, period, op); }
904
906 int src_comp,
907 int dest_comp,
908 int num_comp,
909 const Periodicity& period = Periodicity::NonPeriodic())
910 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp, period, FabArrayBase::ADD); }
912 int src_comp,
913 int dest_comp,
914 int num_comp,
915 const Periodicity& period = Periodicity::NonPeriodic(),
917 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,0,0,period,op); }
918
920 void ParallelAdd (const FabArray<FAB>& src,
921 int src_comp,
922 int dest_comp,
923 int num_comp,
924 int src_nghost,
925 int dst_nghost,
926 const Periodicity& period = Periodicity::NonPeriodic())
927 { ParallelCopy(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),IntVect(dst_nghost),period,
929 void ParallelAdd (const FabArray<FAB>& src,
930 int src_comp,
931 int dest_comp,
932 int num_comp,
933 const IntVect& src_nghost,
934 const IntVect& dst_nghost,
935 const Periodicity& period = Periodicity::NonPeriodic())
936 { ParallelCopy(src,src_comp,dest_comp,num_comp,src_nghost,dst_nghost,period,FabArrayBase::ADD); }
937 void ParallelCopy (const FabArray<FAB>& src,
938 int src_comp,
939 int dest_comp,
940 int num_comp,
941 int src_nghost,
942 int dst_nghost,
943 const Periodicity& period = Periodicity::NonPeriodic(),
945 { ParallelCopy(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),IntVect(dst_nghost),period,op); }
946 void ParallelCopy (const FabArray<FAB>& src,
947 int scomp,
948 int dcomp,
949 int ncomp,
950 const IntVect& snghost,
951 const IntVect& dnghost,
952 const Periodicity& period = Periodicity::NonPeriodic(),
954 const FabArrayBase::CPC* a_cpc = nullptr,
955 bool deterministic = false);
956
958 int src_comp,
959 int dest_comp,
960 int num_comp,
961 int src_nghost,
962 int dst_nghost,
963 const Periodicity& period = Periodicity::NonPeriodic())
964 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),
965 IntVect(dst_nghost),period,FabArrayBase::ADD); }
966
968 int src_comp,
969 int dest_comp,
970 int num_comp,
971 const IntVect& src_nghost,
972 const IntVect& dst_nghost,
973 const Periodicity& period = Periodicity::NonPeriodic())
974 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,src_nghost,
975 dst_nghost,period,FabArrayBase::ADD); }
976
978 int src_comp,
979 int dest_comp,
980 int num_comp,
981 int src_nghost,
982 int dst_nghost,
983 const Periodicity& period = Periodicity::NonPeriodic(),
985 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),
986 IntVect(dst_nghost),period,op); }
987
988 void ParallelCopy_nowait (const FabArray<FAB>& src,
989 int scomp,
990 int dcomp,
991 int ncomp,
992 const IntVect& snghost,
993 const IntVect& dnghost,
994 const Periodicity& period = Periodicity::NonPeriodic(),
996 const FabArrayBase::CPC* a_cpc = nullptr,
997 bool to_ghost_cells_only = false,
998 bool deterministic = false);
999
1000 void ParallelCopy_nowait (const FabArray<FAB>& src,
1001 int scomp,
1002 int dcomp,
1003 int ncomp,
1004 const IntVect& snghost,
1005 const IntVect& dnghost,
1006 const IntVect& offset,
1007 const Periodicity& period = Periodicity::NonPeriodic(),
1009 const FabArrayBase::CPC* a_cpc = nullptr,
1010 bool to_ghost_cells_only = false,
1011 bool deterministic = false);
1012
1013 void ParallelCopy_finish ();
1014
1015 void ParallelCopyToGhost (const FabArray<FAB>& src,
1016 int scomp,
1017 int dcomp,
1018 int ncomp,
1019 const IntVect& snghost,
1020 const IntVect& dnghost,
1021 const Periodicity& period = Periodicity::NonPeriodic());
1022
1024 int scomp,
1025 int dcomp,
1026 int ncomp,
1027 const IntVect& snghost,
1028 const IntVect& dnghost,
1029 const Periodicity& period = Periodicity::NonPeriodic());
1030
1032
1045 void ParallelCopy (const FabArray<FAB>& src, int src_comp, int dest_comp, int num_comp,
1046 const IntVect& snghost, const IntVect& dnghost,
1047 const IntVect& offset, const Periodicity& period);
1048
1061 void ParallelAdd (const FabArray<FAB>& src, int src_comp, int dest_comp, int num_comp,
1062 const IntVect& snghost, const IntVect& dnghost,
1063 const IntVect& offset, const Periodicity& period);
1064
1065 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
1066 void copy (const FabArray<FAB>& src,
1067 int src_comp,
1068 int dest_comp,
1069 int num_comp,
1070 int src_nghost,
1071 int dst_nghost,
1072 const Periodicity& period = Periodicity::NonPeriodic(),
1074 { ParallelCopy(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),IntVect(dst_nghost),period,op); }
1075
1076 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
1077 void copy (const FabArray<FAB>& src,
1078 int src_comp,
1079 int dest_comp,
1080 int num_comp,
1081 const IntVect& src_nghost,
1082 const IntVect& dst_nghost,
1083 const Periodicity& period = Periodicity::NonPeriodic(),
1085 { ParallelCopy(src,src_comp,dest_comp,num_comp,src_nghost,dst_nghost,period,op); }
1086
1088 void Redistribute (const FabArray<FAB>& src,
1089 int scomp,
1090 int dcomp,
1091 int ncomp,
1092 const IntVect& nghost);
1093
1099 void copyTo (FAB& dest, int nghost = 0) const;
1100
1108 void copyTo (FAB& dest, int scomp, int dcomp, int ncomp, int nghost = 0) const;
1109
1111 void shift (const IntVect& v);
1112
1113 bool defined (int K) const noexcept;
1114 bool defined (const MFIter& mfi) const noexcept;
1115
1128 template <typename BUF=value_type>
1129 void FillBoundary (bool cross = false);
1130
1132 template <typename BUF=value_type>
1133 void FillBoundary (const Periodicity& period, bool cross = false);
1134
1135 template <typename BUF=value_type>
1136 void FillBoundary (const IntVect& nghost, const Periodicity& period, bool cross = false);
1137
1140 template <typename BUF=value_type>
1141 void FillBoundary (int scomp, int ncomp, bool cross = false);
1142
1144 template <typename BUF=value_type>
1145 void FillBoundary (int scomp, int ncomp, const Periodicity& period, bool cross = false);
1146
1148 template <typename BUF=value_type>
1149 void FillBoundary (int scomp, int ncomp, const IntVect& nghost, const Periodicity& period, bool cross = false);
1150
1151 template <typename BUF=value_type>
1152 void FillBoundary_nowait (bool cross = false);
1153
1154 template <typename BUF=value_type>
1155 void FillBoundary_nowait (const Periodicity& period, bool cross = false);
1156
1157 template <typename BUF=value_type>
1158 void FillBoundary_nowait (const IntVect& nghost, const Periodicity& period, bool cross = false);
1159
1160 template <typename BUF=value_type>
1161 void FillBoundary_nowait (int scomp, int ncomp, bool cross = false);
1162
1163 template <typename BUF=value_type>
1164 void FillBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool cross = false);
1165
1166 template <typename BUF=value_type>
1167 void FillBoundary_nowait (int scomp, int ncomp, const IntVect& nghost, const Periodicity& period, bool cross = false);
1168
1169 template <typename BUF=value_type,
1170 class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1171 void FillBoundary_finish ();
1172
1173 void FillBoundary_test ();
1174
1175
1206 void FillBoundaryAndSync (int scomp, int ncomp, const IntVect& nghost,
1207 const Periodicity& period);
1209 void FillBoundaryAndSync_nowait (int scomp, int ncomp, const IntVect& nghost,
1210 const Periodicity& period);
1212
1249 void OverrideSync (int scomp, int ncomp, const Periodicity& period);
1251 void OverrideSync_nowait (int scomp, int ncomp, const Periodicity& period);
1253
1265 bool deterministic = false);
1267 void SumBoundary (int scomp, int ncomp, const Periodicity& period = Periodicity::NonPeriodic(),
1268 bool deterministic = false);
1270 bool deterministic = false);
1271 void SumBoundary_nowait (int scomp, int ncomp, const Periodicity& period = Periodicity::NonPeriodic(),
1272 bool deterministic = false);
1273
1284 void SumBoundary (int scomp, int ncomp, IntVect const& nghost,
1285 const Periodicity& period = Periodicity::NonPeriodic(),
1286 bool deterministic = false);
1287 void SumBoundary_nowait (int scomp, int ncomp, IntVect const& nghost,
1288 const Periodicity& period = Periodicity::NonPeriodic(),
1289 bool deterministic = false);
1290
1302 void SumBoundary (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost,
1303 const Periodicity& period = Periodicity::NonPeriodic(),
1304 bool deterministic = false);
1305 void SumBoundary_nowait (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost,
1306 const Periodicity& period = Periodicity::NonPeriodic(),
1307 bool deterministic = false);
1309
1320 void EnforcePeriodicity (const Periodicity& period);
1322 void EnforcePeriodicity (int scomp, int ncomp, const Periodicity& period);
1324 void EnforcePeriodicity (int scomp, int ncomp, const IntVect& nghost,
1325 const Periodicity& period);
1326
1327 // covered : ghost cells covered by valid cells of this FabArray
1328 // (including periodically shifted valid cells)
1329 // notcovered: ghost cells not covered by valid cells
1330 // (including ghost cells outside periodic boundaries)
1331 // physbnd : boundary cells outside the domain (excluding periodic boundaries)
1332 // interior : interior cells (i.e., valid cells)
1333 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1334 void BuildMask (const Box& phys_domain, const Periodicity& period,
1335 value_type covered, value_type notcovered,
1336 value_type physbnd, value_type interior);
1337
1338 // The following are private functions. But we have to make them public for cuda.
1339
1340 template <typename BUF=value_type,
1341 class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1342 void FBEP_nowait (int scomp, int ncomp, const IntVect& nghost,
1343 const Periodicity& period, bool cross,
1344 bool enforce_periodicity_only = false,
1345 bool override_sync = false,
1346 IntVect const& sumboundary_src_nghost = IntVect(-1),
1347 bool deterministic = false);
1348
1349 void FB_local_copy_cpu (const FB& TheFB, int scomp, int ncomp);
1350 void FB_local_add_cpu (const FB& TheFB, int scomp, int ncomp);
1351 void PC_local_cpu (const CPC& thecpc, FabArray<FAB> const& src,
1352 int scomp, int dcomp, int ncomp, CpOp op);
1353
1354 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1355 void setVal (value_type val, const CommMetaData& thecmd, int scomp, int ncomp);
1356
1357 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1359
1360#ifdef AMREX_USE_GPU
1361
1363 FB_get_local_copy_tag_vector (const FB& TheFB);
1364
1365 void FB_local_copy_gpu (const FB& TheFB, int scomp, int ncomp);
1366 void FB_local_add_gpu (const FB& TheFB, int scomp, int ncomp, bool deterministic);
1367 void PC_local_gpu (const CPC& thecpc, FabArray<FAB> const& src,
1368 int scomp, int dcomp, int ncomp, CpOp op, bool deterministic);
1369
1370 void CMD_local_setVal_gpu (value_type x, const CommMetaData& thecmd, int scomp, int ncomp);
1371 void CMD_remote_setVal_gpu (value_type x, const CommMetaData& thecmd, int scomp, int ncomp);
1372
1373#if defined(__CUDACC__)
1374
1375 void FB_local_copy_cuda_graph_1 (const FB& TheFB, int scomp, int ncomp);
1376 void FB_local_copy_cuda_graph_n (const FB& TheFB, int scomp, int ncomp);
1377
1378#endif
1379#endif
1380
1381#ifdef AMREX_USE_MPI
1382
1383#ifdef AMREX_USE_GPU
1384#if defined(__CUDACC__)
1385
1386 void FB_pack_send_buffer_cuda_graph (const FB& TheFB, int scomp, int ncomp,
1387 Vector<char*>& send_data,
1388 Vector<std::size_t> const& send_size,
1389 Vector<const CopyComTagsContainer*> const& send_cctc);
1390
1391 void FB_unpack_recv_buffer_cuda_graph (const FB& TheFB, int dcomp, int ncomp,
1392 Vector<char*> const& recv_data,
1393 Vector<std::size_t> const& recv_size,
1394 Vector<const CopyComTagsContainer*> const& recv_cctc,
1395 bool is_thread_safe);
1396
1397#endif
1398
1399 template <typename BUF = value_type>
1400 static void pack_send_buffer_gpu (FabArray<FAB> const& src, int scomp, int ncomp,
1401 Vector<char*> const& send_data,
1402 Vector<std::size_t> const& send_size,
1403 Vector<const CopyComTagsContainer*> const& send_cctc,
1404 std::uint64_t id);
1405
1406 template <typename BUF = value_type>
1407 static void unpack_recv_buffer_gpu (FabArray<FAB>& dst, int dcomp, int ncomp,
1408 Vector<char*> const& recv_data,
1409 Vector<std::size_t> const& recv_size,
1410 Vector<const CopyComTagsContainer*> const& recv_cctc,
1411 CpOp op, bool is_thread_safe,
1412 std::uint64_t id, bool deterministic);
1413
1414 template <typename BUF>
1417 Vector<std::size_t> const& recv_size,
1418 Vector<CopyComTagsContainer const*> const& recv_cctc,
1419 int ncomp, std::uint64_t id);
1420
1421 template <typename BUF>
1424 Vector<std::size_t> const& send_size,
1425 Vector<CopyComTagsContainer const*> const& send_cctc,
1426 int ncomp, std::uint64_t id) const;
1427
1428#endif
1429
1430 template <typename BUF = value_type>
1431 static void pack_send_buffer_cpu (FabArray<FAB> const& src, int scomp, int ncomp,
1432 Vector<char*> const& send_data,
1433 Vector<std::size_t> const& send_size,
1434 Vector<const CopyComTagsContainer*> const& send_cctc);
1435
1436 template <typename BUF = value_type>
1437 static void unpack_recv_buffer_cpu (FabArray<FAB>& dst, int dcomp, int ncomp,
1438 Vector<char*> const& recv_data,
1439 Vector<std::size_t> const& recv_size,
1440 Vector<const CopyComTagsContainer*> const& recv_cctc,
1441 CpOp op, bool is_thread_safe);
1442
1443#endif
1444
1457 template <typename F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1458 typename F::value_type
1459 norminf (int comp, int ncomp, IntVect const& nghost, bool local = false,
1460 [[maybe_unused]] bool ignore_covered = false) const;
1461
1474 template <typename IFAB, typename F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1475 typename F::value_type
1476 norminf (FabArray<IFAB> const& mask, int comp, int ncomp, IntVect const& nghost,
1477 bool local = false) const;
1478
1479protected:
1480
1481 std::unique_ptr<FabFactory<FAB> > m_factory;
1483 std::unique_ptr<detail::SingleChunkArena> m_single_chunk_arena;
1485
1488
1489 //
1491 std::vector<FAB*> m_fabs_v;
1492
1493#ifdef AMREX_USE_GPU
1494 mutable void* m_dp_arrays = nullptr;
1495#endif
1496 mutable void* m_hp_arrays = nullptr;
1499
1501
1503 struct ShMem {
1504
1505 ShMem () noexcept = default;
1506
1507 ~ShMem () { // NOLINT
1508#if defined(BL_USE_MPI3)
1509 if (win != MPI_WIN_NULL) { MPI_Win_free(&win); }
1510#endif
1511#ifdef BL_USE_TEAM
1512 if (alloc) {
1514 }
1515#endif
1516 }
1517 ShMem (ShMem&& rhs) noexcept
1518 : alloc(rhs.alloc), n_values(rhs.n_values), n_points(rhs.n_points)
1519#if defined(BL_USE_MPI3)
1520 , win(rhs.win)
1521#endif
1522 {
1523 rhs.alloc = false;
1524#if defined(BL_USE_MPI3)
1525 rhs.win = MPI_WIN_NULL;
1526#endif
1527 }
1528 ShMem& operator= (ShMem&& rhs) noexcept {
1529 if (&rhs != this) {
1530 alloc = rhs.alloc;
1531 n_values = rhs.n_values;
1532 n_points = rhs.n_points;
1533 rhs.alloc = false;
1534#if defined(BL_USE_MPI3)
1535 win = rhs.win;
1536 rhs.win = MPI_WIN_NULL;
1537#endif
1538 }
1539 return *this;
1540 }
1541 ShMem (const ShMem&) = delete;
1542 ShMem& operator= (const ShMem&) = delete;
1543 bool alloc{false};
1546#if defined(BL_USE_MPI3)
1547 MPI_Win win = MPI_WIN_NULL;
1548#endif
1549 };
1551
1552 bool SharedMemory () const noexcept { return shmem.alloc; }
1553
1554private:
1555 using Iterator = typename std::vector<FAB*>::iterator;
1556
1557 void AllocFabs (const FabFactory<FAB>& factory, Arena* ar,
1559 bool alloc_single_chunk);
1560
1561 void setFab_assert (int K, FAB const& fab) const;
1562
1563 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1564 void build_arrays () const;
1565
1566 void clear_arrays ();
1567
1568#ifdef AMREX_USE_GPU
1569 std::map<std::uint64_t,
1570 std::unique_ptr<TagVector<Array4CopyTag<value_type>>>>
1571 m_fb_local_copy_handler;
1572
1573 using RecvSendCopyHandlerKey = std::tuple<std::uint64_t,std::size_t,int>;
1574 std::map<RecvSendCopyHandlerKey,
1575 std::unique_ptr<TagVector<CommRecvBufTag<value_type>>>>
1576 m_recv_copy_handler;
1577 mutable std::map<RecvSendCopyHandlerKey,
1578 std::unique_ptr<TagVector<CommSendBufTag<value_type>>>>
1579 m_send_copy_handler;
1580#endif
1581
1582public:
1583
1584#ifdef BL_USE_MPI
1585
1587 template <typename BUF=value_type>
1588 static void PostRcvs (const MapOfCopyComTagContainers& RcvTags,
1589 char*& the_recv_data,
1590 Vector<char*>& recv_data,
1591 Vector<std::size_t>& recv_size,
1592 Vector<int>& recv_from,
1593 Vector<MPI_Request>& recv_reqs,
1594 int ncomp,
1595 int SeqNum);
1596
1597 template <typename BUF=value_type>
1599 static TheFaArenaPointer PostRcvs (const MapOfCopyComTagContainers& RcvTags,
1600 Vector<char*>& recv_data,
1601 Vector<std::size_t>& recv_size,
1602 Vector<int>& recv_from,
1603 Vector<MPI_Request>& recv_reqs,
1604 int ncomp,
1605 int SeqNum);
1606
1607 template <typename BUF=value_type>
1608 static void PrepareSendBuffers (const MapOfCopyComTagContainers& SndTags,
1609 char*& the_send_data,
1610 Vector<char*>& send_data,
1611 Vector<std::size_t>& send_size,
1612 Vector<int>& send_rank,
1613 Vector<MPI_Request>& send_reqs,
1615 int ncomp);
1616
1617 template <typename BUF=value_type>
1619 static TheFaArenaPointer PrepareSendBuffers (const MapOfCopyComTagContainers& SndTags,
1620 Vector<char*>& send_data,
1621 Vector<std::size_t>& send_size,
1622 Vector<int>& send_rank,
1623 Vector<MPI_Request>& send_reqs,
1625 int ncomp);
1626
1627 static void PostSnds (Vector<char*> const& send_data,
1628 Vector<std::size_t> const& send_size,
1629 Vector<int> const& send_rank,
1630 Vector<MPI_Request>& send_reqs,
1631 int SeqNum);
1632#endif
1633
1634 std::unique_ptr<FBData<FAB>> fbd;
1635 std::unique_ptr<PCData<FAB>> pcd;
1636
1637 // Pointer to temporary fab used in non-blocking amrex::OverrideSync
1638 std::unique_ptr< FabArray<FAB> > os_temp;
1639
1640
1641
1653 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1654 static void Saxpy (FabArray<FAB>& y, value_type a, FabArray<FAB> const& x,
1655 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1656
1668 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1669 static void Xpay (FabArray<FAB>& y, value_type a, FabArray<FAB> const& x,
1670 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1671
1686 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1687 static void LinComb (FabArray<FAB>& dst,
1688 value_type a, const FabArray<FAB>& x, int xcomp,
1689 value_type b, const FabArray<FAB>& y, int ycomp,
1690 int dstcomp, int numcomp, const IntVect& nghost);
1691
1705 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1706 static void Saxpy_Xpay (FabArray<FAB>& y, value_type a1, FabArray<FAB> const& x1,
1707 value_type a2, FabArray<FAB> const& x2,
1708 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1709
1724 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1725 static void Saxpy_Saxpy (FabArray<FAB>& y1, value_type a1, FabArray<FAB> const& x1,
1726 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x2,
1727 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1728
1742 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1744 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x,
1745 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1746};
1747
1748}
1749
1750#include <AMReX_FabArrayCommI.H>
1751
1752namespace amrex {
1753
1754template <class FAB>
1755bool
1756FabArray<FAB>::defined (int K) const noexcept
1757{
1758 int li = localindex(K);
1759 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != 0) {
1760 return true;
1761 }
1762 else {
1763 return false;
1764 }
1765}
1766
1767template <class FAB>
1768bool
1769FabArray<FAB>::defined (const MFIter& mfi) const noexcept
1770{
1771 int li = mfi.LocalIndex();
1772 if (li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
1773 return true;
1774 }
1775 else {
1776 return false;
1777 }
1778}
1779
1780template <class FAB>
1781FAB*
1782FabArray<FAB>::fabPtr (const MFIter& mfi) noexcept
1783{
1784 AMREX_ASSERT(mfi.LocalIndex() < indexArray.size());
1785 AMREX_ASSERT(DistributionMap() == mfi.DistributionMap());
1786 int li = mfi.LocalIndex();
1787 return m_fabs_v[li];
1788}
1789
1790template <class FAB>
1791FAB const*
1792FabArray<FAB>::fabPtr (const MFIter& mfi) const noexcept
1793{
1794 AMREX_ASSERT(mfi.LocalIndex() < indexArray.size());
1795 AMREX_ASSERT(DistributionMap() == mfi.DistributionMap());
1796 int li = mfi.LocalIndex();
1797 return m_fabs_v[li];
1798}
1799
1800template <class FAB>
1801FAB*
1803{
1804 int li = localindex(K);
1805 AMREX_ASSERT(li >=0 && li < indexArray.size());
1806 return m_fabs_v[li];
1807}
1808
1809template <class FAB>
1810FAB const*
1811FabArray<FAB>::fabPtr (int K) const noexcept
1812{
1813 int li = localindex(K);
1814 AMREX_ASSERT(li >=0 && li < indexArray.size());
1815 return m_fabs_v[li];
1816}
1817
1818template <class FAB>
1819template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1820void
1822{
1823 using A = Array4<value_type>;
1824 using AC = Array4<value_type const>;
1825 static_assert(sizeof(A) == sizeof(AC), "sizeof(Array4<T>) != sizeof(Array4<T const>)");
1826 if (!m_hp_arrays && local_size() > 0) {
1827 const int n = local_size();
1828#ifdef AMREX_USE_GPU
1829 m_hp_arrays = (void*)The_Pinned_Arena()->alloc(n*2*sizeof(A));
1830 m_dp_arrays = (void*)The_Arena()->alloc(n*2*sizeof(A));
1831#else
1832 m_hp_arrays = std::malloc(n*2*sizeof(A));
1833#endif
1834 for (int li = 0; li < n; ++li) {
1835 if (m_fabs_v[li]) {
1836 new ((A*)m_hp_arrays+li) A(m_fabs_v[li]->array());
1837 new ((AC*)m_hp_arrays+li+n) AC(m_fabs_v[li]->const_array());
1838 } else {
1839 new ((A*)m_hp_arrays+li) A{};
1840 new ((AC*)m_hp_arrays+li+n) AC{};
1841 }
1842 }
1843 m_arrays.hp = (A*)m_hp_arrays;
1844 m_const_arrays.hp = (AC*)m_hp_arrays + n;
1845#ifdef AMREX_USE_GPU
1846 m_arrays.dp = (A*)m_dp_arrays;
1847 m_const_arrays.dp = (AC*)m_dp_arrays + n;
1848 Gpu::htod_memcpy_async(m_dp_arrays, m_hp_arrays, n*2*sizeof(A));
1849 if (!Gpu::inNoSyncRegion()) {
1851 }
1852#endif
1853 }
1854}
1855
1856template <class FAB>
1857void
1858FabArray<FAB>::clear_arrays ()
1859{
1860#ifdef AMREX_USE_GPU
1861 The_Pinned_Arena()->free(m_hp_arrays);
1862 The_Arena()->free(m_dp_arrays);
1863 m_dp_arrays = nullptr;
1864#else
1865 std::free(m_hp_arrays);
1866#endif
1867 m_hp_arrays = nullptr;
1868 m_arrays.hp = nullptr;
1869 m_const_arrays.hp = nullptr;
1870}
1871
1872template <class FAB>
1874FAB*
1876{
1877 const int li = localindex(K);
1878 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
1879 AMREX_ASSERT(m_single_chunk_arena == nullptr);
1880 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
1881 if (nbytes > 0) {
1882 for (auto const& t : m_tags) {
1883 updateMemUsage(t, -nbytes, nullptr);
1884 }
1885 }
1886 return std::exchange(m_fabs_v[li], nullptr);
1887 } else {
1888 return nullptr;
1889 }
1890}
1891
1892template <class FAB>
1894FAB*
1896{
1897 const int li = mfi.LocalIndex();
1898 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
1899 AMREX_ASSERT(m_single_chunk_arena == nullptr);
1900 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
1901 if (nbytes > 0) {
1902 for (auto const& t : m_tags) {
1903 updateMemUsage(t, -nbytes, nullptr);
1904 }
1905 }
1906 return std::exchange(m_fabs_v[li], nullptr);
1907 } else {
1908 return nullptr;
1909 }
1910}
1911
1912template <class FAB>
1913void
1915{
1916 if (define_function_called)
1917 {
1918 define_function_called = false;
1919 clearThisBD();
1920 }
1921
1922 Long nbytes = 0L;
1923 for (auto *x : m_fabs_v) {
1924 if (x) {
1925 nbytes += amrex::nBytesOwned(*x);
1926 m_factory->destroy(x);
1927 }
1928 }
1929 m_fabs_v.clear();
1930 clear_arrays();
1931 m_factory.reset();
1932 m_dallocator.m_arena = nullptr;
1933 // no need to clear the non-blocking fillboundary stuff
1934
1935 if (nbytes > 0) {
1936 for (auto const& t : m_tags) {
1937 updateMemUsage(t, -nbytes, nullptr);
1938 }
1939 }
1940
1941 if (m_single_chunk_arena) {
1942 m_single_chunk_arena.reset();
1943 }
1944 m_single_chunk_size = 0;
1945
1946 m_tags.clear();
1947
1948#ifdef AMREX_USE_GPU
1949 m_fb_local_copy_handler.clear();
1950 m_recv_copy_handler.clear();
1951 m_send_copy_handler.clear();
1952#endif
1953
1955}
1956
1957template <class FAB>
1958template <typename SFAB, typename DFAB,
1959 std::enable_if_t<std::conjunction_v<
1961 std::is_convertible<typename SFAB::value_type,
1962 typename DFAB::value_type>>, int>>
1963void
1964FabArray<FAB>::LocalCopy (FabArray<SFAB> const& src, int scomp, int dcomp, int ncomp,
1965 IntVect const& nghost)
1966{
1967 amrex::Copy(*this, src, scomp, dcomp, ncomp, nghost);
1968}
1969
1970template <class FAB>
1971template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1972void
1973FabArray<FAB>::LocalAdd (FabArray<FAB> const& src, int scomp, int dcomp, int ncomp,
1974 IntVect const& nghost)
1975{
1976 amrex::Add(*this, src, scomp, dcomp, ncomp, nghost);
1977}
1978
1979template <class FAB>
1980template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1981void
1983{
1984 setVal(val,0,n_comp,IntVect(nghost));
1985}
1986
1987template <class FAB>
1988template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1989void
1991{
1992 setVal(val,0,n_comp,nghost);
1993}
1994
1995template <class FAB>
1996template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1997void
1998FabArray<FAB>::setVal (value_type val, const Box& region, int nghost)
1999{
2000 setVal(val,region,0,n_comp,IntVect(nghost));
2001}
2002
2003template <class FAB>
2004template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2005void
2006FabArray<FAB>::setVal (value_type val, const Box& region, const IntVect& nghost)
2007{
2008 setVal(val,region,0,n_comp,nghost);
2009}
2010
2011template <class FAB>
2013 : shmem()
2014{
2015 m_FA_stats.recordBuild();
2016}
2017
2018template <class FAB>
2020 : m_dallocator(a),
2021 shmem()
2022{
2023 m_FA_stats.recordBuild();
2024}
2025
2026template <class FAB>
2028 const DistributionMapping& dm,
2029 int nvar,
2030 int ngrow,
2031 const MFInfo& info,
2032 const FabFactory<FAB>& factory)
2033 : FabArray<FAB>(bxs,dm,nvar,IntVect(ngrow),info,factory)
2034{}
2035
2036template <class FAB>
2038 const DistributionMapping& dm,
2039 int nvar,
2040 const IntVect& ngrow,
2041 const MFInfo& info,
2042 const FabFactory<FAB>& factory)
2043 : m_factory(factory.clone()),
2044 shmem()
2045{
2047 define(bxs,dm,nvar,ngrow,info,*m_factory);
2048}
2049
2050template <class FAB>
2051FabArray<FAB>::FabArray (const FabArray<FAB>& rhs, MakeType maketype, int scomp, int ncomp)
2052 : m_factory(rhs.Factory().clone()),
2053 shmem()
2054{
2056 define(rhs.boxArray(), rhs.DistributionMap(), ncomp, rhs.nGrowVect(),
2057 MFInfo().SetAlloc(false), *m_factory);
2058
2059 if (maketype == amrex::make_alias)
2060 {
2061 for (int i = 0, n = indexArray.size(); i < n; ++i) {
2062 auto const& rhsfab = *(rhs.m_fabs_v[i]);
2063 m_fabs_v.push_back(m_factory->create_alias(rhsfab, scomp, ncomp));
2064 }
2065 }
2066 else
2067 {
2068 amrex::Abort("FabArray: unknown MakeType");
2069 }
2070}
2071
2072template <class FAB>
2074 : FabArrayBase (static_cast<FabArrayBase&&>(rhs))
2075 , m_factory (std::move(rhs.m_factory))
2076 , m_dallocator (rhs.m_dallocator)
2077 , m_single_chunk_arena(std::move(rhs.m_single_chunk_arena))
2078 , m_single_chunk_size(std::exchange(rhs.m_single_chunk_size,0))
2079 , define_function_called(rhs.define_function_called)
2080 , m_fabs_v (std::move(rhs.m_fabs_v))
2081#ifdef AMREX_USE_GPU
2082 , m_dp_arrays (std::exchange(rhs.m_dp_arrays, nullptr))
2083#endif
2084 , m_hp_arrays (std::exchange(rhs.m_hp_arrays, nullptr))
2085 , m_arrays (rhs.m_arrays)
2086 , m_const_arrays(rhs.m_const_arrays)
2087 , m_tags (std::move(rhs.m_tags))
2088 , shmem (std::move(rhs.shmem))
2089#ifdef AMREX_USE_GPU
2090 , m_fb_local_copy_handler(std::move(rhs.m_fb_local_copy_handler))
2091 , m_recv_copy_handler(std::move(rhs.m_recv_copy_handler))
2092 , m_send_copy_handler(std::move(rhs.m_send_copy_handler))
2093#endif
2094 // no need to worry about the data used in non-blocking FillBoundary.
2095{
2096 m_FA_stats.recordBuild();
2097 rhs.define_function_called = false; // the responsibility of clear BD has been transferred.
2098 rhs.m_fabs_v.clear(); // clear the data pointers so that rhs.clear does not delete them.
2099 rhs.clear();
2100}
2101
2102template <class FAB>
2105{
2106 if (&rhs != this)
2107 {
2108 clear();
2109
2110 FabArrayBase::operator=(static_cast<FabArrayBase&&>(rhs));
2111 m_factory = std::move(rhs.m_factory);
2112 m_dallocator = rhs.m_dallocator;
2113 m_single_chunk_arena = std::move(rhs.m_single_chunk_arena);
2114 std::swap(m_single_chunk_size, rhs.m_single_chunk_size);
2115 define_function_called = rhs.define_function_called;
2116 std::swap(m_fabs_v, rhs.m_fabs_v);
2117#ifdef AMREX_USE_GPU
2118 std::swap(m_dp_arrays, rhs.m_dp_arrays);
2119#endif
2120 std::swap(m_hp_arrays, rhs.m_hp_arrays);
2121 m_arrays = rhs.m_arrays;
2122 m_const_arrays = rhs.m_const_arrays;
2123 std::swap(m_tags, rhs.m_tags);
2124 shmem = std::move(rhs.shmem);
2125#ifdef AMREX_USE_GPU
2126 std::swap(m_fb_local_copy_handler, rhs.m_fb_local_copy_handler);
2127 std::swap(m_recv_copy_handler, rhs.m_recv_copy_handler);
2128 std::swap(m_send_copy_handler, rhs.m_send_copy_handler);
2129#endif
2130
2131 rhs.define_function_called = false;
2132 rhs.m_fabs_v.clear();
2133 rhs.m_tags.clear();
2134 rhs.clear();
2135 }
2136 return *this;
2137}
2138
2139template <class FAB>
2141{
2142 m_FA_stats.recordDelete();
2143 clear();
2144}
2145
2146template <class FAB>
2147bool
2149{
2150 if (!define_function_called) { return false; }
2151
2152 int isok = 1;
2153
2154 for (MFIter fai(*this); fai.isValid() && isok; ++fai)
2155 {
2156 if (defined(fai))
2157 {
2158 if (get(fai).box() != fabbox(fai.index()))
2159 {
2160 isok = 0;
2161 }
2162 }
2163 else
2164 {
2165 isok = 0;
2166 }
2167 }
2168
2170
2171 return isok == 1;
2172}
2173
2174template <class FAB>
2175bool
2177{
2178 return define_function_called;
2179}
2180
2181template <class FAB>
2182void
2184 const DistributionMapping& dm,
2185 int nvar,
2186 int ngrow,
2187 const MFInfo& info,
2188 const FabFactory<FAB>& a_factory)
2189{
2190 define(bxs,dm,nvar,IntVect(ngrow),info,a_factory);
2191}
2192
2193template <class FAB>
2194void
2196 const DistributionMapping& dm,
2197 int nvar,
2198 const IntVect& ngrow,
2199 const MFInfo& info,
2200 const FabFactory<FAB>& a_factory)
2201{
2202 std::unique_ptr<FabFactory<FAB> > factory(a_factory.clone());
2203
2204 auto *default_arena = m_dallocator.m_arena;
2205 clear();
2206
2207 m_factory = std::move(factory);
2208 m_dallocator.m_arena = info.arena ? info.arena : default_arena;
2209
2210 define_function_called = true;
2211
2212 AMREX_ASSERT(ngrow.allGE(0));
2213 AMREX_ASSERT(boxarray.empty());
2214 FabArrayBase::define(bxs, dm, nvar, ngrow);
2215
2216 addThisBD();
2217
2218 if(info.alloc) {
2219 AllocFabs(*m_factory, m_dallocator.m_arena, info.tags, info.alloc_single_chunk);
2220#ifdef BL_USE_TEAM
2222#endif
2223 }
2224}
2225
2226template <class FAB>
2227void
2229 const Vector<std::string>& tags, bool alloc_single_chunk)
2230{
2231 if (shmem.alloc) { alloc_single_chunk = false; }
2232 if constexpr (!IsBaseFab_v<FAB>) { alloc_single_chunk = false; }
2233
2234 const int n = indexArray.size();
2235 const int nworkers = ParallelDescriptor::TeamSize();
2236 shmem.alloc = (nworkers > 1);
2237
2238 bool alloc = !shmem.alloc;
2239
2240 FabInfo fab_info;
2241 fab_info.SetAlloc(alloc).SetShared(shmem.alloc).SetArena(ar);
2242
2243 if (alloc_single_chunk) {
2244 m_single_chunk_size = 0L;
2245 for (int i = 0; i < n; ++i) {
2246 int K = indexArray[i];
2247 const Box& tmpbox = fabbox(K);
2248 m_single_chunk_size += factory.nBytes(tmpbox, n_comp, K);
2249 }
2250 AMREX_ASSERT(m_single_chunk_size >= 0); // 0 is okay.
2251 m_single_chunk_arena = std::make_unique<detail::SingleChunkArena>(ar, m_single_chunk_size);
2252 fab_info.SetArena(m_single_chunk_arena.get());
2253 }
2254
2255 m_fabs_v.reserve(n);
2256
2257 Long nbytes = 0L;
2258 for (int i = 0; i < n; ++i)
2259 {
2260 int K = indexArray[i];
2261 const Box& tmpbox = fabbox(K);
2262 m_fabs_v.push_back(factory.create(tmpbox, n_comp, fab_info, K));
2263 nbytes += amrex::nBytesOwned(*m_fabs_v.back());
2264 }
2265
2266 m_tags.clear();
2267 m_tags.emplace_back("All");
2268 for (auto const& t : m_region_tag) {
2269 m_tags.push_back(t);
2270 }
2271 for (auto const& t : tags) {
2272 m_tags.push_back(t);
2273 }
2274 for (auto const& t: m_tags) {
2275 updateMemUsage(t, nbytes, ar);
2276 }
2277
2278#ifdef BL_USE_TEAM
2279 if (shmem.alloc)
2280 {
2281 const int teamlead = ParallelDescriptor::MyTeamLead();
2282
2283 shmem.n_values = 0;
2284 shmem.n_points = 0;
2285 Vector<Long> offset(n,0);
2286 Vector<Long> nextoffset(nworkers,-1);
2287 for (int i = 0; i < n; ++i) {
2288 int K = indexArray[i];
2289 int owner = distributionMap[K] - teamlead;
2290 Long s = m_fabs_v[i]->size();
2291 if (ownership[i]) {
2292 shmem.n_values += s;
2293 shmem.n_points += m_fabs_v[i]->numPts();
2294 }
2295 if (nextoffset[owner] < 0) {
2296 offset[i] = 0;
2297 nextoffset[owner] = s;
2298 } else {
2299 offset[i] = nextoffset[owner];
2300 nextoffset[owner] += s;
2301 }
2302 }
2303
2304 size_t bytes = shmem.n_values*sizeof(value_type);
2305
2306 value_type *mfp;
2307 Vector<value_type*> dps;
2308
2309#if defined (BL_USE_MPI3)
2310
2311 static MPI_Info info = MPI_INFO_NULL;
2312 if (info == MPI_INFO_NULL) {
2313 MPI_Info_create(&info);
2314 MPI_Info_set(info, "alloc_shared_noncontig", "true");
2315 }
2316
2317 const MPI_Comm& team_comm = ParallelDescriptor::MyTeam().get();
2318
2319 BL_MPI_REQUIRE( MPI_Win_allocate_shared(bytes, sizeof(value_type),
2320 info, team_comm, &mfp, &shmem.win) );
2321
2322 for (int w = 0; w < nworkers; ++w) {
2323 MPI_Aint sz;
2324 int disp;
2325 value_type *dptr = 0;
2326 BL_MPI_REQUIRE( MPI_Win_shared_query(shmem.win, w, &sz, &disp, &dptr) );
2327 // AMREX_ASSERT(disp == sizeof(value_type));
2328 dps.push_back(dptr);
2329 }
2330
2331#else
2332
2333 amrex::Abort("BaseFab::define: to allocate shared memory, USE_MPI3 must be true");
2334
2335#endif
2336
2337 for (int i = 0; i < n; ++i) {
2338 int K = indexArray[i];
2339 int owner = distributionMap[K] - teamlead;
2340 value_type *p = dps[owner] + offset[i];
2341 m_fabs_v[i]->setPtr(p, m_fabs_v[i]->size());
2342 }
2343
2344 for (Long i = 0; i < shmem.n_values; i++, mfp++) {
2345 new (mfp) value_type;
2346 }
2347
2348 amrex::update_fab_stats(shmem.n_points, shmem.n_values, sizeof(value_type));
2349 }
2350#endif
2351}
2352
2353template <class FAB>
2354void
2355FabArray<FAB>::setFab_assert (int K, FAB const& fab) const
2356{
2357 amrex::ignore_unused(K,fab);
2358 AMREX_ASSERT(n_comp == fab.nComp());
2359 AMREX_ASSERT(!boxarray.empty());
2360 AMREX_ASSERT(fab.box() == fabbox(K));
2361 AMREX_ASSERT(distributionMap[K] == ParallelDescriptor::MyProc());
2362 AMREX_ASSERT(m_single_chunk_arena == nullptr);
2363}
2364
2365template <class FAB>
2366void
2367FabArray<FAB>::setFab (int boxno, std::unique_ptr<FAB> elem)
2368{
2369 if (n_comp == 0) {
2370 n_comp = elem->nComp();
2371 }
2372
2373 setFab_assert(boxno, *elem);
2374
2375 if (m_fabs_v.empty()) {
2376 m_fabs_v.resize(indexArray.size(),nullptr);
2377 }
2378
2379 const int li = localindex(boxno);
2380 if (m_fabs_v[li]) {
2381 m_factory->destroy(m_fabs_v[li]);
2382 }
2383 m_fabs_v[li] = elem.release();
2384}
2385
2386template <class FAB>
2387template <class F, std::enable_if_t<std::is_move_constructible_v<F>,int> >
2388void
2389FabArray<FAB>::setFab (int boxno, FAB&& elem)
2390{
2391 if (n_comp == 0) {
2392 n_comp = elem.nComp();
2393 }
2394
2395 setFab_assert(boxno, elem);
2396
2397 if (m_fabs_v.empty()) {
2398 m_fabs_v.resize(indexArray.size(),nullptr);
2399 }
2400
2401 const int li = localindex(boxno);
2402 if (m_fabs_v[li]) {
2403 m_factory->destroy(m_fabs_v[li]);
2404 }
2405 m_fabs_v[li] = new FAB(std::move(elem));
2406}
2407
2408template <class FAB>
2409void
2410FabArray<FAB>::setFab (const MFIter& mfi, std::unique_ptr<FAB> elem)
2411{
2412 if (n_comp == 0) {
2413 n_comp = elem->nComp();
2414 }
2415
2416 setFab_assert(mfi.index(), *elem);
2417
2418 if (m_fabs_v.empty()) {
2419 m_fabs_v.resize(indexArray.size(),nullptr);
2420 }
2421
2422 const int li = mfi.LocalIndex();
2423 if (m_fabs_v[li]) {
2424 m_factory->destroy(m_fabs_v[li]);
2425 }
2426 m_fabs_v[li] = elem.release();
2427}
2428
2429template <class FAB>
2430template <class F, std::enable_if_t<std::is_move_constructible_v<F>,int> >
2431void
2432FabArray<FAB>::setFab (const MFIter& mfi, FAB&& elem)
2433{
2434 if (n_comp == 0) {
2435 n_comp = elem.nComp();
2436 }
2437
2438 setFab_assert(mfi.index(), elem);
2439
2440 if (m_fabs_v.empty()) {
2441 m_fabs_v.resize(indexArray.size(),nullptr);
2442 }
2443
2444 const int li = mfi.LocalIndex();
2445 if (m_fabs_v[li]) {
2446 m_factory->destroy(m_fabs_v[li]);
2447 }
2448 m_fabs_v[li] = new FAB(std::move(elem));
2449}
2450
2451template <class FAB>
2452template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2453void
2455{
2456 setBndry(val, 0, n_comp);
2457}
2458
2459template <class FAB>
2460template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2461void
2463 int strt_comp,
2464 int ncomp)
2465{
2466 if (n_grow.max() > 0)
2467 {
2468#ifdef AMREX_USE_GPU
2469 if (Gpu::inLaunchRegion()) {
2470 bool use_mfparfor = true;
2471 const int nboxes = local_size();
2472 if (nboxes == 1) {
2473 if (boxarray[indexArray[0]].numPts() > Long(65*65*65)) {
2474 use_mfparfor = false;
2475 }
2476 } else {
2477 for (int i = 0; i < nboxes; ++i) {
2478 const Long npts = boxarray[indexArray[i]].numPts();
2479 if (npts >= Long(64*64*64)) {
2480 use_mfparfor = false;
2481 break;
2482 } else if (npts <= Long(17*17*17)) {
2483 break;
2484 }
2485 }
2486 }
2487 const IntVect nghost = n_grow;
2488 if (use_mfparfor) {
2489 auto const& ma = this->arrays();
2490 ParallelFor(*this, nghost,
2491 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2492 {
2493 auto const& a = ma[box_no];
2494 Box vbx(a);
2495 vbx.grow(-nghost);
2496 if (!vbx.contains(i,j,k)) {
2497 for (int n = 0; n < ncomp; ++n) {
2498 a(i,j,k,strt_comp+n) = val;
2499 }
2500 }
2501 });
2502 if (!Gpu::inNoSyncRegion()) {
2504 }
2505 } else {
2506 using Tag = Array4BoxTag<value_type>;
2507 Vector<Tag> tags;
2508 for (MFIter mfi(*this); mfi.isValid(); ++mfi) {
2509 Box const& vbx = mfi.validbox();
2510 auto const& a = this->array(mfi);
2511
2512 Box b;
2513#if (AMREX_SPACEDIM == 3)
2514 if (nghost[2] > 0) {
2515 b = vbx;
2516 b.setRange(2, vbx.smallEnd(2)-nghost[2], nghost[2]);
2517 b.grow(IntVect(nghost[0],nghost[1],0));
2518 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2519 b.shift(2, vbx.length(2)+nghost[2]);
2520 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2521 }
2522#endif
2523#if (AMREX_SPACEDIM >= 2)
2524 if (nghost[1] > 0) {
2525 b = vbx;
2526 b.setRange(1, vbx.smallEnd(1)-nghost[1], nghost[1]);
2527 b.grow(0, nghost[0]);
2528 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2529 b.shift(1, vbx.length(1)+nghost[1]);
2530 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2531 }
2532#endif
2533 if (nghost[0] > 0) {
2534 b = vbx;
2535 b.setRange(0, vbx.smallEnd(0)-nghost[0], nghost[0]);
2536 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2537 b.shift(0, vbx.length(0)+nghost[0]);
2538 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2539 }
2540 }
2541
2542 ParallelFor(tags, ncomp,
2543 [=] AMREX_GPU_DEVICE (int i, int j, int k, int n, Tag const& tag) noexcept
2544 {
2545 tag.dfab(i,j,k,strt_comp+n) = val;
2546 });
2547 }
2548 } else
2549#endif
2550 {
2551#ifdef AMREX_USE_OMP
2552#pragma omp parallel
2553#endif
2554 for (MFIter fai(*this); fai.isValid(); ++fai)
2555 {
2556 get(fai).template setComplement<RunOn::Host>(val, fai.validbox(), strt_comp, ncomp);
2557 }
2558 }
2559 }
2560}
2561
2562template <class FAB>
2563template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2564void
2566{
2567 setDomainBndry(val, 0, n_comp, geom);
2568}
2569
2570template <class FAB>
2571template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2572void
2574 int strt_comp,
2575 int ncomp,
2576 const Geometry& geom)
2577{
2578 BL_PROFILE("FabArray::setDomainBndry()");
2579
2580 Box domain_box = amrex::convert(geom.Domain(), boxArray().ixType());
2581 for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
2582 if (geom.isPeriodic(idim)) {
2583 int n = domain_box.length(idim);
2584 domain_box.grow(idim, n);
2585 }
2586 }
2587
2588#ifdef AMREX_USE_OMP
2589#pragma omp parallel if (Gpu::notInLaunchRegion())
2590#endif
2591 for (MFIter fai(*this); fai.isValid(); ++fai)
2592 {
2593 const Box& gbx = fai.fabbox();
2594 if (! domain_box.contains(gbx))
2595 {
2596 get(fai).template setComplement<RunOn::Device>(val, domain_box, strt_comp, ncomp);
2597 }
2598 }
2599}
2600
2601
2602template <class FAB>
2603template <typename I, class F, std::enable_if_t<IsBaseFab<F>::value && std::is_integral_v<I> && (sizeof(I) >= sizeof(Long)), int> FOO>
2604void
2606 AMREX_ASSERT(amrex::isMFIterSafe(*this, mem));
2607 for (MFIter mfi(*this, MFItInfo{}.DisableDeviceSync()); mfi.isValid(); ++mfi) {
2608 mem[mfi] += static_cast<I>((*this)[mfi].nBytesOwned());
2609 }
2610}
2611
2612template <class FAB>
2613template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
2614typename F::value_type
2615FabArray<FAB>::sum (int comp, IntVect const& nghost, bool local) const
2616{
2617 BL_PROFILE("FabArray::sum()");
2618
2619 using T = typename FAB::value_type;
2620 auto sm = T(0.0);
2621#ifdef AMREX_USE_GPU
2622 if (Gpu::inLaunchRegion()) {
2623 auto const& ma = this->const_arrays();
2624 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, *this, nghost,
2625 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2626 -> GpuTuple<T>
2627 {
2628 return ma[box_no](i,j,k,comp);
2629 });
2630 } else
2631#endif
2632 {
2633#ifdef AMREX_USE_OMP
2634#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
2635#endif
2636 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi)
2637 {
2638 Box const& bx = mfi.growntilebox(nghost);
2639 auto const& a = this->const_array(mfi);
2640 auto tmp = T(0.0);
2641 AMREX_LOOP_3D(bx, i, j, k,
2642 {
2643 tmp += a(i,j,k,comp);
2644 });
2645 sm += tmp; // Do it this way so that it does not break regression tests.
2646 }
2647 }
2648
2649 if (!local) {
2651 }
2652
2653 return sm;
2654}
2655
2656template <class FAB>
2657void
2658FabArray<FAB>::copyTo (FAB& dest, int nghost) const
2659{
2660 copyTo(dest, 0, 0, dest.nComp(), nghost);
2661}
2662
2663template <class FAB>
2664template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2665void
2667{
2668 setVal(val,0,n_comp,n_grow);
2669}
2670
2671template <class FAB>
2672template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2675{
2676 setVal(val);
2677 return *this;
2678}
2679
2680template <class FAB>
2681template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2682void
2684 int comp,
2685 int ncomp,
2686 int nghost)
2687{
2688 setVal(val,comp,ncomp,IntVect(nghost));
2689}
2690
2691template <class FAB>
2692template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2693void
2695 int comp,
2696 int ncomp,
2697 const IntVect& nghost)
2698{
2699 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2700 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2701
2702 BL_PROFILE("FabArray::setVal()");
2703
2704#ifdef AMREX_USE_GPU
2705 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2706 auto const& fa = this->arrays();
2707 ParallelFor(*this, nghost, ncomp,
2708 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2709 {
2710 fa[box_no](i,j,k,n+comp) = val;
2711 });
2712 if (!Gpu::inNoSyncRegion()) {
2714 }
2715 } else
2716#endif
2717 {
2718#ifdef AMREX_USE_OMP
2719#pragma omp parallel if (Gpu::notInLaunchRegion())
2720#endif
2721 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
2722 {
2723 const Box& bx = fai.growntilebox(nghost);
2724 auto fab = this->array(fai);
2725 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
2726 {
2727 fab(i,j,k,n+comp) = val;
2728 });
2729 }
2730 }
2731}
2732
2733template <class FAB>
2734template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2735void
2737 const Box& region,
2738 int comp,
2739 int ncomp,
2740 int nghost)
2741{
2742 setVal(val,region,comp,ncomp,IntVect(nghost));
2743}
2744
2745template <class FAB>
2746template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2747void
2749 const Box& region,
2750 int comp,
2751 int ncomp,
2752 const IntVect& nghost)
2753{
2754 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2755 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2756
2757 BL_PROFILE("FabArray::setVal(val,region,comp,ncomp,nghost)");
2758
2759#ifdef AMREX_USE_GPU
2760 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2761 auto const& fa = this->arrays();
2762 ParallelFor(*this, nghost, ncomp,
2763 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2764 {
2765 if (region.contains(i,j,k)) {
2766 fa[box_no](i,j,k,n+comp) = val;
2767 }
2768 });
2769 if (!Gpu::inNoSyncRegion()) {
2771 }
2772 } else
2773#endif
2774 {
2775#ifdef AMREX_USE_OMP
2776 AMREX_ALWAYS_ASSERT(!omp_in_parallel());
2777#pragma omp parallel if (Gpu::notInLaunchRegion())
2778#endif
2779 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
2780 {
2781 Box b = fai.growntilebox(nghost) & region;
2782
2783 if (b.ok()) {
2784 auto fab = this->array(fai);
2785 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( b, ncomp, i, j, k, n,
2786 {
2787 fab(i,j,k,n+comp) = val;
2788 });
2789 }
2790 }
2791 }
2792}
2793
2794template <class FAB>
2795template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2796void
2797FabArray<FAB>::abs (int comp, int ncomp, int nghost)
2798{
2799 abs(comp, ncomp, IntVect(nghost));
2800}
2801
2802template <class FAB>
2803template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2804void
2805FabArray<FAB>::abs (int comp, int ncomp, const IntVect& nghost)
2806{
2807 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2808 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2809 BL_PROFILE("FabArray::abs()");
2810
2811#ifdef AMREX_USE_GPU
2812 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2813 auto const& fa = this->arrays();
2814 ParallelFor(*this, nghost, ncomp,
2815 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2816 {
2817 fa[box_no](i,j,k,n+comp) = std::abs(fa[box_no](i,j,k,n+comp));
2818 });
2819 if (!Gpu::inNoSyncRegion()) {
2821 }
2822 } else
2823#endif
2824 {
2825#ifdef AMREX_USE_OMP
2826#pragma omp parallel if (Gpu::notInLaunchRegion())
2827#endif
2828 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2829 {
2830 const Box& bx = mfi.growntilebox(nghost);
2831 auto fab = this->array(mfi);
2832 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
2833 {
2834 fab(i,j,k,n+comp) = std::abs(fab(i,j,k,n+comp));
2835 });
2836 }
2837 }
2838}
2839
2840template <class FAB>
2841template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2842void
2843FabArray<FAB>::plus (value_type val, int comp, int num_comp, int nghost)
2844{
2845 BL_PROFILE("FabArray::plus()");
2846
2847#ifdef AMREX_USE_GPU
2848 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2849 auto const& fa = this->arrays();
2850 ParallelFor(*this, IntVect(nghost), num_comp,
2851 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2852 {
2853 fa[box_no](i,j,k,n+comp) += val;
2854 });
2855 if (!Gpu::inNoSyncRegion()) {
2857 }
2858 } else
2859#endif
2860 {
2861#ifdef AMREX_USE_OMP
2862#pragma omp parallel if (Gpu::notInLaunchRegion())
2863#endif
2864 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2865 {
2866 const Box& bx = mfi.growntilebox(nghost);
2867 auto fab = this->array(mfi);
2868 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2869 {
2870 fab(i,j,k,n+comp) += val;
2871 });
2872 }
2873 }
2874}
2875
2876template <class FAB>
2877template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2878void
2879FabArray<FAB>::plus (value_type val, const Box& region, int comp, int num_comp, int nghost)
2880{
2881 BL_PROFILE("FabArray::plus(val, region, comp, num_comp, nghost)");
2882
2883#ifdef AMREX_USE_GPU
2884 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2885 auto const& fa = this->arrays();
2886 ParallelFor(*this, IntVect(nghost), num_comp,
2887 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2888 {
2889 if (region.contains(i,j,k)) {
2890 fa[box_no](i,j,k,n+comp) += val;
2891 }
2892 });
2893 if (!Gpu::inNoSyncRegion()) {
2895 }
2896 } else
2897#endif
2898 {
2899#ifdef AMREX_USE_OMP
2900#pragma omp parallel if (Gpu::notInLaunchRegion())
2901#endif
2902 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2903 {
2904 const Box& bx = mfi.growntilebox(nghost) & region;
2905 if (bx.ok()) {
2906 auto fab = this->array(mfi);
2907 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2908 {
2909 fab(i,j,k,n+comp) += val;
2910 });
2911 }
2912 }
2913 }
2914}
2915
2916template <class FAB>
2917template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2918void
2919FabArray<FAB>::mult (value_type val, int comp, int num_comp, int nghost)
2920{
2921 BL_PROFILE("FabArray::mult()");
2922
2923#ifdef AMREX_USE_GPU
2924 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2925 auto const& fa = this->arrays();
2926 ParallelFor(*this, IntVect(nghost), num_comp,
2927 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2928 {
2929 fa[box_no](i,j,k,n+comp) *= val;
2930 });
2931 if (!Gpu::inNoSyncRegion()) {
2933 }
2934 } else
2935#endif
2936 {
2937#ifdef AMREX_USE_OMP
2938#pragma omp parallel if (Gpu::notInLaunchRegion())
2939#endif
2940 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2941 {
2942 const Box& bx = mfi.growntilebox(nghost);
2943 auto fab = this->array(mfi);
2944 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2945 {
2946 fab(i,j,k,n+comp) *= val;
2947 });
2948 }
2949 }
2950}
2951
2952template <class FAB>
2953template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2954void
2955FabArray<FAB>::mult (value_type val, const Box& region, int comp, int num_comp, int nghost)
2956{
2957 BL_PROFILE("FabArray::mult(val, region, comp, num_comp, nghost)");
2958
2959#ifdef AMREX_USE_GPU
2960 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2961 auto const& fa = this->arrays();
2962 ParallelFor(*this, IntVect(nghost), num_comp,
2963 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2964 {
2965 if (region.contains(i,j,k)) {
2966 fa[box_no](i,j,k,n+comp) *= val;
2967 }
2968 });
2969 if (!Gpu::inNoSyncRegion()) {
2971 }
2972 } else
2973#endif
2974 {
2975#ifdef AMREX_USE_OMP
2976#pragma omp parallel if (Gpu::notInLaunchRegion())
2977#endif
2978 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2979 {
2980 const Box& bx = mfi.growntilebox(nghost) & region;
2981 if (bx.ok()) {
2982 auto fab = this->array(mfi);
2983 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2984 {
2985 fab(i,j,k,n+comp) *= val;
2986 });
2987 }
2988 }
2989 }
2990}
2991
2992template <class FAB>
2993template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2994void
2995FabArray<FAB>::invert (value_type numerator, int comp, int num_comp, int nghost)
2996{
2997 BL_PROFILE("FabArray::invert()");
2998
2999#ifdef AMREX_USE_GPU
3000 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3001 auto const& fa = this->arrays();
3002 ParallelFor(*this, IntVect(nghost), num_comp,
3003 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3004 {
3005 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
3006 });
3007 if (!Gpu::inNoSyncRegion()) {
3009 }
3010 } else
3011#endif
3012 {
3013#ifdef AMREX_USE_OMP
3014#pragma omp parallel if (Gpu::notInLaunchRegion())
3015#endif
3016 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3017 {
3018 const Box& bx = mfi.growntilebox(nghost);
3019 auto fab = this->array(mfi);
3020 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3021 {
3022 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
3023 });
3024 }
3025 }
3026}
3027
3028template <class FAB>
3029template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
3030void
3031FabArray<FAB>::invert (value_type numerator, const Box& region, int comp, int num_comp, int nghost)
3032{
3033 BL_PROFILE("FabArray::invert(numerator, region, comp, num_comp, nghost)");
3034
3035#ifdef AMREX_USE_GPU
3036 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3037 auto const& fa = this->arrays();
3038 ParallelFor(*this, IntVect(nghost), num_comp,
3039 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3040 {
3041 if (region.contains(i,j,k)) {
3042 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
3043 }
3044 });
3045 if (!Gpu::inNoSyncRegion()) {
3047 }
3048 } else
3049#endif
3050 {
3051#ifdef AMREX_USE_OMP
3052#pragma omp parallel if (Gpu::notInLaunchRegion())
3053#endif
3054 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3055 {
3056 const Box& bx = mfi.growntilebox(nghost) & region;
3057 if (bx.ok()) {
3058 auto fab = this->array(mfi);
3059 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3060 {
3061 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
3062 });
3063 }
3064 }
3065 }
3066}
3067
3068template <class FAB>
3069void
3071{
3072 clearThisBD(); // The new boxarray will have a different ID.
3073 boxarray.shift(v);
3074 addThisBD();
3075#ifdef AMREX_USE_OMP
3076#pragma omp parallel
3077#endif
3078 for (MFIter fai(*this); fai.isValid(); ++fai)
3079 {
3080 get(fai).shift(v);
3081 }
3082 clear_arrays();
3083}
3084
3085template <class FAB>
3086template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3088 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3089{
3090 AMREX_ASSERT(y.boxArray() == x.boxArray());
3091 AMREX_ASSERT(y.distributionMap == x.distributionMap);
3092 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
3093
3094 BL_PROFILE("FabArray::Saxpy()");
3095
3096#ifdef AMREX_USE_GPU
3097 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3098 auto const& yma = y.arrays();
3099 auto const& xma = x.const_arrays();
3100 ParallelFor(y, nghost, ncomp,
3101 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3102 {
3103 yma[box_no](i,j,k,ycomp+n) += a * xma[box_no](i,j,k,xcomp+n);
3104 });
3105 if (!Gpu::inNoSyncRegion()) {
3107 }
3108 } else
3109#endif
3110 {
3111#ifdef AMREX_USE_OMP
3112#pragma omp parallel if (Gpu::notInLaunchRegion())
3113#endif
3114 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3115 {
3116 const Box& bx = mfi.growntilebox(nghost);
3117
3118 if (bx.ok()) {
3119 auto const& xfab = x.const_array(mfi);
3120 auto const& yfab = y.array(mfi);
3121 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3122 {
3123 yfab(i,j,k,ycomp+n) += a * xfab(i,j,k,xcomp+n);
3124 });
3125 }
3126 }
3127 }
3128}
3129
3130template <class FAB>
3131template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3132void
3134 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3135{
3136 AMREX_ASSERT(y.boxArray() == x.boxArray());
3137 AMREX_ASSERT(y.distributionMap == x.distributionMap);
3138 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
3139
3140 BL_PROFILE("FabArray::Xpay()");
3141
3142#ifdef AMREX_USE_GPU
3143 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3144 auto const& yfa = y.arrays();
3145 auto const& xfa = x.const_arrays();
3146 ParallelFor(y, nghost, ncomp,
3147 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3148 {
3149 yfa[box_no](i,j,k,n+ycomp) = xfa[box_no](i,j,k,n+xcomp)
3150 + a * yfa[box_no](i,j,k,n+ycomp);
3151 });
3152 if (!Gpu::inNoSyncRegion()) {
3154 }
3155 } else
3156#endif
3157 {
3158#ifdef AMREX_USE_OMP
3159#pragma omp parallel if (Gpu::notInLaunchRegion())
3160#endif
3161 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3162 {
3163 const Box& bx = mfi.growntilebox(nghost);
3164 auto const& xFab = x.const_array(mfi);
3165 auto const& yFab = y.array(mfi);
3166 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3167 {
3168 yFab(i,j,k,n+ycomp) = xFab(i,j,k,n+xcomp)
3169 + a * yFab(i,j,k,n+ycomp);
3170 });
3171 }
3172 }
3173}
3174
3175template <class FAB>
3176template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3178 value_type a2, FabArray<FAB> const& x2,
3179 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3180{
3181 AMREX_ASSERT(y.boxArray() == x1.boxArray() &&
3182 y.boxArray() == x2.boxArray() &&
3183 y.distributionMap == x1.distributionMap &&
3184 y.distributionMap == x2.distributionMap &&
3185 y.nGrowVect().allGE(nghost) &&
3186 x1.nGrowVect().allGE(nghost) &&
3187 x2.nGrowVect().allGE(nghost));
3188
3189 BL_PROFILE("FabArray::Saxpy_Xpay()");
3190
3191#ifdef AMREX_USE_GPU
3192 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3193 auto const& yma = y.arrays();
3194 auto const& xma1 = x1.const_arrays();
3195 auto const& xma2 = x2.const_arrays();
3196 ParallelFor(y, nghost, ncomp,
3197 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3198 {
3199 yma[box_no](i,j,k,ycomp+n) = xma2[box_no](i,j,k,xcomp+n)
3200 + a2 * (yma [box_no](i,j,k,ycomp+n)
3201 + a1 * xma1[box_no](i,j,k,xcomp+n));
3202 });
3203 if (!Gpu::inNoSyncRegion()) {
3205 }
3206 } else
3207#endif
3208 {
3209#ifdef AMREX_USE_OMP
3210#pragma omp parallel if (Gpu::notInLaunchRegion())
3211#endif
3212 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3213 {
3214 const Box& bx = mfi.growntilebox(nghost);
3215
3216 if (bx.ok()) {
3217 auto const& xfab1 = x1.const_array(mfi);
3218 auto const& xfab2 = x2.const_array(mfi);
3219 auto const& yfab = y.array(mfi);
3220 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3221 {
3222 yfab(i,j,k,ycomp+n) = xfab2(i,j,k,xcomp+n)
3223 + a2 * (yfab (i,j,k,ycomp+n)
3224 + a1 * xfab1(i,j,k,xcomp+n));
3225 });
3226 }
3227 }
3228 }
3229}
3230
3231template <class FAB>
3232template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3234 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x2,
3235 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3236{
3237 AMREX_ASSERT(y1.boxArray() == y2.boxArray() &&
3238 y1.boxArray() == x1.boxArray() &&
3239 y1.boxArray() == x2.boxArray() &&
3243 y1.nGrowVect().allGE(nghost) &&
3244 y2.nGrowVect().allGE(nghost) &&
3245 x1.nGrowVect().allGE(nghost) &&
3246 x2.nGrowVect().allGE(nghost));
3247
3248 BL_PROFILE("FabArray::Saxpy_Saxpy()");
3249
3250#ifdef AMREX_USE_GPU
3251 if (Gpu::inLaunchRegion() && y1.isFusingCandidate()) {
3252 auto const& y1ma = y1.arrays();
3253 auto const& x1ma = x1.const_arrays();
3254 auto const& y2ma = y2.arrays();
3255 auto const& x2ma = x2.const_arrays();
3256 ParallelFor(y1, nghost, ncomp,
3257 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3258 {
3259 y1ma[box_no](i,j,k,ycomp+n) += a1 * x1ma[box_no](i,j,k,xcomp+n);
3260 y2ma[box_no](i,j,k,ycomp+n) += a2 * x2ma[box_no](i,j,k,xcomp+n);
3261 });
3262 if (!Gpu::inNoSyncRegion()) {
3264 }
3265 } else
3266#endif
3267 {
3268#ifdef AMREX_USE_OMP
3269#pragma omp parallel if (Gpu::notInLaunchRegion())
3270#endif
3271 for (MFIter mfi(y1,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3272 {
3273 const Box& bx = mfi.growntilebox(nghost);
3274
3275 if (bx.ok()) {
3276 auto const& x1fab = x1.const_array(mfi);
3277 auto const& y1fab = y1.array(mfi);
3278 auto const& x2fab = x2.const_array(mfi);
3279 auto const& y2fab = y2.array(mfi);
3280 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3281 {
3282 y1fab(i,j,k,ycomp+n) += a1 * x1fab(i,j,k,xcomp+n);
3283 y2fab(i,j,k,ycomp+n) += a2 * x2fab(i,j,k,xcomp+n);
3284 });
3285 }
3286 }
3287 }
3288}
3289
3290template <class FAB>
3291template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3293 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x,
3294 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3295{
3296 AMREX_ASSERT(y1.boxArray() == y2.boxArray() &&
3297 y1.boxArray() == x.boxArray() &&
3299 y1.distributionMap == x.distributionMap &&
3300 y1.nGrowVect().allGE(nghost) &&
3301 y2.nGrowVect().allGE(nghost) &&
3302 x.nGrowVect().allGE(nghost));
3303
3304 BL_PROFILE("FabArray::Saypy_Saxpy()");
3305
3306#ifdef AMREX_USE_GPU
3307 if (Gpu::inLaunchRegion() && y1.isFusingCandidate()) {
3308 auto const& y1ma = y1.arrays();
3309 auto const& y2ma = y2.arrays();
3310 auto const& xma = x.const_arrays();
3311 ParallelFor(y1, nghost, ncomp,
3312 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3313 {
3314 y1ma[box_no](i,j,k,ycomp+n) += a1 * y2ma[box_no](i,j,k,ycomp+n);
3315 y2ma[box_no](i,j,k,ycomp+n) += a2 * xma[box_no](i,j,k,xcomp+n);
3316 });
3317 if (!Gpu::inNoSyncRegion()) {
3319 }
3320 } else
3321#endif
3322 {
3323#ifdef AMREX_USE_OMP
3324#pragma omp parallel if (Gpu::notInLaunchRegion())
3325#endif
3326 for (MFIter mfi(y1,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3327 {
3328 const Box& bx = mfi.growntilebox(nghost);
3329
3330 if (bx.ok()) {
3331 auto const& xfab = x.const_array(mfi);
3332 auto const& y1fab = y1.array(mfi);
3333 auto const& y2fab = y2.array(mfi);
3334 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3335 {
3336 y1fab(i,j,k,ycomp+n) += a1 * y2fab(i,j,k,ycomp+n);
3337 y2fab(i,j,k,ycomp+n) += a2 * xfab(i,j,k,xcomp+n);
3338 });
3339 }
3340 }
3341 }
3342}
3343
3344template <class FAB>
3345template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3346void
3348 value_type a, const FabArray<FAB>& x, int xcomp,
3349 value_type b, const FabArray<FAB>& y, int ycomp,
3350 int dstcomp, int numcomp, const IntVect& nghost)
3351{
3352 AMREX_ASSERT(dst.boxArray() == x.boxArray());
3353 AMREX_ASSERT(dst.distributionMap == x.distributionMap);
3354 AMREX_ASSERT(dst.boxArray() == y.boxArray());
3355 AMREX_ASSERT(dst.distributionMap == y.distributionMap);
3356 AMREX_ASSERT(dst.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost) && y.nGrowVect().allGE(nghost));
3357
3358 BL_PROFILE("FabArray::LinComb()");
3359
3360#ifdef AMREX_USE_GPU
3361 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
3362 auto const& dstma = dst.arrays();
3363 auto const& xma = x.const_arrays();
3364 auto const& yma = y.const_arrays();
3365 ParallelFor(dst, nghost, numcomp,
3366 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3367 {
3368 dstma[box_no](i,j,k,dstcomp+n) = a*xma[box_no](i,j,k,xcomp+n)
3369 + b*yma[box_no](i,j,k,ycomp+n);
3370 });
3371 if (!Gpu::inNoSyncRegion()) {
3373 }
3374 } else
3375#endif
3376 {
3377#ifdef AMREX_USE_OMP
3378#pragma omp parallel if (Gpu::notInLaunchRegion())
3379#endif
3380 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3381 {
3382 const Box& bx = mfi.growntilebox(nghost);
3383 auto const& xfab = x.const_array(mfi);
3384 auto const& yfab = y.const_array(mfi);
3385 auto const& dfab = dst.array(mfi);
3386 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
3387 {
3388 dfab(i,j,k,dstcomp+n) = a*xfab(i,j,k,xcomp+n) + b*yfab(i,j,k,ycomp+n);
3389 });
3390 }
3391 }
3392}
3393
3394template <class FAB>
3395template <typename BUF>
3396void
3398{
3399 BL_PROFILE("FabArray::FillBoundary()");
3400 if ( n_grow.max() > 0 ) {
3401 FillBoundary_nowait<BUF>(0, nComp(), n_grow, Periodicity::NonPeriodic(), cross);
3402 FillBoundary_finish<BUF>();
3403 }
3404}
3405
3406template <class FAB>
3407template <typename BUF>
3408void
3409FabArray<FAB>::FillBoundary (const Periodicity& period, bool cross)
3410{
3411 BL_PROFILE("FabArray::FillBoundary()");
3412 if ( n_grow.max() > 0 ) {
3413 FillBoundary_nowait<BUF>(0, nComp(), n_grow, period, cross);
3414 FillBoundary_finish<BUF>();
3415 }
3416}
3417
3418template <class FAB>
3419template <typename BUF>
3420void
3421FabArray<FAB>::FillBoundary (const IntVect& nghost, const Periodicity& period, bool cross)
3422{
3423 BL_PROFILE("FabArray::FillBoundary()");
3425 "FillBoundary: asked to fill more ghost cells than we have");
3426 if ( nghost.max() > 0 ) {
3427 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3428 FillBoundary_finish<BUF>();
3429 }
3430}
3431
3432template <class FAB>
3433template <typename BUF>
3434void
3435FabArray<FAB>::FillBoundary (int scomp, int ncomp, bool cross)
3436{
3437 BL_PROFILE("FabArray::FillBoundary()");
3438 if ( n_grow.max() > 0 ) {
3439 FillBoundary_nowait<BUF>(scomp, ncomp, n_grow, Periodicity::NonPeriodic(), cross);
3440 FillBoundary_finish<BUF>();
3441 }
3442}
3443
3444template <class FAB>
3445template <typename BUF>
3446void
3447FabArray<FAB>::FillBoundary (int scomp, int ncomp, const Periodicity& period, bool cross)
3448{
3449 BL_PROFILE("FabArray::FillBoundary()");
3450 if ( n_grow.max() > 0 ) {
3451 FillBoundary_nowait<BUF>(scomp, ncomp, n_grow, period, cross);
3452 FillBoundary_finish<BUF>();
3453 }
3454}
3455
3456template <class FAB>
3457template <typename BUF>
3458void
3459FabArray<FAB>::FillBoundary (int scomp, int ncomp, const IntVect& nghost,
3460 const Periodicity& period, bool cross)
3461{
3462 BL_PROFILE("FabArray::FillBoundary()");
3464 "FillBoundary: asked to fill more ghost cells than we have");
3465 if ( nghost.max() > 0 ) {
3466 FillBoundary_nowait<BUF>(scomp, ncomp, nghost, period, cross);
3467 FillBoundary_finish<BUF>();
3468 }
3469}
3470
3471template <class FAB>
3472template <typename BUF>
3473void
3475{
3476 FillBoundary_nowait<BUF>(0, nComp(), nGrowVect(), Periodicity::NonPeriodic(), cross);
3477}
3478
3479template <class FAB>
3480template <typename BUF>
3481void
3483{
3484 FillBoundary_nowait<BUF>(0, nComp(), nGrowVect(), period, cross);
3485}
3486
3487template <class FAB>
3488template <typename BUF>
3489void
3490FabArray<FAB>::FillBoundary_nowait (const IntVect& nghost, const Periodicity& period, bool cross)
3491{
3492 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3493}
3494
3495template <class FAB>
3496template <typename BUF>
3497void
3498FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, bool cross)
3499{
3500 FillBoundary_nowait<BUF>(scomp, ncomp, nGrowVect(), Periodicity::NonPeriodic(), cross);
3501}
3502
3503template <class FAB>
3504void
3506{
3507 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3508 if (n_grow.max() > 0 || !is_cell_centered()) {
3509 FillBoundaryAndSync_nowait(0, nComp(), n_grow, period);
3511 }
3512}
3513
3514template <class FAB>
3515void
3516FabArray<FAB>::FillBoundaryAndSync (int scomp, int ncomp, const IntVect& nghost,
3517 const Periodicity& period)
3518{
3519 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3520 if (nghost.max() > 0 || !is_cell_centered()) {
3521 FillBoundaryAndSync_nowait(scomp, ncomp, nghost, period);
3523 }
3524}
3525
3526template <class FAB>
3527void
3532
3533template <class FAB>
3534void
3535FabArray<FAB>::FillBoundaryAndSync_nowait (int scomp, int ncomp, const IntVect& nghost,
3536 const Periodicity& period)
3537{
3538 BL_PROFILE("FillBoundaryAndSync_nowait()");
3539 FBEP_nowait(scomp, ncomp, nghost, period, false, false, true);
3540}
3541
3542template <class FAB>
3543void
3545{
3546 BL_PROFILE("FillBoundaryAndSync_finish()");
3548}
3549
3550template <class FAB>
3551void
3553{
3554 BL_PROFILE("FAbArray::OverrideSync()");
3555 if (!is_cell_centered()) {
3556 OverrideSync_nowait(0, nComp(), period);
3558 }
3559}
3560
3561template <class FAB>
3562void
3563FabArray<FAB>::OverrideSync (int scomp, int ncomp, const Periodicity& period)
3564{
3565 BL_PROFILE("FAbArray::OverrideSync()");
3566 if (!is_cell_centered()) {
3567 OverrideSync_nowait(scomp, ncomp, period);
3569 }
3570}
3571
3572template <class FAB>
3573void
3575{
3576 OverrideSync_nowait(0, nComp(), period);
3577}
3578
3579template <class FAB>
3580void
3581FabArray<FAB>::OverrideSync_nowait (int scomp, int ncomp, const Periodicity& period)
3582{
3583 BL_PROFILE("OverrideSync_nowait()");
3584 FBEP_nowait(scomp, ncomp, IntVect(0), period, false, false, true);
3585}
3586
3587template <class FAB>
3588void
3590{
3591 BL_PROFILE("OverrideSync_finish()");
3593}
3594
3595template <class FAB>
3596void
3597FabArray<FAB>::SumBoundary (const Periodicity& period, bool deterministic)
3598{
3599 SumBoundary(0, n_comp, IntVect(0), period, deterministic);
3600}
3601
3602template <class FAB>
3603void
3604FabArray<FAB>::SumBoundary (int scomp, int ncomp, const Periodicity& period, bool deterministic)
3605{
3606 SumBoundary(scomp, ncomp, IntVect(0), period, deterministic);
3607}
3608
3609template <class FAB>
3610void
3611FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period, bool deterministic)
3612{
3613 SumBoundary(scomp, ncomp, this->nGrowVect(), nghost, period, deterministic);
3614}
3615
3616template <class FAB>
3617void
3618FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period, bool deterministic)
3619{
3620 BL_PROFILE("FabArray<FAB>::SumBoundary()");
3621
3622 SumBoundary_nowait(scomp, ncomp, src_nghost, dst_nghost, period, deterministic);
3623 SumBoundary_finish();
3624}
3625
3626template <class FAB>
3627void
3628FabArray<FAB>::SumBoundary_nowait (const Periodicity& period, bool deterministic)
3629{
3630 SumBoundary_nowait(0, n_comp, IntVect(0), period, deterministic);
3631}
3632
3633template <class FAB>
3634void
3635FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool deterministic)
3636{
3637 SumBoundary_nowait(scomp, ncomp, IntVect(0), period, deterministic);
3638}
3639
3640template <class FAB>
3641void
3642FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period, bool deterministic)
3643{
3644 SumBoundary_nowait(scomp, ncomp, this->nGrowVect(), nghost, period, deterministic);
3645}
3646
3647template <class FAB>
3648void
3649FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period, bool deterministic)
3650{
3651 BL_PROFILE("FabArray<FAB>::SumBoundary_nowait()");
3652
3653 if ( n_grow == IntVect::TheZeroVector() && boxArray().ixType().cellCentered()) { return; }
3654
3655 AMREX_ALWAYS_ASSERT(src_nghost.allLE(n_grow) && dst_nghost.allLE(n_grow));
3656
3657 FBEP_nowait(scomp, ncomp, dst_nghost, period, false, false, false, src_nghost, deterministic);
3658}
3659
3660template <class FAB>
3661void
3663{
3664 BL_PROFILE("FabArray<FAB>::SumBoundary_finish()");
3666}
3667
3668template <class FAB>
3669void
3671{
3672 BL_PROFILE("FabArray::EnforcePeriodicity");
3673 if (period.isAnyPeriodic()) {
3674 FBEP_nowait(0, nComp(), nGrowVect(), period, false, true);
3675 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3676 }
3677}
3678
3679template <class FAB>
3680void
3681FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const Periodicity& period)
3682{
3683 BL_PROFILE("FabArray::EnforcePeriodicity");
3684 if (period.isAnyPeriodic()) {
3685 FBEP_nowait(scomp, ncomp, nGrowVect(), period, false, true);
3686 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3687 }
3688}
3689
3690template <class FAB>
3691void
3692FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const IntVect& nghost,
3693 const Periodicity& period)
3694{
3695 BL_PROFILE("FabArray::EnforcePeriodicity");
3696 if (period.isAnyPeriodic()) {
3697 FBEP_nowait(scomp, ncomp, nghost, period, false, true);
3698 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3699 }
3700}
3701
3702template <class FAB>
3703template <typename BUF>
3704void
3705FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool cross)
3706{
3707 FBEP_nowait<BUF>(scomp, ncomp, nGrowVect(), period, cross);
3708}
3709
3710template <class FAB>
3711template <typename BUF>
3712void
3713FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const IntVect& nghost,
3714 const Periodicity& period, bool cross)
3715{
3716 FBEP_nowait<BUF>(scomp, ncomp, nghost, period, cross);
3717}
3718
3719template <class FAB>
3720template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
3721void
3722FabArray<FAB>::BuildMask (const Box& phys_domain, const Periodicity& period,
3723 value_type covered, value_type notcovered,
3725{
3726 BL_PROFILE("FabArray::BuildMask()");
3727
3728 int ncomp = this->nComp();
3729 const IntVect& ngrow = this->nGrowVect();
3730
3731 Box domain = amrex::convert(phys_domain, boxArray().ixType());
3732 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
3733 if (period.isPeriodic(i)) {
3734 domain.grow(i, ngrow[i]);
3735 }
3736 }
3737
3738#ifdef AMREX_USE_GPU
3739 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3740 auto const& fa = this->arrays();
3741 ParallelFor(*this, ngrow, ncomp,
3742 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3743 {
3744 auto const& fab = fa[box_no];
3745 Box vbx(fab);
3746 vbx.grow(-ngrow);
3747 if (vbx.contains(i,j,k)) {
3748 fab(i,j,k,n) = interior;
3749 } else if (domain.contains(i,j,k)) {
3750 fab(i,j,k,n) = notcovered;
3751 } else {
3752 fab(i,j,k,n) = physbnd;
3753 }
3754 });
3755 if (!Gpu::inNoSyncRegion()) {
3757 }
3758 } else
3759#endif
3760 {
3761#ifdef AMREX_USE_OMP
3762#pragma omp parallel if (Gpu::notInLaunchRegion())
3763#endif
3764 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3765 {
3766 auto const& fab = this->array(mfi);
3767 Box const& fbx = mfi.growntilebox();
3768 Box const& gbx = fbx & domain;
3769 Box const& vbx = mfi.validbox();
3770 AMREX_HOST_DEVICE_FOR_4D(fbx, ncomp, i, j, k, n,
3771 {
3772 if (vbx.contains(i,j,k)) {
3773 fab(i,j,k,n) = interior;
3774 } else if (gbx.contains(i,j,k)) {
3775 fab(i,j,k,n) = notcovered;
3776 } else {
3777 fab(i,j,k,n) = physbnd;
3778 }
3779 });
3780 }
3781 }
3782
3783 const FabArrayBase::FB& TheFB = this->getFB(ngrow,period);
3784 setVal(covered, TheFB, 0, ncomp);
3785}
3786
3787template <class FAB>
3788template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
3789void
3790FabArray<FAB>::setVal (value_type val, const CommMetaData& thecmd, int scomp, int ncomp)
3791{
3792 BL_PROFILE("FabArray::setVal(val, thecmd, scomp, ncomp)");
3793
3794#ifdef AMREX_USE_GPU
3795 if (Gpu::inLaunchRegion())
3796 {
3797 CMD_local_setVal_gpu(val, thecmd, scomp, ncomp);
3798 CMD_remote_setVal_gpu(val, thecmd, scomp, ncomp);
3799 }
3800 else
3801#endif
3802 {
3803 AMREX_ASSERT(thecmd.m_LocTags && thecmd.m_RcvTags);
3804 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
3805 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
3806 auto N_locs = static_cast<int>(LocTags.size());
3807#ifdef AMREX_USE_OMP
3808#pragma omp parallel for if (thecmd.m_threadsafe_loc)
3809#endif
3810 for (int i = 0; i < N_locs; ++i) {
3811 const CopyComTag& tag = LocTags[i];
3812 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
3813 }
3814
3815 for (const auto & RcvTag : RcvTags) {
3816 auto N = static_cast<int>(RcvTag.second.size());
3817#ifdef AMREX_USE_OMP
3818#pragma omp parallel for if (thecmd.m_threadsafe_rcv)
3819#endif
3820 for (int i = 0; i < N; ++i) {
3821 const CopyComTag& tag = RcvTag.second[i];
3822 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
3823 }
3824 }
3825 }
3826}
3827
3828template <class FAB>
3829template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
3832{
3833 BL_PROFILE("FabArray::RecvLayoutMask()");
3834
3835 LayoutData<int> r(this->boxArray(), this->DistributionMap());
3836#ifdef AMREX_USE_OMP
3837#pragma omp parallel if (thecmd.m_threadsafe_rcv)
3838#endif
3839 for (MFIter mfi(r); mfi.isValid(); ++mfi) {
3840 r[mfi] = 0;
3841 }
3842
3843 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
3844 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
3845
3846 auto N_locs = static_cast<int>(LocTags.size());
3847 for (int i = 0; i < N_locs; ++i) {
3848 const CopyComTag& tag = LocTags[i];
3849 r[tag.dstIndex] = 1;
3850 }
3851
3852 for (const auto & RcvTag : RcvTags) {
3853 auto N = static_cast<int>(RcvTag.second.size());
3854 for (int i = 0; i < N; ++i) {
3855 const CopyComTag& tag = RcvTag.second[i];
3856 r[tag.dstIndex] = 1;
3857 }
3858 }
3859 return r;
3860}
3861
3862template <class FAB>
3863template <typename F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3864typename F::value_type
3865FabArray<FAB>::norminf (int comp, int ncomp, IntVect const& nghost, bool local,
3866 [[maybe_unused]] bool ignore_covered) const
3867{
3868 BL_PROFILE("FabArray::norminf()");
3869
3870 using RT = typename F::value_type;
3871
3872 auto nm0 = RT(0.0);
3873
3874#ifdef AMREX_USE_EB
3875 if ( this->is_cell_centered() && this->hasEBFabFactory() && ignore_covered )
3876 {
3877 const auto& ebfactory = dynamic_cast<EBFArrayBoxFactory const&>(this->Factory());
3878 auto const& flags = ebfactory.getMultiEBCellFlagFab();
3879#ifdef AMREX_USE_GPU
3880 if (Gpu::inLaunchRegion()) {
3881 auto const& flagsma = flags.const_arrays();
3882 auto const& ma = this->const_arrays();
3883 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost,
3884 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<RT>
3885 {
3886 if (flagsma[box_no](i,j,k).isCovered()) {
3887 return RT(0.0);
3888 } else {
3889 auto tmp = RT(0.0);
3890 auto const& a = ma[box_no];
3891 for (int n = 0; n < ncomp; ++n) {
3892 tmp = amrex::max(tmp, std::abs(a(i,j,k,comp+n)));
3893 }
3894 return tmp;
3895 }
3896 });
3897 } else
3898#endif
3899 {
3900#ifdef AMREX_USE_OMP
3901#pragma omp parallel reduction(max:nm0)
3902#endif
3903 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
3904 Box const& bx = mfi.growntilebox(nghost);
3905 if (flags[mfi].getType(bx) != FabType::covered) {
3906 auto const& flag = flags.const_array(mfi);
3907 auto const& a = this->const_array(mfi);
3908 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
3909 {
3910 if (!flag(i,j,k).isCovered()) {
3911 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
3912 }
3913 });
3914 }
3915 }
3916 }
3917 }
3918 else
3919#endif
3920 {
3921#ifdef AMREX_USE_GPU
3922 if (Gpu::inLaunchRegion()) {
3923 auto const& ma = this->const_arrays();
3924 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost, ncomp,
3925 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept -> GpuTuple<RT>
3926 {
3927 return std::abs(ma[box_no](i,j,k,comp+n));
3928 });
3929 } else
3930#endif
3931 {
3932#ifdef AMREX_USE_OMP
3933#pragma omp parallel reduction(max:nm0)
3934#endif
3935 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
3936 Box const& bx = mfi.growntilebox(nghost);
3937 auto const& a = this->const_array(mfi);
3938 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
3939 {
3940 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
3941 });
3942 }
3943 }
3944 }
3945
3946 if (!local) {
3948 }
3949
3950 return nm0;
3951}
3952
3953template <class FAB>
3954template <typename IFAB, typename F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3955typename F::value_type
3956FabArray<FAB>::norminf (FabArray<IFAB> const& mask, int comp, int ncomp,
3957 IntVect const& nghost, bool local) const
3958{
3959 BL_PROFILE("FabArray::norminf(mask)");
3960
3961 using RT = typename F::value_type;
3962
3963 auto nm0 = RT(0.0);
3964
3965#ifdef AMREX_USE_GPU
3966 if (Gpu::inLaunchRegion()) {
3967 auto const& ma = this->const_arrays();
3968 auto const& maskma = mask.const_arrays();
3969 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, IntVect(nghost),
3970 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<RT>
3971 {
3972 if (maskma[box_no](i,j,k)) {
3973 auto tmp = RT(0.0);
3974 auto const& a = ma[box_no];
3975 for (int n = 0; n < ncomp; ++n) {
3976 tmp = amrex::max(tmp, std::abs(a(i,j,k,comp+n)));
3977 }
3978 return tmp;
3979 } else {
3980 return RT(0.0);
3981 }
3982 });
3983 } else
3984#endif
3985 {
3986#ifdef AMREX_USE_OMP
3987#pragma omp parallel reduction(max:nm0)
3988#endif
3989 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
3990 Box const& bx = mfi.growntilebox(nghost);
3991 auto const& a = this->const_array(mfi);
3992 auto const& mskfab = mask.const_array(mfi);
3993 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
3994 {
3995 if (mskfab(i,j,k)) {
3996 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
3997 }
3998 });
3999 }
4000 }
4001
4002 if (!local) {
4004 }
4005
4006 return nm0;
4007}
4008
4010
4011}
4012
4013#endif /*BL_FABARRAY_H*/
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#define AMREX_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:49
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
#define AMREX_NODISCARD
Definition AMReX_Extension.H:252
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_RESTRICT
Definition AMReX_Extension.H:32
#define AMREX_HOST_DEVICE_FOR_4D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:107
#define AMREX_HOST_DEVICE_PARALLEL_FOR_4D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:111
#define AMREX_IF_ON_DEVICE(CODE)
Definition AMReX_GpuQualifiers.H:56
#define AMREX_IF_ON_HOST(CODE)
Definition AMReX_GpuQualifiers.H:58
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
Array4< int const > offset
Definition AMReX_HypreMLABecLap.cpp:1139
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
A virtual base class for objects that manage their own dynamic memory allocation.
Definition AMReX_Arena.H:132
virtual void free(void *pt)=0
A pure virtual function for deleting the arena pointed to by pt.
virtual void * alloc(std::size_t sz)=0
A FortranArrayBox(FAB)-like object.
Definition AMReX_BaseFab.H:190
A collection of Boxes stored in an Array.
Definition AMReX_BoxArray.H:564
__host__ __device__ BoxND & grow(int i) noexcept
Definition AMReX_Box.H:641
__host__ __device__ IntVectND< dim > length() const noexcept
Return the length of the BoxND.
Definition AMReX_Box.H:154
__host__ __device__ bool contains(const IntVectND< dim > &p) const noexcept
Return true if argument is contained within BoxND.
Definition AMReX_Box.H:212
__host__ __device__ BoxND & shift(int dir, int nzones) noexcept
Shift this BoxND nzones indexing positions in coordinate direction dir.
Definition AMReX_Box.H:509
__host__ __device__ BoxND & setRange(int dir, int sm_index, int n_cells=1) noexcept
Set the entire range in a given direction, starting at sm_index with length n_cells....
Definition AMReX_Box.H:1108
__host__ __device__ bool ok() const noexcept
Checks if it is a proper BoxND (including a valid type).
Definition AMReX_Box.H:208
__host__ __device__ const IntVectND< dim > & smallEnd() const &noexcept
Return the inclusive lower bound of the box.
Definition AMReX_Box.H:111
Definition AMReX_FabFactory.H:76
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:43
Definition AMReX_EBFabFactory.H:32
const FabArray< EBCellFlagFab > & getMultiEBCellFlagFab() const noexcept
EB cell flags for all boxes.
Definition AMReX_EBFabFactory.H:73
bool isAllRegular() const noexcept
Definition AMReX_EBFabFactory.cpp:148
Base class for FabArray.
Definition AMReX_FabArrayBase.H:42
IntVect nGrowVect() const noexcept
Definition AMReX_FabArrayBase.H:80
void clear()
Definition AMReX_FabArrayBase.cpp:207
Vector< int > indexArray
Definition AMReX_FabArrayBase.H:446
static FabArrayStats m_FA_stats
Definition AMReX_FabArrayBase.H:726
static bool getAllocSingleChunk()
Definition AMReX_FabArrayBase.H:730
bool isFusingCandidate() const noexcept
Is this a good candidate for kernel fusing?
Definition AMReX_FabArrayBase.cpp:2705
int size() const noexcept
Return the number of FABs in the FabArray.
Definition AMReX_FabArrayBase.H:110
FabArrayBase & operator=(const FabArrayBase &rhs)=default
void define(const BoxArray &bxs, const DistributionMapping &dm, int nvar, int ngrow)
Definition AMReX_FabArrayBase.cpp:175
CopyComTag::CopyComTagsContainer CopyComTagsContainer
Definition AMReX_FabArrayBase.H:220
CopyComTag::MapOfCopyComTagContainers MapOfCopyComTagContainers
Definition AMReX_FabArrayBase.H:221
const DistributionMapping & DistributionMap() const noexcept
Return constant reference to associated DistributionMapping.
Definition AMReX_FabArrayBase.H:131
int local_size() const noexcept
Return the number of local FABs in the FabArray.
Definition AMReX_FabArrayBase.H:113
CpOp
parallel copy or add
Definition AMReX_FabArrayBase.H:394
@ ADD
Definition AMReX_FabArrayBase.H:394
@ COPY
Definition AMReX_FabArrayBase.H:394
DistributionMapping distributionMap
Definition AMReX_FabArrayBase.H:445
friend void FillBoundary(Vector< FabArray< FAB > * > const &mf, const Periodicity &period)
int nComp() const noexcept
Return number of variables (aka components) associated with each point.
Definition AMReX_FabArrayBase.H:83
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:95
An Array of FortranArrayBox(FAB)-like Objects.
Definition AMReX_FabArray.H:351
void ParallelCopyToGhost_finish()
Definition AMReX_FabArrayCommI.H:381
void setFab(int boxno, std::unique_ptr< FAB > elem)
Explicitly set the Kth FAB in the FabArray to point to elem.
Definition AMReX_FabArray.H:2367
void copy(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, int src_nghost, int dst_nghost, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:1066
void setFab(const MFIter &mfi, FAB &&elem)
Explicitly set the FAB associated with mfi in the FabArray to point to elem.
Definition AMReX_FabArray.H:2432
F::value_type sum(int comp, IntVect const &nghost, bool local=false) const
Returns the sum of component "comp".
Definition AMReX_FabArray.H:2615
TagVector< CommSendBufTag< value_type > > const * get_send_copy_tag_vector(Vector< char * > const &send_data, Vector< std::size_t > const &send_size, Vector< CopyComTagsContainer const * > const &send_cctc, int ncomp, std::uint64_t id) const
void SumBoundary_nowait(int scomp, int ncomp, const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3635
void abs(int comp, int ncomp, int nghost=0)
Definition AMReX_FabArray.H:2797
void FBEP_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross, bool enforce_periodicity_only=false, bool override_sync=false, IntVect const &sumboundary_src_nghost=IntVect(-1), bool deterministic=false)
Definition AMReX_FabArrayCommI.H:10
void copy(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const IntVect &src_nghost, const IntVect &dst_nghost, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:1077
Array4< typename FabArray< FAB >::value_type const > const_array(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:593
static void unpack_recv_buffer_cpu(FabArray< FAB > &dst, int dcomp, int ncomp, Vector< char * > const &recv_data, Vector< std::size_t > const &recv_size, Vector< const CopyComTagsContainer * > const &recv_cctc, CpOp op, bool is_thread_safe)
Definition AMReX_FBI.H:1411
void * m_dp_arrays
Definition AMReX_FabArray.H:1494
void ParallelCopy(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:855
void setFab(const MFIter &mfi, std::unique_ptr< FAB > elem)
Explicitly set the FAB associated with mfi in the FabArray to point to elem.
Definition AMReX_FabArray.H:2410
typename std::conditional_t< IsBaseFab< FAB >::value, FAB, FABType >::value_type value_type
Definition AMReX_FabArray.H:362
std::unique_ptr< FabArray< FAB > > os_temp
Definition AMReX_FabArray.H:1638
void FillBoundary(const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3421
const FabFactory< FAB > & Factory() const noexcept
Definition AMReX_FabArray.H:449
void mult(value_type val, const Box &region, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2955
void invert(value_type numerator, const Box &region, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:3031
void CMD_remote_setVal_gpu(value_type x, const CommMetaData &thecmd, int scomp, int ncomp)
Definition AMReX_FBI.H:683
void Redistribute(const FabArray< FAB > &src, int scomp, int dcomp, int ncomp, const IntVect &nghost)
Copy from src to this. this and src have the same BoxArray, but different DistributionMapping.
Definition AMReX_FabArrayCommI.H:979
void prefetchToDevice(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:559
void FillBoundary_nowait(const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3482
void shift(const IntVect &v)
Shift the boxarray by vector v.
Definition AMReX_FabArray.H:3070
FAB * release(int K)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:1875
bool ok() const
Return true if the FabArray is well-defined. That is, the FabArray has a BoxArray and DistributionMap...
Definition AMReX_FabArray.H:2148
Array4< typename FabArray< FAB >::value_type const > array(const MFIter &mfi, int start_comp) const noexcept
Definition AMReX_FabArray.H:605
const FAB & operator[](const MFIter &mfi) const noexcept
Return a constant reference to the FAB associated with mfi.
Definition AMReX_FabArray.H:515
void ParallelAdd_nowait(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:866
void setDomainBndry(value_type val, int strt_comp, int ncomp, const Geometry &geom)
Set ncomp values outside the Geometry domain to val, starting at start_comp.
Definition AMReX_FabArray.H:2573
FabArray(FabArray< FAB > &&rhs) noexcept
Definition AMReX_FabArray.H:2073
Array4< typename FabArray< FAB >::value_type const > array(int K, int start_comp) const noexcept
Definition AMReX_FabArray.H:617
FabArray(const BoxArray &bxs, const DistributionMapping &dm, int nvar, const IntVect &ngrow, const MFInfo &info=MFInfo(), const FabFactory< FAB > &factory=DefaultFabFactory< FAB >())
Definition AMReX_FabArray.H:2037
bool defined(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:1769
void setVal(value_type val, const CommMetaData &thecmd, int scomp, int ncomp)
Definition AMReX_FabArray.H:3790
void setVal(value_type val, const Box &region, int comp, int ncomp, const IntVect &nghost)
Definition AMReX_FabArray.H:2748
void OverrideSync_nowait(int scomp, int ncomp, const Periodicity &period)
Definition AMReX_FabArray.H:3581
FabArray(const FabArray< FAB > &rhs)=delete
void ParallelCopyToGhost(const FabArray< FAB > &src, int scomp, int dcomp, int ncomp, const IntVect &snghost, const IntVect &dnghost, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArrayCommI.H:350
void ParallelCopy_finish()
Definition AMReX_FabArrayCommI.H:669
void setVal(value_type val, const Box &region, int comp, int ncomp, int nghost=0)
Set the value of num_comp components in the valid region of each FAB in the FabArray,...
Definition AMReX_FabArray.H:2736
static void pack_send_buffer_cpu(FabArray< FAB > const &src, int scomp, int ncomp, Vector< char * > const &send_data, Vector< std::size_t > const &send_size, Vector< const CopyComTagsContainer * > const &send_cctc)
Definition AMReX_FBI.H:1372
FAB & get(int K) noexcept
Return a reference to the FAB associated with the Kth element.
Definition AMReX_FabArray.H:536
void setVal(value_type val, int comp, int ncomp, const IntVect &nghost)
Definition AMReX_FabArray.H:2694
static void Saypy_Saxpy(FabArray< FAB > &y1, value_type a1, FabArray< FAB > &y2, value_type a2, FabArray< FAB > const &x, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
y1 += a1*y2; y2 += a2*x;
Definition AMReX_FabArray.H:3292
FAB const * fabPtr(int K) const noexcept
Definition AMReX_FabArray.H:1811
void SumBoundary_nowait(const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3628
void abs(int comp, int ncomp, const IntVect &nghost)
Definition AMReX_FabArray.H:2805
void ParallelCopy(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, int src_nghost, int dst_nghost, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:937
Long m_single_chunk_size
Definition AMReX_FabArray.H:1484
FAB & get(const MFIter &mfi) noexcept
Returns a reference to the FAB associated mfi.
Definition AMReX_FabArray.H:524
static void LinComb(FabArray< FAB > &dst, value_type a, const FabArray< FAB > &x, int xcomp, value_type b, const FabArray< FAB > &y, int ycomp, int dstcomp, int numcomp, const IntVect &nghost)
dst = a*x + b*y
Definition AMReX_FabArray.H:3347
void OverrideSync_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3574
void setDomainBndry(value_type val, const Geometry &geom)
Set all values outside the Geometry domain to val.
Definition AMReX_FabArray.H:2565
std::unique_ptr< PCData< FAB > > pcd
Definition AMReX_FabArray.H:1635
void define(const BoxArray &bxs, const DistributionMapping &dm, int nvar, int ngrow, const MFInfo &info=MFInfo(), const FabFactory< FAB > &factory=DefaultFabFactory< FAB >())
Define this FabArray identically to that performed by the constructor having an analogous function si...
Definition AMReX_FabArray.H:2183
void ParallelAdd_nowait(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const IntVect &src_nghost, const IntVect &dst_nghost, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:967
void PC_local_cpu(const CPC &thecpc, FabArray< FAB > const &src, int scomp, int dcomp, int ncomp, CpOp op)
Definition AMReX_PCI.H:8
std::unique_ptr< FBData< FAB > > fbd
Definition AMReX_FabArray.H:1634
std::unique_ptr< detail::SingleChunkArena > m_single_chunk_arena
Definition AMReX_FabArray.H:1483
void SumBoundary_nowait(int scomp, int ncomp, IntVect const &src_nghost, IntVect const &dst_nghost, const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3649
FabArray(const FabArray< FAB > &rhs, MakeType maketype, int scomp, int ncomp)
Definition AMReX_FabArray.H:2051
void ParallelAdd(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic())
This function copies data from src to this FabArray. Each FAB in fa is intersected with all FABs in t...
Definition AMReX_FabArray.H:852
FAB fab_type
Definition AMReX_FabArray.H:364
void setVal(value_type val, const IntVect &nghost)
Definition AMReX_FabArray.H:1990
void BuildMask(const Box &phys_domain, const Periodicity &period, value_type covered, value_type notcovered, value_type physbnd, value_type interior)
Definition AMReX_FabArray.H:3722
void LocalCopy(FabArray< SFAB > const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
Perform local copy of FabArray data.
Definition AMReX_FabArray.H:1964
void FB_local_add_cpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:442
bool SharedMemory() const noexcept
Definition AMReX_FabArray.H:1552
LayoutData< int > RecvLayoutMask(const CommMetaData &thecmd)
Definition AMReX_FabArray.H:3831
void FillBoundary_nowait(const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3490
Vector< std::string > m_tags
Definition AMReX_FabArray.H:1500
void ParallelCopyToGhost_nowait(const FabArray< FAB > &src, int scomp, int dcomp, int ncomp, const IntVect &snghost, const IntVect &dnghost, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArrayCommI.H:367
void invert(value_type numerator, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2995
void ParallelAdd_nowait(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:905
void FB_local_add_gpu(const FB &TheFB, int scomp, int ncomp, bool deterministic)
Definition AMReX_FBI.H:605
Array4< typename FabArray< FAB >::value_type const > array(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:569
void FB_local_copy_gpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:533
Arena * arena() const noexcept
Definition AMReX_FabArray.H:452
Array4< typename FabArray< FAB >::value_type const > const_array(int K) const noexcept
Definition AMReX_FabArray.H:599
void plus(value_type val, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2843
DataAllocator m_dallocator
Definition AMReX_FabArray.H:1482
void copy(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:861
static void unpack_recv_buffer_gpu(FabArray< FAB > &dst, int dcomp, int ncomp, Vector< char * > const &recv_data, Vector< std::size_t > const &recv_size, Vector< const CopyComTagsContainer * > const &recv_cctc, CpOp op, bool is_thread_safe, std::uint64_t id, bool deterministic)
Definition AMReX_FBI.H:1210
void FillBoundaryAndSync_finish()
Definition AMReX_FabArray.H:3544
void ParallelCopy_nowait(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, int src_nghost, int dst_nghost, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:977
static void Saxpy_Saxpy(FabArray< FAB > &y1, value_type a1, FabArray< FAB > const &x1, FabArray< FAB > &y2, value_type a2, FabArray< FAB > const &x2, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
y1 += a1*x1; y2 += a2*x2;
Definition AMReX_FabArray.H:3233
void FillBoundary_nowait(bool cross=false)
Definition AMReX_FabArray.H:3474
static void Saxpy_Xpay(FabArray< FAB > &y, value_type a1, FabArray< FAB > const &x1, value_type a2, FabArray< FAB > const &x2, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
y = x2+a2*(y+a1*x1)
Definition AMReX_FabArray.H:3177
static void Xpay(FabArray< FAB > &y, value_type a, FabArray< FAB > const &x, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
y = x + a*y
Definition AMReX_FabArray.H:3133
void clear()
Releases FAB memory in the FabArray.
Definition AMReX_FabArray.H:1914
void FillBoundary_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3713
const Vector< std::string > & tags() const noexcept
Definition AMReX_FabArray.H:454
void CMD_local_setVal_gpu(value_type x, const CommMetaData &thecmd, int scomp, int ncomp)
Definition AMReX_FBI.H:653
void FillBoundary_nowait(int scomp, int ncomp, bool cross=false)
Definition AMReX_FabArray.H:3498
Array4< typename FabArray< FAB >::value_type > array(const MFIter &mfi) noexcept
Definition AMReX_FabArray.H:575
value_type * singleChunkPtr() noexcept
Definition AMReX_FabArray.H:467
std::vector< FAB * > m_fabs_v
The data.
Definition AMReX_FabArray.H:1491
void setBndry(value_type val)
Set all values in the boundary region to val.
Definition AMReX_FabArray.H:2454
void ParallelAdd(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const IntVect &src_nghost, const IntVect &dst_nghost, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:929
bool define_function_called
has define() been called?
Definition AMReX_FabArray.H:1487
void ParallelAdd(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const Periodicity &period=Periodicity::NonPeriodic())
This function copies data from src to this FabArray. Each FAB in src is intersected with all FABs in ...
Definition AMReX_FabArray.H:882
FabArray() noexcept
Constructs an empty FabArray<FAB>.
Definition AMReX_FabArray.H:2012
void FillBoundary_test()
Definition AMReX_FabArrayCommI.H:1006
bool defined(int K) const noexcept
Definition AMReX_FabArray.H:1756
FAB * fabPtr(int K) noexcept
Definition AMReX_FabArray.H:1802
void ParallelAdd(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, int src_nghost, int dst_nghost, const Periodicity &period=Periodicity::NonPeriodic())
Similar to the above function, except that source and destination are grown by src_nghost and dst_ngh...
Definition AMReX_FabArray.H:920
const FAB & atLocalIdx(int L) const noexcept
Definition AMReX_FabArray.H:540
std::unique_ptr< FabFactory< FAB > > m_factory
Definition AMReX_FabArray.H:1481
void setVal(value_type val)
Set all components in the entire region of each FAB to val.
Definition AMReX_FabArray.H:2666
void setVal(value_type val, int comp, int ncomp, int nghost=0)
Set the value of num_comp components in the valid region of each FAB in the FabArray,...
Definition AMReX_FabArray.H:2683
void copy(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:897
MultiArray4< typename FabArray< FAB >::value_type > arrays() noexcept
Definition AMReX_FabArray.H:641
MultiArray4< typename FabArray< FAB >::value_type const > arrays() const noexcept
Definition AMReX_FabArray.H:648
void setVal(value_type val, int nghost)
Set all components in the valid region of each FAB in the FabArray to val, including nghost boundary ...
Definition AMReX_FabArray.H:1982
void copyTo(FAB &dest, int nghost=0) const
Copy the values contained in the intersection of the valid + nghost region of this FabArray with the ...
Definition AMReX_FabArray.H:2658
void ParallelAdd_nowait(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, int src_nghost, int dst_nghost, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:957
void setBndry(value_type val, int strt_comp, int ncomp)
Set ncomp values in the boundary region, starting at start_comp to val.
Definition AMReX_FabArray.H:2462
void setVal(value_type val, const Box &region, const IntVect &nghost)
Definition AMReX_FabArray.H:2006
void FillBoundary_nowait(int scomp, int ncomp, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3705
const FAB & get(const MFIter &mfi) const noexcept
Return a constant reference to the FAB associated with mfi.
Definition AMReX_FabArray.H:518
void SumBoundary_finish()
Definition AMReX_FabArray.H:3662
std::size_t singleChunkSize() const noexcept
Definition AMReX_FabArray.H:479
void SumBoundary_nowait(int scomp, int ncomp, IntVect const &nghost, const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3642
void capacityOfFabs(LayoutData< I > &mem) const
Get capacity of the FabArray.
Definition AMReX_FabArray.H:2605
void mult(value_type val, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2919
void FB_local_copy_cpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:383
static void Saxpy(FabArray< FAB > &y, value_type a, FabArray< FAB > const &x, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
y += a*x
Definition AMReX_FabArray.H:3087
MultiArray4< value_type > m_arrays
Definition AMReX_FabArray.H:1497
void FillBoundaryAndSync_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3528
void PC_local_gpu(const CPC &thecpc, FabArray< FAB > const &src, int scomp, int dcomp, int ncomp, CpOp op, bool deterministic)
Definition AMReX_PCI.H:90
Array4< typename FabArray< FAB >::value_type const > const_array(int K, int start_comp) const noexcept
Definition AMReX_FabArray.H:635
void FillBoundaryAndSync_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Definition AMReX_FabArray.H:3535
Array4< typename FabArray< FAB >::value_type > array(int K) noexcept
Definition AMReX_FabArray.H:587
void * m_hp_arrays
Definition AMReX_FabArray.H:1496
ShMem shmem
Definition AMReX_FabArray.H:1550
void LocalAdd(FabArray< FAB > const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
Perform local addition of FabArray data.
Definition AMReX_FabArray.H:1973
void setFab(int boxno, FAB &&elem)
Explicitly set the Kth FAB in the FabArray to point to elem.
Definition AMReX_FabArray.H:2389
FabArray< FAB > & operator=(FabArray< FAB > &&rhs) noexcept
Definition AMReX_FabArray.H:2104
MultiArray4< value_type const > m_const_arrays
Definition AMReX_FabArray.H:1498
void ParallelCopy(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:888
bool hasEBFabFactory() const noexcept
Definition AMReX_FabArray.H:456
Array4< typename FabArray< FAB >::value_type const > array(int K) const noexcept
Definition AMReX_FabArray.H:581
TagVector< Array4CopyTag< value_type > > const * FB_get_local_copy_tag_vector(const FB &TheFB)
Definition AMReX_FBI.H:490
bool isAllRegular() const noexcept
Definition AMReX_FabArray.H:481
Array4< typename FabArray< FAB >::value_type const > const_array(const MFIter &mfi, int start_comp) const noexcept
Definition AMReX_FabArray.H:629
void plus(value_type val, const Box &region, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2879
FAB * fabPtr(const MFIter &mfi) noexcept
Return pointer to FAB.
Definition AMReX_FabArray.H:1782
Array4< typename FabArray< FAB >::value_type > array(const MFIter &mfi, int start_comp) noexcept
Definition AMReX_FabArray.H:611
void OverrideSync_finish()
Definition AMReX_FabArray.H:3589
static void pack_send_buffer_gpu(FabArray< FAB > const &src, int scomp, int ncomp, Vector< char * > const &send_data, Vector< std::size_t > const &send_size, Vector< const CopyComTagsContainer * > const &send_cctc, std::uint64_t id)
Definition AMReX_FBI.H:1112
FAB * release(const MFIter &mfi)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:1895
MultiArray4< typename FabArray< FAB >::value_type const > const_arrays() const noexcept
Definition AMReX_FabArray.H:655
TagVector< CommRecvBufTag< value_type > > const * get_recv_copy_tag_vector(Vector< char * > const &recv_data, Vector< std::size_t > const &recv_size, Vector< CopyComTagsContainer const * > const &recv_cctc, int ncomp, std::uint64_t id)
void prefetchToHost(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:549
FAB & atLocalIdx(int L) noexcept
Return a reference to the FAB associated with local index L.
Definition AMReX_FabArray.H:539
void define(const BoxArray &bxs, const DistributionMapping &dm, int nvar, const IntVect &ngrow, const MFInfo &info=MFInfo(), const FabFactory< FAB > &factory=DefaultFabFactory< FAB >())
Definition AMReX_FabArray.H:2195
void ParallelCopy_nowait(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:869
const FAB & get(int K) const noexcept
Return a constant reference to the FAB associated with the Kth element.
Definition AMReX_FabArray.H:530
void FillBoundary_finish()
Definition AMReX_FabArrayCommI.H:219
FAB const * fabPtr(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:1792
void ParallelCopy_nowait(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:911
Array4< typename FabArray< FAB >::value_type > array(int K, int start_comp) noexcept
Definition AMReX_FabArray.H:623
bool isDefined() const
Definition AMReX_FabArray.H:2176
void setVal(value_type val, const Box &region, int nghost)
Set all components in the valid region of each FAB in the FabArray to val, including nghost boundary ...
Definition AMReX_FabArray.H:1998
value_type const * singleChunkPtr() const noexcept
Definition AMReX_FabArray.H:473
~FabArray()
The destructor – deletes all FABs in the array.
Definition AMReX_FabArray.H:2140
Definition AMReX_FabFactory.H:50
virtual Long nBytes(const Box &box, int ncomps, int) const
Definition AMReX_FabFactory.H:64
virtual FabFactory< FAB > * clone() const =0
virtual FAB * create(const Box &box, int ncomps, const FabInfo &info, int box_index) const =0
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:75
const Box & Domain() const noexcept
Returns our rectangular domain.
Definition AMReX_Geometry.H:216
bool isPeriodic(int dir) const noexcept
Is the domain periodic in the specified direction?
Definition AMReX_Geometry.H:337
GPU-compatible tuple.
Definition AMReX_Tuple.H:98
__host__ __device__ constexpr bool allGE(const IntVectND< dim > &rhs) const noexcept
Returns true if this is greater than or equal to argument for all components. NOTE: This is NOT a str...
Definition AMReX_IntVect.H:542
__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__ __device__ constexpr int max() const noexcept
maximum (no absolute values) value
Definition AMReX_IntVect.H:313
__host__ __device__ constexpr bool allLE(const IntVectND< dim > &rhs) const noexcept
Returns true if this is less than or equal to argument for all components. NOTE: This is NOT a strict...
Definition AMReX_IntVect.H:492
a one-thingy-per-box distributed object
Definition AMReX_LayoutData.H:13
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
int index() const noexcept
The index into the underlying BoxArray of the current FAB.
Definition AMReX_MFIter.H:175
int LocalIndex() const noexcept
Return local index into the vector of fab pointers, m_fabs_v When AllBoxes is on, local_index_map is ...
Definition AMReX_MFIter.H:190
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
bool isAnyPeriodic() const noexcept
Definition AMReX_Periodicity.H:22
bool isPeriodic(int dir) const noexcept
Definition AMReX_Periodicity.H:26
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:28
Long size() const noexcept
Definition AMReX_Vector.H:53
amrex_long Long
Definition AMReX_INT.H:30
void EnforcePeriodicity(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Definition AMReX_FabArray.H:3692
void SumBoundary(int scomp, int ncomp, const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3604
void SumBoundary(int scomp, int ncomp, IntVect const &nghost, const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Sum values in overlapped cells.
Definition AMReX_FabArray.H:3611
void OverrideSync(const Periodicity &period=Periodicity::NonPeriodic())
Synchronize nodal data.
Definition AMReX_FabArray.H:3552
void FillBoundary(bool cross=false)
Copy on intersection within a FabArray.
Definition AMReX_FabArray.H:3397
F::value_type norminf(int comp, int ncomp, IntVect const &nghost, bool local=false, bool ignore_covered=false) const
Return infinity norm.
Definition AMReX_FabArray.H:3865
void OverrideSync(int scomp, int ncomp, const Periodicity &period)
Synchronize nodal data.
Definition AMReX_FabArray.H:3563
void FillBoundary(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3459
void FillBoundaryAndSync(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Fill ghost cells and synchronize nodal data.
Definition AMReX_FabArray.H:3516
void FillBoundary(const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3409
void FillBoundary(int scomp, int ncomp, bool cross=false)
Definition AMReX_FabArray.H:3435
void FillBoundaryAndSync(const Periodicity &period=Periodicity::NonPeriodic())
Fill ghost cells and synchronize nodal data.
Definition AMReX_FabArray.H:3505
void SumBoundary(const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Sum values in overlapped cells.
Definition AMReX_FabArray.H:3597
void SumBoundary(int scomp, int ncomp, IntVect const &src_nghost, IntVect const &dst_nghost, const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Sum values in overlapped cells.
Definition AMReX_FabArray.H:3618
void EnforcePeriodicity(const Periodicity &period)
Fill ghost cells with values from their corresponding cells across periodic boundaries,...
Definition AMReX_FabArray.H:3670
void FillBoundary(int scomp, int ncomp, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3447
F::value_type norminf(FabArray< IFAB > const &mask, int comp, int ncomp, IntVect const &nghost, bool local=false) const
Return infinity norm in masked region.
Definition AMReX_FabArray.H:3956
void EnforcePeriodicity(int scomp, int ncomp, const Periodicity &period)
Definition AMReX_FabArray.H:3681
Arena * The_Comms_Arena()
Definition AMReX_Arena.cpp:880
Arena * The_Pinned_Arena()
Definition AMReX_Arena.cpp:860
Arena * The_Arena()
Definition AMReX_Arena.cpp:820
int MyProc() noexcept
Definition AMReX_ParallelDescriptor.H:128
void Min(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:161
void Sum(T &v, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:221
void Max(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:133
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:310
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
int MyTeamLead() noexcept
Definition AMReX_ParallelDescriptor.H:325
int TeamSize() noexcept
Definition AMReX_ParallelDescriptor.H:310
const ProcessTeam & MyTeam() noexcept
Definition AMReX_ParallelDescriptor.H:365
int MPI_Comm
Definition AMReX_ccse-mpi.H:51
Definition AMReX_Amr.cpp:50
std::enable_if_t< IsFabArray< MF >::value > FillBoundaryAndSync_nowait(Vector< MF * > const &mf, Vector< int > const &scomp, Vector< int > const &ncomp, Vector< IntVect > const &nghost, Vector< Periodicity > const &period)
Launch FillBoundaryAndSync_nowait across a vector of FabArrays.
Definition AMReX_FabArrayCommI.H:1136
MakeType
Definition AMReX_MakeType.H:7
@ make_alias
Definition AMReX_MakeType.H:7
__host__ __device__ void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:139
std::enable_if_t< IsFabArray< MF >::value > FillBoundaryAndSync_finish(Vector< MF * > const &mf)
Wait for outstanding FillBoundaryAndSync_nowait operations launched with the vector helper to complet...
Definition AMReX_FabArrayCommI.H:1178
__host__ __device__ BoxND< dim > convert(const BoxND< dim > &b, const IntVectND< dim > &typ) noexcept
Return a BoxND with different type.
Definition AMReX_Box.H:1558
int nComp(FabArrayBase const &fa)
Definition AMReX_FabArrayBase.cpp:2852
std::enable_if_t< std::is_integral_v< T > > ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:193
std::unique_ptr< char, TheFaArenaDeleter > TheFaArenaPointer
Definition AMReX_FabArray.H:105
DistributionMapping const & DistributionMap(FabArrayBase const &fa)
Definition AMReX_FabArrayBase.cpp:2867
IntVect nGrowVect(FabArrayBase const &fa)
Definition AMReX_FabArrayBase.cpp:2857
std::enable_if_t< IsFabArray< MF >::value > FillBoundary_finish(Vector< MF * > const &mf)
Wait for outstanding FillBoundary_nowait operations launched with the vector helper to complete.
Definition AMReX_FabArrayCommI.H:1113
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 Copy(FabArray< DFAB > &dst, FabArray< SFAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Definition AMReX_FabArray.H:182
BoxND< 3 > Box
Box is an alias for amrex::BoxND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:30
Long nBytesOwned(T const &) noexcept
Definition AMReX_FabArray.H:59
bool isMFIterSafe(const FabArrayBase &x, const FabArrayBase &y)
Definition AMReX_MFIter.H:252
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:33
__host__ __device__ constexpr const T & max(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:44
void setBndry(MF &dst, typename MF::value_type val, int scomp, int ncomp)
dst = val in ghost cells.
Definition AMReX_FabArrayUtility.H:1934
__host__ __device__ T abs(const GpuComplex< T > &a_z) noexcept
Return the absolute value of a complex number.
Definition AMReX_GpuComplex.H:361
bool TilingIfNotGPU() noexcept
Definition AMReX_MFIter.H:12
void Add(FabArray< FAB > &dst, FabArray< FAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Definition AMReX_FabArray.H:245
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:241
void OverrideSync_finish(FabArray< FAB > &fa)
Definition AMReX_FabArrayUtility.H:1501
void update_fab_stats(Long n, Long s, size_t szt) noexcept
Definition AMReX_BaseFab.cpp:146
void setVal(MF &dst, typename MF::value_type val)
dst = val
Definition AMReX_FabArrayUtility.H:1927
BoxArray const & boxArray(FabArrayBase const &fa)
Definition AMReX_FabArrayBase.cpp:2862
void OverrideSync_nowait(FabArray< FAB > &fa, FabArray< IFAB > const &msk, const Periodicity &period)
Definition AMReX_FabArrayUtility.H:1454
__host__ __device__ constexpr int get(IntVectND< dim > const &iv) noexcept
Get I'th element of IntVectND<dim>
Definition AMReX_IntVect.H:1334
Definition AMReX_TagParallelFor.H:58
A multidimensional array accessor.
Definition AMReX_Array4.H:283
Definition AMReX_DataAllocator.H:9
Arena * arena() const noexcept
Definition AMReX_DataAllocator.H:24
Arena * m_arena
Definition AMReX_DataAllocator.H:10
Definition AMReX_FabArray.H:109
const FabArrayBase::FB * fb
Definition AMReX_FabArray.H:111
bool deterministic
Definition AMReX_FabArray.H:128
char * the_recv_data
Definition AMReX_FabArray.H:116
Vector< MPI_Request > recv_reqs
Definition AMReX_FabArray.H:121
Vector< char * > recv_data
Definition AMReX_FabArray.H:119
Vector< MPI_Status > recv_stat
Definition AMReX_FabArray.H:122
int scomp
Definition AMReX_FabArray.H:112
Vector< int > recv_from
Definition AMReX_FabArray.H:118
char * the_send_data
Definition AMReX_FabArray.H:117
Vector< MPI_Request > send_reqs
Definition AMReX_FabArray.H:125
Vector< char * > send_data
Definition AMReX_FabArray.H:124
Vector< std::size_t > recv_size
Definition AMReX_FabArray.H:120
int ncomp
Definition AMReX_FabArray.H:113
int tag
Definition AMReX_FabArray.H:126
parallel copy or add
Definition AMReX_FabArrayBase.H:538
Definition AMReX_FabArrayBase.H:472
std::unique_ptr< MapOfCopyComTagContainers > m_RcvTags
Definition AMReX_FabArrayBase.H:478
std::unique_ptr< CopyComTagsContainer > m_LocTags
Definition AMReX_FabArrayBase.H:476
Used by a bunch of routines when communicating via MPI.
Definition AMReX_FabArrayBase.H:195
Box dbox
Definition AMReX_FabArrayBase.H:196
int dstIndex
Definition AMReX_FabArrayBase.H:198
FillBoundary.
Definition AMReX_FabArrayBase.H:488
void recordBuild() noexcept
Definition AMReX_FabArrayBase.H:704
Definition AMReX_FabArray.H:354
FAB value_type
Definition AMReX_FabArray.H:355
for shared memory
Definition AMReX_FabArray.H:1503
ShMem(ShMem &&rhs) noexcept
Definition AMReX_FabArray.H:1517
ShMem() noexcept=default
Long n_values
Definition AMReX_FabArray.H:1544
Long n_points
Definition AMReX_FabArray.H:1545
bool alloc
Definition AMReX_FabArray.H:1543
ShMem & operator=(ShMem &&rhs) noexcept
Definition AMReX_FabArray.H:1528
ShMem(const ShMem &)=delete
Definition AMReX_TypeTraits.H:18
FabArray memory allocation information.
Definition AMReX_FabArray.H:67
MFInfo & SetTag(T &&t, Ts &&... ts) noexcept
Definition AMReX_FabArray.H:93
MFInfo & SetTag(const std::string &t) noexcept
Definition AMReX_FabArray.H:87
Arena * arena
Definition AMReX_FabArray.H:71
MFInfo & SetArena(Arena *ar) noexcept
Definition AMReX_FabArray.H:78
MFInfo & SetTag() noexcept
Definition AMReX_FabArray.H:80
bool alloc
Definition AMReX_FabArray.H:69
MFInfo & SetAlloc(bool a) noexcept
Definition AMReX_FabArray.H:74
bool alloc_single_chunk
Definition AMReX_FabArray.H:70
MFInfo & SetAllocSingleChunk(bool a) noexcept
Definition AMReX_FabArray.H:76
Vector< std::string > tags
Definition AMReX_FabArray.H:72
MFInfo & SetTag(const char *t) noexcept
Definition AMReX_FabArray.H:82
Definition AMReX_MFIter.H:20
MFItInfo & DisableDeviceSync() noexcept
Definition AMReX_MFIter.H:47
Definition AMReX_FabArray.H:155
Array4< T > const *__restrict__ hp
Definition AMReX_FabArray.H:171
__host__ __device__ Array4< T > const & operator[](int li) const noexcept
Definition AMReX_FabArray.H:157
Array4< T > const *__restrict__ dp
Definition AMReX_FabArray.H:169
Definition AMReX_FabArray.H:133
int actual_n_rcvs
Definition AMReX_FabArray.H:139
Vector< std::size_t > recv_size
Definition AMReX_FabArray.H:146
int DC
Definition AMReX_FabArray.H:140
Vector< MPI_Request > send_reqs
Definition AMReX_FabArray.H:148
int tag
Definition AMReX_FabArray.H:138
const FabArray< FAB > * src
Definition AMReX_FabArray.H:136
char * the_recv_data
Definition AMReX_FabArray.H:142
FabArrayBase::CpOp op
Definition AMReX_FabArray.H:137
Vector< MPI_Request > recv_reqs
Definition AMReX_FabArray.H:147
char * the_send_data
Definition AMReX_FabArray.H:143
const FabArrayBase::CPC * cpc
Definition AMReX_FabArray.H:135
Vector< int > recv_from
Definition AMReX_FabArray.H:144
bool deterministic
Definition AMReX_FabArray.H:149
int NC
Definition AMReX_FabArray.H:140
int SC
Definition AMReX_FabArray.H:140
Vector< char * > recv_data
Definition AMReX_FabArray.H:145
void MemoryBarrier() const
memory fence
Definition AMReX_ParallelDescriptor.H:161
const team_t & get() const
Definition AMReX_ParallelDescriptor.H:189
Definition AMReX_TagParallelFor.H:158
Definition AMReX_FabArray.H:99
char * pointer
Definition AMReX_FabArray.H:100
void operator()(pointer p) const noexcept
Definition AMReX_FabArray.H:101
Struct for holding types.
Definition AMReX_TypeList.H:13