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