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_Concepts.H>
28#include <AMReX_LayoutData.H>
29#include <AMReX_BaseFab.H>
31#include <AMReX_MFParallelFor.H>
33#include <AMReX_ParReduce.H>
34
35#include <AMReX_Gpu.H>
36
42#ifdef AMREX_USE_EB
43#include <AMReX_EBFabFactory.H>
44#endif
45
46#ifdef AMREX_USE_OMP
47#include <omp.h>
48#endif
49
50#include <algorithm>
51#include <cstring>
52#include <iterator>
53#include <limits>
54#include <map>
55#include <memory>
56#include <utility>
57#include <set>
58#include <string>
59#include <vector>
60
61namespace amrex {
62
63template <typename T>
64requires (!BaseFabType<T>)
65Long nBytesOwned (T const&) noexcept { return 0; }
66
67template <typename T>
68Long nBytesOwned (BaseFab<T> const& fab) noexcept { return fab.nBytesOwned(); }
69
73struct MFInfo {
74 // alloc: allocate memory or not
75 bool alloc = true;
77 Arena* arena = nullptr;
79
81 MFInfo& SetAlloc (bool a) noexcept { alloc = a; return *this; }
82
84 MFInfo& SetAllocSingleChunk (bool a) noexcept { alloc_single_chunk = a; return *this; }
85
87 MFInfo& SetArena (Arena* ar) noexcept { arena = ar; return *this; }
88
90 MFInfo& SetTag () noexcept { return *this; }
91
93 MFInfo& SetTag (const char* t) noexcept {
94 tags.emplace_back(t);
95 return *this;
96 }
97
99 MFInfo& SetTag (const std::string& t) noexcept {
100 tags.emplace_back(t);
101 return *this;
102 }
103
105 template <typename T, typename... Ts>
106 MFInfo& SetTag (T&& t, Ts&&... ts) noexcept {
107 tags.emplace_back(std::forward<T>(t));
108 return SetTag(std::forward<Ts>(ts)...);
109 }
110};
111
113 using pointer = char*;
114 void operator()(pointer p) const noexcept {
115 The_Comms_Arena()->free(p);
116 }
117};
118using TheFaArenaPointer = std::unique_ptr<char, TheFaArenaDeleter>;
119
120// Data used in non-blocking fill boundary.
121template <class FAB>
143
144// Data used in non-blocking parallel copy.
145template <class FAB>
165
166template <typename T>
168{
170 Array4<T> const& operator[] (int li) const noexcept {
171 AMREX_IF_ON_DEVICE((return dp[li];))
172 AMREX_IF_ON_HOST((return hp[li];))
173 }
174
176 explicit operator bool() const noexcept {
177 AMREX_IF_ON_DEVICE((return dp != nullptr;))
178 AMREX_IF_ON_HOST((return hp != nullptr;))
179 }
180
181#ifdef AMREX_USE_GPU
182 Array4<T> const* AMREX_RESTRICT dp = nullptr;
183#endif
184 Array4<T> const* AMREX_RESTRICT hp = nullptr;
185};
186
187template <class FAB> class FabArray;
188
189template <BaseFabType DFAB, BaseFabType SFAB>
190requires (std::is_convertible_v<typename SFAB::value_type, typename DFAB::value_type>)
191void
192Copy (FabArray<DFAB>& dst, FabArray<SFAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
193{
194 Copy(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
195}
196
197template <BaseFabType DFAB, BaseFabType SFAB>
198requires (std::is_convertible_v<typename SFAB::value_type, typename DFAB::value_type>)
199void
200Copy (FabArray<DFAB>& dst, FabArray<SFAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
201{
202 BL_PROFILE("amrex::Copy()");
203
204 using DT = typename DFAB::value_type;
205
206 if (dst.local_size() == 0) { return; }
207
208 // avoid self copy
209 if constexpr (std::is_same_v<typename SFAB::value_type, typename DFAB::value_type>) {
210 if (dst.atLocalIdx(0).dataPtr(dstcomp) == src.atLocalIdx(0).dataPtr(srccomp)) {
211 return;
212 }
213 }
214
215#ifdef AMREX_USE_GPU
216 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
217 auto const& srcarr = src.const_arrays();
218 auto const& dstarr = dst.arrays();
219 ParallelFor(dst, nghost, numcomp,
220 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
221 {
222 dstarr[box_no](i,j,k,dstcomp+n) = DT(srcarr[box_no](i,j,k,srccomp+n));
223 });
224 if (!Gpu::inNoSyncRegion()) {
226 }
227 } else
228#endif
229 {
230#ifdef AMREX_USE_OMP
231#pragma omp parallel if (Gpu::notInLaunchRegion())
232#endif
233 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
234 {
235 const Box& bx = mfi.growntilebox(nghost);
236 if (bx.ok())
237 {
238 auto const& srcFab = src.const_array(mfi);
239 auto const& dstFab = dst.array(mfi);
240 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
241 {
242 dstFab(i,j,k,dstcomp+n) = DT(srcFab(i,j,k,srccomp+n));
243 });
244 }
245 }
246 }
247}
248
249template <BaseFabType FAB>
250void
251Add (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
252{
253 Add(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
254}
255
256template <BaseFabType FAB>
257void
258Add (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
259{
260 BL_PROFILE("amrex::Add()");
261
262#ifdef AMREX_USE_GPU
263 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
264 auto const& dstfa = dst.arrays();
265 auto const& srcfa = src.const_arrays();
266 ParallelFor(dst, nghost, numcomp,
267 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
268 {
269 dstfa[box_no](i,j,k,n+dstcomp) += srcfa[box_no](i,j,k,n+srccomp);
270 });
271 if (!Gpu::inNoSyncRegion()) {
273 }
274 } else
275#endif
276 {
277#ifdef AMREX_USE_OMP
278#pragma omp parallel if (Gpu::notInLaunchRegion())
279#endif
280 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
281 {
282 const Box& bx = mfi.growntilebox(nghost);
283 if (bx.ok())
284 {
285 auto const srcFab = src.array(mfi);
286 auto dstFab = dst.array(mfi);
287 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
288 {
289 dstFab(i,j,k,n+dstcomp) += srcFab(i,j,k,n+srccomp);
290 });
291 }
292 }
293 }
294}
295
352template <class FAB>
354 :
355 public FabArrayBase
356{
357public:
358
359 struct FABType {
360 using value_type = FAB;
361 };
362
363 /*
364 * if FAB is a BaseFab or its child, value_type = FAB::value_type
365 * else value_type = FAB;
366 */
367 using value_type = typename std::conditional_t<IsBaseFab<FAB>::value, FAB, FABType>::value_type;
368
369 using fab_type = FAB;
370
371 //
373 FabArray () noexcept;
374
382 explicit FabArray (Arena* a) noexcept;
383
389 FabArray (const BoxArray& bxs,
390 const DistributionMapping& dm,
391 int nvar,
392 int ngrow,
393#ifdef AMREX_STRICT_MODE
394 const MFInfo& info,
395 const FabFactory<FAB>& factory);
396#else
397 const MFInfo& info = MFInfo(),
398 const FabFactory<FAB>& factory = DefaultFabFactory<FAB>());
399#endif
400
402 FabArray (const BoxArray& bxs,
403 const DistributionMapping& dm,
404 int nvar,
405 const IntVect& ngrow,
406#ifdef AMREX_STRICT_MODE
407 const MFInfo& info,
408 const FabFactory<FAB>& factory);
409#else
410 const MFInfo& info = MFInfo(),
411 const FabFactory<FAB>& factory = DefaultFabFactory<FAB>());
412#endif
413
422 FabArray (const FabArray<FAB>& rhs, MakeType maketype, int scomp, int ncomp);
423
426
427 FabArray (FabArray<FAB>&& rhs) noexcept;
429
430 FabArray (const FabArray<FAB>& rhs) = delete;
432
439 void define (const BoxArray& bxs,
440 const DistributionMapping& dm,
441 int nvar,
442 int ngrow,
443#ifdef AMREX_STRICT_MODE
444 const MFInfo& info,
445 const FabFactory<FAB>& factory);
446#else
447 const MFInfo& info = MFInfo(),
448 const FabFactory<FAB>& factory = DefaultFabFactory<FAB>());
449#endif
450
452 void define (const BoxArray& bxs,
453 const DistributionMapping& dm,
454 int nvar,
455 const IntVect& ngrow,
456#ifdef AMREX_STRICT_MODE
457 const MFInfo& info,
458 const FabFactory<FAB>& factory);
459#else
460 const MFInfo& info = MFInfo(),
461 const FabFactory<FAB>& factory = DefaultFabFactory<FAB>());
462#endif
463
471 const FabFactory<FAB>& Factory () const noexcept { return *m_factory; }
472
480 Arena* arena () const noexcept { return m_dallocator.arena(); }
481
488 const Vector<std::string>& tags () const noexcept { return m_tags; }
489
493 bool hasEBFabFactory () const noexcept {
494#ifdef AMREX_USE_EB
495 const auto *const f = dynamic_cast<EBFArrayBoxFactory const*>(m_factory.get());
496 return (f != nullptr);
497#else
498 return false;
499#endif
500 }
501
504 [[nodiscard]] value_type* singleChunkPtr () noexcept {
505 return m_single_chunk_arena ? (value_type*)m_single_chunk_arena->data() : nullptr;
506 }
507
510 [[nodiscard]] value_type const* singleChunkPtr () const noexcept {
511 return m_single_chunk_arena ? (value_type const*)m_single_chunk_arena->data() : nullptr;
512 }
513
516 [[nodiscard]] std::size_t singleChunkSize () const noexcept { return m_single_chunk_size; }
517
521 bool isAllRegular () const noexcept {
522#ifdef AMREX_USE_EB
523 const auto *const f = dynamic_cast<EBFArrayBoxFactory const*>(m_factory.get());
524 if (f) {
525 return f->isAllRegular();
526 } else {
527 return true;
528 }
529#else
530 return true;
531#endif
532 }
533
543 bool ok () const;
544
552 bool isDefined () const;
553
555 const FAB& operator[] (const MFIter& mfi) const noexcept { return *(this->fabPtr(mfi)); }
556
558 const FAB& get (const MFIter& mfi) const noexcept { return *(this->fabPtr(mfi)); }
559
561 FAB& operator[] (const MFIter& mfi) noexcept { return *(this->fabPtr(mfi)); }
562
564 FAB& get (const MFIter& mfi) noexcept { return *(this->fabPtr(mfi)); }
565
567 const FAB& operator[] (int K) const noexcept { return *(this->fabPtr(K)); }
568
570 const FAB& get (int K) const noexcept { return *(this->fabPtr(K)); }
571
573 FAB& operator[] (int K) noexcept { return *(this->fabPtr(K)); }
574
576 FAB& get (int K) noexcept { return *(this->fabPtr(K)); }
577
579 FAB& atLocalIdx (int L) noexcept { return *m_fabs_v[L]; }
580 const FAB& atLocalIdx (int L) const noexcept { return *m_fabs_v[L]; }
581
583 FAB * fabPtr (const MFIter& mfi) noexcept;
584 FAB const* fabPtr (const MFIter& mfi) const noexcept;
585 FAB * fabPtr (int K) noexcept; // Here K is global index
586 FAB const* fabPtr (int K) const noexcept;
587
592 void prefetchToHost (const MFIter& mfi) const noexcept
593 requires (BaseFabType<FAB>)
594 {
595 // BaseFab::prefetchToHost() does the managed-memory check and the
596 // per-backend dispatch, so guard only against non-GPU builds here.
597#ifdef AMREX_USE_GPU
598 this->fabPtr(mfi)->prefetchToHost();
599#else
601#endif
602 }
603
608 void prefetchToDevice (const MFIter& mfi) const noexcept
609 requires (BaseFabType<FAB>)
610 {
611 // BaseFab::prefetchToDevice() does the managed-memory check and the
612 // per-backend dispatch, so guard only against non-GPU builds here.
613#ifdef AMREX_USE_GPU
614 this->fabPtr(mfi)->prefetchToDevice();
615#else
617#endif
618 }
619
621 Array4<typename FabArray<FAB>::value_type const> array (const MFIter& mfi) const noexcept
622 requires (BaseFabType<FAB>)
623 {
624 return fabPtr(mfi)->const_array();
625 }
626
629 requires (BaseFabType<FAB>)
630 {
631 return fabPtr(mfi)->array();
632 }
633
636 requires (BaseFabType<FAB>)
637 {
638 return fabPtr(K)->const_array();
639 }
640
643 requires (BaseFabType<FAB>)
644 {
645 return fabPtr(K)->array();
646 }
647
650 requires (BaseFabType<FAB>)
651 {
652 return fabPtr(mfi)->const_array();
653 }
654
657 requires (BaseFabType<FAB>)
658 {
659 return fabPtr(K)->const_array();
660 }
661
664 Array4<typename FabArray<FAB>::value_type const> array (const MFIter& mfi, int start_comp) const noexcept
665 requires (BaseFabType<FAB>)
666 {
667 return fabPtr(mfi)->const_array(start_comp);
668 }
669
672 Array4<typename FabArray<FAB>::value_type> array (const MFIter& mfi, int start_comp) noexcept
673 requires (BaseFabType<FAB>)
674 {
675 return fabPtr(mfi)->array(start_comp);
676 }
677
680 Array4<typename FabArray<FAB>::value_type const> array (int K, int start_comp) const noexcept
681 requires (BaseFabType<FAB>)
682 {
683 return fabPtr(K)->const_array(start_comp);
684 }
685
688 Array4<typename FabArray<FAB>::value_type> array (int K, int start_comp) noexcept
689 requires (BaseFabType<FAB>)
690 {
691 return fabPtr(K)->array(start_comp);
692 }
693
696 Array4<typename FabArray<FAB>::value_type const> const_array (const MFIter& mfi, int start_comp) const noexcept
697 requires (BaseFabType<FAB>)
698 {
699 return fabPtr(mfi)->const_array(start_comp);
700 }
701
704 Array4<typename FabArray<FAB>::value_type const> const_array (int K, int start_comp) const noexcept
705 requires (BaseFabType<FAB>)
706 {
707 return fabPtr(K)->const_array(start_comp);
708 }
709
714 requires (BaseFabType<FAB>)
715 {
716 build_arrays();
717 return m_arrays;
718 }
719
724 requires (BaseFabType<FAB>)
725 {
726 build_arrays();
727 return m_const_arrays;
728 }
729
732 requires (BaseFabType<FAB>)
733 {
734 build_arrays();
735 return m_const_arrays;
736 }
737
739 void setFab (int boxno, std::unique_ptr<FAB> elem);
740
742 template <class F=FAB>
743 requires (std::is_move_constructible_v<F>)
744 void setFab (int boxno, FAB&& elem);
745
747 void setFab (const MFIter&mfi, std::unique_ptr<FAB> elem);
748
750 template <class F=FAB>
751 requires (std::is_move_constructible_v<F>)
752 void setFab (const MFIter&mfi, FAB&& elem);
753
755 [[nodiscard]]
756 FAB* release (int K);
757
759 [[nodiscard]]
760 FAB* release (const MFIter& mfi);
761
763 void clear ();
764
779 template <BaseFabType SFAB, BaseFabType DFAB = FAB>
780 requires (std::is_convertible_v<typename SFAB::value_type,
781 typename DFAB::value_type>)
782 void LocalCopy (FabArray<SFAB> const& src, int scomp, int dcomp, int ncomp,
783 IntVect const& nghost);
784
797 template <class F=FAB>
798 requires (BaseFabType<F>)
799 void LocalAdd (FabArray<FAB> const& src, int scomp, int dcomp, int ncomp,
800 IntVect const& nghost);
801
803 template <class F=FAB>
804 requires (BaseFabType<F>)
805 void setVal (value_type val);
806
808 template <class F=FAB>
809 requires (BaseFabType<F>)
810 FabArray<FAB>& operator= (value_type val);
811
817 template <class F=FAB>
818 requires (BaseFabType<F>)
820 int comp,
821 int ncomp,
822 int nghost = 0);
823
824 template <class F=FAB>
825 requires (BaseFabType<F>)
827 int comp,
828 int ncomp,
829 const IntVect& nghost);
830
837 template <class F=FAB>
838 requires (BaseFabType<F>)
840 const Box& region,
841 int comp,
842 int ncomp,
843 int nghost = 0);
844
845 template <class F=FAB>
846 requires (BaseFabType<F>)
848 const Box& region,
849 int comp,
850 int ncomp,
851 const IntVect& nghost);
856 template <class F=FAB>
857 requires (BaseFabType<F>)
858 void setVal (value_type val, int nghost);
859
860 template <class F=FAB>
861 requires (BaseFabType<F>)
862 void setVal (value_type val, const IntVect& nghost);
863
869 template <class F=FAB>
870 requires (BaseFabType<F>)
871 void setVal (value_type val, const Box& region, int nghost);
872
873 template <class F=FAB>
874 requires (BaseFabType<F>)
875 void setVal (value_type val, const Box& region, const IntVect& nghost);
876
877 template <class F=FAB>
878 requires (BaseFabType<F>)
879 void abs (int comp, int ncomp, int nghost = 0);
880
881 template <class F=FAB>
882 requires (BaseFabType<F>)
883 void abs (int comp, int ncomp, const IntVect& nghost);
884
885 template <class F=FAB>
886 requires (BaseFabType<F>)
887 void plus (value_type val, int comp, int num_comp, int nghost = 0);
888
889 template <class F=FAB>
890 requires (BaseFabType<F>)
891 void plus (value_type val, const Box& region, int comp, int num_comp, int nghost = 0);
892
893 template <class F=FAB>
894 requires (BaseFabType<F>)
895 void mult (value_type val, int comp, int num_comp, int nghost = 0);
896
897 template <class F=FAB>
898 requires (BaseFabType<F>)
899 void mult (value_type val, const Box& region, int comp, int num_comp, int nghost = 0);
900
901 template <class F=FAB>
902 requires (BaseFabType<F>)
903 void invert (value_type numerator, int comp, int num_comp, int nghost = 0);
904
905 template <class F=FAB>
906 requires (BaseFabType<F>)
907 void invert (value_type numerator, const Box& region, int comp, int num_comp, int nghost = 0);
908
910 template <class F=FAB>
911 requires (BaseFabType<F>)
913
915 template <class F=FAB>
916 requires (BaseFabType<F>)
917 void setBndry (value_type val, int strt_comp, int ncomp);
918
924 template <class F=FAB>
925 requires (BaseFabType<F>)
926 void setDomainBndry (value_type val, const Geometry& geom);
927
934 template <class F=FAB>
935 requires (BaseFabType<F>)
936 void setDomainBndry (value_type val, int strt_comp, int ncomp, const Geometry& geom);
937
944 template <std::integral I>
945 requires (BaseFabType<FAB> && (sizeof(I) >= sizeof(Long)))
946 void capacityOfFabs (LayoutData<I>& mem) const;
947
957 template <typename F=FAB>
958 requires (BaseFabType<F>)
959 typename F::value_type
960 sum (int comp, IntVect const& nghost, bool local = false) const;
961
968 void ParallelAdd (const FabArray<FAB>& src,
969 const Periodicity& period = Periodicity::NonPeriodic())
970 { ParallelCopy(src,period,FabArray::ADD); }
971 void ParallelCopy (const FabArray<FAB>& src,
972 const Periodicity& period = Periodicity::NonPeriodic(),
974 { ParallelCopy(src,0,0,nComp(),0,0,period,op); }
975
976 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
977 void copy (const FabArray<FAB>& src,
978 const Periodicity& period = Periodicity::NonPeriodic(),
980 { ParallelCopy(src,period,op); }
981
991 const Periodicity& period = Periodicity::NonPeriodic())
992 { ParallelCopy_nowait(src,period,FabArray::ADD); }
993
1004 const Periodicity& period = Periodicity::NonPeriodic(),
1006 { ParallelCopy_nowait(src,0,0,nComp(),0,0,period,op); }
1007
1016 void ParallelAdd (const FabArray<FAB>& src,
1017 int src_comp,
1018 int dest_comp,
1019 int num_comp,
1020 const Periodicity& period = Periodicity::NonPeriodic())
1021 { ParallelCopy(src,src_comp,dest_comp,num_comp, period, FabArrayBase::ADD); }
1022 void ParallelCopy (const FabArray<FAB>& src,
1023 int src_comp,
1024 int dest_comp,
1025 int num_comp,
1026 const Periodicity& period = Periodicity::NonPeriodic(),
1028 { ParallelCopy(src,src_comp,dest_comp,num_comp,0,0,period,op); }
1029
1030 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
1031 void copy (const FabArray<FAB>& src,
1032 int src_comp,
1033 int dest_comp,
1034 int num_comp,
1035 const Periodicity& period = Periodicity::NonPeriodic(),
1037 { ParallelCopy(src,src_comp,dest_comp,num_comp, period, op); }
1038
1051 int src_comp,
1052 int dest_comp,
1053 int num_comp,
1054 const Periodicity& period = Periodicity::NonPeriodic())
1055 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp, period, FabArrayBase::ADD); }
1056
1070 int src_comp,
1071 int dest_comp,
1072 int num_comp,
1073 const Periodicity& period = Periodicity::NonPeriodic(),
1075 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,0,0,period,op); }
1076
1078 void ParallelAdd (const FabArray<FAB>& src,
1079 int src_comp,
1080 int dest_comp,
1081 int num_comp,
1082 int src_nghost,
1083 int dst_nghost,
1084 const Periodicity& period = Periodicity::NonPeriodic())
1085 { ParallelCopy(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),IntVect(dst_nghost),period,
1087 void ParallelAdd (const FabArray<FAB>& src,
1088 int src_comp,
1089 int dest_comp,
1090 int num_comp,
1091 const IntVect& src_nghost,
1092 const IntVect& dst_nghost,
1093 const Periodicity& period = Periodicity::NonPeriodic())
1094 { ParallelCopy(src,src_comp,dest_comp,num_comp,src_nghost,dst_nghost,period,FabArrayBase::ADD); }
1095 void ParallelCopy (const FabArray<FAB>& src,
1096 int src_comp,
1097 int dest_comp,
1098 int num_comp,
1099 int src_nghost,
1100 int dst_nghost,
1101 const Periodicity& period = Periodicity::NonPeriodic(),
1103 { ParallelCopy(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),IntVect(dst_nghost),period,op); }
1104 void ParallelCopy (const FabArray<FAB>& src,
1105 int scomp,
1106 int dcomp,
1107 int ncomp,
1108 const IntVect& snghost,
1109 const IntVect& dnghost,
1110 const Periodicity& period = Periodicity::NonPeriodic(),
1112 const FabArrayBase::CPC* a_cpc = nullptr,
1113 bool deterministic = false);
1114
1129 int src_comp,
1130 int dest_comp,
1131 int num_comp,
1132 int src_nghost,
1133 int dst_nghost,
1134 const Periodicity& period = Periodicity::NonPeriodic())
1135 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),
1136 IntVect(dst_nghost),period,FabArrayBase::ADD); }
1137
1152 int src_comp,
1153 int dest_comp,
1154 int num_comp,
1155 const IntVect& src_nghost,
1156 const IntVect& dst_nghost,
1157 const Periodicity& period = Periodicity::NonPeriodic())
1158 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,src_nghost,
1159 dst_nghost,period,FabArrayBase::ADD); }
1160
1176 int src_comp,
1177 int dest_comp,
1178 int num_comp,
1179 int src_nghost,
1180 int dst_nghost,
1181 const Periodicity& period = Periodicity::NonPeriodic(),
1183 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),
1184 IntVect(dst_nghost),period,op); }
1185
1203 void ParallelCopy_nowait (const FabArray<FAB>& src,
1204 int scomp,
1205 int dcomp,
1206 int ncomp,
1207 const IntVect& snghost,
1208 const IntVect& dnghost,
1209 const Periodicity& period = Periodicity::NonPeriodic(),
1211 const FabArrayBase::CPC* a_cpc = nullptr,
1212 bool to_ghost_cells_only = false,
1213 bool deterministic = false);
1214
1235 void ParallelCopy_nowait (const FabArray<FAB>& src,
1236 int scomp,
1237 int dcomp,
1238 int ncomp,
1239 const IntVect& snghost,
1240 const IntVect& dnghost,
1241 const IntVect& offset,
1242 const Periodicity& period = Periodicity::NonPeriodic(),
1244 const FabArrayBase::CPC* a_cpc = nullptr,
1245 bool to_ghost_cells_only = false,
1246 bool deterministic = false);
1247
1251 void ParallelCopy_finish ();
1252
1264 void ParallelCopyToGhost (const FabArray<FAB>& src,
1265 int scomp,
1266 int dcomp,
1267 int ncomp,
1268 const IntVect& snghost,
1269 const IntVect& dnghost,
1270 const Periodicity& period = Periodicity::NonPeriodic());
1271
1286 int scomp,
1287 int dcomp,
1288 int ncomp,
1289 const IntVect& snghost,
1290 const IntVect& dnghost,
1291 const Periodicity& period = Periodicity::NonPeriodic());
1292
1295
1308 void ParallelCopy (const FabArray<FAB>& src, int src_comp, int dest_comp, int num_comp,
1309 const IntVect& snghost, const IntVect& dnghost,
1310 const IntVect& offset, const Periodicity& period);
1311
1324 void ParallelAdd (const FabArray<FAB>& src, int src_comp, int dest_comp, int num_comp,
1325 const IntVect& snghost, const IntVect& dnghost,
1326 const IntVect& offset, const Periodicity& period);
1327
1328 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
1329 void copy (const FabArray<FAB>& src,
1330 int src_comp,
1331 int dest_comp,
1332 int num_comp,
1333 int src_nghost,
1334 int dst_nghost,
1335 const Periodicity& period = Periodicity::NonPeriodic(),
1337 { ParallelCopy(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),IntVect(dst_nghost),period,op); }
1338
1339 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
1340 void copy (const FabArray<FAB>& src,
1341 int src_comp,
1342 int dest_comp,
1343 int num_comp,
1344 const IntVect& src_nghost,
1345 const IntVect& dst_nghost,
1346 const Periodicity& period = Periodicity::NonPeriodic(),
1348 { ParallelCopy(src,src_comp,dest_comp,num_comp,src_nghost,dst_nghost,period,op); }
1349
1351 void Redistribute (const FabArray<FAB>& src,
1352 int scomp,
1353 int dcomp,
1354 int ncomp,
1355 const IntVect& nghost);
1356
1362 void copyTo (FAB& dest, int nghost = 0) const;
1363
1371 void copyTo (FAB& dest, int scomp, int dcomp, int ncomp, int nghost = 0) const;
1372
1374 void shift (const IntVect& v);
1375
1376 bool defined (int K) const noexcept;
1377 bool defined (const MFIter& mfi) const noexcept;
1378
1391 template <typename BUF=value_type>
1392 void FillBoundary (bool cross = false);
1393
1395 template <typename BUF=value_type>
1396 void FillBoundary (const Periodicity& period, bool cross = false);
1397
1398 template <typename BUF=value_type>
1399 void FillBoundary (const IntVect& nghost, const Periodicity& period, bool cross = false);
1400
1403 template <typename BUF=value_type>
1404 void FillBoundary (int scomp, int ncomp, bool cross = false);
1405
1407 template <typename BUF=value_type>
1408 void FillBoundary (int scomp, int ncomp, const Periodicity& period, bool cross = false);
1409
1411 template <typename BUF=value_type>
1412 void FillBoundary (int scomp, int ncomp, const IntVect& nghost, const Periodicity& period, bool cross = false);
1413
1414 template <typename BUF=value_type>
1415 void FillBoundary_nowait (bool cross = false);
1416
1417 template <typename BUF=value_type>
1418 void FillBoundary_nowait (const Periodicity& period, bool cross = false);
1419
1420 template <typename BUF=value_type>
1421 void FillBoundary_nowait (const IntVect& nghost, const Periodicity& period, bool cross = false);
1422
1423 template <typename BUF=value_type>
1424 void FillBoundary_nowait (int scomp, int ncomp, bool cross = false);
1425
1426 template <typename BUF=value_type>
1427 void FillBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool cross = false);
1428
1429 template <typename BUF=value_type>
1430 void FillBoundary_nowait (int scomp, int ncomp, const IntVect& nghost, const Periodicity& period, bool cross = false);
1431
1432 template <typename BUF=value_type, class F=FAB>
1433 requires (BaseFabType<F>)
1434 void FillBoundary_finish ();
1435
1436 void FillBoundary_test ();
1437
1468 void FillBoundaryAndSync (int scomp, int ncomp, const IntVect& nghost,
1469 const Periodicity& period);
1471 void FillBoundaryAndSync_nowait (int scomp, int ncomp, const IntVect& nghost,
1472 const Periodicity& period);
1474
1511 void OverrideSync (int scomp, int ncomp, const Periodicity& period);
1513 void OverrideSync_nowait (int scomp, int ncomp, const Periodicity& period);
1515
1527 bool deterministic = false);
1529 void SumBoundary (int scomp, int ncomp, const Periodicity& period = Periodicity::NonPeriodic(),
1530 bool deterministic = false);
1532 bool deterministic = false);
1533 void SumBoundary_nowait (int scomp, int ncomp, const Periodicity& period = Periodicity::NonPeriodic(),
1534 bool deterministic = false);
1535
1546 void SumBoundary (int scomp, int ncomp, IntVect const& nghost,
1547 const Periodicity& period = Periodicity::NonPeriodic(),
1548 bool deterministic = false);
1549 void SumBoundary_nowait (int scomp, int ncomp, IntVect const& nghost,
1550 const Periodicity& period = Periodicity::NonPeriodic(),
1551 bool deterministic = false);
1552
1564 void SumBoundary (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost,
1565 const Periodicity& period = Periodicity::NonPeriodic(),
1566 bool deterministic = false);
1567 void SumBoundary_nowait (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost,
1568 const Periodicity& period = Periodicity::NonPeriodic(),
1569 bool deterministic = false);
1571
1582 void EnforcePeriodicity (const Periodicity& period);
1584 void EnforcePeriodicity (int scomp, int ncomp, const Periodicity& period);
1586 void EnforcePeriodicity (int scomp, int ncomp, const IntVect& nghost,
1587 const Periodicity& period);
1588
1589 // covered : ghost cells covered by valid cells of this FabArray
1590 // (including periodically shifted valid cells)
1591 // notcovered: ghost cells not covered by valid cells
1592 // (including ghost cells outside periodic boundaries)
1593 // physbnd : boundary cells outside the domain (excluding periodic boundaries)
1594 // interior : interior cells (i.e., valid cells)
1595 template <class F=FAB>
1596 requires (BaseFabType<F>)
1597 void BuildMask (const Box& phys_domain, const Periodicity& period,
1598 value_type covered, value_type notcovered,
1599 value_type physbnd, value_type interior);
1600
1601 // The following are private functions. But we have to make them public for cuda.
1602
1603 template <typename BUF=value_type, class F=FAB>
1604 requires (BaseFabType<F>)
1605 void FBEP_nowait (int scomp, int ncomp, const IntVect& nghost,
1606 const Periodicity& period, bool cross,
1607 bool enforce_periodicity_only = false,
1608 bool override_sync = false,
1609 IntVect const& sumboundary_src_nghost = IntVect(-1),
1610 bool deterministic = false);
1611
1612 void FB_local_copy_cpu (const FB& TheFB, int scomp, int ncomp);
1613 void FB_local_add_cpu (const FB& TheFB, int scomp, int ncomp);
1614 void PC_local_cpu (const CPC& thecpc, FabArray<FAB> const& src,
1615 int scomp, int dcomp, int ncomp, CpOp op);
1616
1617 template <class F=FAB>
1618 requires (BaseFabType<F>)
1619 void setVal (value_type val, const CommMetaData& thecmd, int scomp, int ncomp);
1620
1621 template <class F=FAB>
1622 requires (BaseFabType<F>)
1624
1625#ifdef AMREX_USE_GPU
1626
1628 FB_get_local_copy_tag_vector (const FB& TheFB);
1629
1630 void FB_local_copy_gpu (const FB& TheFB, int scomp, int ncomp);
1631 void FB_local_add_gpu (const FB& TheFB, int scomp, int ncomp, bool deterministic);
1632 void PC_local_gpu (const CPC& thecpc, FabArray<FAB> const& src,
1633 int scomp, int dcomp, int ncomp, CpOp op, bool deterministic);
1634
1635 void CMD_local_setVal_gpu (value_type x, const CommMetaData& thecmd, int scomp, int ncomp);
1636 void CMD_remote_setVal_gpu (value_type x, const CommMetaData& thecmd, int scomp, int ncomp);
1637
1638#if defined(__CUDACC__)
1639
1640 void FB_local_copy_cuda_graph_1 (const FB& TheFB, int scomp, int ncomp);
1641 void FB_local_copy_cuda_graph_n (const FB& TheFB, int scomp, int ncomp);
1642
1643#endif
1644#endif
1645
1646#ifdef AMREX_USE_MPI
1647
1648#ifdef AMREX_USE_GPU
1649#if defined(__CUDACC__)
1650
1651 void FB_pack_send_buffer_cuda_graph (const FB& TheFB, int scomp, int ncomp,
1652 Vector<char*>& send_data,
1653 Vector<std::size_t> const& send_size,
1654 Vector<const CopyComTagsContainer*> const& send_cctc);
1655
1656 void FB_unpack_recv_buffer_cuda_graph (const FB& TheFB, int dcomp, int ncomp,
1657 Vector<char*> const& recv_data,
1658 Vector<std::size_t> const& recv_size,
1659 Vector<const CopyComTagsContainer*> const& recv_cctc,
1660 bool is_thread_safe);
1661
1662#endif
1663
1664 template <typename BUF = value_type>
1665 static void pack_send_buffer_gpu (FabArray<FAB> const& src, int scomp, int ncomp,
1666 Vector<char*> const& send_data,
1667 Vector<std::size_t> const& send_size,
1668 Vector<const CopyComTagsContainer*> const& send_cctc,
1669 std::uint64_t id);
1670
1671 template <typename BUF = value_type>
1672 static void unpack_recv_buffer_gpu (FabArray<FAB>& dst, int dcomp, int ncomp,
1673 Vector<char*> const& recv_data,
1674 Vector<std::size_t> const& recv_size,
1675 Vector<const CopyComTagsContainer*> const& recv_cctc,
1676 CpOp op, bool is_thread_safe,
1677 std::uint64_t id, bool deterministic);
1678
1679 template <typename BUF>
1682 Vector<std::size_t> const& recv_size,
1683 Vector<CopyComTagsContainer const*> const& recv_cctc,
1684 int ncomp, std::uint64_t id);
1685
1686 template <typename BUF>
1689 Vector<std::size_t> const& send_size,
1690 Vector<CopyComTagsContainer const*> const& send_cctc,
1691 int ncomp, std::uint64_t id) const;
1692
1693#endif
1694
1695 template <typename BUF = value_type>
1696 static void pack_send_buffer_cpu (FabArray<FAB> const& src, int scomp, int ncomp,
1697 Vector<char*> const& send_data,
1698 Vector<std::size_t> const& send_size,
1699 Vector<const CopyComTagsContainer*> const& send_cctc);
1700
1701 template <typename BUF = value_type>
1702 static void unpack_recv_buffer_cpu (FabArray<FAB>& dst, int dcomp, int ncomp,
1703 Vector<char*> const& recv_data,
1704 Vector<std::size_t> const& recv_size,
1705 Vector<const CopyComTagsContainer*> const& recv_cctc,
1706 CpOp op, bool is_thread_safe);
1707
1708#endif
1709
1722 template <typename F=FAB>
1723 requires (BaseFabType<F>)
1724 typename F::value_type
1725 norminf (int comp, int ncomp, IntVect const& nghost, bool local = false,
1726 [[maybe_unused]] bool ignore_covered = false) const;
1727
1740 template <typename IFAB, typename F=FAB>
1741 requires (BaseFabType<F>)
1742 typename F::value_type
1743 norminf (FabArray<IFAB> const& mask, int comp, int ncomp, IntVect const& nghost,
1744 bool local = false) const;
1745
1746protected:
1747
1748 std::unique_ptr<FabFactory<FAB> > m_factory;
1750 std::unique_ptr<detail::SingleChunkArena> m_single_chunk_arena;
1752
1755
1756 //
1758 std::vector<FAB*> m_fabs_v;
1759
1760#ifdef AMREX_USE_GPU
1761 mutable void* m_dp_arrays = nullptr;
1762#endif
1763 mutable void* m_hp_arrays = nullptr;
1766
1768
1770 struct ShMem {
1771
1772 ShMem () noexcept = default;
1773
1774 ~ShMem () { // NOLINT
1775#if defined(BL_USE_MPI3)
1776 if (win != MPI_WIN_NULL) { MPI_Win_free(&win); }
1777#endif
1778#ifdef BL_USE_TEAM
1779 if (alloc) {
1781 }
1782#endif
1783 }
1784 ShMem (ShMem&& rhs) noexcept
1785 : alloc(rhs.alloc), n_values(rhs.n_values), n_points(rhs.n_points)
1786#if defined(BL_USE_MPI3)
1787 , win(rhs.win)
1788#endif
1789 {
1790 rhs.alloc = false;
1791#if defined(BL_USE_MPI3)
1792 rhs.win = MPI_WIN_NULL;
1793#endif
1794 }
1795 ShMem& operator= (ShMem&& rhs) noexcept {
1796 if (&rhs != this) {
1797 alloc = rhs.alloc;
1798 n_values = rhs.n_values;
1799 n_points = rhs.n_points;
1800 rhs.alloc = false;
1801#if defined(BL_USE_MPI3)
1802 win = rhs.win;
1803 rhs.win = MPI_WIN_NULL;
1804#endif
1805 }
1806 return *this;
1807 }
1808 ShMem (const ShMem&) = delete;
1809 ShMem& operator= (const ShMem&) = delete;
1810 bool alloc{false};
1813#if defined(BL_USE_MPI3)
1814 MPI_Win win = MPI_WIN_NULL;
1815#endif
1816 };
1818
1819 bool SharedMemory () const noexcept { return shmem.alloc; }
1820
1821private:
1822 using Iterator = typename std::vector<FAB*>::iterator;
1823
1824 void AllocFabs (const FabFactory<FAB>& factory, Arena* ar,
1826 bool alloc_single_chunk);
1827
1828 void setFab_assert (int K, FAB const& fab) const;
1829
1830 template <class F=FAB>
1831 requires (BaseFabType<F>)
1832 void build_arrays () const;
1833
1834 void clear_arrays ();
1835
1836#ifdef AMREX_USE_GPU
1837 std::map<std::uint64_t,
1838 std::unique_ptr<TagVector<Array4CopyTag<value_type>>>>
1839 m_fb_local_copy_handler;
1840
1841 using RecvSendCopyHandlerKey = std::tuple<std::uint64_t,std::size_t,int>;
1842 std::map<RecvSendCopyHandlerKey,
1843 std::unique_ptr<TagVector<CommRecvBufTag<value_type>>>>
1844 m_recv_copy_handler;
1845 mutable std::map<RecvSendCopyHandlerKey,
1846 std::unique_ptr<TagVector<CommSendBufTag<value_type>>>>
1847 m_send_copy_handler;
1848#endif
1849
1850public:
1851
1852#ifdef BL_USE_MPI
1853
1855 template <typename BUF=value_type>
1856 static void PostRcvs (const MapOfCopyComTagContainers& RcvTags,
1857 char*& the_recv_data,
1858 Vector<char*>& recv_data,
1859 Vector<std::size_t>& recv_size,
1860 Vector<int>& recv_from,
1861 Vector<MPI_Request>& recv_reqs,
1862 int ncomp,
1863 int SeqNum);
1864
1865 template <typename BUF=value_type>
1866 [[nodiscard]]
1867 static TheFaArenaPointer PostRcvs (const MapOfCopyComTagContainers& RcvTags,
1868 Vector<char*>& recv_data,
1869 Vector<std::size_t>& recv_size,
1870 Vector<int>& recv_from,
1871 Vector<MPI_Request>& recv_reqs,
1872 int ncomp,
1873 int SeqNum);
1874
1875 template <typename BUF=value_type>
1876 static void PrepareSendBuffers (const MapOfCopyComTagContainers& SndTags,
1877 char*& the_send_data,
1878 Vector<char*>& send_data,
1879 Vector<std::size_t>& send_size,
1880 Vector<int>& send_rank,
1881 Vector<MPI_Request>& send_reqs,
1883 int ncomp);
1884
1885 template <typename BUF=value_type>
1886 [[nodiscard]]
1887 static TheFaArenaPointer PrepareSendBuffers (const MapOfCopyComTagContainers& SndTags,
1888 Vector<char*>& send_data,
1889 Vector<std::size_t>& send_size,
1890 Vector<int>& send_rank,
1891 Vector<MPI_Request>& send_reqs,
1893 int ncomp);
1894
1895 static void PostSnds (Vector<char*> const& send_data,
1896 Vector<std::size_t> const& send_size,
1897 Vector<int> const& send_rank,
1898 Vector<MPI_Request>& send_reqs,
1899 int SeqNum);
1900#endif
1901
1902 std::unique_ptr<FBData<FAB>> fbd;
1903 std::unique_ptr<PCData<FAB>> pcd;
1904
1905 // Pointer to temporary fab used in non-blocking amrex::OverrideSync
1906 std::unique_ptr< FabArray<FAB> > os_temp;
1907
1919 template <class F=FAB>
1920 requires (BaseFabType<F>)
1921 static void Saxpy (FabArray<FAB>& y, value_type a, FabArray<FAB> const& x,
1922 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1923
1935 template <class F=FAB>
1936 requires (BaseFabType<F>)
1937 static void Xpay (FabArray<FAB>& y, value_type a, FabArray<FAB> const& x,
1938 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1939
1954 template <class F=FAB>
1955 requires (BaseFabType<F>)
1956 static void LinComb (FabArray<FAB>& dst,
1957 value_type a, const FabArray<FAB>& x, int xcomp,
1958 value_type b, const FabArray<FAB>& y, int ycomp,
1959 int dstcomp, int numcomp, const IntVect& nghost);
1960
1974 template <class F=FAB>
1975 requires (BaseFabType<F>)
1976 static void Saxpy_Xpay (FabArray<FAB>& y, value_type a1, FabArray<FAB> const& x1,
1977 value_type a2, FabArray<FAB> const& x2,
1978 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1979
1994 template <class F=FAB>
1995 requires (BaseFabType<F>)
1996 static void Saxpy_Saxpy (FabArray<FAB>& y1, value_type a1, FabArray<FAB> const& x1,
1997 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x2,
1998 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1999
2013 template <class F=FAB>
2014 requires (BaseFabType<F>)
2016 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x,
2017 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
2018};
2019
2020}
2021
2022#include <AMReX_FabArrayCommI.H>
2023
2024namespace amrex {
2025
2026template <class FAB>
2027bool
2028FabArray<FAB>::defined (int K) const noexcept
2029{
2030 int li = localindex(K);
2031 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != 0) {
2032 return true;
2033 }
2034 else {
2035 return false;
2036 }
2037}
2038
2039template <class FAB>
2040bool
2041FabArray<FAB>::defined (const MFIter& mfi) const noexcept
2042{
2043 int li = mfi.LocalIndex();
2044 if (li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
2045 return true;
2046 }
2047 else {
2048 return false;
2049 }
2050}
2051
2052template <class FAB>
2053FAB*
2054FabArray<FAB>::fabPtr (const MFIter& mfi) noexcept
2055{
2056 AMREX_ASSERT(mfi.LocalIndex() < indexArray.size());
2058 int li = mfi.LocalIndex();
2059 return m_fabs_v[li];
2060}
2061
2062template <class FAB>
2063FAB const*
2064FabArray<FAB>::fabPtr (const MFIter& mfi) const noexcept
2065{
2066 AMREX_ASSERT(mfi.LocalIndex() < indexArray.size());
2068 int li = mfi.LocalIndex();
2069 return m_fabs_v[li];
2070}
2071
2072template <class FAB>
2073FAB*
2075{
2076 int li = localindex(K);
2077 AMREX_ASSERT(li >=0 && li < indexArray.size());
2078 return m_fabs_v[li];
2079}
2080
2081template <class FAB>
2082FAB const*
2083FabArray<FAB>::fabPtr (int K) const noexcept
2084{
2085 int li = localindex(K);
2086 AMREX_ASSERT(li >=0 && li < indexArray.size());
2087 return m_fabs_v[li];
2088}
2089
2090template <class FAB>
2091template <class F>
2092requires (BaseFabType<F>)
2093void
2095{
2096 using A = Array4<value_type>;
2097 using AC = Array4<value_type const>;
2098 static_assert(sizeof(A) == sizeof(AC), "sizeof(Array4<T>) != sizeof(Array4<T const>)");
2099 if (!m_hp_arrays && local_size() > 0) {
2100 const int n = local_size();
2101#ifdef AMREX_USE_GPU
2102 m_hp_arrays = (void*)The_Pinned_Arena()->alloc(n*2*sizeof(A));
2103 m_dp_arrays = (void*)The_Arena()->alloc(n*2*sizeof(A));
2104#else
2105 m_hp_arrays = std::malloc(n*2*sizeof(A));
2106#endif
2107 for (int li = 0; li < n; ++li) {
2108 if (m_fabs_v[li]) {
2109 new ((A*)m_hp_arrays+li) A(m_fabs_v[li]->array());
2110 new ((AC*)m_hp_arrays+li+n) AC(m_fabs_v[li]->const_array());
2111 } else {
2112 new ((A*)m_hp_arrays+li) A{};
2113 new ((AC*)m_hp_arrays+li+n) AC{};
2114 }
2115 }
2116 m_arrays.hp = (A*)m_hp_arrays;
2117 m_const_arrays.hp = (AC*)m_hp_arrays + n;
2118#ifdef AMREX_USE_GPU
2119 m_arrays.dp = (A*)m_dp_arrays;
2120 m_const_arrays.dp = (AC*)m_dp_arrays + n;
2121 Gpu::htod_memcpy_async(m_dp_arrays, m_hp_arrays, n*2*sizeof(A));
2122 if (!Gpu::inNoSyncRegion()) {
2124 }
2125#endif
2126 }
2127}
2128
2129template <class FAB>
2130void
2131FabArray<FAB>::clear_arrays ()
2132{
2133#ifdef AMREX_USE_GPU
2134 The_Pinned_Arena()->free(m_hp_arrays);
2135 The_Arena()->free(m_dp_arrays);
2136 m_dp_arrays = nullptr;
2137#else
2138 std::free(m_hp_arrays);
2139#endif
2140 m_hp_arrays = nullptr;
2141 m_arrays.hp = nullptr;
2142 m_const_arrays.hp = nullptr;
2143}
2144
2145template <class FAB>
2146[[nodiscard]]
2147FAB*
2149{
2150 const int li = localindex(K);
2151 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
2152 AMREX_ASSERT(m_single_chunk_arena == nullptr);
2153 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
2154 if (nbytes > 0) {
2155 for (auto const& t : m_tags) {
2156 updateMemUsage(t, -nbytes, nullptr);
2157 }
2158 }
2159 return std::exchange(m_fabs_v[li], nullptr);
2160 } else {
2161 return nullptr;
2162 }
2163}
2164
2165template <class FAB>
2166[[nodiscard]]
2167FAB*
2169{
2170 const int li = mfi.LocalIndex();
2171 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
2172 AMREX_ASSERT(m_single_chunk_arena == nullptr);
2173 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
2174 if (nbytes > 0) {
2175 for (auto const& t : m_tags) {
2176 updateMemUsage(t, -nbytes, nullptr);
2177 }
2178 }
2179 return std::exchange(m_fabs_v[li], nullptr);
2180 } else {
2181 return nullptr;
2182 }
2183}
2184
2185template <class FAB>
2186void
2188{
2189 if (define_function_called)
2190 {
2191 define_function_called = false;
2192 clearThisBD();
2193 }
2194
2195 Long nbytes = 0L;
2196 for (auto *x : m_fabs_v) {
2197 if (x) {
2198 nbytes += amrex::nBytesOwned(*x);
2199 m_factory->destroy(x);
2200 }
2201 }
2202 m_fabs_v.clear();
2203 clear_arrays();
2204 m_factory.reset();
2205 m_dallocator.m_arena = nullptr;
2206 // no need to clear the non-blocking fillboundary stuff
2207
2208 if (nbytes > 0) {
2209 for (auto const& t : m_tags) {
2210 updateMemUsage(t, -nbytes, nullptr);
2211 }
2212 }
2213
2214 if (m_single_chunk_arena) {
2215 m_single_chunk_arena.reset();
2216 }
2217 m_single_chunk_size = 0;
2218
2219 m_tags.clear();
2220
2221#ifdef AMREX_USE_GPU
2222 m_fb_local_copy_handler.clear();
2223 m_recv_copy_handler.clear();
2224 m_send_copy_handler.clear();
2225#endif
2226
2228}
2229
2230template <class FAB>
2231template <BaseFabType SFAB, BaseFabType DFAB>
2232requires (std::is_convertible_v<typename SFAB::value_type, typename DFAB::value_type>)
2233void
2234FabArray<FAB>::LocalCopy (FabArray<SFAB> const& src, int scomp, int dcomp, int ncomp,
2235 IntVect const& nghost)
2236{
2237 amrex::Copy(*this, src, scomp, dcomp, ncomp, nghost);
2238}
2239
2240template <class FAB>
2241template <class F>
2242requires (BaseFabType<F>)
2243void
2244FabArray<FAB>::LocalAdd (FabArray<FAB> const& src, int scomp, int dcomp, int ncomp,
2245 IntVect const& nghost)
2246{
2247 amrex::Add(*this, src, scomp, dcomp, ncomp, nghost);
2248}
2249
2250template <class FAB>
2251template <class F>
2252requires (BaseFabType<F>)
2253void
2255{
2256 setVal(val,0,n_comp,IntVect(nghost));
2257}
2258
2259template <class FAB>
2260template <class F>
2261requires (BaseFabType<F>)
2262void
2264{
2265 setVal(val,0,n_comp,nghost);
2266}
2267
2268template <class FAB>
2269template <class F>
2270requires (BaseFabType<F>)
2271void
2272FabArray<FAB>::setVal (value_type val, const Box& region, int nghost)
2273{
2274 setVal(val,region,0,n_comp,IntVect(nghost));
2275}
2276
2277template <class FAB>
2278template <class F>
2279requires (BaseFabType<F>)
2280void
2281FabArray<FAB>::setVal (value_type val, const Box& region, const IntVect& nghost)
2282{
2283 setVal(val,region,0,n_comp,nghost);
2284}
2285
2286template <class FAB>
2288 : shmem()
2289{
2290 m_FA_stats.recordBuild();
2291}
2292
2293template <class FAB>
2295 : m_dallocator(a),
2296 shmem()
2297{
2298 m_FA_stats.recordBuild();
2299}
2300
2301template <class FAB>
2303 const DistributionMapping& dm,
2304 int nvar,
2305 int ngrow,
2306 const MFInfo& info,
2307 const FabFactory<FAB>& factory)
2308 : FabArray<FAB>(bxs,dm,nvar,IntVect(ngrow),info,factory)
2309{}
2310
2311template <class FAB>
2313 const DistributionMapping& dm,
2314 int nvar,
2315 const IntVect& ngrow,
2316 const MFInfo& info,
2317 const FabFactory<FAB>& factory)
2318 : m_factory(factory.clone()),
2319 shmem()
2320{
2322 define(bxs,dm,nvar,ngrow,info,*m_factory);
2323}
2324
2325template <class FAB>
2326FabArray<FAB>::FabArray (const FabArray<FAB>& rhs, MakeType maketype, int scomp, int ncomp)
2327 : m_factory(rhs.Factory().clone()),
2328 shmem()
2329{
2331 define(rhs.boxArray(), rhs.DistributionMap(), ncomp, rhs.nGrowVect(),
2332 MFInfo().SetAlloc(false), *m_factory);
2333
2334 if (maketype == amrex::make_alias)
2335 {
2336 for (int i = 0, n = indexArray.size(); i < n; ++i) {
2337 auto const& rhsfab = *(rhs.m_fabs_v[i]);
2338 m_fabs_v.push_back(m_factory->create_alias(rhsfab, scomp, ncomp));
2339 }
2340 }
2341 else
2342 {
2343 amrex::Abort("FabArray: unknown MakeType");
2344 }
2345}
2346
2347template <class FAB>
2349 : FabArrayBase (static_cast<FabArrayBase&&>(rhs))
2350 , m_factory (std::move(rhs.m_factory))
2351 , m_dallocator (rhs.m_dallocator)
2352 , m_single_chunk_arena(std::move(rhs.m_single_chunk_arena))
2353 , m_single_chunk_size(std::exchange(rhs.m_single_chunk_size,0))
2354 , define_function_called(rhs.define_function_called)
2355 , m_fabs_v (std::move(rhs.m_fabs_v))
2356#ifdef AMREX_USE_GPU
2357 , m_dp_arrays (std::exchange(rhs.m_dp_arrays, nullptr))
2358#endif
2359 , m_hp_arrays (std::exchange(rhs.m_hp_arrays, nullptr))
2360 , m_arrays (rhs.m_arrays)
2361 , m_const_arrays(rhs.m_const_arrays)
2362 , m_tags (std::move(rhs.m_tags))
2363 , shmem (std::move(rhs.shmem))
2364#ifdef AMREX_USE_GPU
2365 , m_fb_local_copy_handler(std::move(rhs.m_fb_local_copy_handler))
2366 , m_recv_copy_handler(std::move(rhs.m_recv_copy_handler))
2367 , m_send_copy_handler(std::move(rhs.m_send_copy_handler))
2368#endif
2369 // no need to worry about the data used in non-blocking FillBoundary.
2370{
2371 m_FA_stats.recordBuild();
2372 rhs.define_function_called = false; // the responsibility of clear BD has been transferred.
2373 rhs.m_fabs_v.clear(); // clear the data pointers so that rhs.clear does not delete them.
2374 rhs.clear();
2375}
2376
2377template <class FAB>
2380{
2381 if (&rhs != this)
2382 {
2383 clear();
2384
2385 FabArrayBase::operator=(static_cast<FabArrayBase&&>(rhs));
2386 m_factory = std::move(rhs.m_factory);
2387 m_dallocator = rhs.m_dallocator;
2388 m_single_chunk_arena = std::move(rhs.m_single_chunk_arena);
2389 std::swap(m_single_chunk_size, rhs.m_single_chunk_size);
2390 define_function_called = rhs.define_function_called;
2391 std::swap(m_fabs_v, rhs.m_fabs_v);
2392#ifdef AMREX_USE_GPU
2393 std::swap(m_dp_arrays, rhs.m_dp_arrays);
2394#endif
2395 std::swap(m_hp_arrays, rhs.m_hp_arrays);
2396 m_arrays = rhs.m_arrays;
2397 m_const_arrays = rhs.m_const_arrays;
2398 std::swap(m_tags, rhs.m_tags);
2399 shmem = std::move(rhs.shmem);
2400#ifdef AMREX_USE_GPU
2401 std::swap(m_fb_local_copy_handler, rhs.m_fb_local_copy_handler);
2402 std::swap(m_recv_copy_handler, rhs.m_recv_copy_handler);
2403 std::swap(m_send_copy_handler, rhs.m_send_copy_handler);
2404#endif
2405
2406 rhs.define_function_called = false;
2407 rhs.m_fabs_v.clear();
2408 rhs.m_tags.clear();
2409 rhs.clear();
2410 }
2411 return *this;
2412}
2413
2414template <class FAB>
2416{
2417 m_FA_stats.recordDelete();
2418 clear();
2419}
2420
2421template <class FAB>
2422bool
2424{
2425 if (!define_function_called) { return false; }
2426
2427 int isok = 1;
2428
2429 for (MFIter fai(*this); fai.isValid() && isok; ++fai)
2430 {
2431 if (defined(fai))
2432 {
2433 if (get(fai).box() != fabbox(fai.index()))
2434 {
2435 isok = 0;
2436 }
2437 }
2438 else
2439 {
2440 isok = 0;
2441 }
2442 }
2443
2445
2446 return isok == 1;
2447}
2448
2449template <class FAB>
2450bool
2452{
2453 return define_function_called;
2454}
2455
2456template <class FAB>
2457void
2459 const DistributionMapping& dm,
2460 int nvar,
2461 int ngrow,
2462 const MFInfo& info,
2463 const FabFactory<FAB>& a_factory)
2464{
2465 define(bxs,dm,nvar,IntVect(ngrow),info,a_factory);
2466}
2467
2468template <class FAB>
2469void
2471 const DistributionMapping& dm,
2472 int nvar,
2473 const IntVect& ngrow,
2474 const MFInfo& info,
2475 const FabFactory<FAB>& a_factory)
2476{
2477 std::unique_ptr<FabFactory<FAB> > factory(a_factory.clone());
2478
2479 auto *default_arena = m_dallocator.m_arena;
2480 clear();
2481
2482 m_factory = std::move(factory);
2483 m_dallocator.m_arena = info.arena ? info.arena : default_arena;
2484
2485 define_function_called = true;
2486
2487 AMREX_ASSERT(ngrow.allGE(0));
2488 AMREX_ASSERT(boxarray.empty());
2489 FabArrayBase::define(bxs, dm, nvar, ngrow);
2490
2491 addThisBD();
2492
2493 if(info.alloc) {
2494 AllocFabs(*m_factory, m_dallocator.m_arena, info.tags, info.alloc_single_chunk);
2495#ifdef BL_USE_TEAM
2497#endif
2498 }
2499}
2500
2501template <class FAB>
2502void
2504 const Vector<std::string>& tags, bool alloc_single_chunk)
2505{
2506 if (shmem.alloc) { alloc_single_chunk = false; }
2507 if constexpr (!IsBaseFab_v<FAB>) { alloc_single_chunk = false; }
2508
2509 const int n = indexArray.size();
2510 const int nworkers = ParallelDescriptor::TeamSize();
2511 shmem.alloc = (nworkers > 1);
2512
2513 bool alloc = !shmem.alloc;
2514
2515 FabInfo fab_info;
2516 fab_info.SetAlloc(alloc).SetShared(shmem.alloc).SetArena(ar);
2517
2518 if (alloc_single_chunk) {
2519 m_single_chunk_size = 0L;
2520 for (int i = 0; i < n; ++i) {
2521 int K = indexArray[i];
2522 const Box& tmpbox = fabbox(K);
2523 m_single_chunk_size += factory.nBytes(tmpbox, n_comp, K);
2524 }
2525 AMREX_ASSERT(m_single_chunk_size >= 0); // 0 is okay.
2526 m_single_chunk_arena = std::make_unique<detail::SingleChunkArena>(ar, m_single_chunk_size);
2527 fab_info.SetArena(m_single_chunk_arena.get());
2528 }
2529
2530 m_fabs_v.reserve(n);
2531
2532 Long nbytes = 0L;
2533 for (int i = 0; i < n; ++i)
2534 {
2535 int K = indexArray[i];
2536 const Box& tmpbox = fabbox(K);
2537 m_fabs_v.push_back(factory.create(tmpbox, n_comp, fab_info, K));
2538 nbytes += amrex::nBytesOwned(*m_fabs_v.back());
2539 }
2540
2541 m_tags.clear();
2542 m_tags.emplace_back("All");
2543 for (auto const& t : m_region_tag) {
2544 m_tags.push_back(t);
2545 }
2546 for (auto const& t : tags) {
2547 m_tags.push_back(t);
2548 }
2549 for (auto const& t: m_tags) {
2550 updateMemUsage(t, nbytes, ar);
2551 }
2552
2553#ifdef BL_USE_TEAM
2554 if (shmem.alloc)
2555 {
2556 const int teamlead = ParallelDescriptor::MyTeamLead();
2557
2558 shmem.n_values = 0;
2559 shmem.n_points = 0;
2560 Vector<Long> offset(n,0);
2561 Vector<Long> nextoffset(nworkers,-1);
2562 for (int i = 0; i < n; ++i) {
2563 int K = indexArray[i];
2564 int owner = distributionMap[K] - teamlead;
2565 Long s = m_fabs_v[i]->size();
2566 if (ownership[i]) {
2567 shmem.n_values += s;
2568 shmem.n_points += m_fabs_v[i]->numPts();
2569 }
2570 if (nextoffset[owner] < 0) {
2571 offset[i] = 0;
2572 nextoffset[owner] = s;
2573 } else {
2574 offset[i] = nextoffset[owner];
2575 nextoffset[owner] += s;
2576 }
2577 }
2578
2579 size_t bytes = shmem.n_values*sizeof(value_type);
2580
2581 value_type *mfp;
2582 Vector<value_type*> dps;
2583
2584#if defined (BL_USE_MPI3)
2585
2586 static MPI_Info info = MPI_INFO_NULL;
2587 if (info == MPI_INFO_NULL) {
2588 MPI_Info_create(&info);
2589 MPI_Info_set(info, "alloc_shared_noncontig", "true");
2590 }
2591
2592 const MPI_Comm& team_comm = ParallelDescriptor::MyTeam().get();
2593
2594 BL_MPI_REQUIRE( MPI_Win_allocate_shared(bytes, sizeof(value_type),
2595 info, team_comm, &mfp, &shmem.win) );
2596
2597 for (int w = 0; w < nworkers; ++w) {
2598 MPI_Aint sz;
2599 int disp;
2600 value_type *dptr = 0;
2601 BL_MPI_REQUIRE( MPI_Win_shared_query(shmem.win, w, &sz, &disp, &dptr) );
2602 // AMREX_ASSERT(disp == sizeof(value_type));
2603 dps.push_back(dptr);
2604 }
2605
2606#else
2607
2608 amrex::Abort("BaseFab::define: to allocate shared memory, USE_MPI3 must be true");
2609
2610#endif
2611
2612 for (int i = 0; i < n; ++i) {
2613 int K = indexArray[i];
2614 int owner = distributionMap[K] - teamlead;
2615 value_type *p = dps[owner] + offset[i];
2616 m_fabs_v[i]->setPtr(p, m_fabs_v[i]->size());
2617 }
2618
2619 for (Long i = 0; i < shmem.n_values; i++, mfp++) {
2620 new (mfp) value_type;
2621 }
2622
2623 amrex::update_fab_stats(shmem.n_points, shmem.n_values, sizeof(value_type));
2624 }
2625#endif
2626}
2627
2628template <class FAB>
2629void
2630FabArray<FAB>::setFab_assert (int K, FAB const& fab) const
2631{
2632 amrex::ignore_unused(K,fab);
2633 AMREX_ASSERT(n_comp == fab.nComp());
2634 AMREX_ASSERT(!boxarray.empty());
2635 AMREX_ASSERT(fab.box() == fabbox(K));
2636 AMREX_ASSERT(distributionMap[K] == ParallelDescriptor::MyProc());
2637 AMREX_ASSERT(m_single_chunk_arena == nullptr);
2638}
2639
2640template <class FAB>
2641void
2642FabArray<FAB>::setFab (int boxno, std::unique_ptr<FAB> elem)
2643{
2644 if (n_comp == 0) {
2645 n_comp = elem->nComp();
2646 }
2647
2648 setFab_assert(boxno, *elem);
2649
2650 if (m_fabs_v.empty()) {
2651 m_fabs_v.resize(indexArray.size(),nullptr);
2652 }
2653
2654 const int li = localindex(boxno);
2655 if (m_fabs_v[li]) {
2656 m_factory->destroy(m_fabs_v[li]);
2657 }
2658 m_fabs_v[li] = elem.release();
2659}
2660
2661template <class FAB>
2662template <class F>
2663requires (std::is_move_constructible_v<F>)
2664void
2665FabArray<FAB>::setFab (int boxno, FAB&& elem)
2666{
2667 if (n_comp == 0) {
2668 n_comp = elem.nComp();
2669 }
2670
2671 setFab_assert(boxno, elem);
2672
2673 if (m_fabs_v.empty()) {
2674 m_fabs_v.resize(indexArray.size(),nullptr);
2675 }
2676
2677 const int li = localindex(boxno);
2678 if (m_fabs_v[li]) {
2679 m_factory->destroy(m_fabs_v[li]);
2680 }
2681 m_fabs_v[li] = new FAB(std::move(elem));
2682}
2683
2684template <class FAB>
2685void
2686FabArray<FAB>::setFab (const MFIter& mfi, std::unique_ptr<FAB> elem)
2687{
2688 if (n_comp == 0) {
2689 n_comp = elem->nComp();
2690 }
2691
2692 setFab_assert(mfi.index(), *elem);
2693
2694 if (m_fabs_v.empty()) {
2695 m_fabs_v.resize(indexArray.size(),nullptr);
2696 }
2697
2698 const int li = mfi.LocalIndex();
2699 if (m_fabs_v[li]) {
2700 m_factory->destroy(m_fabs_v[li]);
2701 }
2702 m_fabs_v[li] = elem.release();
2703}
2704
2705template <class FAB>
2706template <class F>
2707requires (std::is_move_constructible_v<F>)
2708void
2709FabArray<FAB>::setFab (const MFIter& mfi, FAB&& elem)
2710{
2711 if (n_comp == 0) {
2712 n_comp = elem.nComp();
2713 }
2714
2715 setFab_assert(mfi.index(), elem);
2716
2717 if (m_fabs_v.empty()) {
2718 m_fabs_v.resize(indexArray.size(),nullptr);
2719 }
2720
2721 const int li = mfi.LocalIndex();
2722 if (m_fabs_v[li]) {
2723 m_factory->destroy(m_fabs_v[li]);
2724 }
2725 m_fabs_v[li] = new FAB(std::move(elem));
2726}
2727
2728template <class FAB>
2729template <class F>
2730requires (BaseFabType<F>)
2731void
2733{
2734 setBndry(val, 0, n_comp);
2735}
2736
2737template <class FAB>
2738template <class F>
2739requires (BaseFabType<F>)
2740void
2742 int strt_comp,
2743 int ncomp)
2744{
2745 if (n_grow.max() > 0)
2746 {
2747#ifdef AMREX_USE_GPU
2748 if (Gpu::inLaunchRegion()) {
2749 bool use_mfparfor = true;
2750 const int nboxes = local_size();
2751 if (nboxes == 1) {
2752 if (boxarray[indexArray[0]].numPts() > Long(65*65*65)) {
2753 use_mfparfor = false;
2754 }
2755 } else {
2756 for (int i = 0; i < nboxes; ++i) {
2757 const Long npts = boxarray[indexArray[i]].numPts();
2758 if (npts >= Long(64*64*64)) {
2759 use_mfparfor = false;
2760 break;
2761 } else if (npts <= Long(17*17*17)) {
2762 break;
2763 }
2764 }
2765 }
2766 const IntVect nghost = n_grow;
2767 if (use_mfparfor) {
2768 auto const& ma = this->arrays();
2769 ParallelFor(*this, nghost,
2770 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2771 {
2772 auto const& a = ma[box_no];
2773 Box vbx(a);
2774 vbx.grow(-nghost);
2775 if (!vbx.contains(i,j,k)) {
2776 for (int n = 0; n < ncomp; ++n) {
2777 a(i,j,k,strt_comp+n) = val;
2778 }
2779 }
2780 });
2781 if (!Gpu::inNoSyncRegion()) {
2783 }
2784 } else {
2785 using Tag = Array4BoxTag<value_type>;
2786 Vector<Tag> tags;
2787 for (MFIter mfi(*this); mfi.isValid(); ++mfi) {
2788 Box const& vbx = mfi.validbox();
2789 auto const& a = this->array(mfi);
2790
2791 Box b;
2792#if (AMREX_SPACEDIM == 3)
2793 if (nghost[2] > 0) {
2794 b = vbx;
2795 b.setRange(2, vbx.smallEnd(2)-nghost[2], nghost[2]);
2796 b.grow(IntVect(nghost[0],nghost[1],0));
2797 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2798 b.shift(2, vbx.length(2)+nghost[2]);
2799 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2800 }
2801#endif
2802#if (AMREX_SPACEDIM >= 2)
2803 if (nghost[1] > 0) {
2804 b = vbx;
2805 b.setRange(1, vbx.smallEnd(1)-nghost[1], nghost[1]);
2806 b.grow(0, nghost[0]);
2807 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2808 b.shift(1, vbx.length(1)+nghost[1]);
2809 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2810 }
2811#endif
2812 if (nghost[0] > 0) {
2813 b = vbx;
2814 b.setRange(0, vbx.smallEnd(0)-nghost[0], nghost[0]);
2815 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2816 b.shift(0, vbx.length(0)+nghost[0]);
2817 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2818 }
2819 }
2820
2821 ParallelFor(tags, ncomp,
2822 [=] AMREX_GPU_DEVICE (int i, int j, int k, int n, Tag const& tag) noexcept
2823 {
2824 tag.dfab(i,j,k,strt_comp+n) = val;
2825 });
2826 }
2827 } else
2828#endif
2829 {
2830#ifdef AMREX_USE_OMP
2831#pragma omp parallel
2832#endif
2833 for (MFIter fai(*this); fai.isValid(); ++fai)
2834 {
2835 get(fai).template setComplement<RunOn::Host>(val, fai.validbox(), strt_comp, ncomp);
2836 }
2837 }
2838 }
2839}
2840
2841template <class FAB>
2842template <class F>
2843requires (BaseFabType<F>)
2844void
2846{
2847 setDomainBndry(val, 0, n_comp, geom);
2848}
2849
2850template <class FAB>
2851template <class F>
2852requires (BaseFabType<F>)
2853void
2855 int strt_comp,
2856 int ncomp,
2857 const Geometry& geom)
2858{
2859 BL_PROFILE("FabArray::setDomainBndry()");
2860
2861 Box domain_box = amrex::convert(geom.Domain(), boxArray().ixType());
2862 for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
2863 if (geom.isPeriodic(idim)) {
2864 int n = domain_box.length(idim);
2865 domain_box.grow(idim, n);
2866 }
2867 }
2868
2869#ifdef AMREX_USE_OMP
2870#pragma omp parallel if (Gpu::notInLaunchRegion())
2871#endif
2872 for (MFIter fai(*this); fai.isValid(); ++fai)
2873 {
2874 const Box& gbx = fai.fabbox();
2875 if (! domain_box.contains(gbx))
2876 {
2877 get(fai).template setComplement<RunOn::Device>(val, domain_box, strt_comp, ncomp);
2878 }
2879 }
2880}
2881
2882template <class FAB>
2883template <std::integral I>
2884requires (BaseFabType<FAB> && (sizeof(I) >= sizeof(Long)))
2885void
2887{
2888 AMREX_ASSERT(amrex::isMFIterSafe(*this, mem));
2889 for (MFIter mfi(*this, MFItInfo{}.DisableDeviceSync()); mfi.isValid(); ++mfi) {
2890 mem[mfi] += static_cast<I>((*this)[mfi].nBytesOwned());
2891 }
2892}
2893
2894template <class FAB>
2895template <class F>
2896requires (BaseFabType<F>)
2897typename F::value_type
2898FabArray<FAB>::sum (int comp, IntVect const& nghost, bool local) const
2899{
2900 BL_PROFILE("FabArray::sum()");
2901
2902 using T = typename FAB::value_type;
2903 auto sm = T(0.0);
2904#ifdef AMREX_USE_GPU
2905 if (Gpu::inLaunchRegion()) {
2906 auto const& ma = this->const_arrays();
2907 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, *this, nghost,
2908 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2909 -> GpuTuple<T>
2910 {
2911 return ma[box_no](i,j,k,comp);
2912 });
2913 } else
2914#endif
2915 {
2916#ifdef AMREX_USE_OMP
2917#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
2918#endif
2919 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi)
2920 {
2921 Box const& bx = mfi.growntilebox(nghost);
2922 auto const& a = this->const_array(mfi);
2923 auto tmp = T(0.0);
2924 AMREX_LOOP_3D(bx, i, j, k,
2925 {
2926 tmp += a(i,j,k,comp);
2927 });
2928 sm += tmp; // Do it this way so that it does not break regression tests.
2929 }
2930 }
2931
2932 if (!local) {
2934 }
2935
2936 return sm;
2937}
2938
2939template <class FAB>
2940void
2941FabArray<FAB>::copyTo (FAB& dest, int nghost) const
2942{
2943 copyTo(dest, 0, 0, dest.nComp(), nghost);
2944}
2945
2946template <class FAB>
2947template <class F>
2948requires (BaseFabType<F>)
2949void
2951{
2952 setVal(val,0,n_comp,n_grow);
2953}
2954
2955template <class FAB>
2956template <class F>
2957requires (BaseFabType<F>)
2960{
2961 setVal(val);
2962 return *this;
2963}
2964
2965template <class FAB>
2966template <class F>
2967requires (BaseFabType<F>)
2968void
2970 int comp,
2971 int ncomp,
2972 int nghost)
2973{
2974 setVal(val,comp,ncomp,IntVect(nghost));
2975}
2976
2977template <class FAB>
2978template <class F>
2979requires (BaseFabType<F>)
2980void
2982 int comp,
2983 int ncomp,
2984 const IntVect& nghost)
2985{
2986 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2987 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2988
2989 BL_PROFILE("FabArray::setVal()");
2990
2991#ifdef AMREX_USE_GPU
2992 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2993 auto const& fa = this->arrays();
2994 ParallelFor(*this, nghost, ncomp,
2995 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2996 {
2997 fa[box_no](i,j,k,n+comp) = val;
2998 });
2999 if (!Gpu::inNoSyncRegion()) {
3001 }
3002 } else
3003#endif
3004 {
3005#ifdef AMREX_USE_OMP
3006#pragma omp parallel if (Gpu::notInLaunchRegion())
3007#endif
3008 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
3009 {
3010 const Box& bx = fai.growntilebox(nghost);
3011 auto fab = this->array(fai);
3012 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3013 {
3014 fab(i,j,k,n+comp) = val;
3015 });
3016 }
3017 }
3018}
3019
3020template <class FAB>
3021template <class F>
3022requires (BaseFabType<F>)
3023void
3025 const Box& region,
3026 int comp,
3027 int ncomp,
3028 int nghost)
3029{
3030 setVal(val,region,comp,ncomp,IntVect(nghost));
3031}
3032
3033template <class FAB>
3034template <class F>
3035requires (BaseFabType<F>)
3036void
3038 const Box& region,
3039 int comp,
3040 int ncomp,
3041 const IntVect& nghost)
3042{
3043 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
3044 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
3045
3046 BL_PROFILE("FabArray::setVal(val,region,comp,ncomp,nghost)");
3047
3048#ifdef AMREX_USE_GPU
3049 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3050 auto const& fa = this->arrays();
3051 ParallelFor(*this, nghost, ncomp,
3052 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3053 {
3054 if (region.contains(i,j,k)) {
3055 fa[box_no](i,j,k,n+comp) = val;
3056 }
3057 });
3058 if (!Gpu::inNoSyncRegion()) {
3060 }
3061 } else
3062#endif
3063 {
3064#ifdef AMREX_USE_OMP
3065 AMREX_ALWAYS_ASSERT(!omp_in_parallel());
3066#pragma omp parallel if (Gpu::notInLaunchRegion())
3067#endif
3068 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
3069 {
3070 Box b = fai.growntilebox(nghost) & region;
3071
3072 if (b.ok()) {
3073 auto fab = this->array(fai);
3074 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( b, ncomp, i, j, k, n,
3075 {
3076 fab(i,j,k,n+comp) = val;
3077 });
3078 }
3079 }
3080 }
3081}
3082
3083template <class FAB>
3084template <class F>
3085requires (BaseFabType<F>)
3086void
3087FabArray<FAB>::abs (int comp, int ncomp, int nghost)
3088{
3089 abs(comp, ncomp, IntVect(nghost));
3090}
3091
3092template <class FAB>
3093template <class F>
3094requires (BaseFabType<F>)
3095void
3096FabArray<FAB>::abs (int comp, int ncomp, const IntVect& nghost)
3097{
3098 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
3099 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
3100 BL_PROFILE("FabArray::abs()");
3101
3102#ifdef AMREX_USE_GPU
3103 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3104 auto const& fa = this->arrays();
3105 ParallelFor(*this, nghost, ncomp,
3106 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3107 {
3108 fa[box_no](i,j,k,n+comp) = std::abs(fa[box_no](i,j,k,n+comp));
3109 });
3110 if (!Gpu::inNoSyncRegion()) {
3112 }
3113 } else
3114#endif
3115 {
3116#ifdef AMREX_USE_OMP
3117#pragma omp parallel if (Gpu::notInLaunchRegion())
3118#endif
3119 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3120 {
3121 const Box& bx = mfi.growntilebox(nghost);
3122 auto fab = this->array(mfi);
3123 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3124 {
3125 fab(i,j,k,n+comp) = std::abs(fab(i,j,k,n+comp));
3126 });
3127 }
3128 }
3129}
3130
3131template <class FAB>
3132template <class F>
3133requires (BaseFabType<F>)
3134void
3135FabArray<FAB>::plus (value_type val, int comp, int num_comp, int nghost)
3136{
3137 BL_PROFILE("FabArray::plus()");
3138
3139#ifdef AMREX_USE_GPU
3140 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3141 auto const& fa = this->arrays();
3142 ParallelFor(*this, IntVect(nghost), num_comp,
3143 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3144 {
3145 fa[box_no](i,j,k,n+comp) += val;
3146 });
3147 if (!Gpu::inNoSyncRegion()) {
3149 }
3150 } else
3151#endif
3152 {
3153#ifdef AMREX_USE_OMP
3154#pragma omp parallel if (Gpu::notInLaunchRegion())
3155#endif
3156 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3157 {
3158 const Box& bx = mfi.growntilebox(nghost);
3159 auto fab = this->array(mfi);
3160 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3161 {
3162 fab(i,j,k,n+comp) += val;
3163 });
3164 }
3165 }
3166}
3167
3168template <class FAB>
3169template <class F>
3170requires (BaseFabType<F>)
3171void
3172FabArray<FAB>::plus (value_type val, const Box& region, int comp, int num_comp, int nghost)
3173{
3174 BL_PROFILE("FabArray::plus(val, region, comp, num_comp, nghost)");
3175
3176#ifdef AMREX_USE_GPU
3177 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3178 auto const& fa = this->arrays();
3179 ParallelFor(*this, IntVect(nghost), num_comp,
3180 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3181 {
3182 if (region.contains(i,j,k)) {
3183 fa[box_no](i,j,k,n+comp) += val;
3184 }
3185 });
3186 if (!Gpu::inNoSyncRegion()) {
3188 }
3189 } else
3190#endif
3191 {
3192#ifdef AMREX_USE_OMP
3193#pragma omp parallel if (Gpu::notInLaunchRegion())
3194#endif
3195 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3196 {
3197 const Box& bx = mfi.growntilebox(nghost) & region;
3198 if (bx.ok()) {
3199 auto fab = this->array(mfi);
3200 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3201 {
3202 fab(i,j,k,n+comp) += val;
3203 });
3204 }
3205 }
3206 }
3207}
3208
3209template <class FAB>
3210template <class F>
3211requires (BaseFabType<F>)
3212void
3213FabArray<FAB>::mult (value_type val, int comp, int num_comp, int nghost)
3214{
3215 BL_PROFILE("FabArray::mult()");
3216
3217#ifdef AMREX_USE_GPU
3218 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3219 auto const& fa = this->arrays();
3220 ParallelFor(*this, IntVect(nghost), num_comp,
3221 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3222 {
3223 fa[box_no](i,j,k,n+comp) *= val;
3224 });
3225 if (!Gpu::inNoSyncRegion()) {
3227 }
3228 } else
3229#endif
3230 {
3231#ifdef AMREX_USE_OMP
3232#pragma omp parallel if (Gpu::notInLaunchRegion())
3233#endif
3234 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3235 {
3236 const Box& bx = mfi.growntilebox(nghost);
3237 auto fab = this->array(mfi);
3238 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3239 {
3240 fab(i,j,k,n+comp) *= val;
3241 });
3242 }
3243 }
3244}
3245
3246template <class FAB>
3247template <class F>
3248requires (BaseFabType<F>)
3249void
3250FabArray<FAB>::mult (value_type val, const Box& region, int comp, int num_comp, int nghost)
3251{
3252 BL_PROFILE("FabArray::mult(val, region, comp, num_comp, nghost)");
3253
3254#ifdef AMREX_USE_GPU
3255 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3256 auto const& fa = this->arrays();
3257 ParallelFor(*this, IntVect(nghost), num_comp,
3258 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3259 {
3260 if (region.contains(i,j,k)) {
3261 fa[box_no](i,j,k,n+comp) *= val;
3262 }
3263 });
3264 if (!Gpu::inNoSyncRegion()) {
3266 }
3267 } else
3268#endif
3269 {
3270#ifdef AMREX_USE_OMP
3271#pragma omp parallel if (Gpu::notInLaunchRegion())
3272#endif
3273 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3274 {
3275 const Box& bx = mfi.growntilebox(nghost) & region;
3276 if (bx.ok()) {
3277 auto fab = this->array(mfi);
3278 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3279 {
3280 fab(i,j,k,n+comp) *= val;
3281 });
3282 }
3283 }
3284 }
3285}
3286
3287template <class FAB>
3288template <class F>
3289requires (BaseFabType<F>)
3290void
3291FabArray<FAB>::invert (value_type numerator, int comp, int num_comp, int nghost)
3292{
3293 BL_PROFILE("FabArray::invert()");
3294
3295#ifdef AMREX_USE_GPU
3296 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3297 auto const& fa = this->arrays();
3298 ParallelFor(*this, IntVect(nghost), num_comp,
3299 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3300 {
3301 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
3302 });
3303 if (!Gpu::inNoSyncRegion()) {
3305 }
3306 } else
3307#endif
3308 {
3309#ifdef AMREX_USE_OMP
3310#pragma omp parallel if (Gpu::notInLaunchRegion())
3311#endif
3312 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3313 {
3314 const Box& bx = mfi.growntilebox(nghost);
3315 auto fab = this->array(mfi);
3316 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3317 {
3318 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
3319 });
3320 }
3321 }
3322}
3323
3324template <class FAB>
3325template <class F>
3326requires (BaseFabType<F>)
3327void
3328FabArray<FAB>::invert (value_type numerator, const Box& region, int comp, int num_comp, int nghost)
3329{
3330 BL_PROFILE("FabArray::invert(numerator, region, comp, num_comp, nghost)");
3331
3332#ifdef AMREX_USE_GPU
3333 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3334 auto const& fa = this->arrays();
3335 ParallelFor(*this, IntVect(nghost), num_comp,
3336 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3337 {
3338 if (region.contains(i,j,k)) {
3339 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
3340 }
3341 });
3342 if (!Gpu::inNoSyncRegion()) {
3344 }
3345 } else
3346#endif
3347 {
3348#ifdef AMREX_USE_OMP
3349#pragma omp parallel if (Gpu::notInLaunchRegion())
3350#endif
3351 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3352 {
3353 const Box& bx = mfi.growntilebox(nghost) & region;
3354 if (bx.ok()) {
3355 auto fab = this->array(mfi);
3356 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3357 {
3358 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
3359 });
3360 }
3361 }
3362 }
3363}
3364
3365template <class FAB>
3366void
3368{
3369 clearThisBD(); // The new boxarray will have a different ID.
3370 boxarray.shift(v);
3371 addThisBD();
3372#ifdef AMREX_USE_OMP
3373#pragma omp parallel
3374#endif
3375 for (MFIter fai(*this); fai.isValid(); ++fai)
3376 {
3377 get(fai).shift(v);
3378 }
3379 clear_arrays();
3380}
3381
3382template <class FAB>
3383template <class F>
3384requires (BaseFabType<F>)
3386 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3387{
3388 AMREX_ASSERT(y.boxArray() == x.boxArray());
3389 AMREX_ASSERT(y.distributionMap == x.distributionMap);
3390 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
3391
3392 BL_PROFILE("FabArray::Saxpy()");
3393
3394#ifdef AMREX_USE_GPU
3395 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3396 auto const& yma = y.arrays();
3397 auto const& xma = x.const_arrays();
3398 ParallelFor(y, nghost, ncomp,
3399 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3400 {
3401 yma[box_no](i,j,k,ycomp+n) += a * xma[box_no](i,j,k,xcomp+n);
3402 });
3403 if (!Gpu::inNoSyncRegion()) {
3405 }
3406 } else
3407#endif
3408 {
3409#ifdef AMREX_USE_OMP
3410#pragma omp parallel if (Gpu::notInLaunchRegion())
3411#endif
3412 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3413 {
3414 const Box& bx = mfi.growntilebox(nghost);
3415
3416 if (bx.ok()) {
3417 auto const& xfab = x.const_array(mfi);
3418 auto const& yfab = y.array(mfi);
3419 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3420 {
3421 yfab(i,j,k,ycomp+n) += a * xfab(i,j,k,xcomp+n);
3422 });
3423 }
3424 }
3425 }
3426}
3427
3428template <class FAB>
3429template <class F>
3430requires (BaseFabType<F>)
3431void
3433 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3434{
3435 AMREX_ASSERT(y.boxArray() == x.boxArray());
3436 AMREX_ASSERT(y.distributionMap == x.distributionMap);
3437 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
3438
3439 BL_PROFILE("FabArray::Xpay()");
3440
3441#ifdef AMREX_USE_GPU
3442 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3443 auto const& yfa = y.arrays();
3444 auto const& xfa = x.const_arrays();
3445 ParallelFor(y, nghost, ncomp,
3446 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3447 {
3448 yfa[box_no](i,j,k,n+ycomp) = xfa[box_no](i,j,k,n+xcomp)
3449 + a * yfa[box_no](i,j,k,n+ycomp);
3450 });
3451 if (!Gpu::inNoSyncRegion()) {
3453 }
3454 } else
3455#endif
3456 {
3457#ifdef AMREX_USE_OMP
3458#pragma omp parallel if (Gpu::notInLaunchRegion())
3459#endif
3460 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3461 {
3462 const Box& bx = mfi.growntilebox(nghost);
3463 auto const& xFab = x.const_array(mfi);
3464 auto const& yFab = y.array(mfi);
3465 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3466 {
3467 yFab(i,j,k,n+ycomp) = xFab(i,j,k,n+xcomp)
3468 + a * yFab(i,j,k,n+ycomp);
3469 });
3470 }
3471 }
3472}
3473
3474template <class FAB>
3475template <class F>
3476requires (BaseFabType<F>)
3478 value_type a2, FabArray<FAB> const& x2,
3479 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3480{
3481 AMREX_ASSERT(y.boxArray() == x1.boxArray() &&
3482 y.boxArray() == x2.boxArray() &&
3483 y.distributionMap == x1.distributionMap &&
3484 y.distributionMap == x2.distributionMap &&
3485 y.nGrowVect().allGE(nghost) &&
3486 x1.nGrowVect().allGE(nghost) &&
3487 x2.nGrowVect().allGE(nghost));
3488
3489 BL_PROFILE("FabArray::Saxpy_Xpay()");
3490
3491#ifdef AMREX_USE_GPU
3492 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3493 auto const& yma = y.arrays();
3494 auto const& xma1 = x1.const_arrays();
3495 auto const& xma2 = x2.const_arrays();
3496 ParallelFor(y, nghost, ncomp,
3497 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3498 {
3499 yma[box_no](i,j,k,ycomp+n) = xma2[box_no](i,j,k,xcomp+n)
3500 + a2 * (yma [box_no](i,j,k,ycomp+n)
3501 + a1 * xma1[box_no](i,j,k,xcomp+n));
3502 });
3503 if (!Gpu::inNoSyncRegion()) {
3505 }
3506 } else
3507#endif
3508 {
3509#ifdef AMREX_USE_OMP
3510#pragma omp parallel if (Gpu::notInLaunchRegion())
3511#endif
3512 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3513 {
3514 const Box& bx = mfi.growntilebox(nghost);
3515
3516 if (bx.ok()) {
3517 auto const& xfab1 = x1.const_array(mfi);
3518 auto const& xfab2 = x2.const_array(mfi);
3519 auto const& yfab = y.array(mfi);
3520 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3521 {
3522 yfab(i,j,k,ycomp+n) = xfab2(i,j,k,xcomp+n)
3523 + a2 * (yfab (i,j,k,ycomp+n)
3524 + a1 * xfab1(i,j,k,xcomp+n));
3525 });
3526 }
3527 }
3528 }
3529}
3530
3531template <class FAB>
3532template <class F>
3533requires (BaseFabType<F>)
3535 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x2,
3536 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3537{
3538 AMREX_ASSERT(y1.boxArray() == y2.boxArray() &&
3539 y1.boxArray() == x1.boxArray() &&
3540 y1.boxArray() == x2.boxArray() &&
3544 y1.nGrowVect().allGE(nghost) &&
3545 y2.nGrowVect().allGE(nghost) &&
3546 x1.nGrowVect().allGE(nghost) &&
3547 x2.nGrowVect().allGE(nghost));
3548
3549 BL_PROFILE("FabArray::Saxpy_Saxpy()");
3550
3551#ifdef AMREX_USE_GPU
3552 if (Gpu::inLaunchRegion() && y1.isFusingCandidate()) {
3553 auto const& y1ma = y1.arrays();
3554 auto const& x1ma = x1.const_arrays();
3555 auto const& y2ma = y2.arrays();
3556 auto const& x2ma = x2.const_arrays();
3557 ParallelFor(y1, nghost, ncomp,
3558 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3559 {
3560 y1ma[box_no](i,j,k,ycomp+n) += a1 * x1ma[box_no](i,j,k,xcomp+n);
3561 y2ma[box_no](i,j,k,ycomp+n) += a2 * x2ma[box_no](i,j,k,xcomp+n);
3562 });
3563 if (!Gpu::inNoSyncRegion()) {
3565 }
3566 } else
3567#endif
3568 {
3569#ifdef AMREX_USE_OMP
3570#pragma omp parallel if (Gpu::notInLaunchRegion())
3571#endif
3572 for (MFIter mfi(y1,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3573 {
3574 const Box& bx = mfi.growntilebox(nghost);
3575
3576 if (bx.ok()) {
3577 auto const& x1fab = x1.const_array(mfi);
3578 auto const& y1fab = y1.array(mfi);
3579 auto const& x2fab = x2.const_array(mfi);
3580 auto const& y2fab = y2.array(mfi);
3581 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3582 {
3583 y1fab(i,j,k,ycomp+n) += a1 * x1fab(i,j,k,xcomp+n);
3584 y2fab(i,j,k,ycomp+n) += a2 * x2fab(i,j,k,xcomp+n);
3585 });
3586 }
3587 }
3588 }
3589}
3590
3591template <class FAB>
3592template <class F>
3593requires (BaseFabType<F>)
3595 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x,
3596 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3597{
3598 AMREX_ASSERT(y1.boxArray() == y2.boxArray() &&
3599 y1.boxArray() == x.boxArray() &&
3601 y1.distributionMap == x.distributionMap &&
3602 y1.nGrowVect().allGE(nghost) &&
3603 y2.nGrowVect().allGE(nghost) &&
3604 x.nGrowVect().allGE(nghost));
3605
3606 BL_PROFILE("FabArray::Saypy_Saxpy()");
3607
3608#ifdef AMREX_USE_GPU
3609 if (Gpu::inLaunchRegion() && y1.isFusingCandidate()) {
3610 auto const& y1ma = y1.arrays();
3611 auto const& y2ma = y2.arrays();
3612 auto const& xma = x.const_arrays();
3613 ParallelFor(y1, nghost, ncomp,
3614 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3615 {
3616 y1ma[box_no](i,j,k,ycomp+n) += a1 * y2ma[box_no](i,j,k,ycomp+n);
3617 y2ma[box_no](i,j,k,ycomp+n) += a2 * xma[box_no](i,j,k,xcomp+n);
3618 });
3619 if (!Gpu::inNoSyncRegion()) {
3621 }
3622 } else
3623#endif
3624 {
3625#ifdef AMREX_USE_OMP
3626#pragma omp parallel if (Gpu::notInLaunchRegion())
3627#endif
3628 for (MFIter mfi(y1,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3629 {
3630 const Box& bx = mfi.growntilebox(nghost);
3631
3632 if (bx.ok()) {
3633 auto const& xfab = x.const_array(mfi);
3634 auto const& y1fab = y1.array(mfi);
3635 auto const& y2fab = y2.array(mfi);
3636 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3637 {
3638 y1fab(i,j,k,ycomp+n) += a1 * y2fab(i,j,k,ycomp+n);
3639 y2fab(i,j,k,ycomp+n) += a2 * xfab(i,j,k,xcomp+n);
3640 });
3641 }
3642 }
3643 }
3644}
3645
3646template <class FAB>
3647template <class F>
3648requires (BaseFabType<F>)
3649void
3651 value_type a, const FabArray<FAB>& x, int xcomp,
3652 value_type b, const FabArray<FAB>& y, int ycomp,
3653 int dstcomp, int numcomp, const IntVect& nghost)
3654{
3655 AMREX_ASSERT(dst.boxArray() == x.boxArray());
3656 AMREX_ASSERT(dst.distributionMap == x.distributionMap);
3657 AMREX_ASSERT(dst.boxArray() == y.boxArray());
3658 AMREX_ASSERT(dst.distributionMap == y.distributionMap);
3659 AMREX_ASSERT(dst.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost) && y.nGrowVect().allGE(nghost));
3660
3661 BL_PROFILE("FabArray::LinComb()");
3662
3663#ifdef AMREX_USE_GPU
3664 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
3665 auto const& dstma = dst.arrays();
3666 auto const& xma = x.const_arrays();
3667 auto const& yma = y.const_arrays();
3668 ParallelFor(dst, nghost, numcomp,
3669 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3670 {
3671 dstma[box_no](i,j,k,dstcomp+n) = a*xma[box_no](i,j,k,xcomp+n)
3672 + b*yma[box_no](i,j,k,ycomp+n);
3673 });
3674 if (!Gpu::inNoSyncRegion()) {
3676 }
3677 } else
3678#endif
3679 {
3680#ifdef AMREX_USE_OMP
3681#pragma omp parallel if (Gpu::notInLaunchRegion())
3682#endif
3683 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3684 {
3685 const Box& bx = mfi.growntilebox(nghost);
3686 auto const& xfab = x.const_array(mfi);
3687 auto const& yfab = y.const_array(mfi);
3688 auto const& dfab = dst.array(mfi);
3689 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
3690 {
3691 dfab(i,j,k,dstcomp+n) = a*xfab(i,j,k,xcomp+n) + b*yfab(i,j,k,ycomp+n);
3692 });
3693 }
3694 }
3695}
3696
3697template <class FAB>
3698template <typename BUF>
3699void
3701{
3702 BL_PROFILE("FabArray::FillBoundary()");
3703 if ( n_grow.max() > 0 ) {
3704 FillBoundary_nowait<BUF>(0, nComp(), n_grow, Periodicity::NonPeriodic(), cross);
3705 FillBoundary_finish<BUF>();
3706 }
3707}
3708
3709template <class FAB>
3710template <typename BUF>
3711void
3712FabArray<FAB>::FillBoundary (const Periodicity& period, bool cross)
3713{
3714 BL_PROFILE("FabArray::FillBoundary()");
3715 if ( n_grow.max() > 0 ) {
3716 FillBoundary_nowait<BUF>(0, nComp(), n_grow, period, cross);
3717 FillBoundary_finish<BUF>();
3718 }
3719}
3720
3721template <class FAB>
3722template <typename BUF>
3723void
3724FabArray<FAB>::FillBoundary (const IntVect& nghost, const Periodicity& period, bool cross)
3725{
3726 BL_PROFILE("FabArray::FillBoundary()");
3728 "FillBoundary: asked to fill more ghost cells than we have");
3729 if ( nghost.max() > 0 ) {
3730 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3731 FillBoundary_finish<BUF>();
3732 }
3733}
3734
3735template <class FAB>
3736template <typename BUF>
3737void
3738FabArray<FAB>::FillBoundary (int scomp, int ncomp, bool cross)
3739{
3740 BL_PROFILE("FabArray::FillBoundary()");
3741 if ( n_grow.max() > 0 ) {
3742 FillBoundary_nowait<BUF>(scomp, ncomp, n_grow, Periodicity::NonPeriodic(), cross);
3743 FillBoundary_finish<BUF>();
3744 }
3745}
3746
3747template <class FAB>
3748template <typename BUF>
3749void
3750FabArray<FAB>::FillBoundary (int scomp, int ncomp, const Periodicity& period, bool cross)
3751{
3752 BL_PROFILE("FabArray::FillBoundary()");
3753 if ( n_grow.max() > 0 ) {
3754 FillBoundary_nowait<BUF>(scomp, ncomp, n_grow, period, cross);
3755 FillBoundary_finish<BUF>();
3756 }
3757}
3758
3759template <class FAB>
3760template <typename BUF>
3761void
3762FabArray<FAB>::FillBoundary (int scomp, int ncomp, const IntVect& nghost,
3763 const Periodicity& period, bool cross)
3764{
3765 BL_PROFILE("FabArray::FillBoundary()");
3767 "FillBoundary: asked to fill more ghost cells than we have");
3768 if ( nghost.max() > 0 ) {
3769 FillBoundary_nowait<BUF>(scomp, ncomp, nghost, period, cross);
3770 FillBoundary_finish<BUF>();
3771 }
3772}
3773
3774template <class FAB>
3775template <typename BUF>
3776void
3778{
3779 FillBoundary_nowait<BUF>(0, nComp(), nGrowVect(), Periodicity::NonPeriodic(), cross);
3780}
3781
3782template <class FAB>
3783template <typename BUF>
3784void
3786{
3787 FillBoundary_nowait<BUF>(0, nComp(), nGrowVect(), period, cross);
3788}
3789
3790template <class FAB>
3791template <typename BUF>
3792void
3793FabArray<FAB>::FillBoundary_nowait (const IntVect& nghost, const Periodicity& period, bool cross)
3794{
3795 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3796}
3797
3798template <class FAB>
3799template <typename BUF>
3800void
3801FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, bool cross)
3802{
3803 FillBoundary_nowait<BUF>(scomp, ncomp, nGrowVect(), Periodicity::NonPeriodic(), cross);
3804}
3805
3806template <class FAB>
3807void
3809{
3810 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3811 if (n_grow.max() > 0 || !is_cell_centered()) {
3812 FillBoundaryAndSync_nowait(0, nComp(), n_grow, period);
3814 }
3815}
3816
3817template <class FAB>
3818void
3819FabArray<FAB>::FillBoundaryAndSync (int scomp, int ncomp, const IntVect& nghost,
3820 const Periodicity& period)
3821{
3822 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3823 if (nghost.max() > 0 || !is_cell_centered()) {
3824 FillBoundaryAndSync_nowait(scomp, ncomp, nghost, period);
3826 }
3827}
3828
3829template <class FAB>
3830void
3835
3836template <class FAB>
3837void
3838FabArray<FAB>::FillBoundaryAndSync_nowait (int scomp, int ncomp, const IntVect& nghost,
3839 const Periodicity& period)
3840{
3841 BL_PROFILE("FillBoundaryAndSync_nowait()");
3842 FBEP_nowait(scomp, ncomp, nghost, period, false, false, true);
3843}
3844
3845template <class FAB>
3846void
3848{
3849 BL_PROFILE("FillBoundaryAndSync_finish()");
3851}
3852
3853template <class FAB>
3854void
3856{
3857 BL_PROFILE("FAbArray::OverrideSync()");
3858 if (!is_cell_centered()) {
3859 OverrideSync_nowait(0, nComp(), period);
3861 }
3862}
3863
3864template <class FAB>
3865void
3866FabArray<FAB>::OverrideSync (int scomp, int ncomp, const Periodicity& period)
3867{
3868 BL_PROFILE("FAbArray::OverrideSync()");
3869 if (!is_cell_centered()) {
3870 OverrideSync_nowait(scomp, ncomp, period);
3872 }
3873}
3874
3875template <class FAB>
3876void
3878{
3879 OverrideSync_nowait(0, nComp(), period);
3880}
3881
3882template <class FAB>
3883void
3884FabArray<FAB>::OverrideSync_nowait (int scomp, int ncomp, const Periodicity& period)
3885{
3886 BL_PROFILE("OverrideSync_nowait()");
3887 FBEP_nowait(scomp, ncomp, IntVect(0), period, false, false, true);
3888}
3889
3890template <class FAB>
3891void
3893{
3894 BL_PROFILE("OverrideSync_finish()");
3896}
3897
3898template <class FAB>
3899void
3900FabArray<FAB>::SumBoundary (const Periodicity& period, bool deterministic)
3901{
3902 SumBoundary(0, n_comp, IntVect(0), period, deterministic);
3903}
3904
3905template <class FAB>
3906void
3907FabArray<FAB>::SumBoundary (int scomp, int ncomp, const Periodicity& period, bool deterministic)
3908{
3909 SumBoundary(scomp, ncomp, IntVect(0), period, deterministic);
3910}
3911
3912template <class FAB>
3913void
3914FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period, bool deterministic)
3915{
3916 SumBoundary(scomp, ncomp, this->nGrowVect(), nghost, period, deterministic);
3917}
3918
3919template <class FAB>
3920void
3921FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period, bool deterministic)
3922{
3923 BL_PROFILE("FabArray<FAB>::SumBoundary()");
3924
3925 SumBoundary_nowait(scomp, ncomp, src_nghost, dst_nghost, period, deterministic);
3926 SumBoundary_finish();
3927}
3928
3929template <class FAB>
3930void
3931FabArray<FAB>::SumBoundary_nowait (const Periodicity& period, bool deterministic)
3932{
3933 SumBoundary_nowait(0, n_comp, IntVect(0), period, deterministic);
3934}
3935
3936template <class FAB>
3937void
3938FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool deterministic)
3939{
3940 SumBoundary_nowait(scomp, ncomp, IntVect(0), period, deterministic);
3941}
3942
3943template <class FAB>
3944void
3945FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period, bool deterministic)
3946{
3947 SumBoundary_nowait(scomp, ncomp, this->nGrowVect(), nghost, period, deterministic);
3948}
3949
3950template <class FAB>
3951void
3952FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period, bool deterministic)
3953{
3954 BL_PROFILE("FabArray<FAB>::SumBoundary_nowait()");
3955
3956 if ( n_grow == IntVect::TheZeroVector() && boxArray().ixType().cellCentered()) { return; }
3957
3958 AMREX_ALWAYS_ASSERT(src_nghost.allLE(n_grow) && dst_nghost.allLE(n_grow));
3959
3960 FBEP_nowait(scomp, ncomp, dst_nghost, period, false, false, false, src_nghost, deterministic);
3961}
3962
3963template <class FAB>
3964void
3966{
3967 BL_PROFILE("FabArray<FAB>::SumBoundary_finish()");
3969}
3970
3971template <class FAB>
3972void
3974{
3975 BL_PROFILE("FabArray::EnforcePeriodicity");
3976 if (period.isAnyPeriodic()) {
3977 FBEP_nowait(0, nComp(), nGrowVect(), period, false, true);
3978 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3979 }
3980}
3981
3982template <class FAB>
3983void
3984FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const Periodicity& period)
3985{
3986 BL_PROFILE("FabArray::EnforcePeriodicity");
3987 if (period.isAnyPeriodic()) {
3988 FBEP_nowait(scomp, ncomp, nGrowVect(), period, false, true);
3989 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3990 }
3991}
3992
3993template <class FAB>
3994void
3995FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const IntVect& nghost,
3996 const Periodicity& period)
3997{
3998 BL_PROFILE("FabArray::EnforcePeriodicity");
3999 if (period.isAnyPeriodic()) {
4000 FBEP_nowait(scomp, ncomp, nghost, period, false, true);
4001 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
4002 }
4003}
4004
4005template <class FAB>
4006template <typename BUF>
4007void
4008FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool cross)
4009{
4010 FBEP_nowait<BUF>(scomp, ncomp, nGrowVect(), period, cross);
4011}
4012
4013template <class FAB>
4014template <typename BUF>
4015void
4016FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const IntVect& nghost,
4017 const Periodicity& period, bool cross)
4018{
4019 FBEP_nowait<BUF>(scomp, ncomp, nghost, period, cross);
4020}
4021
4022template <class FAB>
4023template <class F>
4024requires (BaseFabType<F>)
4025void
4026FabArray<FAB>::BuildMask (const Box& phys_domain, const Periodicity& period,
4027 value_type covered, value_type notcovered,
4029{
4030 BL_PROFILE("FabArray::BuildMask()");
4031
4032 int ncomp = this->nComp();
4033 const IntVect& ngrow = this->nGrowVect();
4034
4035 Box domain = amrex::convert(phys_domain, boxArray().ixType());
4036 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
4037 if (period.isPeriodic(i)) {
4038 domain.grow(i, ngrow[i]);
4039 }
4040 }
4041
4042#ifdef AMREX_USE_GPU
4043 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
4044 auto const& fa = this->arrays();
4045 ParallelFor(*this, ngrow, ncomp,
4046 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
4047 {
4048 auto const& fab = fa[box_no];
4049 Box vbx(fab);
4050 vbx.grow(-ngrow);
4051 if (vbx.contains(i,j,k)) {
4052 fab(i,j,k,n) = interior;
4053 } else if (domain.contains(i,j,k)) {
4054 fab(i,j,k,n) = notcovered;
4055 } else {
4056 fab(i,j,k,n) = physbnd;
4057 }
4058 });
4059 if (!Gpu::inNoSyncRegion()) {
4061 }
4062 } else
4063#endif
4064 {
4065#ifdef AMREX_USE_OMP
4066#pragma omp parallel if (Gpu::notInLaunchRegion())
4067#endif
4068 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
4069 {
4070 auto const& fab = this->array(mfi);
4071 Box const& fbx = mfi.growntilebox();
4072 Box const& gbx = fbx & domain;
4073 Box const& vbx = mfi.validbox();
4074 AMREX_HOST_DEVICE_FOR_4D(fbx, ncomp, i, j, k, n,
4075 {
4076 if (vbx.contains(i,j,k)) {
4077 fab(i,j,k,n) = interior;
4078 } else if (gbx.contains(i,j,k)) {
4079 fab(i,j,k,n) = notcovered;
4080 } else {
4081 fab(i,j,k,n) = physbnd;
4082 }
4083 });
4084 }
4085 }
4086
4087 const FabArrayBase::FB& TheFB = this->getFB(ngrow,period);
4088 setVal(covered, TheFB, 0, ncomp);
4089}
4090
4091template <class FAB>
4092template <class F>
4093requires (BaseFabType<F>)
4094void
4095FabArray<FAB>::setVal (value_type val, const CommMetaData& thecmd, int scomp, int ncomp)
4096{
4097 BL_PROFILE("FabArray::setVal(val, thecmd, scomp, ncomp)");
4098
4099#ifdef AMREX_USE_GPU
4100 if (Gpu::inLaunchRegion())
4101 {
4102 CMD_local_setVal_gpu(val, thecmd, scomp, ncomp);
4103 CMD_remote_setVal_gpu(val, thecmd, scomp, ncomp);
4104 }
4105 else
4106#endif
4107 {
4108 AMREX_ASSERT(thecmd.m_LocTags && thecmd.m_RcvTags);
4109 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
4110 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
4111 auto N_locs = static_cast<int>(LocTags.size());
4112#ifdef AMREX_USE_OMP
4113#pragma omp parallel for if (thecmd.m_threadsafe_loc)
4114#endif
4115 for (int i = 0; i < N_locs; ++i) {
4116 const CopyComTag& tag = LocTags[i];
4117 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
4118 }
4119
4120 for (const auto & RcvTag : RcvTags) {
4121 auto N = static_cast<int>(RcvTag.second.size());
4122#ifdef AMREX_USE_OMP
4123#pragma omp parallel for if (thecmd.m_threadsafe_rcv)
4124#endif
4125 for (int i = 0; i < N; ++i) {
4126 const CopyComTag& tag = RcvTag.second[i];
4127 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
4128 }
4129 }
4130 }
4131}
4132
4133template <class FAB>
4134template <class F>
4135requires (BaseFabType<F>)
4138{
4139 BL_PROFILE("FabArray::RecvLayoutMask()");
4140
4141 LayoutData<int> r(this->boxArray(), this->DistributionMap());
4142#ifdef AMREX_USE_OMP
4143#pragma omp parallel if (thecmd.m_threadsafe_rcv)
4144#endif
4145 for (MFIter mfi(r); mfi.isValid(); ++mfi) {
4146 r[mfi] = 0;
4147 }
4148
4149 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
4150 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
4151
4152 auto N_locs = static_cast<int>(LocTags.size());
4153 for (int i = 0; i < N_locs; ++i) {
4154 const CopyComTag& tag = LocTags[i];
4155 r[tag.dstIndex] = 1;
4156 }
4157
4158 for (const auto & RcvTag : RcvTags) {
4159 auto N = static_cast<int>(RcvTag.second.size());
4160 for (int i = 0; i < N; ++i) {
4161 const CopyComTag& tag = RcvTag.second[i];
4162 r[tag.dstIndex] = 1;
4163 }
4164 }
4165 return r;
4166}
4167
4168template <class FAB>
4169template <typename F>
4170requires (BaseFabType<F>)
4171typename F::value_type
4172FabArray<FAB>::norminf (int comp, int ncomp, IntVect const& nghost, bool local,
4173 [[maybe_unused]] bool ignore_covered) const
4174{
4175 BL_PROFILE("FabArray::norminf()");
4176
4177 using RT = typename F::value_type;
4178
4179 auto nm0 = RT(0.0);
4180
4181#ifdef AMREX_USE_EB
4182 if ( this->is_cell_centered() && this->hasEBFabFactory() && ignore_covered )
4183 {
4184 const auto& ebfactory = dynamic_cast<EBFArrayBoxFactory const&>(this->Factory());
4185 auto const& flags = ebfactory.getMultiEBCellFlagFab();
4186#ifdef AMREX_USE_GPU
4187 if (Gpu::inLaunchRegion()) {
4188 auto const& flagsma = flags.const_arrays();
4189 auto const& ma = this->const_arrays();
4190 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost,
4191 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<RT>
4192 {
4193 if (flagsma[box_no](i,j,k).isCovered()) {
4194 return RT(0.0);
4195 } else {
4196 auto tmp = RT(0.0);
4197 auto const& a = ma[box_no];
4198 for (int n = 0; n < ncomp; ++n) {
4199 tmp = amrex::max(tmp, std::abs(a(i,j,k,comp+n)));
4200 }
4201 return tmp;
4202 }
4203 });
4204 } else
4205#endif
4206 {
4207#ifdef AMREX_USE_OMP
4208#pragma omp parallel reduction(max:nm0)
4209#endif
4210 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
4211 Box const& bx = mfi.growntilebox(nghost);
4212 if (flags[mfi].getType(bx) != FabType::covered) {
4213 auto const& flag = flags.const_array(mfi);
4214 auto const& a = this->const_array(mfi);
4215 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
4216 {
4217 if (!flag(i,j,k).isCovered()) {
4218 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
4219 }
4220 });
4221 }
4222 }
4223 }
4224 }
4225 else
4226#endif
4227 {
4228#ifdef AMREX_USE_GPU
4229 if (Gpu::inLaunchRegion()) {
4230 auto const& ma = this->const_arrays();
4231 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost, ncomp,
4232 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept -> GpuTuple<RT>
4233 {
4234 return std::abs(ma[box_no](i,j,k,comp+n));
4235 });
4236 } else
4237#endif
4238 {
4239#ifdef AMREX_USE_OMP
4240#pragma omp parallel reduction(max:nm0)
4241#endif
4242 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
4243 Box const& bx = mfi.growntilebox(nghost);
4244 auto const& a = this->const_array(mfi);
4245 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
4246 {
4247 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
4248 });
4249 }
4250 }
4251 }
4252
4253 if (!local) {
4255 }
4256
4257 return nm0;
4258}
4259
4260template <class FAB>
4261template <typename IFAB, typename F>
4262requires (BaseFabType<F>)
4263typename F::value_type
4264FabArray<FAB>::norminf (FabArray<IFAB> const& mask, int comp, int ncomp,
4265 IntVect const& nghost, bool local) const
4266{
4267 BL_PROFILE("FabArray::norminf(mask)");
4268
4269 using RT = typename F::value_type;
4270
4271 auto nm0 = RT(0.0);
4272
4273#ifdef AMREX_USE_GPU
4274 if (Gpu::inLaunchRegion()) {
4275 auto const& ma = this->const_arrays();
4276 auto const& maskma = mask.const_arrays();
4277 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, IntVect(nghost),
4278 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<RT>
4279 {
4280 if (maskma[box_no](i,j,k)) {
4281 auto tmp = RT(0.0);
4282 auto const& a = ma[box_no];
4283 for (int n = 0; n < ncomp; ++n) {
4284 tmp = amrex::max(tmp, std::abs(a(i,j,k,comp+n)));
4285 }
4286 return tmp;
4287 } else {
4288 return RT(0.0);
4289 }
4290 });
4291 } else
4292#endif
4293 {
4294#ifdef AMREX_USE_OMP
4295#pragma omp parallel reduction(max:nm0)
4296#endif
4297 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
4298 Box const& bx = mfi.growntilebox(nghost);
4299 auto const& a = this->const_array(mfi);
4300 auto const& mskfab = mask.const_array(mfi);
4301 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
4302 {
4303 if (mskfab(i,j,k)) {
4304 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
4305 }
4306 });
4307 }
4308 }
4309
4310 if (!local) {
4312 }
4313
4314 return nm0;
4315}
4316
4318
4319}
4320
4321#endif /*BL_FABARRAY_H*/
Runtime initialization/finalization helpers and global diagnostics.
Fixed-size array types for use on GPU and CPU.
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
Assertion macros used across AMReX for runtime consistency checks.
#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
Helper routines for manipulating BaseFab data and related arrays.
BaseFab container template providing box-based field storage.
Container and helper utilities for sets of boxes on integer index space.
Disjoint-list representation of boxes and associated utilities.
Integer-lattice boxes and helpers for defining index-space regions.
Maps FABs in a FabArray to MPI processes.
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:124
#define AMREX_RESTRICT
Definition AMReX_Extension.H:37
Common infrastructure shared by FabArray specializations.
Inline FabArray communication routines: FillBoundary, ParallelCopy, ParallelCopyToGhost,...
Abstract factory interface for creating and destroying FAB objects.
#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:1129
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
Abstract base class for memory arenas.
Definition AMReX_Arena.H:153
virtual void free(void *pt)=0
Free a previously allocated block pointed to by pt.
virtual void * alloc(std::size_t sz)=0
Allocate sz bytes from this arena.
A FortranArrayBox(FAB)-like object.
Definition AMReX_BaseFab.H:222
Reference-counted collection of Boxes.
Definition AMReX_BoxArray.H:676
__host__ __device__ BoxND & grow(int i) noexcept
Grow in all directions by i cells (negative shrinks).
Definition AMReX_Box.H:668
__host__ __device__ IntVectND< dim > length() const noexcept
Return the length of the BoxND.
Definition AMReX_Box.H:167
__host__ __device__ bool contains(const IntVectND< dim > &p) const noexcept
Return true if argument is contained within BoxND.
Definition AMReX_Box.H:233
__host__ __device__ BoxND & shift(int dir, int nzones) noexcept
Shift this BoxND nzones indexing positions in coordinate direction dir.
Definition AMReX_Box.H:538
__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:1143
__host__ __device__ bool ok() const noexcept
Return true if high bounds are >= low bounds and the index type is valid.
Definition AMReX_Box.H:229
__host__ __device__ const IntVectND< dim > & smallEnd() const &noexcept
Return the inclusive lower bound of the box.
Definition AMReX_Box.H:124
Default FabFactory that calls new / delete on the FAB type directly.
Definition AMReX_FabFactory.H:124
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:51
Definition AMReX_EBFabFactory.H:32
const FabArray< EBCellFlagFab > & getMultiEBCellFlagFab() const noexcept
EB cell flags for all boxes.
Definition AMReX_EBFabFactory.H:73
bool isAllRegular() const noexcept
Definition AMReX_EBFabFactory.cpp:148
Base class for FabArray.
Definition AMReX_FabArrayBase.H:47
IntVect nGrowVect() const noexcept
Definition AMReX_FabArrayBase.H:85
void clear()
Clear this object's BoxArray, DistributionMapping, local index/ownership data, and BDKey so the conta...
Definition AMReX_FabArrayBase.cpp:207
Vector< int > indexArray
Definition AMReX_FabArrayBase.H:516
static FabArrayStats m_FA_stats
Definition AMReX_FabArrayBase.H:841
static bool getAllocSingleChunk()
Query whether single-chunk allocation is enabled for new FabArrays.
Definition AMReX_FabArrayBase.H:846
bool isFusingCandidate() const noexcept
Is this a good candidate for kernel fusing?
Definition AMReX_FabArrayBase.cpp:2705
int size() const noexcept
Return the number of FABs in the FabArray.
Definition AMReX_FabArrayBase.H:115
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:236
CopyComTag::MapOfCopyComTagContainers MapOfCopyComTagContainers
Definition AMReX_FabArrayBase.H:237
const DistributionMapping & DistributionMap() const noexcept
Return constant reference to associated DistributionMapping.
Definition AMReX_FabArrayBase.H:135
int local_size() const noexcept
Return the number of local FABs in the FabArray.
Definition AMReX_FabArrayBase.H:118
CpOp
parallel copy or add
Definition AMReX_FabArrayBase.H:411
@ ADD
Definition AMReX_FabArrayBase.H:411
@ COPY
Definition AMReX_FabArrayBase.H:411
DistributionMapping distributionMap
Definition AMReX_FabArrayBase.H:515
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:88
const BoxArray & boxArray() const noexcept
Return a constant reference to the BoxArray that defines the valid region associated with this FabArr...
Definition AMReX_FabArrayBase.H:100
An Array of FortranArrayBox(FAB)-like Objects.
Definition AMReX_FabArray.H:356
void ParallelCopyToGhost_finish()
Finish the current ParallelCopyToGhost_nowait() operation.
Definition AMReX_FabArrayCommI.H:389
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:2642
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:1329
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:3938
void mult(value_type val, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:3213
void setBndry(value_type val)
Set all values in the boundary region to val.
Definition AMReX_FabArray.H:2732
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:1340
void FillBoundary_finish()
Definition AMReX_FabArrayCommI.H:227
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:1424
void * m_dp_arrays
Definition AMReX_FabArray.H:1761
void ParallelCopy(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:971
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:2686
typename std::conditional_t< IsBaseFab< FAB >::value, FAB, FABType >::value_type value_type
Definition AMReX_FabArray.H:367
std::unique_ptr< FabArray< FAB > > os_temp
Definition AMReX_FabArray.H:1906
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:3477
void FillBoundary(const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3724
const FabFactory< FAB > & Factory() const noexcept
Factory used to create FAB instances for this FabArray.
Definition AMReX_FabArray.H:471
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:17
void CMD_remote_setVal_gpu(value_type x, const CommMetaData &thecmd, int scomp, int ncomp)
Definition AMReX_FBI.H:696
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:989
LayoutData< int > RecvLayoutMask(const CommMetaData &thecmd)
Definition AMReX_FabArray.H:4137
void FillBoundary_nowait(const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3785
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:3650
void shift(const IntVect &v)
Shift the boxarray by vector v.
Definition AMReX_FabArray.H:3367
FAB * release(int K)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:2148
bool ok() const
Return true if the FabArray is well-defined. That is, the FabArray has a BoxArray and DistributionMap...
Definition AMReX_FabArray.H:2423
const FAB & operator[](const MFIter &mfi) const noexcept
Return a constant reference to the FAB associated with mfi.
Definition AMReX_FabArray.H:555
void ParallelAdd_nowait(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic())
Start an asynchronous ParallelAdd over all components.
Definition AMReX_FabArray.H:990
FabArray(FabArray< FAB > &&rhs) noexcept
Definition AMReX_FabArray.H:2348
FabArray(const BoxArray &bxs, const DistributionMapping &dm, int nvar, const IntVect &ngrow, const MFInfo &info=MFInfo(), const FabFactory< FAB > &factory=DefaultFabFactory< FAB >())
Construct a FabArray with a per-direction grow vector.
Definition AMReX_FabArray.H:2312
bool defined(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:2041
void prefetchToHost(const MFIter &mfi) const noexcept
Request that the FAB selected by iterator mfi be prefetched to host memory, where supported.
Definition AMReX_FabArray.H:592
void OverrideSync_nowait(int scomp, int ncomp, const Periodicity &period)
Definition AMReX_FabArray.H:3884
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())
Copy source data to destination ghost cells only.
Definition AMReX_FabArrayCommI.H:358
MultiArray4< typename FabArray< FAB >::value_type > arrays() noexcept
Build, if needed, and return mutable Array4 views for local FABs.
Definition AMReX_FabArray.H:713
void ParallelCopy_finish()
Finish the current nowait ParallelCopy or ParallelAdd operation.
Definition AMReX_FabArrayCommI.H:679
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:1385
FAB & get(int K) noexcept
Return a reference to the FAB associated with the Kth element.
Definition AMReX_FabArray.H:576
FAB const * fabPtr(int K) const noexcept
Definition AMReX_FabArray.H:2083
Array4< typename FabArray< FAB >::value_type > array(const MFIter &mfi, int start_comp) noexcept
Definition AMReX_FabArray.H:672
void SumBoundary_nowait(const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3931
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:3534
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:1095
Long m_single_chunk_size
Definition AMReX_FabArray.H:1751
FAB & get(const MFIter &mfi) noexcept
Returns a reference to the FAB associated mfi.
Definition AMReX_FabArray.H:564
void OverrideSync_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3877
std::unique_ptr< PCData< FAB > > pcd
Definition AMReX_FabArray.H:1903
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:2458
void setDomainBndry(value_type val, const Geometry &geom)
Set all values outside the Geometry domain described by geom to val.
Definition AMReX_FabArray.H:2845
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())
Asynchronous ParallelAdd with per-direction ghost-cell growth.
Definition AMReX_FabArray.H:1151
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:1902
std::unique_ptr< detail::SingleChunkArena > m_single_chunk_arena
Definition AMReX_FabArray.H:1750
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:3952
FabArray(const FabArray< FAB > &rhs, MakeType maketype, int scomp, int ncomp)
Construct a component alias of rhs.
Definition AMReX_FabArray.H:2326
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:968
FAB fab_type
Definition AMReX_FabArray.H:369
void FB_local_add_cpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:455
Array4< typename FabArray< FAB >::value_type const > array(int K) const noexcept
Read-only Array4 view for the FAB identified by global index K.
Definition AMReX_FabArray.H:635
bool SharedMemory() const noexcept
Definition AMReX_FabArray.H:1819
Array4< typename FabArray< FAB >::value_type const > const_array(int K) const noexcept
Read-only Array4 view for the FAB identified by global index K.
Definition AMReX_FabArray.H:656
void prefetchToDevice(const MFIter &mfi) const noexcept
Request that the FAB selected by iterator mfi be prefetched to device memory, where supported.
Definition AMReX_FabArray.H:608
void FillBoundary_nowait(const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3793
Vector< std::string > m_tags
Definition AMReX_FabArray.H:1767
void ParallelCopyToGhost_nowait(const FabArray< FAB > &src, int scomp, int dcomp, int ncomp, const IntVect &snghost, const IntVect &dnghost, const Periodicity &period=Periodicity::NonPeriodic())
Start an asynchronous version of ParallelCopyToGhost().
Definition AMReX_FabArrayCommI.H:375
void ParallelAdd_nowait(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const Periodicity &period=Periodicity::NonPeriodic())
Start an asynchronous ParallelAdd for a component subset.
Definition AMReX_FabArray.H:1050
void FB_local_add_gpu(const FB &TheFB, int scomp, int ncomp, bool deterministic)
Definition AMReX_FBI.H:618
void FB_local_copy_gpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:546
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:2234
Arena * arena() const noexcept
Arena configured for allocations by this FabArray.
Definition AMReX_FabArray.H:480
DataAllocator m_dallocator
Definition AMReX_FabArray.H:1749
void copy(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:977
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:1223
Array4< typename FabArray< FAB >::value_type > array(const MFIter &mfi) noexcept
Mutable Array4 view for the FAB referenced by iterator mfi.
Definition AMReX_FabArray.H:628
void FillBoundaryAndSync_finish()
Definition AMReX_FabArray.H:3847
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)
Asynchronous ParallelCopy with scalar ghost-cell growth.
Definition AMReX_FabArray.H:1175
void FillBoundary_nowait(bool cross=false)
Definition AMReX_FabArray.H:3777
void clear()
Releases FAB memory in the FabArray.
Definition AMReX_FabArray.H:2187
void FillBoundary_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:4016
const Vector< std::string > & tags() const noexcept
Memory-usage tags recorded for this FabArray's allocations.
Definition AMReX_FabArray.H:488
void CMD_local_setVal_gpu(value_type x, const CommMetaData &thecmd, int scomp, int ncomp)
Definition AMReX_FBI.H:666
MultiArray4< typename FabArray< FAB >::value_type const > arrays() const noexcept
Build, if needed, and return read-only Array4 views for local FABs.
Definition AMReX_FabArray.H:723
void FillBoundary_nowait(int scomp, int ncomp, bool cross=false)
Definition AMReX_FabArray.H:3801
value_type * singleChunkPtr() noexcept
Definition AMReX_FabArray.H:504
std::vector< FAB * > m_fabs_v
The data.
Definition AMReX_FabArray.H:1758
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:1087
bool define_function_called
has define() been called?
Definition AMReX_FabArray.H:1754
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:1016
FabArray() noexcept
Constructs an empty FabArray<FAB>.
Definition AMReX_FabArray.H:2287
void FillBoundary_test()
Definition AMReX_FabArrayCommI.H:1016
void plus(value_type val, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:3135
bool defined(int K) const noexcept
Definition AMReX_FabArray.H:2028
FAB * fabPtr(int K) noexcept
Definition AMReX_FabArray.H:2074
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:1078
const FAB & atLocalIdx(int L) const noexcept
Definition AMReX_FabArray.H:580
MultiArray4< typename FabArray< FAB >::value_type const > const_arrays() const noexcept
Read-only convenience wrapper equivalent to arrays() const.
Definition AMReX_FabArray.H:731
std::unique_ptr< FabFactory< FAB > > m_factory
Definition AMReX_FabArray.H:1748
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:1031
void invert(value_type numerator, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:3291
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:2941
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())
Asynchronous ParallelAdd with scalar ghost-cell growth.
Definition AMReX_FabArray.H:1128
void setVal(value_type val)
Set all components in the entire region of each FAB to val.
Definition AMReX_FabArray.H:2950
Array4< typename FabArray< FAB >::value_type const > array(const MFIter &mfi) const noexcept
Read-only Array4 view for the FAB referenced by iterator mfi.
Definition AMReX_FabArray.H:621
void FillBoundary_nowait(int scomp, int ncomp, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:4008
const FAB & get(const MFIter &mfi) const noexcept
Return a constant reference to the FAB associated with mfi.
Definition AMReX_FabArray.H:558
void SumBoundary_finish()
Definition AMReX_FabArray.H:3965
std::size_t singleChunkSize() const noexcept
Definition AMReX_FabArray.H:516
void SumBoundary_nowait(int scomp, int ncomp, IntVect const &nghost, const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3945
void FB_local_copy_cpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:396
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:3385
MultiArray4< value_type > m_arrays
Definition AMReX_FabArray.H:1764
void FillBoundaryAndSync_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3831
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
void FillBoundaryAndSync_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Definition AMReX_FabArray.H:3838
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:4026
void * m_hp_arrays
Definition AMReX_FabArray.H:1763
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:3594
ShMem shmem
Definition AMReX_FabArray.H:1817
FabArray< FAB > & operator=(FabArray< FAB > &&rhs) noexcept
Definition AMReX_FabArray.H:2379
Array4< typename FabArray< FAB >::value_type > array(int K, int start_comp) noexcept
Definition AMReX_FabArray.H:688
MultiArray4< value_type const > m_const_arrays
Definition AMReX_FabArray.H:1765
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:1022
bool hasEBFabFactory() const noexcept
Return whether this FabArray uses an EBFArrayBoxFactory.
Definition AMReX_FabArray.H:493
TagVector< Array4CopyTag< value_type > > const * FB_get_local_copy_tag_vector(const FB &TheFB)
Definition AMReX_FBI.H:503
Array4< typename FabArray< FAB >::value_type const > array(int K, int start_comp) const noexcept
Definition AMReX_FabArray.H:680
bool isAllRegular() const noexcept
Return the EB factory's all-regular status, or true for other factories.
Definition AMReX_FabArray.H:521
Array4< typename FabArray< FAB >::value_type > array(int K) noexcept
Mutable Array4 view for the FAB identified by global index K.
Definition AMReX_FabArray.H:642
FAB * fabPtr(const MFIter &mfi) noexcept
Return pointer to FAB.
Definition AMReX_FabArray.H:2054
void OverrideSync_finish()
Definition AMReX_FabArray.H:3892
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:1125
FAB * release(const MFIter &mfi)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:2168
Array4< typename FabArray< FAB >::value_type const > const_array(const MFIter &mfi, int start_comp) const noexcept
Definition AMReX_FabArray.H:696
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:3432
void capacityOfFabs(LayoutData< I > &mem) const
Accumulate the per-FAB allocation sizes.
Definition AMReX_FabArray.H:2886
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)
FAB & atLocalIdx(int L) noexcept
Return a reference to the FAB associated with local index L.
Definition AMReX_FabArray.H:579
void define(const BoxArray &bxs, const DistributionMapping &dm, int nvar, const IntVect &ngrow, const MFInfo &info=MFInfo(), const FabFactory< FAB > &factory=DefaultFabFactory< FAB >())
Define this FabArray with a per-direction grow vector.
Definition AMReX_FabArray.H:2470
void ParallelCopy_nowait(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Start an asynchronous ParallelCopy that copies every component.
Definition AMReX_FabArray.H:1003
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:2244
Array4< typename FabArray< FAB >::value_type const > const_array(const MFIter &mfi) const noexcept
Synonym for array(const MFIter&) that highlights read-only semantics.
Definition AMReX_FabArray.H:649
const FAB & get(int K) const noexcept
Return a constant reference to the FAB associated with the Kth element.
Definition AMReX_FabArray.H:570
FAB const * fabPtr(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:2064
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)
Start an asynchronous ParallelCopy for a component subset.
Definition AMReX_FabArray.H:1069
bool isDefined() const
Definition AMReX_FabArray.H:2451
value_type const * singleChunkPtr() const noexcept
Definition AMReX_FabArray.H:510
~FabArray()
The destructor – deletes all FABs in the array.
Definition AMReX_FabArray.H:2415
Array4< typename FabArray< FAB >::value_type const > array(const MFIter &mfi, int start_comp) const noexcept
Definition AMReX_FabArray.H:664
Array4< typename FabArray< FAB >::value_type const > const_array(int K, int start_comp) const noexcept
Definition AMReX_FabArray.H:704
F::value_type sum(int comp, IntVect const &nghost, bool local=false) const
Returns the sum of component "comp".
Definition AMReX_FabArray.H:2898
Abstract factory interface for creating, aliasing, and destroying FAB objects.
Definition AMReX_FabFactory.H:73
virtual Long nBytes(const Box &box, int ncomps, int) const
Return the storage size for ncomps components in box, or -1 if unavailable.
Definition AMReX_FabFactory.H:106
virtual FabFactory< FAB > * clone() const =0
Return a heap-allocated copy of this factory.
virtual FAB * create(const Box &box, int ncomps, const FabInfo &info, int box_index) const =0
Create a FAB covering box with ncomps components.
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:75
const Box & Domain() const noexcept
Returns our rectangular domain.
Definition AMReX_Geometry.H:216
bool isPeriodic(int dir) const noexcept
Is the domain periodic in the specified direction?
Definition AMReX_Geometry.H:337
GPU-compatible tuple.
Definition AMReX_Tuple.H:98
__host__ __device__ constexpr bool allGE(const IntVectND< dim > &rhs) const noexcept
Returns true if this is greater than or equal to argument for all components. NOTE: This is NOT a str...
Definition AMReX_IntVect.H:542
__host__ static __device__ constexpr IntVectND< dim > TheZeroVector() noexcept
This static member function returns a reference to a constant IntVectND object, all of whose dim argu...
Definition AMReX_IntVect.H:771
__host__ __device__ constexpr int max() const noexcept
maximum (no absolute values) value
Definition AMReX_IntVect.H:313
__host__ __device__ constexpr bool allLE(const IntVectND< dim > &rhs) const noexcept
Returns true if this is less than or equal to argument for all components. NOTE: This is NOT a strict...
Definition AMReX_IntVect.H:492
a one-thingy-per-box distributed object
Definition AMReX_LayoutData.H:13
Iterator for looping ever tiles and boxes of amrex::FabArray based containers.
Definition AMReX_MFIter.H:88
Box growntilebox(int ng=-1000000) const noexcept
Return the tile box at the current index grown to include ghost cells.
Definition AMReX_MFIter.cpp:476
const DistributionMapping & DistributionMap() const noexcept
Definition AMReX_MFIter.H:197
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:172
Box validbox() const noexcept
Return the valid Box in which the current tile resides.
Definition AMReX_MFIter.H:163
int index() const noexcept
The index into the underlying BoxArray of the current FAB.
Definition AMReX_MFIter.H:175
int LocalIndex() const noexcept
Return local index into the vector of fab pointers, m_fabs_v When AllBoxes is on, local_index_map is ...
Definition AMReX_MFIter.H:190
This provides length of period for periodic domains. 0 means it is not periodic in that direction....
Definition AMReX_Periodicity.H:17
static const Periodicity & NonPeriodic() noexcept
Definition AMReX_Periodicity.cpp:52
bool isAnyPeriodic() const noexcept
Definition AMReX_Periodicity.H:22
bool isPeriodic(int dir) const noexcept
Definition AMReX_Periodicity.H:26
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:29
Long size() const noexcept
Definition AMReX_Vector.H:54
Checks if a type is derived from amrex::BaseFab.
Definition AMReX_Concepts.H:13
amrex_long Long
Definition AMReX_INT.H:30
@ covered
Every cell in the region is covered.
void EnforcePeriodicity(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Definition AMReX_FabArray.H:3995
void SumBoundary(int scomp, int ncomp, const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3907
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:3914
void OverrideSync(const Periodicity &period=Periodicity::NonPeriodic())
Synchronize nodal data.
Definition AMReX_FabArray.H:3855
void FillBoundary(bool cross=false)
Copy on intersection within a FabArray.
Definition AMReX_FabArray.H:3700
void OverrideSync(int scomp, int ncomp, const Periodicity &period)
Synchronize nodal data.
Definition AMReX_FabArray.H:3866
void FillBoundary(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3762
void FillBoundaryAndSync(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Fill ghost cells and synchronize nodal data.
Definition AMReX_FabArray.H:3819
void FillBoundary(const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3712
void FillBoundary(int scomp, int ncomp, bool cross=false)
Definition AMReX_FabArray.H:3738
void FillBoundaryAndSync(const Periodicity &period=Periodicity::NonPeriodic())
Fill ghost cells and synchronize nodal data.
Definition AMReX_FabArray.H:3808
void SumBoundary(const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Sum values in overlapped cells.
Definition AMReX_FabArray.H:3900
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:3921
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:4172
void EnforcePeriodicity(const Periodicity &period)
Fill ghost cells with values from their corresponding cells across periodic boundaries,...
Definition AMReX_FabArray.H:3973
void FillBoundary(int scomp, int ncomp, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3750
void EnforcePeriodicity(int scomp, int ncomp, const Periodicity &period)
Definition AMReX_FabArray.H:3984
__host__ __device__ BoxND< dim > convert(const BoxND< dim > &b, const IntVectND< dim > &typ) noexcept
Return a copy of b converted to the nodal flags typ.
Definition AMReX_Box.H:1630
Arena * The_Comms_Arena()
Definition AMReX_Arena.cpp:880
Arena * The_Pinned_Arena()
Definition AMReX_Arena.cpp:860
Arena * The_Arena()
Definition AMReX_Arena.cpp:820
int MyProc() noexcept
Definition AMReX_ParallelDescriptor.H:128
void Min(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:161
void Sum(Gpu::DeviceVector< T > &v, MPI_Comm comm)
Definition AMReX_GpuParallelReduce.H:34
void Max(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:133
__host__ __device__ constexpr const T & max(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:53
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:310
bool inLaunchRegion() noexcept
Definition AMReX_GpuControl.H:88
bool inNoSyncRegion() noexcept
Definition AMReX_GpuControl.H:148
void htod_memcpy_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:421
MPI_Comm CommunicatorSub() noexcept
sub-communicator for current frame
Definition AMReX_ParallelContext.H:70
int MyTeamLead() noexcept
Definition AMReX_ParallelDescriptor.H:325
int TeamSize() noexcept
Definition AMReX_ParallelDescriptor.H:310
const ProcessTeam & MyTeam() noexcept
Definition AMReX_ParallelDescriptor.H:365
int MPI_Comm
Definition AMReX_ccse-mpi.H:51
Definition AMReX_Amr.cpp:50
MakeType
Definition AMReX_MakeType.H:7
@ make_alias
Definition AMReX_MakeType.H:7
__host__ __device__ void ignore_unused(const Ts &...)
No-op helper that marks variables as intentionally unused.
Definition AMReX.H:259
void FillBoundary_finish(Vector< MF * > const &mf)
Wait for outstanding FillBoundary_nowait operations launched with the vector helper to complete.
Definition AMReX_FabArrayCommI.H:1123
void Copy(FabArray< DFAB > &dst, FabArray< SFAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Definition AMReX_FabArray.H:192
void OverrideSync_nowait(FabArray< FAB > &fa, FabArray< IFAB > const &msk, const Periodicity &period)
Start the masked OverrideSync operation; call OverrideSync_finish() to complete it.
Definition AMReX_FabArrayUtility.H:1659
void Add(FabArray< FAB > &dst, FabArray< FAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Definition AMReX_FabArray.H:251
std::unique_ptr< char, TheFaArenaDeleter > TheFaArenaPointer
Definition AMReX_FabArray.H:118
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
Long nBytesOwned(T const &) noexcept
Definition AMReX_FabArray.H:65
BoxArray const & boxArray(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.boxArray().
Definition AMReX_FabArrayBase.cpp:2862
DistributionMapping const & DistributionMap(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.DistributionMap().
Definition AMReX_FabArrayBase.cpp:2867
void FillBoundaryAndSync_nowait(Vector< MF * > const &mf, Vector< int > const &scomp, Vector< int > const &ncomp, Vector< IntVect > const &nghost, Vector< Periodicity > const &period)
Launch FillBoundaryAndSync_nowait across a vector of FabArrays.
Definition AMReX_FabArrayCommI.H:1146
void ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:202
BoxND< 3 > Box
Box is an alias for amrex::BoxND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:35
bool isMFIterSafe(const FabArrayBase &x, const FabArrayBase &y)
Definition AMReX_MFIter.H:252
int nComp(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.nComp().
Definition AMReX_FabArrayBase.cpp:2852
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
__host__ __device__ T abs(const GpuComplex< T > &a_z) noexcept
Return the absolute value of a complex number.
Definition AMReX_GpuComplex.H:361
void OverrideSync_finish(FabArray< FAB > &fa)
Finish the current masked OverrideSync_nowait() operation.
Definition AMReX_FabArrayUtility.H:1707
IntVect nGrowVect(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.nGrowVect().
Definition AMReX_FabArrayBase.cpp:2857
bool TilingIfNotGPU() noexcept
Definition AMReX_MFIter.H:12
void setBndry(MF &dst, typename MF::value_type val, int scomp, int ncomp)
dst = val in ghost cells.
Definition AMReX_FabArrayUtility.H:2150
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:241
void update_fab_stats(Long n, Long s, size_t szt) noexcept
Definition AMReX_BaseFab.cpp:146
void FillBoundaryAndSync_finish(Vector< MF * > const &mf)
Wait for outstanding FillBoundaryAndSync_nowait operations launched with the vector helper to complet...
Definition AMReX_FabArrayCommI.H:1188
void setVal(MF &dst, typename MF::value_type val)
dst = val
Definition AMReX_FabArrayUtility.H:2143
__host__ __device__ constexpr int get(IntVectND< dim > const &iv) noexcept
Get I'th element of IntVectND<dim>
Definition AMReX_IntVect.H:1334
Definition AMReX_TagParallelFor.H:58
A multidimensional array accessor.
Definition AMReX_Array4.H:288
Lightweight allocator/deallocator backed by an Arena.
Definition AMReX_DataAllocator.H:21
Arena * arena() const noexcept
Return the stored arena, or The_Arena() if none was set.
Definition AMReX_DataAllocator.H:41
Arena * m_arena
Stored arena pointer (may be null).
Definition AMReX_DataAllocator.H:22
Definition AMReX_FabArray.H:122
const FabArrayBase::FB * fb
Definition AMReX_FabArray.H:124
bool deterministic
Definition AMReX_FabArray.H:141
char * the_recv_data
Definition AMReX_FabArray.H:129
Vector< MPI_Request > recv_reqs
Definition AMReX_FabArray.H:134
Vector< char * > recv_data
Definition AMReX_FabArray.H:132
Vector< MPI_Status > recv_stat
Definition AMReX_FabArray.H:135
int scomp
Definition AMReX_FabArray.H:125
Vector< int > recv_from
Definition AMReX_FabArray.H:131
char * the_send_data
Definition AMReX_FabArray.H:130
Vector< MPI_Request > send_reqs
Definition AMReX_FabArray.H:138
Vector< char * > send_data
Definition AMReX_FabArray.H:137
Vector< std::size_t > recv_size
Definition AMReX_FabArray.H:133
int ncomp
Definition AMReX_FabArray.H:126
int tag
Definition AMReX_FabArray.H:139
parallel copy or add
Definition AMReX_FabArrayBase.H:630
Definition AMReX_FabArrayBase.H:542
std::unique_ptr< MapOfCopyComTagContainers > m_RcvTags
Definition AMReX_FabArrayBase.H:548
std::unique_ptr< CopyComTagsContainer > m_LocTags
Definition AMReX_FabArrayBase.H:546
Used by a bunch of routines when communicating via MPI.
Definition AMReX_FabArrayBase.H:211
Box dbox
Definition AMReX_FabArrayBase.H:212
int dstIndex
Definition AMReX_FabArrayBase.H:214
FillBoundary.
Definition AMReX_FabArrayBase.H:567
void recordBuild() noexcept
Definition AMReX_FabArrayBase.H:819
Definition AMReX_FabArray.H:359
FAB value_type
Definition AMReX_FabArray.H:360
for shared memory
Definition AMReX_FabArray.H:1770
ShMem(ShMem &&rhs) noexcept
Definition AMReX_FabArray.H:1784
ShMem() noexcept=default
Long n_values
Definition AMReX_FabArray.H:1811
Long n_points
Definition AMReX_FabArray.H:1812
bool alloc
Definition AMReX_FabArray.H:1810
ShMem & operator=(ShMem &&rhs) noexcept
Definition AMReX_FabArray.H:1795
ShMem(const ShMem &)=delete
FabArray memory allocation information.
Definition AMReX_FabArray.H:73
MFInfo & SetTag(T &&t, Ts &&... ts) noexcept
Append one or more memory-usage tags.
Definition AMReX_FabArray.H:106
MFInfo & SetTag(const std::string &t) noexcept
Append memory-usage tag t.
Definition AMReX_FabArray.H:99
Arena * arena
Definition AMReX_FabArray.H:77
MFInfo & SetArena(Arena *ar) noexcept
Select the Arena used for FAB storage.
Definition AMReX_FabArray.H:87
MFInfo & SetTag() noexcept
Terminate a variadic SetTag() call.
Definition AMReX_FabArray.H:90
bool alloc
Definition AMReX_FabArray.H:75
MFInfo & SetAlloc(bool a) noexcept
Control whether FAB storage is allocated when the FabArray is defined.
Definition AMReX_FabArray.H:81
bool alloc_single_chunk
Definition AMReX_FabArray.H:76
MFInfo & SetAllocSingleChunk(bool a) noexcept
Control whether eligible FABs use one contiguous allocation.
Definition AMReX_FabArray.H:84
Vector< std::string > tags
Definition AMReX_FabArray.H:78
MFInfo & SetTag(const char *t) noexcept
Append memory-usage tag t.
Definition AMReX_FabArray.H:93
Definition AMReX_MFIter.H:20
MFItInfo & DisableDeviceSync() noexcept
Definition AMReX_MFIter.H:47
Definition AMReX_FabArray.H:168
Array4< T > const *__restrict__ hp
Definition AMReX_FabArray.H:184
__host__ __device__ Array4< T > const & operator[](int li) const noexcept
Definition AMReX_FabArray.H:170
Array4< T > const *__restrict__ dp
Definition AMReX_FabArray.H:182
Definition AMReX_FabArray.H:146
int actual_n_rcvs
Definition AMReX_FabArray.H:152
Vector< std::size_t > recv_size
Definition AMReX_FabArray.H:159
int DC
Definition AMReX_FabArray.H:153
Vector< MPI_Request > send_reqs
Definition AMReX_FabArray.H:161
int tag
Definition AMReX_FabArray.H:151
const FabArray< FAB > * src
Definition AMReX_FabArray.H:149
char * the_recv_data
Definition AMReX_FabArray.H:155
FabArrayBase::CpOp op
Definition AMReX_FabArray.H:150
Vector< MPI_Request > recv_reqs
Definition AMReX_FabArray.H:160
char * the_send_data
Definition AMReX_FabArray.H:156
const FabArrayBase::CPC * cpc
Definition AMReX_FabArray.H:148
Vector< int > recv_from
Definition AMReX_FabArray.H:157
bool deterministic
Definition AMReX_FabArray.H:162
int NC
Definition AMReX_FabArray.H:153
int SC
Definition AMReX_FabArray.H:153
Vector< char * > recv_data
Definition AMReX_FabArray.H:158
void MemoryBarrier() const
memory fence
Definition AMReX_ParallelDescriptor.H:161
const team_t & get() const
Definition AMReX_ParallelDescriptor.H:189
Definition AMReX_TagParallelFor.H:156
Definition AMReX_FabArray.H:112
char * pointer
Definition AMReX_FabArray.H:113
void operator()(pointer p) const noexcept
Definition AMReX_FabArray.H:114
Struct for holding types.
Definition AMReX_TypeList.H:13