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