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
41
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 {
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 Int>
945 requires (BaseFabType<FAB> && (sizeof(Int) >= sizeof(Long)))
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
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
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
1252
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>)
1435
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);
1521 void OverrideSync_nowait (int scomp, int ncomp, const Periodicity& period);
1523
1535 bool deterministic = false);
1537 void SumBoundary (int scomp, int ncomp, const Periodicity& period = Periodicity::NonPeriodic(),
1538 bool deterministic = false);
1540 bool deterministic = false);
1541 void SumBoundary_nowait (int scomp, int ncomp, const Periodicity& period = Periodicity::NonPeriodic(),
1542 bool deterministic = false);
1543
1554 void SumBoundary (int scomp, int ncomp, IntVect const& nghost,
1555 const Periodicity& period = Periodicity::NonPeriodic(),
1556 bool deterministic = false);
1557 void SumBoundary_nowait (int scomp, int ncomp, IntVect const& nghost,
1558 const Periodicity& period = Periodicity::NonPeriodic(),
1559 bool deterministic = false);
1560
1572 void SumBoundary (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost,
1573 const Periodicity& period = Periodicity::NonPeriodic(),
1574 bool deterministic = false);
1575 void SumBoundary_nowait (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost,
1576 const Periodicity& period = Periodicity::NonPeriodic(),
1577 bool deterministic = false);
1579
1590 void EnforcePeriodicity (const Periodicity& period);
1592 void EnforcePeriodicity (int scomp, int ncomp, const Periodicity& period);
1594 void EnforcePeriodicity (int scomp, int ncomp, const IntVect& nghost,
1595 const Periodicity& period);
1596
1597 // covered : ghost cells covered by valid cells of this FabArray
1598 // (including periodically shifted valid cells)
1599 // notcovered: ghost cells not covered by valid cells
1600 // (including ghost cells outside periodic boundaries)
1601 // physbnd : boundary cells outside the domain (excluding periodic boundaries)
1602 // interior : interior cells (i.e., valid cells)
1603 template <class F=FAB>
1604 requires (BaseFabType<F>)
1605 void BuildMask (const Box& phys_domain, const Periodicity& period,
1606 value_type covered, value_type notcovered,
1607 value_type physbnd, value_type interior);
1608
1609 // The following are private functions. But we have to make them public for cuda.
1610
1611 template <typename BUF=value_type, class F=FAB>
1612 requires (BaseFabType<F>)
1613 void FBEP_nowait (int scomp, int ncomp, const IntVect& nghost,
1614 const Periodicity& period, bool cross,
1615 bool enforce_periodicity_only = false,
1616 bool override_sync = false,
1617 IntVect const& sumboundary_src_nghost = IntVect(-1),
1618 bool deterministic = false);
1619
1620 void FB_local_copy_cpu (const FB& TheFB, int scomp, int ncomp);
1621 void FB_local_add_cpu (const FB& TheFB, int scomp, int ncomp);
1622 void PC_local_cpu (const CPC& thecpc, FabArray<FAB> const& src,
1623 int scomp, int dcomp, int ncomp, CpOp op);
1624
1625 template <class F=FAB>
1626 requires (BaseFabType<F>)
1627 void setVal (value_type val, const CommMetaData& thecmd, int scomp, int ncomp);
1628
1629 template <class F=FAB>
1630 requires (BaseFabType<F>)
1632
1633#ifdef AMREX_USE_GPU
1634
1637
1638 void FB_local_copy_gpu (const FB& TheFB, int scomp, int ncomp);
1639 void FB_local_add_gpu (const FB& TheFB, int scomp, int ncomp, bool deterministic);
1640 void PC_local_gpu (const CPC& thecpc, FabArray<FAB> const& src,
1641 int scomp, int dcomp, int ncomp, CpOp op, bool deterministic);
1642
1643 void CMD_local_setVal_gpu (value_type x, const CommMetaData& thecmd, int scomp, int ncomp);
1644 void CMD_remote_setVal_gpu (value_type x, const CommMetaData& thecmd, int scomp, int ncomp);
1645
1646#if defined(__CUDACC__)
1647
1648 void FB_local_copy_cuda_graph_1 (const FB& TheFB, int scomp, int ncomp);
1649 void FB_local_copy_cuda_graph_n (const FB& TheFB, int scomp, int ncomp);
1650
1651#endif
1652#endif
1653
1654#ifdef AMREX_USE_MPI
1655
1656#ifdef AMREX_USE_GPU
1657#if defined(__CUDACC__)
1658
1659 void FB_pack_send_buffer_cuda_graph (const FB& TheFB, int scomp, int ncomp,
1660 Vector<char*>& send_data,
1661 Vector<std::size_t> const& send_size,
1662 Vector<const CopyComTagsContainer*> const& send_cctc);
1663
1664 void FB_unpack_recv_buffer_cuda_graph (const FB& TheFB, int dcomp, int ncomp,
1665 Vector<char*> const& recv_data,
1666 Vector<std::size_t> const& recv_size,
1667 Vector<const CopyComTagsContainer*> const& recv_cctc,
1668 bool is_thread_safe);
1669
1670#endif
1671
1672 template <typename BUF = value_type>
1673 static void pack_send_buffer_gpu (FabArray<FAB> const& src, int scomp, int ncomp,
1674 Vector<char*> const& send_data,
1675 Vector<std::size_t> const& send_size,
1676 Vector<const CopyComTagsContainer*> const& send_cctc,
1677 std::uint64_t id);
1678
1679 template <typename BUF = value_type>
1680 static void unpack_recv_buffer_gpu (FabArray<FAB>& dst, int dcomp, int ncomp,
1681 Vector<char*> const& recv_data,
1682 Vector<std::size_t> const& recv_size,
1683 Vector<const CopyComTagsContainer*> const& recv_cctc,
1684 CpOp op, bool is_thread_safe,
1685 std::uint64_t id, bool deterministic);
1686
1687 template <typename BUF>
1690 Vector<std::size_t> const& recv_size,
1691 Vector<CopyComTagsContainer const*> const& recv_cctc,
1692 int ncomp, std::uint64_t id);
1693
1694 template <typename BUF>
1697 Vector<std::size_t> const& send_size,
1698 Vector<CopyComTagsContainer const*> const& send_cctc,
1699 int ncomp, std::uint64_t id) const;
1700
1701#endif
1702
1703 template <typename BUF = value_type>
1704 static void pack_send_buffer_cpu (FabArray<FAB> const& src, int scomp, int ncomp,
1705 Vector<char*> const& send_data,
1706 Vector<std::size_t> const& send_size,
1707 Vector<const CopyComTagsContainer*> const& send_cctc);
1708
1709 template <typename BUF = value_type>
1710 static void unpack_recv_buffer_cpu (FabArray<FAB>& dst, int dcomp, int ncomp,
1711 Vector<char*> const& recv_data,
1712 Vector<std::size_t> const& recv_size,
1713 Vector<const CopyComTagsContainer*> const& recv_cctc,
1714 CpOp op, bool is_thread_safe);
1715
1716#endif
1717
1730 template <typename F=FAB>
1731 requires (BaseFabType<F>)
1732 typename F::value_type
1733 norminf (int comp, int ncomp, IntVect const& nghost, bool local = false,
1734 [[maybe_unused]] bool ignore_covered = false) const;
1735
1748 template <typename IFAB, typename F=FAB>
1749 requires (BaseFabType<F>)
1750 typename F::value_type
1751 norminf (FabArray<IFAB> const& mask, int comp, int ncomp, IntVect const& nghost,
1752 bool local = false) const;
1753
1754protected:
1755
1756 std::unique_ptr<FabFactory<FAB> > m_factory;
1758 std::unique_ptr<detail::SingleChunkArena> m_single_chunk_arena;
1760
1763
1766
1767 //
1769 std::vector<FAB*> m_fabs_v;
1770
1771#ifdef AMREX_USE_GPU
1772 mutable void* m_dp_arrays = nullptr;
1773#endif
1774 mutable void* m_hp_arrays = nullptr;
1777
1779
1781 struct ShMem {
1782
1783 ShMem () noexcept = default;
1784
1785 ~ShMem () { // NOLINT
1786#if defined(BL_USE_MPI3)
1787 if (win != MPI_WIN_NULL) { MPI_Win_free(&win); }
1788#endif
1789#ifdef BL_USE_TEAM
1790 if (alloc) {
1792 }
1793#endif
1794 }
1795 ShMem (ShMem&& rhs) noexcept
1796 : alloc(rhs.alloc), n_values(rhs.n_values), n_points(rhs.n_points)
1797#if defined(BL_USE_MPI3)
1798 , win(rhs.win)
1799#endif
1800 {
1801 rhs.alloc = false;
1802#if defined(BL_USE_MPI3)
1803 rhs.win = MPI_WIN_NULL;
1804#endif
1805 }
1806 ShMem& operator= (ShMem&& rhs) noexcept {
1807 if (&rhs != this) {
1808 alloc = rhs.alloc;
1809 n_values = rhs.n_values;
1810 n_points = rhs.n_points;
1811 rhs.alloc = false;
1812#if defined(BL_USE_MPI3)
1813 win = rhs.win;
1814 rhs.win = MPI_WIN_NULL;
1815#endif
1816 }
1817 return *this;
1818 }
1819 ShMem (const ShMem&) = delete;
1820 ShMem& operator= (const ShMem&) = delete;
1821 bool alloc{false};
1824#if defined(BL_USE_MPI3)
1825 MPI_Win win = MPI_WIN_NULL;
1826#endif
1827 };
1828 ShMem shmem;
1829
1830 bool SharedMemory () const noexcept { return shmem.alloc; }
1831
1832private:
1833 using Iterator = typename std::vector<FAB*>::iterator;
1834
1835 void AllocFabs (const FabFactory<FAB>& factory, Arena* ar,
1837 bool alloc_single_chunk);
1838
1839 void setFab_assert (int K, FAB const& fab) const;
1840
1841 template <class F=FAB>
1842 requires (BaseFabType<F>)
1843 void build_arrays () const;
1844
1845 void clear_fab_caches ();
1846
1847#ifdef AMREX_USE_GPU
1848 std::map<std::uint64_t,
1849 std::unique_ptr<TagVector<Array4CopyTag<value_type>>>>
1850 m_fb_local_copy_handler;
1851
1852 using RecvSendCopyHandlerKey = std::tuple<std::uint64_t,std::size_t,int>;
1853 std::map<RecvSendCopyHandlerKey,
1854 std::unique_ptr<TagVector<CommRecvBufTag<value_type>>>>
1855 m_recv_copy_handler;
1856 mutable std::map<RecvSendCopyHandlerKey,
1857 std::unique_ptr<TagVector<CommSendBufTag<value_type>>>>
1858 m_send_copy_handler;
1859#endif
1860
1861public:
1862
1863#ifdef BL_USE_MPI
1864
1866 template <typename BUF=value_type>
1867 static void PostRcvs (const MapOfCopyComTagContainers& RcvTags,
1868 char*& the_recv_data,
1869 Vector<char*>& recv_data,
1870 Vector<std::size_t>& recv_size,
1871 Vector<int>& recv_from,
1872 Vector<MPI_Request>& recv_reqs,
1873 int ncomp,
1874 int SeqNum);
1875
1876 template <typename BUF=value_type>
1877 [[nodiscard]]
1878 static TheFaArenaPointer PostRcvs (const MapOfCopyComTagContainers& RcvTags,
1879 Vector<char*>& recv_data,
1880 Vector<std::size_t>& recv_size,
1881 Vector<int>& recv_from,
1882 Vector<MPI_Request>& recv_reqs,
1883 int ncomp,
1884 int SeqNum);
1885
1886 template <typename BUF=value_type>
1887 static void PrepareSendBuffers (const MapOfCopyComTagContainers& SndTags,
1888 char*& the_send_data,
1889 Vector<char*>& send_data,
1890 Vector<std::size_t>& send_size,
1891 Vector<int>& send_rank,
1892 Vector<MPI_Request>& send_reqs,
1894 int ncomp);
1895
1896 template <typename BUF=value_type>
1897 [[nodiscard]]
1898 static TheFaArenaPointer PrepareSendBuffers (const MapOfCopyComTagContainers& SndTags,
1899 Vector<char*>& send_data,
1900 Vector<std::size_t>& send_size,
1901 Vector<int>& send_rank,
1902 Vector<MPI_Request>& send_reqs,
1904 int ncomp);
1905
1906 static void PostSnds (Vector<char*> const& send_data,
1907 Vector<std::size_t> const& send_size,
1908 Vector<int> const& send_rank,
1909 Vector<MPI_Request>& send_reqs,
1910 int SeqNum);
1911#endif
1912
1913 std::unique_ptr<FBData<FAB>> fbd;
1914 std::unique_ptr<PCData<FAB>> pcd;
1915
1916 // Pointer to temporary fab used in non-blocking amrex::OverrideSync
1917 std::unique_ptr< FabArray<FAB> > os_temp;
1918
1930 template <class F=FAB>
1931 requires (BaseFabType<F>)
1932 static void Saxpy (FabArray<FAB>& y, value_type a, FabArray<FAB> const& x,
1933 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1934
1946 template <class F=FAB>
1947 requires (BaseFabType<F>)
1948 static void Xpay (FabArray<FAB>& y, value_type a, FabArray<FAB> const& x,
1949 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1950
1965 template <class F=FAB>
1966 requires (BaseFabType<F>)
1967 static void LinComb (FabArray<FAB>& dst,
1968 value_type a, const FabArray<FAB>& x, int xcomp,
1969 value_type b, const FabArray<FAB>& y, int ycomp,
1970 int dstcomp, int numcomp, const IntVect& nghost);
1971
1985 template <class F=FAB>
1986 requires (BaseFabType<F>)
1987 static void Saxpy_Xpay (FabArray<FAB>& y, value_type a1, FabArray<FAB> const& x1,
1988 value_type a2, FabArray<FAB> const& x2,
1989 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1990
2005 template <class F=FAB>
2006 requires (BaseFabType<F>)
2007 static void Saxpy_Saxpy (FabArray<FAB>& y1, value_type a1, FabArray<FAB> const& x1,
2008 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x2,
2009 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
2010
2024 template <class F=FAB>
2025 requires (BaseFabType<F>)
2027 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x,
2028 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
2029};
2030
2031}
2032
2033#include <AMReX_FabArrayCommI.H>
2034
2035namespace amrex {
2036
2037template <class FAB>
2038bool
2039FabArray<FAB>::defined (int K) const noexcept
2040{
2041 int li = localindex(K);
2042 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != 0) {
2043 return true;
2044 }
2045 else {
2046 return false;
2047 }
2048}
2049
2050template <class FAB>
2051bool
2052FabArray<FAB>::defined (const MFIter& mfi) const noexcept
2053{
2054 int li = mfi.LocalIndex();
2055 if (li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
2056 return true;
2057 }
2058 else {
2059 return false;
2060 }
2061}
2062
2063template <class FAB>
2064FAB*
2065FabArray<FAB>::fabPtr (const MFIter& mfi) noexcept
2066{
2067 AMREX_ASSERT(mfi.LocalIndex() < indexArray.size());
2069 int li = mfi.LocalIndex();
2070 return m_fabs_v[li];
2071}
2072
2073template <class FAB>
2074FAB const*
2075FabArray<FAB>::fabPtr (const MFIter& mfi) const noexcept
2076{
2077 AMREX_ASSERT(mfi.LocalIndex() < indexArray.size());
2079 int li = mfi.LocalIndex();
2080 return m_fabs_v[li];
2081}
2082
2083template <class FAB>
2084FAB*
2086{
2087 int li = localindex(K);
2088 AMREX_ASSERT(li >=0 && li < indexArray.size());
2089 return m_fabs_v[li];
2090}
2091
2092template <class FAB>
2093FAB const*
2094FabArray<FAB>::fabPtr (int K) const noexcept
2095{
2096 int li = localindex(K);
2097 AMREX_ASSERT(li >=0 && li < indexArray.size());
2098 return m_fabs_v[li];
2099}
2100
2101template <class FAB>
2102template <class F>
2103requires (BaseFabType<F>)
2104void
2105FabArray<FAB>::build_arrays () const
2106{
2107 using A = Array4<value_type>;
2108 using AC = Array4<value_type const>;
2109 static_assert(sizeof(A) == sizeof(AC), "sizeof(Array4<T>) != sizeof(Array4<T const>)");
2110 if (!m_hp_arrays && local_size() > 0) {
2111 const int n = local_size();
2112#ifdef AMREX_USE_GPU
2113 m_hp_arrays = (void*)The_Pinned_Arena()->alloc(n*2*sizeof(A));
2114 m_dp_arrays = (void*)The_Arena()->alloc(n*2*sizeof(A));
2115#else
2116 m_hp_arrays = std::malloc(n*2*sizeof(A));
2117#endif
2118 for (int li = 0; li < n; ++li) {
2119 if (m_fabs_v[li]) {
2120 new ((A*)m_hp_arrays+li) A(m_fabs_v[li]->array());
2121 new ((AC*)m_hp_arrays+li+n) AC(m_fabs_v[li]->const_array());
2122 } else {
2123 new ((A*)m_hp_arrays+li) A{};
2124 new ((AC*)m_hp_arrays+li+n) AC{};
2125 }
2126 }
2127 m_arrays.hp = (A*)m_hp_arrays;
2128 m_const_arrays.hp = (AC*)m_hp_arrays + n;
2129#ifdef AMREX_USE_GPU
2130 m_arrays.dp = (A*)m_dp_arrays;
2131 m_const_arrays.dp = (AC*)m_dp_arrays + n;
2132 Gpu::htod_memcpy_async(m_dp_arrays, m_hp_arrays, n*2*sizeof(A));
2133 if (!Gpu::inNoSyncRegion()) {
2135 }
2136#endif
2137 }
2138}
2139
2140template <class FAB>
2141void
2143{
2144#ifdef AMREX_USE_GPU
2145 // The host-to-device copy of the Array4s issued in build_arrays() is
2146 // asynchronous and is not synchronized when we are in a NoSync region.
2147 // Use stream-ordered frees so that the pinned and device buffers are not
2148 // reused before the copy and any kernels using them have completed.
2149 if (m_hp_arrays) {
2152 }
2153 m_dp_arrays = nullptr;
2154#else
2155 std::free(m_hp_arrays);
2156#endif
2157 m_hp_arrays = nullptr;
2158 m_arrays.hp = nullptr;
2159 m_const_arrays.hp = nullptr;
2160}
2161
2162template <class FAB>
2163void
2164FabArray<FAB>::clear_fab_caches ()
2165{
2166 clear_arrays();
2167#ifdef AMREX_USE_GPU
2168 m_fb_local_copy_handler.clear();
2169 m_recv_copy_handler.clear();
2170 m_send_copy_handler.clear();
2171#endif
2172}
2173
2174template <class FAB>
2175[[nodiscard]]
2176FAB*
2178{
2179 const int li = localindex(K);
2180 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
2182 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
2183 if (nbytes > 0) {
2184 for (auto const& t : m_tags) {
2185 updateMemUsage(t, -nbytes, nullptr);
2186 }
2187 }
2188 clear_fab_caches();
2189 return std::exchange(m_fabs_v[li], nullptr);
2190 } else {
2191 return nullptr;
2192 }
2193}
2194
2195template <class FAB>
2196[[nodiscard]]
2197FAB*
2199{
2200 const int li = mfi.LocalIndex();
2201 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
2203 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
2204 if (nbytes > 0) {
2205 for (auto const& t : m_tags) {
2206 updateMemUsage(t, -nbytes, nullptr);
2207 }
2208 }
2209 clear_fab_caches();
2210 return std::exchange(m_fabs_v[li], nullptr);
2211 } else {
2212 return nullptr;
2213 }
2214}
2215
2216template <class FAB>
2217void
2219{
2221 {
2222 define_function_called = false;
2223 clearThisBD();
2224 }
2225
2226 Long nbytes = 0L;
2227 for (auto *x : m_fabs_v) {
2228 if (x) {
2229 nbytes += amrex::nBytesOwned(*x);
2230 m_factory->destroy(x);
2231 }
2232 }
2233 m_fabs_v.clear();
2234 clear_arrays();
2235 m_factory.reset();
2236 m_dallocator.m_arena = nullptr;
2237 // no need to clear the non-blocking fillboundary stuff
2238
2239 if (nbytes > 0) {
2240 for (auto const& t : m_tags) {
2241 updateMemUsage(t, -nbytes, nullptr);
2242 }
2243 }
2244
2246 m_single_chunk_arena.reset();
2247 }
2249
2250 m_tags.clear();
2251
2252#ifdef AMREX_USE_GPU
2253 m_fb_local_copy_handler.clear();
2254 m_recv_copy_handler.clear();
2255 m_send_copy_handler.clear();
2256#endif
2257
2259}
2260
2261template <class FAB>
2262template <BaseFabType SFAB, BaseFabType DFAB>
2263requires (std::is_convertible_v<typename SFAB::value_type, typename DFAB::value_type>)
2264void
2265FabArray<FAB>::LocalCopy (FabArray<SFAB> const& src, int scomp, int dcomp, int ncomp,
2266 IntVect const& nghost)
2267{
2268 amrex::Copy(*this, src, scomp, dcomp, ncomp, nghost);
2269}
2270
2271template <class FAB>
2272template <class F>
2273requires (BaseFabType<F>)
2274void
2275FabArray<FAB>::LocalAdd (FabArray<FAB> const& src, int scomp, int dcomp, int ncomp,
2276 IntVect const& nghost)
2277{
2278 amrex::Add(*this, src, scomp, dcomp, ncomp, nghost);
2279}
2280
2281template <class FAB>
2282template <class F>
2283requires (BaseFabType<F>)
2284void
2286{
2287 setVal(val,0,n_comp,IntVect(nghost));
2288}
2289
2290template <class FAB>
2291template <class F>
2292requires (BaseFabType<F>)
2293void
2295{
2296 setVal(val,0,n_comp,nghost);
2297}
2298
2299template <class FAB>
2300template <class F>
2301requires (BaseFabType<F>)
2302void
2303FabArray<FAB>::setVal (value_type val, const Box& region, int nghost)
2304{
2305 setVal(val,region,0,n_comp,IntVect(nghost));
2306}
2307
2308template <class FAB>
2309template <class F>
2310requires (BaseFabType<F>)
2311void
2312FabArray<FAB>::setVal (value_type val, const Box& region, const IntVect& nghost)
2313{
2314 setVal(val,region,0,n_comp,nghost);
2315}
2316
2317template <class FAB>
2319 : shmem()
2320{
2321 m_FA_stats.recordBuild();
2322}
2323
2324template <class FAB>
2326 : m_dallocator(a),
2327 shmem()
2328{
2329 m_FA_stats.recordBuild();
2330}
2331
2332template <class FAB>
2334 const DistributionMapping& dm,
2335 int nvar,
2336 int ngrow,
2337 const MFInfo& info,
2338 const FabFactory<FAB>& factory)
2339 : FabArray<FAB>(bxs,dm,nvar,IntVect(ngrow),info,factory)
2340{}
2341
2342template <class FAB>
2344 const DistributionMapping& dm,
2345 int nvar,
2346 const IntVect& ngrow,
2347 const MFInfo& info,
2348 const FabFactory<FAB>& factory)
2349 : m_factory(factory.clone()),
2350 shmem()
2351{
2352 m_FA_stats.recordBuild();
2353 define(bxs,dm,nvar,ngrow,info,*m_factory);
2354}
2355
2356template <class FAB>
2357FabArray<FAB>::FabArray (const FabArray<FAB>& rhs, MakeType maketype, int scomp, int ncomp)
2358 : m_factory(rhs.Factory().clone()),
2359 shmem()
2360{
2361 m_FA_stats.recordBuild();
2362 define(rhs.boxArray(), rhs.DistributionMap(), ncomp, rhs.nGrowVect(),
2363 MFInfo().SetAlloc(false), *m_factory);
2364
2365 if (maketype == amrex::make_alias)
2366 {
2367 for (int i = 0, n = indexArray.size(); i < n; ++i) {
2368 auto const& rhsfab = *(rhs.m_fabs_v[i]);
2369 m_fabs_v.push_back(m_factory->create_alias(rhsfab, scomp, ncomp));
2370 }
2371 }
2372 else
2373 {
2374 amrex::Abort("FabArray: unknown MakeType");
2375 }
2376}
2377
2378template <class FAB>
2380 : FabArrayBase (static_cast<FabArrayBase&&>(rhs))
2381 , m_factory (std::move(rhs.m_factory))
2382 , m_dallocator (rhs.m_dallocator)
2383 , m_single_chunk_arena(std::move(rhs.m_single_chunk_arena))
2384 , m_single_chunk_size(std::exchange(rhs.m_single_chunk_size,0))
2385 , define_function_called(rhs.define_function_called)
2386 , m_fabs_v (std::move(rhs.m_fabs_v))
2387#ifdef AMREX_USE_GPU
2388 , m_dp_arrays (std::exchange(rhs.m_dp_arrays, nullptr))
2389#endif
2390 , m_hp_arrays (std::exchange(rhs.m_hp_arrays, nullptr))
2391 , m_arrays (rhs.m_arrays)
2392 , m_const_arrays(rhs.m_const_arrays)
2393 , m_tags (std::move(rhs.m_tags))
2394 , shmem (std::move(rhs.shmem))
2395#ifdef AMREX_USE_GPU
2396 , m_fb_local_copy_handler(std::move(rhs.m_fb_local_copy_handler))
2397 , m_recv_copy_handler(std::move(rhs.m_recv_copy_handler))
2398 , m_send_copy_handler(std::move(rhs.m_send_copy_handler))
2399#endif
2400 // no need to worry about the data used in non-blocking FillBoundary.
2401{
2402 m_FA_stats.recordBuild();
2403 rhs.define_function_called = false; // the responsibility of clear BD has been transferred.
2404 rhs.m_fabs_v.clear(); // clear the data pointers so that rhs.clear does not delete them.
2405 rhs.clear();
2406}
2407
2408template <class FAB>
2411{
2412 if (&rhs != this)
2413 {
2414 clear();
2415
2416 FabArrayBase::operator=(static_cast<FabArrayBase&&>(rhs));
2417 m_factory = std::move(rhs.m_factory);
2418 m_dallocator = rhs.m_dallocator;
2419 m_single_chunk_arena = std::move(rhs.m_single_chunk_arena);
2420 std::swap(m_single_chunk_size, rhs.m_single_chunk_size);
2421 define_function_called = rhs.define_function_called;
2422 std::swap(m_fabs_v, rhs.m_fabs_v);
2423#ifdef AMREX_USE_GPU
2424 std::swap(m_dp_arrays, rhs.m_dp_arrays);
2425#endif
2426 std::swap(m_hp_arrays, rhs.m_hp_arrays);
2427 m_arrays = rhs.m_arrays;
2428 m_const_arrays = rhs.m_const_arrays;
2429 std::swap(m_tags, rhs.m_tags);
2430 shmem = std::move(rhs.shmem);
2431#ifdef AMREX_USE_GPU
2432 std::swap(m_fb_local_copy_handler, rhs.m_fb_local_copy_handler);
2433 std::swap(m_recv_copy_handler, rhs.m_recv_copy_handler);
2434 std::swap(m_send_copy_handler, rhs.m_send_copy_handler);
2435#endif
2436
2437 rhs.define_function_called = false;
2438 rhs.m_fabs_v.clear();
2439 rhs.m_tags.clear();
2440 rhs.clear();
2441 }
2442 return *this;
2443}
2444
2445template <class FAB>
2447{
2448 m_FA_stats.recordDelete();
2449 clear();
2450}
2451
2452template <class FAB>
2453bool
2455{
2456 if (!define_function_called) { return false; }
2457
2458 int isok = 1;
2459
2460 for (MFIter fai(*this); fai.isValid() && isok; ++fai)
2461 {
2462 if (defined(fai))
2463 {
2464 if (get(fai).box() != fabbox(fai.index()))
2465 {
2466 isok = 0;
2467 }
2468 }
2469 else
2470 {
2471 isok = 0;
2472 }
2473 }
2474
2476
2477 return isok == 1;
2478}
2479
2480template <class FAB>
2481bool
2483{
2485}
2486
2487template <class FAB>
2488void
2490 const DistributionMapping& dm,
2491 int nvar,
2492 int ngrow,
2493 const MFInfo& info,
2494 const FabFactory<FAB>& a_factory)
2495{
2496 define(bxs,dm,nvar,IntVect(ngrow),info,a_factory);
2497}
2498
2499template <class FAB>
2500void
2502 const DistributionMapping& dm,
2503 int nvar,
2504 const IntVect& ngrow,
2505 const MFInfo& info,
2506 const FabFactory<FAB>& a_factory)
2507{
2508 std::unique_ptr<FabFactory<FAB> > factory(a_factory.clone());
2509
2510 auto *default_arena = m_dallocator.m_arena;
2511 clear();
2512
2513 m_factory = std::move(factory);
2514 m_dallocator.m_arena = info.arena ? info.arena : default_arena;
2515
2517
2518 AMREX_ASSERT(ngrow.allGE(0));
2519 AMREX_ASSERT(boxarray.empty());
2520 FabArrayBase::define(bxs, dm, nvar, ngrow);
2521
2522 addThisBD();
2523
2524 if(info.alloc) {
2525 AllocFabs(*m_factory, m_dallocator.m_arena, info.tags, info.alloc_single_chunk);
2526#ifdef BL_USE_TEAM
2528#endif
2529 }
2530}
2531
2532template <class FAB>
2533void
2534FabArray<FAB>::AllocFabs (const FabFactory<FAB>& factory, Arena* ar,
2535 const Vector<std::string>& tags, bool alloc_single_chunk)
2536{
2537 if (shmem.alloc) { alloc_single_chunk = false; }
2538 if constexpr (!IsBaseFab_v<FAB>) { alloc_single_chunk = false; }
2539
2540 const int n = indexArray.size();
2541 const int nworkers = ParallelDescriptor::TeamSize();
2542 shmem.alloc = (nworkers > 1);
2543
2544 bool alloc = !shmem.alloc;
2545
2546 FabInfo fab_info;
2547 fab_info.SetAlloc(alloc).SetShared(shmem.alloc).SetArena(ar);
2548
2549 if (alloc_single_chunk) {
2550 m_single_chunk_size = 0L;
2551 for (int i = 0; i < n; ++i) {
2552 int K = indexArray[i];
2553 const Box& tmpbox = fabbox(K);
2554 m_single_chunk_size += factory.nBytes(tmpbox, n_comp, K);
2555 }
2556 AMREX_ASSERT(m_single_chunk_size >= 0); // 0 is okay.
2557 m_single_chunk_arena = std::make_unique<detail::SingleChunkArena>(ar, m_single_chunk_size);
2558 fab_info.SetArena(m_single_chunk_arena.get());
2559 }
2560
2561 m_fabs_v.reserve(n);
2562
2563 Long nbytes = 0L;
2564 for (int i = 0; i < n; ++i)
2565 {
2566 int K = indexArray[i];
2567 const Box& tmpbox = fabbox(K);
2568 m_fabs_v.push_back(factory.create(tmpbox, n_comp, fab_info, K));
2569 nbytes += amrex::nBytesOwned(*m_fabs_v.back());
2570 }
2571
2572 m_tags.clear();
2573 m_tags.emplace_back("All");
2574 for (auto const& t : m_region_tag) {
2575 m_tags.push_back(t);
2576 }
2577 for (auto const& t : tags) {
2578 m_tags.push_back(t);
2579 }
2580 for (auto const& t: m_tags) {
2581 updateMemUsage(t, nbytes, ar);
2582 }
2583
2584#ifdef BL_USE_TEAM
2585 if (shmem.alloc)
2586 {
2587 const int teamlead = ParallelDescriptor::MyTeamLead();
2588
2589 shmem.n_values = 0;
2590 shmem.n_points = 0;
2591 Vector<Long> offset(n,0);
2592 Vector<Long> nextoffset(nworkers,-1);
2593 for (int i = 0; i < n; ++i) {
2594 int K = indexArray[i];
2595 int owner = distributionMap[K] - teamlead;
2596 Long s = m_fabs_v[i]->size();
2597 if (ownership[i]) {
2598 shmem.n_values += s;
2599 shmem.n_points += m_fabs_v[i]->numPts();
2600 }
2601 if (nextoffset[owner] < 0) {
2602 offset[i] = 0;
2603 nextoffset[owner] = s;
2604 } else {
2605 offset[i] = nextoffset[owner];
2606 nextoffset[owner] += s;
2607 }
2608 }
2609
2610 size_t bytes = shmem.n_values*sizeof(value_type);
2611
2612 value_type *mfp;
2614
2615#if defined (BL_USE_MPI3)
2616
2617 static MPI_Info info = MPI_INFO_NULL;
2618 if (info == MPI_INFO_NULL) {
2619 MPI_Info_create(&info);
2620 MPI_Info_set(info, "alloc_shared_noncontig", "true");
2621 }
2622
2623 const MPI_Comm& team_comm = ParallelDescriptor::MyTeam().get();
2624
2625 BL_MPI_REQUIRE( MPI_Win_allocate_shared(bytes, sizeof(value_type),
2626 info, team_comm, &mfp, &shmem.win) );
2627
2628 for (int w = 0; w < nworkers; ++w) {
2629 MPI_Aint sz;
2630 int disp;
2631 value_type *dptr = 0;
2632 BL_MPI_REQUIRE( MPI_Win_shared_query(shmem.win, w, &sz, &disp, &dptr) );
2633 // AMREX_ASSERT(disp == sizeof(value_type));
2634 dps.push_back(dptr);
2635 }
2636
2637#else
2638
2639 amrex::Abort("BaseFab::define: to allocate shared memory, USE_MPI3 must be true");
2640
2641#endif
2642
2643 for (int i = 0; i < n; ++i) {
2644 int K = indexArray[i];
2645 int owner = distributionMap[K] - teamlead;
2646 value_type *p = dps[owner] + offset[i];
2647 m_fabs_v[i]->setPtr(p, m_fabs_v[i]->size());
2648 }
2649
2650 for (Long i = 0; i < shmem.n_values; i++, mfp++) {
2651 new (mfp) value_type;
2652 }
2653
2654 amrex::update_fab_stats(shmem.n_points, shmem.n_values, sizeof(value_type));
2655 }
2656#endif
2657}
2658
2659template <class FAB>
2660void
2661FabArray<FAB>::setFab_assert (int K, FAB const& fab) const
2662{
2663 amrex::ignore_unused(K,fab);
2664 AMREX_ASSERT(n_comp == fab.nComp());
2665 AMREX_ASSERT(!boxarray.empty());
2666 AMREX_ASSERT(fab.box() == fabbox(K));
2667 AMREX_ASSERT(distributionMap[K] == ParallelDescriptor::MyProc());
2668 AMREX_ASSERT(m_single_chunk_arena == nullptr);
2669}
2670
2671template <class FAB>
2672void
2673FabArray<FAB>::setFab (int boxno, std::unique_ptr<FAB> elem)
2674{
2675 if (n_comp == 0) {
2676 n_comp = elem->nComp();
2677 }
2678
2679 setFab_assert(boxno, *elem);
2680
2681 if (m_fabs_v.empty()) {
2682 m_fabs_v.resize(indexArray.size(),nullptr);
2683 }
2684
2685 const int li = localindex(boxno);
2686 if (m_fabs_v[li]) {
2687 m_factory->destroy(m_fabs_v[li]);
2688 }
2689 m_fabs_v[li] = elem.release();
2690 clear_fab_caches();
2691}
2692
2693template <class FAB>
2694template <class F>
2695requires (std::is_move_constructible_v<F>)
2696void
2697FabArray<FAB>::setFab (int boxno, FAB&& elem)
2698{
2699 if (n_comp == 0) {
2700 n_comp = elem.nComp();
2701 }
2702
2703 setFab_assert(boxno, elem);
2704
2705 if (m_fabs_v.empty()) {
2706 m_fabs_v.resize(indexArray.size(),nullptr);
2707 }
2708
2709 const int li = localindex(boxno);
2710 if (m_fabs_v[li]) {
2711 m_factory->destroy(m_fabs_v[li]);
2712 }
2713 m_fabs_v[li] = new FAB(std::move(elem));
2714 clear_fab_caches();
2715}
2716
2717template <class FAB>
2718void
2719FabArray<FAB>::setFab (const MFIter& mfi, std::unique_ptr<FAB> elem)
2720{
2721 if (n_comp == 0) {
2722 n_comp = elem->nComp();
2723 }
2724
2725 setFab_assert(mfi.index(), *elem);
2726
2727 if (m_fabs_v.empty()) {
2728 m_fabs_v.resize(indexArray.size(),nullptr);
2729 }
2730
2731 const int li = mfi.LocalIndex();
2732 if (m_fabs_v[li]) {
2733 m_factory->destroy(m_fabs_v[li]);
2734 }
2735 m_fabs_v[li] = elem.release();
2736 clear_fab_caches();
2737}
2738
2739template <class FAB>
2740template <class F>
2741requires (std::is_move_constructible_v<F>)
2742void
2743FabArray<FAB>::setFab (const MFIter& mfi, FAB&& elem)
2744{
2745 if (n_comp == 0) {
2746 n_comp = elem.nComp();
2747 }
2748
2749 setFab_assert(mfi.index(), elem);
2750
2751 if (m_fabs_v.empty()) {
2752 m_fabs_v.resize(indexArray.size(),nullptr);
2753 }
2754
2755 const int li = mfi.LocalIndex();
2756 if (m_fabs_v[li]) {
2757 m_factory->destroy(m_fabs_v[li]);
2758 }
2759 m_fabs_v[li] = new FAB(std::move(elem));
2760 clear_fab_caches();
2761}
2762
2763template <class FAB>
2764template <class F>
2765requires (BaseFabType<F>)
2766void
2768{
2769 setBndry(val, 0, n_comp);
2770}
2771
2772template <class FAB>
2773template <class F>
2774requires (BaseFabType<F>)
2775void
2777 int strt_comp,
2778 int ncomp)
2779{
2780 if (n_grow.max() > 0)
2781 {
2782#ifdef AMREX_USE_GPU
2783 if (Gpu::inLaunchRegion()) {
2784 bool use_mfparfor = true;
2785 const int nboxes = local_size();
2786 if (nboxes == 1) {
2787 if (boxarray[indexArray[0]].numPts() > Long(65*65*65)) {
2788 use_mfparfor = false;
2789 }
2790 } else {
2791 for (int i = 0; i < nboxes; ++i) {
2792 const Long npts = boxarray[indexArray[i]].numPts();
2793 if (npts >= Long(64*64*64)) {
2794 use_mfparfor = false;
2795 break;
2796 } else if (npts <= Long(17*17*17)) {
2797 break;
2798 }
2799 }
2800 }
2801 const IntVect nghost = n_grow;
2802 if (use_mfparfor) {
2803 auto const& ma = this->arrays();
2804 ParallelFor(*this, nghost,
2805 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2806 {
2807 auto const& a = ma[box_no];
2808 Box vbx(a);
2809 vbx.grow(-nghost);
2810 if (!vbx.contains(i,j,k)) {
2811 for (int n = 0; n < ncomp; ++n) {
2812 a(i,j,k,strt_comp+n) = val;
2813 }
2814 }
2815 });
2816 if (!Gpu::inNoSyncRegion()) {
2818 }
2819 } else {
2820 using Tag = Array4BoxTag<value_type>;
2822 for (MFIter mfi(*this); mfi.isValid(); ++mfi) {
2823 Box const& vbx = mfi.validbox();
2824 auto const& a = this->array(mfi);
2825
2826 Box b;
2827#if (AMREX_SPACEDIM == 3)
2828 if (nghost[2] > 0) {
2829 b = vbx;
2830 b.setRange(2, vbx.smallEnd(2)-nghost[2], nghost[2]);
2831 b.grow(IntVect(nghost[0],nghost[1],0));
2832 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2833 b.shift(2, vbx.length(2)+nghost[2]);
2834 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2835 }
2836#endif
2837#if (AMREX_SPACEDIM >= 2)
2838 if (nghost[1] > 0) {
2839 b = vbx;
2840 b.setRange(1, vbx.smallEnd(1)-nghost[1], nghost[1]);
2841 b.grow(0, nghost[0]);
2842 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2843 b.shift(1, vbx.length(1)+nghost[1]);
2844 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2845 }
2846#endif
2847 if (nghost[0] > 0) {
2848 b = vbx;
2849 b.setRange(0, vbx.smallEnd(0)-nghost[0], nghost[0]);
2850 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2851 b.shift(0, vbx.length(0)+nghost[0]);
2852 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2853 }
2854 }
2855
2856 ParallelFor(tags, ncomp,
2857 [=] AMREX_GPU_DEVICE (int i, int j, int k, int n, Tag const& tag) noexcept
2858 {
2859 tag.dfab(i,j,k,strt_comp+n) = val;
2860 });
2861 }
2862 } else
2863#endif
2864 {
2865#ifdef AMREX_USE_OMP
2866#pragma omp parallel
2867#endif
2868 for (MFIter fai(*this); fai.isValid(); ++fai)
2869 {
2870 get(fai).template setComplement<RunOn::Host>(val, fai.validbox(), strt_comp, ncomp);
2871 }
2872 }
2873 }
2874}
2875
2876template <class FAB>
2877template <class F>
2878requires (BaseFabType<F>)
2879void
2881{
2882 setDomainBndry(val, 0, n_comp, geom);
2883}
2884
2885template <class FAB>
2886template <class F>
2887requires (BaseFabType<F>)
2888void
2890 int strt_comp,
2891 int ncomp,
2892 const Geometry& geom)
2893{
2894 BL_PROFILE("FabArray::setDomainBndry()");
2895
2896 Box domain_box = amrex::convert(geom.Domain(), boxArray().ixType());
2897 for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
2898 if (geom.isPeriodic(idim)) {
2899 int n = domain_box.length(idim);
2900 domain_box.grow(idim, n);
2901 }
2902 }
2903
2904#ifdef AMREX_USE_OMP
2905#pragma omp parallel if (Gpu::notInLaunchRegion())
2906#endif
2907 for (MFIter fai(*this); fai.isValid(); ++fai)
2908 {
2909 const Box& gbx = fai.fabbox();
2910 if (! domain_box.contains(gbx))
2911 {
2912 get(fai).template setComplement<RunOn::Device>(val, domain_box, strt_comp, ncomp);
2913 }
2914 }
2915}
2916
2917template <class FAB>
2918template <std::integral Int>
2919requires (BaseFabType<FAB> && (sizeof(Int) >= sizeof(Long)))
2920void
2922{
2923 AMREX_ASSERT(amrex::isMFIterSafe(*this, mem));
2924 for (MFIter mfi(*this, MFItInfo{}.DisableDeviceSync()); mfi.isValid(); ++mfi) {
2925 mem[mfi] += static_cast<Int>((*this)[mfi].nBytesOwned());
2926 }
2927}
2928
2929template <class FAB>
2930template <class F>
2931requires (BaseFabType<F>)
2932typename F::value_type
2933FabArray<FAB>::sum (int comp, IntVect const& nghost, bool local) const
2934{
2935 BL_PROFILE("FabArray::sum()");
2936
2937 using T = typename FAB::value_type;
2938 auto sm = T(0.0);
2939#ifdef AMREX_USE_GPU
2940 if (Gpu::inLaunchRegion())
2941#endif
2942 {
2943 auto const& ma = this->const_arrays();
2944 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, *this, nghost,
2945 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2946 -> GpuTuple<T>
2947 {
2948 return ma[box_no](i,j,k,comp);
2949 });
2950 }
2951#ifdef AMREX_USE_GPU
2952 else {
2953#ifdef AMREX_USE_OMP
2954#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
2955#endif
2956 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi)
2957 {
2958 Box const& bx = mfi.growntilebox(nghost);
2959 auto const& a = this->const_array(mfi);
2960 auto tmp = T(0.0);
2961 AMREX_LOOP_3D(bx, i, j, k,
2962 {
2963 tmp += a(i,j,k,comp);
2964 });
2965 sm += tmp; // Do it this way so that it does not break regression tests.
2966 }
2967 }
2968#endif
2969
2970 if (!local) {
2972 }
2973
2974 return sm;
2975}
2976
2977template <class FAB>
2978void
2979FabArray<FAB>::copyTo (FAB& dest, int nghost) const
2980{
2981 copyTo(dest, 0, 0, dest.nComp(), nghost);
2982}
2983
2984template <class FAB>
2985template <class F>
2986requires (BaseFabType<F>)
2987void
2989{
2990 setVal(val,0,n_comp,n_grow);
2991}
2992
2993template <class FAB>
2994template <class F>
2995requires (BaseFabType<F>)
2998{
2999 setVal(val);
3000 return *this;
3001}
3002
3003template <class FAB>
3004template <class F>
3005requires (BaseFabType<F>)
3006void
3008 int comp,
3009 int ncomp,
3010 int nghost)
3011{
3012 setVal(val,comp,ncomp,IntVect(nghost));
3013}
3014
3015template <class FAB>
3016template <class F>
3017requires (BaseFabType<F>)
3018void
3020 int comp,
3021 int ncomp,
3022 const IntVect& nghost)
3023{
3024 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
3025 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
3026
3027 BL_PROFILE("FabArray::setVal()");
3028
3029#ifdef AMREX_USE_GPU
3030 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3031 auto const& fa = this->arrays();
3032 ParallelFor(*this, nghost, ncomp,
3033 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3034 {
3035 fa[box_no](i,j,k,n+comp) = val;
3036 });
3037 if (!Gpu::inNoSyncRegion()) {
3039 }
3040 } else
3041#endif
3042 {
3043#ifdef AMREX_USE_OMP
3044#pragma omp parallel if (Gpu::notInLaunchRegion())
3045#endif
3046 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
3047 {
3048 const Box& bx = fai.growntilebox(nghost);
3049 auto fab = this->array(fai);
3050 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3051 {
3052 fab(i,j,k,n+comp) = val;
3053 });
3054 }
3055 }
3056}
3057
3058template <class FAB>
3059template <class F>
3060requires (BaseFabType<F>)
3061void
3063 const Box& region,
3064 int comp,
3065 int ncomp,
3066 int nghost)
3067{
3068 setVal(val,region,comp,ncomp,IntVect(nghost));
3069}
3070
3071template <class FAB>
3072template <class F>
3073requires (BaseFabType<F>)
3074void
3076 const Box& region,
3077 int comp,
3078 int ncomp,
3079 const IntVect& nghost)
3080{
3081 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
3082 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
3083
3084 BL_PROFILE("FabArray::setVal(val,region,comp,ncomp,nghost)");
3085
3086#ifdef AMREX_USE_GPU
3087 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3088 auto const& fa = this->arrays();
3089 ParallelFor(*this, nghost, ncomp,
3090 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3091 {
3092 if (region.contains(i,j,k)) {
3093 fa[box_no](i,j,k,n+comp) = val;
3094 }
3095 });
3096 if (!Gpu::inNoSyncRegion()) {
3098 }
3099 } else
3100#endif
3101 {
3102#ifdef AMREX_USE_OMP
3103 AMREX_ALWAYS_ASSERT(!omp_in_parallel());
3104#pragma omp parallel if (Gpu::notInLaunchRegion())
3105#endif
3106 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
3107 {
3108 Box b = fai.growntilebox(nghost) & region;
3109
3110 if (b.ok()) {
3111 auto fab = this->array(fai);
3112 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( b, ncomp, i, j, k, n,
3113 {
3114 fab(i,j,k,n+comp) = val;
3115 });
3116 }
3117 }
3118 }
3119}
3120
3121template <class FAB>
3122template <class F>
3123requires (BaseFabType<F>)
3124void
3125FabArray<FAB>::abs (int comp, int ncomp, int nghost)
3126{
3127 abs(comp, ncomp, IntVect(nghost));
3128}
3129
3130template <class FAB>
3131template <class F>
3132requires (BaseFabType<F>)
3133void
3134FabArray<FAB>::abs (int comp, int ncomp, const IntVect& nghost)
3135{
3136 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
3137 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
3138 BL_PROFILE("FabArray::abs()");
3139
3140#ifdef AMREX_USE_GPU
3141 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3142 auto const& fa = this->arrays();
3143 ParallelFor(*this, nghost, ncomp,
3144 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3145 {
3146 fa[box_no](i,j,k,n+comp) = std::abs(fa[box_no](i,j,k,n+comp));
3147 });
3148 if (!Gpu::inNoSyncRegion()) {
3150 }
3151 } else
3152#endif
3153 {
3154#ifdef AMREX_USE_OMP
3155#pragma omp parallel if (Gpu::notInLaunchRegion())
3156#endif
3157 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3158 {
3159 const Box& bx = mfi.growntilebox(nghost);
3160 auto fab = this->array(mfi);
3161 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3162 {
3163 fab(i,j,k,n+comp) = std::abs(fab(i,j,k,n+comp));
3164 });
3165 }
3166 }
3167}
3168
3169template <class FAB>
3170template <class F>
3171requires (BaseFabType<F>)
3172void
3173FabArray<FAB>::plus (value_type val, int comp, int num_comp, int nghost)
3174{
3175 BL_PROFILE("FabArray::plus()");
3176
3177#ifdef AMREX_USE_GPU
3178 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3179 auto const& fa = this->arrays();
3180 ParallelFor(*this, IntVect(nghost), num_comp,
3181 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3182 {
3183 fa[box_no](i,j,k,n+comp) += val;
3184 });
3185 if (!Gpu::inNoSyncRegion()) {
3187 }
3188 } else
3189#endif
3190 {
3191#ifdef AMREX_USE_OMP
3192#pragma omp parallel if (Gpu::notInLaunchRegion())
3193#endif
3194 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3195 {
3196 const Box& bx = mfi.growntilebox(nghost);
3197 auto fab = this->array(mfi);
3198 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3199 {
3200 fab(i,j,k,n+comp) += val;
3201 });
3202 }
3203 }
3204}
3205
3206template <class FAB>
3207template <class F>
3208requires (BaseFabType<F>)
3209void
3210FabArray<FAB>::plus (value_type val, const Box& region, int comp, int num_comp, int nghost)
3211{
3212 BL_PROFILE("FabArray::plus(val, region, comp, num_comp, nghost)");
3213
3214#ifdef AMREX_USE_GPU
3215 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3216 auto const& fa = this->arrays();
3217 ParallelFor(*this, IntVect(nghost), num_comp,
3218 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3219 {
3220 if (region.contains(i,j,k)) {
3221 fa[box_no](i,j,k,n+comp) += val;
3222 }
3223 });
3224 if (!Gpu::inNoSyncRegion()) {
3226 }
3227 } else
3228#endif
3229 {
3230#ifdef AMREX_USE_OMP
3231#pragma omp parallel if (Gpu::notInLaunchRegion())
3232#endif
3233 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3234 {
3235 const Box& bx = mfi.growntilebox(nghost) & region;
3236 if (bx.ok()) {
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}
3246
3247template <class FAB>
3248template <class F>
3249requires (BaseFabType<F>)
3250void
3251FabArray<FAB>::mult (value_type val, int comp, int num_comp, int nghost)
3252{
3253 BL_PROFILE("FabArray::mult()");
3254
3255#ifdef AMREX_USE_GPU
3256 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3257 auto const& fa = this->arrays();
3258 ParallelFor(*this, IntVect(nghost), num_comp,
3259 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3260 {
3261 fa[box_no](i,j,k,n+comp) *= val;
3262 });
3263 if (!Gpu::inNoSyncRegion()) {
3265 }
3266 } else
3267#endif
3268 {
3269#ifdef AMREX_USE_OMP
3270#pragma omp parallel if (Gpu::notInLaunchRegion())
3271#endif
3272 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3273 {
3274 const Box& bx = mfi.growntilebox(nghost);
3275 auto fab = this->array(mfi);
3276 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3277 {
3278 fab(i,j,k,n+comp) *= val;
3279 });
3280 }
3281 }
3282}
3283
3284template <class FAB>
3285template <class F>
3286requires (BaseFabType<F>)
3287void
3288FabArray<FAB>::mult (value_type val, const Box& region, int comp, int num_comp, int nghost)
3289{
3290 BL_PROFILE("FabArray::mult(val, region, comp, num_comp, nghost)");
3291
3292#ifdef AMREX_USE_GPU
3293 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3294 auto const& fa = this->arrays();
3295 ParallelFor(*this, IntVect(nghost), num_comp,
3296 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3297 {
3298 if (region.contains(i,j,k)) {
3299 fa[box_no](i,j,k,n+comp) *= val;
3300 }
3301 });
3302 if (!Gpu::inNoSyncRegion()) {
3304 }
3305 } else
3306#endif
3307 {
3308#ifdef AMREX_USE_OMP
3309#pragma omp parallel if (Gpu::notInLaunchRegion())
3310#endif
3311 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3312 {
3313 const Box& bx = mfi.growntilebox(nghost) & region;
3314 if (bx.ok()) {
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) *= val;
3319 });
3320 }
3321 }
3322 }
3323}
3324
3325template <class FAB>
3326template <class F>
3327requires (BaseFabType<F>)
3328void
3329FabArray<FAB>::invert (value_type numerator, int comp, int num_comp, int nghost)
3330{
3331 BL_PROFILE("FabArray::invert()");
3332
3333#ifdef AMREX_USE_GPU
3334 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3335 auto const& fa = this->arrays();
3336 ParallelFor(*this, IntVect(nghost), num_comp,
3337 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3338 {
3339 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
3340 });
3341 if (!Gpu::inNoSyncRegion()) {
3343 }
3344 } else
3345#endif
3346 {
3347#ifdef AMREX_USE_OMP
3348#pragma omp parallel if (Gpu::notInLaunchRegion())
3349#endif
3350 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3351 {
3352 const Box& bx = mfi.growntilebox(nghost);
3353 auto fab = this->array(mfi);
3354 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3355 {
3356 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
3357 });
3358 }
3359 }
3360}
3361
3362template <class FAB>
3363template <class F>
3364requires (BaseFabType<F>)
3365void
3366FabArray<FAB>::invert (value_type numerator, const Box& region, int comp, int num_comp, int nghost)
3367{
3368 BL_PROFILE("FabArray::invert(numerator, region, comp, num_comp, nghost)");
3369
3370#ifdef AMREX_USE_GPU
3371 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3372 auto const& fa = this->arrays();
3373 ParallelFor(*this, IntVect(nghost), num_comp,
3374 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3375 {
3376 if (region.contains(i,j,k)) {
3377 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
3378 }
3379 });
3380 if (!Gpu::inNoSyncRegion()) {
3382 }
3383 } else
3384#endif
3385 {
3386#ifdef AMREX_USE_OMP
3387#pragma omp parallel if (Gpu::notInLaunchRegion())
3388#endif
3389 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3390 {
3391 const Box& bx = mfi.growntilebox(nghost) & region;
3392 if (bx.ok()) {
3393 auto fab = this->array(mfi);
3394 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3395 {
3396 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
3397 });
3398 }
3399 }
3400 }
3401}
3402
3403template <class FAB>
3404void
3406{
3407 clearThisBD(); // The new boxarray will have a different ID.
3408 boxarray.shift(v);
3409 addThisBD();
3410#ifdef AMREX_USE_OMP
3411#pragma omp parallel
3412#endif
3413 for (MFIter fai(*this); fai.isValid(); ++fai)
3414 {
3415 get(fai).shift(v);
3416 }
3417 clear_arrays();
3418}
3419
3420template <class FAB>
3421template <class F>
3422requires (BaseFabType<F>)
3424 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3425{
3426 AMREX_ASSERT(y.boxArray() == x.boxArray());
3427 AMREX_ASSERT(y.distributionMap == x.distributionMap);
3428 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
3429
3430 BL_PROFILE("FabArray::Saxpy()");
3431
3432#ifdef AMREX_USE_GPU
3433 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3434 auto const& yma = y.arrays();
3435 auto const& xma = x.const_arrays();
3436 ParallelFor(y, nghost, ncomp,
3437 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3438 {
3439 yma[box_no](i,j,k,ycomp+n) += a * xma[box_no](i,j,k,xcomp+n);
3440 });
3441 if (!Gpu::inNoSyncRegion()) {
3443 }
3444 } else
3445#endif
3446 {
3447#ifdef AMREX_USE_OMP
3448#pragma omp parallel if (Gpu::notInLaunchRegion())
3449#endif
3450 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3451 {
3452 const Box& bx = mfi.growntilebox(nghost);
3453
3454 if (bx.ok()) {
3455 auto const& xfab = x.const_array(mfi);
3456 auto const& yfab = y.array(mfi);
3457 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3458 {
3459 yfab(i,j,k,ycomp+n) += a * xfab(i,j,k,xcomp+n);
3460 });
3461 }
3462 }
3463 }
3464}
3465
3466template <class FAB>
3467template <class F>
3468requires (BaseFabType<F>)
3469void
3471 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3472{
3473 AMREX_ASSERT(y.boxArray() == x.boxArray());
3474 AMREX_ASSERT(y.distributionMap == x.distributionMap);
3475 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
3476
3477 BL_PROFILE("FabArray::Xpay()");
3478
3479#ifdef AMREX_USE_GPU
3480 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3481 auto const& yfa = y.arrays();
3482 auto const& xfa = x.const_arrays();
3483 ParallelFor(y, nghost, ncomp,
3484 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3485 {
3486 yfa[box_no](i,j,k,n+ycomp) = xfa[box_no](i,j,k,n+xcomp)
3487 + a * yfa[box_no](i,j,k,n+ycomp);
3488 });
3489 if (!Gpu::inNoSyncRegion()) {
3491 }
3492 } else
3493#endif
3494 {
3495#ifdef AMREX_USE_OMP
3496#pragma omp parallel if (Gpu::notInLaunchRegion())
3497#endif
3498 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3499 {
3500 const Box& bx = mfi.growntilebox(nghost);
3501 auto const& xFab = x.const_array(mfi);
3502 auto const& yFab = y.array(mfi);
3503 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3504 {
3505 yFab(i,j,k,n+ycomp) = xFab(i,j,k,n+xcomp)
3506 + a * yFab(i,j,k,n+ycomp);
3507 });
3508 }
3509 }
3510}
3511
3512template <class FAB>
3513template <class F>
3514requires (BaseFabType<F>)
3516 value_type a2, FabArray<FAB> const& x2,
3517 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3518{
3519 AMREX_ASSERT(y.boxArray() == x1.boxArray() &&
3520 y.boxArray() == x2.boxArray() &&
3521 y.distributionMap == x1.distributionMap &&
3522 y.distributionMap == x2.distributionMap &&
3523 y.nGrowVect().allGE(nghost) &&
3524 x1.nGrowVect().allGE(nghost) &&
3525 x2.nGrowVect().allGE(nghost));
3526
3527 BL_PROFILE("FabArray::Saxpy_Xpay()");
3528
3529#ifdef AMREX_USE_GPU
3530 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3531 auto const& yma = y.arrays();
3532 auto const& xma1 = x1.const_arrays();
3533 auto const& xma2 = x2.const_arrays();
3534 ParallelFor(y, nghost, ncomp,
3535 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3536 {
3537 yma[box_no](i,j,k,ycomp+n) = xma2[box_no](i,j,k,xcomp+n)
3538 + a2 * (yma [box_no](i,j,k,ycomp+n)
3539 + a1 * xma1[box_no](i,j,k,xcomp+n));
3540 });
3541 if (!Gpu::inNoSyncRegion()) {
3543 }
3544 } else
3545#endif
3546 {
3547#ifdef AMREX_USE_OMP
3548#pragma omp parallel if (Gpu::notInLaunchRegion())
3549#endif
3550 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3551 {
3552 const Box& bx = mfi.growntilebox(nghost);
3553
3554 if (bx.ok()) {
3555 auto const& xfab1 = x1.const_array(mfi);
3556 auto const& xfab2 = x2.const_array(mfi);
3557 auto const& yfab = y.array(mfi);
3558 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3559 {
3560 yfab(i,j,k,ycomp+n) = xfab2(i,j,k,xcomp+n)
3561 + a2 * (yfab (i,j,k,ycomp+n)
3562 + a1 * xfab1(i,j,k,xcomp+n));
3563 });
3564 }
3565 }
3566 }
3567}
3568
3569template <class FAB>
3570template <class F>
3571requires (BaseFabType<F>)
3573 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x2,
3574 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3575{
3576 AMREX_ASSERT(y1.boxArray() == y2.boxArray() &&
3577 y1.boxArray() == x1.boxArray() &&
3578 y1.boxArray() == x2.boxArray() &&
3582 y1.nGrowVect().allGE(nghost) &&
3583 y2.nGrowVect().allGE(nghost) &&
3584 x1.nGrowVect().allGE(nghost) &&
3585 x2.nGrowVect().allGE(nghost));
3586
3587 BL_PROFILE("FabArray::Saxpy_Saxpy()");
3588
3589#ifdef AMREX_USE_GPU
3590 if (Gpu::inLaunchRegion() && y1.isFusingCandidate()) {
3591 auto const& y1ma = y1.arrays();
3592 auto const& x1ma = x1.const_arrays();
3593 auto const& y2ma = y2.arrays();
3594 auto const& x2ma = x2.const_arrays();
3595 ParallelFor(y1, nghost, ncomp,
3596 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3597 {
3598 y1ma[box_no](i,j,k,ycomp+n) += a1 * x1ma[box_no](i,j,k,xcomp+n);
3599 y2ma[box_no](i,j,k,ycomp+n) += a2 * x2ma[box_no](i,j,k,xcomp+n);
3600 });
3601 if (!Gpu::inNoSyncRegion()) {
3603 }
3604 } else
3605#endif
3606 {
3607#ifdef AMREX_USE_OMP
3608#pragma omp parallel if (Gpu::notInLaunchRegion())
3609#endif
3610 for (MFIter mfi(y1,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3611 {
3612 const Box& bx = mfi.growntilebox(nghost);
3613
3614 if (bx.ok()) {
3615 auto const& x1fab = x1.const_array(mfi);
3616 auto const& y1fab = y1.array(mfi);
3617 auto const& x2fab = x2.const_array(mfi);
3618 auto const& y2fab = y2.array(mfi);
3619 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3620 {
3621 y1fab(i,j,k,ycomp+n) += a1 * x1fab(i,j,k,xcomp+n);
3622 y2fab(i,j,k,ycomp+n) += a2 * x2fab(i,j,k,xcomp+n);
3623 });
3624 }
3625 }
3626 }
3627}
3628
3629template <class FAB>
3630template <class F>
3631requires (BaseFabType<F>)
3633 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x,
3634 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3635{
3636 AMREX_ASSERT(y1.boxArray() == y2.boxArray() &&
3637 y1.boxArray() == x.boxArray() &&
3639 y1.distributionMap == x.distributionMap &&
3640 y1.nGrowVect().allGE(nghost) &&
3641 y2.nGrowVect().allGE(nghost) &&
3642 x.nGrowVect().allGE(nghost));
3643
3644 BL_PROFILE("FabArray::Saypy_Saxpy()");
3645
3646#ifdef AMREX_USE_GPU
3647 if (Gpu::inLaunchRegion() && y1.isFusingCandidate()) {
3648 auto const& y1ma = y1.arrays();
3649 auto const& y2ma = y2.arrays();
3650 auto const& xma = x.const_arrays();
3651 ParallelFor(y1, nghost, ncomp,
3652 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3653 {
3654 y1ma[box_no](i,j,k,ycomp+n) += a1 * y2ma[box_no](i,j,k,ycomp+n);
3655 y2ma[box_no](i,j,k,ycomp+n) += a2 * xma[box_no](i,j,k,xcomp+n);
3656 });
3657 if (!Gpu::inNoSyncRegion()) {
3659 }
3660 } else
3661#endif
3662 {
3663#ifdef AMREX_USE_OMP
3664#pragma omp parallel if (Gpu::notInLaunchRegion())
3665#endif
3666 for (MFIter mfi(y1,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3667 {
3668 const Box& bx = mfi.growntilebox(nghost);
3669
3670 if (bx.ok()) {
3671 auto const& xfab = x.const_array(mfi);
3672 auto const& y1fab = y1.array(mfi);
3673 auto const& y2fab = y2.array(mfi);
3674 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3675 {
3676 y1fab(i,j,k,ycomp+n) += a1 * y2fab(i,j,k,ycomp+n);
3677 y2fab(i,j,k,ycomp+n) += a2 * xfab(i,j,k,xcomp+n);
3678 });
3679 }
3680 }
3681 }
3682}
3683
3684template <class FAB>
3685template <class F>
3686requires (BaseFabType<F>)
3687void
3689 value_type a, const FabArray<FAB>& x, int xcomp,
3690 value_type b, const FabArray<FAB>& y, int ycomp,
3691 int dstcomp, int numcomp, const IntVect& nghost)
3692{
3693 AMREX_ASSERT(dst.boxArray() == x.boxArray());
3694 AMREX_ASSERT(dst.distributionMap == x.distributionMap);
3695 AMREX_ASSERT(dst.boxArray() == y.boxArray());
3696 AMREX_ASSERT(dst.distributionMap == y.distributionMap);
3697 AMREX_ASSERT(dst.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost) && y.nGrowVect().allGE(nghost));
3698
3699 BL_PROFILE("FabArray::LinComb()");
3700
3701#ifdef AMREX_USE_GPU
3702 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
3703 auto const& dstma = dst.arrays();
3704 auto const& xma = x.const_arrays();
3705 auto const& yma = y.const_arrays();
3706 ParallelFor(dst, nghost, numcomp,
3707 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3708 {
3709 dstma[box_no](i,j,k,dstcomp+n) = a*xma[box_no](i,j,k,xcomp+n)
3710 + b*yma[box_no](i,j,k,ycomp+n);
3711 });
3712 if (!Gpu::inNoSyncRegion()) {
3714 }
3715 } else
3716#endif
3717 {
3718#ifdef AMREX_USE_OMP
3719#pragma omp parallel if (Gpu::notInLaunchRegion())
3720#endif
3721 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3722 {
3723 const Box& bx = mfi.growntilebox(nghost);
3724 auto const& xfab = x.const_array(mfi);
3725 auto const& yfab = y.const_array(mfi);
3726 auto const& dfab = dst.array(mfi);
3727 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
3728 {
3729 dfab(i,j,k,dstcomp+n) = a*xfab(i,j,k,xcomp+n) + b*yfab(i,j,k,ycomp+n);
3730 });
3731 }
3732 }
3733}
3734
3735template <class FAB>
3736template <typename BUF>
3737void
3739{
3740 BL_PROFILE("FabArray::FillBoundary()");
3741 if ( n_grow.max() > 0 ) {
3744 }
3745}
3746
3747template <class FAB>
3748template <typename BUF>
3749void
3750FabArray<FAB>::FillBoundary (const Periodicity& period, bool cross)
3751{
3752 BL_PROFILE("FabArray::FillBoundary()");
3753 if ( n_grow.max() > 0 ) {
3754 FillBoundary_nowait<BUF>(0, nComp(), n_grow, period, cross);
3756 }
3757}
3758
3759template <class FAB>
3760template <typename BUF>
3761void
3762FabArray<FAB>::FillBoundary (const IntVect& nghost, const Periodicity& period, bool cross)
3763{
3764 BL_PROFILE("FabArray::FillBoundary()");
3766 "FillBoundary: asked to fill more ghost cells than we have");
3767 if ( nghost.max() > 0 ) {
3768 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3770 }
3771}
3772
3773template <class FAB>
3774template <typename BUF>
3775void
3776FabArray<FAB>::FillBoundary (int scomp, int ncomp, bool cross)
3777{
3778 BL_PROFILE("FabArray::FillBoundary()");
3779 if ( n_grow.max() > 0 ) {
3782 }
3783}
3784
3785template <class FAB>
3786template <typename BUF>
3787void
3788FabArray<FAB>::FillBoundary (int scomp, int ncomp, const Periodicity& period, bool cross)
3789{
3790 BL_PROFILE("FabArray::FillBoundary()");
3791 if ( n_grow.max() > 0 ) {
3792 FillBoundary_nowait<BUF>(scomp, ncomp, n_grow, period, cross);
3794 }
3795}
3796
3797template <class FAB>
3798template <typename BUF>
3799void
3800FabArray<FAB>::FillBoundary (int scomp, int ncomp, const IntVect& nghost,
3801 const Periodicity& period, bool cross)
3802{
3803 BL_PROFILE("FabArray::FillBoundary()");
3805 "FillBoundary: asked to fill more ghost cells than we have");
3806 if ( nghost.max() > 0 ) {
3807 FillBoundary_nowait<BUF>(scomp, ncomp, nghost, period, cross);
3809 }
3810}
3811
3812template <class FAB>
3813template <typename BUF>
3814void
3819
3820template <class FAB>
3821template <typename BUF>
3822void
3824{
3825 FillBoundary_nowait<BUF>(0, nComp(), nGrowVect(), period, cross);
3826}
3827
3828template <class FAB>
3829template <typename BUF>
3830void
3831FabArray<FAB>::FillBoundary_nowait (const IntVect& nghost, const Periodicity& period, bool cross)
3832{
3833 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3834}
3835
3836template <class FAB>
3837template <typename BUF>
3838void
3839FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, bool cross)
3840{
3842}
3843
3844template <class FAB>
3845void
3847{
3848 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3849 if (n_grow.max() > 0 || !is_cell_centered()) {
3852 }
3853}
3854
3855template <class FAB>
3856void
3857FabArray<FAB>::FillBoundaryAndSync (int scomp, int ncomp, const IntVect& nghost,
3858 const Periodicity& period)
3859{
3860 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3861 if (nghost.max() > 0 || !is_cell_centered()) {
3862 FillBoundaryAndSync_nowait(scomp, ncomp, nghost, period);
3864 }
3865}
3866
3867template <class FAB>
3868void
3873
3874template <class FAB>
3875void
3876FabArray<FAB>::FillBoundaryAndSync_nowait (int scomp, int ncomp, const IntVect& nghost,
3877 const Periodicity& period)
3878{
3879 BL_PROFILE("FillBoundaryAndSync_nowait()");
3880 FBEP_nowait(scomp, ncomp, nghost, period, false, false, true);
3881}
3882
3883template <class FAB>
3884void
3886{
3887 BL_PROFILE("FillBoundaryAndSync_finish()");
3889}
3890
3891template <class FAB>
3892void
3894{
3895 BL_PROFILE("FAbArray::OverrideSync()");
3896 if (!is_cell_centered()) {
3897 OverrideSync_nowait(0, nComp(), period);
3899 }
3900}
3901
3902template <class FAB>
3903void
3904FabArray<FAB>::OverrideSync (int scomp, int ncomp, const Periodicity& period)
3905{
3906 BL_PROFILE("FAbArray::OverrideSync()");
3907 if (!is_cell_centered()) {
3908 OverrideSync_nowait(scomp, ncomp, period);
3910 }
3911}
3912
3913template <class FAB>
3914void
3916{
3917 OverrideSync_nowait(0, nComp(), period);
3918}
3919
3920template <class FAB>
3921void
3922FabArray<FAB>::OverrideSync_nowait (int scomp, int ncomp, const Periodicity& period)
3923{
3924 BL_PROFILE("OverrideSync_nowait()");
3925 FBEP_nowait(scomp, ncomp, IntVect(0), period, false, false, true);
3926}
3927
3928template <class FAB>
3929void
3931{
3932 BL_PROFILE("OverrideSync_finish()");
3934}
3935
3936template <class FAB>
3937void
3938FabArray<FAB>::SumBoundary (const Periodicity& period, bool deterministic)
3939{
3940 SumBoundary(0, n_comp, IntVect(0), period, deterministic);
3941}
3942
3943template <class FAB>
3944void
3945FabArray<FAB>::SumBoundary (int scomp, int ncomp, const Periodicity& period, bool deterministic)
3946{
3947 SumBoundary(scomp, ncomp, IntVect(0), period, deterministic);
3948}
3949
3950template <class FAB>
3951void
3952FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period, bool deterministic)
3953{
3954 SumBoundary(scomp, ncomp, this->nGrowVect(), nghost, period, deterministic);
3955}
3956
3957template <class FAB>
3958void
3959FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period, bool deterministic)
3960{
3961 BL_PROFILE("FabArray<FAB>::SumBoundary()");
3962
3963 SumBoundary_nowait(scomp, ncomp, src_nghost, dst_nghost, period, deterministic);
3965}
3966
3967template <class FAB>
3968void
3969FabArray<FAB>::SumBoundary_nowait (const Periodicity& period, bool deterministic)
3970{
3971 SumBoundary_nowait(0, n_comp, IntVect(0), period, deterministic);
3972}
3973
3974template <class FAB>
3975void
3976FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool deterministic)
3977{
3978 SumBoundary_nowait(scomp, ncomp, IntVect(0), period, deterministic);
3979}
3980
3981template <class FAB>
3982void
3983FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period, bool deterministic)
3984{
3985 SumBoundary_nowait(scomp, ncomp, this->nGrowVect(), nghost, period, deterministic);
3986}
3987
3988template <class FAB>
3989void
3990FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period, bool deterministic)
3991{
3992 BL_PROFILE("FabArray<FAB>::SumBoundary_nowait()");
3993
3994 if ( n_grow == IntVect::TheZeroVector() && boxArray().ixType().cellCentered()) { return; }
3995
3996 AMREX_ALWAYS_ASSERT(src_nghost.allLE(n_grow) && dst_nghost.allLE(n_grow));
3997
3998 FBEP_nowait(scomp, ncomp, dst_nghost, period, false, false, false, src_nghost, deterministic);
3999}
4000
4001template <class FAB>
4002void
4004{
4005 BL_PROFILE("FabArray<FAB>::SumBoundary_finish()");
4007}
4008
4009template <class FAB>
4010void
4012{
4013 BL_PROFILE("FabArray::EnforcePeriodicity");
4014 if (period.isAnyPeriodic()) {
4015 FBEP_nowait(0, nComp(), nGrowVect(), period, false, true);
4016 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
4017 }
4018}
4019
4020template <class FAB>
4021void
4022FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const Periodicity& period)
4023{
4024 BL_PROFILE("FabArray::EnforcePeriodicity");
4025 if (period.isAnyPeriodic()) {
4026 FBEP_nowait(scomp, ncomp, nGrowVect(), period, false, true);
4027 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
4028 }
4029}
4030
4031template <class FAB>
4032void
4033FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const IntVect& nghost,
4034 const Periodicity& period)
4035{
4036 BL_PROFILE("FabArray::EnforcePeriodicity");
4037 if (period.isAnyPeriodic()) {
4038 FBEP_nowait(scomp, ncomp, nghost, period, false, true);
4039 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
4040 }
4041}
4042
4043template <class FAB>
4044template <typename BUF>
4045void
4046FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool cross)
4047{
4048 FBEP_nowait<BUF>(scomp, ncomp, nGrowVect(), period, cross);
4049}
4050
4051template <class FAB>
4052template <typename BUF>
4053void
4054FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const IntVect& nghost,
4055 const Periodicity& period, bool cross)
4056{
4057 FBEP_nowait<BUF>(scomp, ncomp, nghost, period, cross);
4058}
4059
4060template <class FAB>
4061template <class F>
4062requires (BaseFabType<F>)
4063void
4064FabArray<FAB>::BuildMask (const Box& phys_domain, const Periodicity& period,
4065 value_type covered, value_type notcovered,
4067{
4068 BL_PROFILE("FabArray::BuildMask()");
4069
4070 int ncomp = this->nComp();
4071 const IntVect& ngrow = this->nGrowVect();
4072
4073 Box domain = amrex::convert(phys_domain, boxArray().ixType());
4074 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
4075 if (period.isPeriodic(i)) {
4076 domain.grow(i, ngrow[i]);
4077 }
4078 }
4079
4080#ifdef AMREX_USE_GPU
4081 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
4082 auto const& fa = this->arrays();
4083 ParallelFor(*this, ngrow, ncomp,
4084 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
4085 {
4086 auto const& fab = fa[box_no];
4087 Box vbx(fab);
4088 vbx.grow(-ngrow);
4089 if (vbx.contains(i,j,k)) {
4090 fab(i,j,k,n) = interior;
4091 } else if (domain.contains(i,j,k)) {
4092 fab(i,j,k,n) = notcovered;
4093 } else {
4094 fab(i,j,k,n) = physbnd;
4095 }
4096 });
4097 if (!Gpu::inNoSyncRegion()) {
4099 }
4100 } else
4101#endif
4102 {
4103#ifdef AMREX_USE_OMP
4104#pragma omp parallel if (Gpu::notInLaunchRegion())
4105#endif
4106 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
4107 {
4108 auto const& fab = this->array(mfi);
4109 Box const& fbx = mfi.growntilebox();
4110 Box const& gbx = fbx & domain;
4111 Box const& vbx = mfi.validbox();
4112 AMREX_HOST_DEVICE_FOR_4D(fbx, ncomp, i, j, k, n,
4113 {
4114 if (vbx.contains(i,j,k)) {
4115 fab(i,j,k,n) = interior;
4116 } else if (gbx.contains(i,j,k)) {
4117 fab(i,j,k,n) = notcovered;
4118 } else {
4119 fab(i,j,k,n) = physbnd;
4120 }
4121 });
4122 }
4123 }
4124
4125 const FabArrayBase::FB& TheFB = this->getFB(ngrow,period);
4126 setVal(covered, TheFB, 0, ncomp);
4127}
4128
4129template <class FAB>
4130template <class F>
4131requires (BaseFabType<F>)
4132void
4133FabArray<FAB>::setVal (value_type val, const CommMetaData& thecmd, int scomp, int ncomp)
4134{
4135 BL_PROFILE("FabArray::setVal(val, thecmd, scomp, ncomp)");
4136
4137#ifdef AMREX_USE_GPU
4138 if (Gpu::inLaunchRegion())
4139 {
4140 CMD_local_setVal_gpu(val, thecmd, scomp, ncomp);
4141 CMD_remote_setVal_gpu(val, thecmd, scomp, ncomp);
4142 }
4143 else
4144#endif
4145 {
4146 AMREX_ASSERT(thecmd.m_LocTags && thecmd.m_RcvTags);
4147 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
4148 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
4149 auto N_locs = static_cast<int>(LocTags.size());
4150#ifdef AMREX_USE_OMP
4151#pragma omp parallel for if (thecmd.m_threadsafe_loc)
4152#endif
4153 for (int i = 0; i < N_locs; ++i) {
4154 const CopyComTag& tag = LocTags[i];
4155 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
4156 }
4157
4158 for (const auto & RcvTag : RcvTags) {
4159 auto N = static_cast<int>(RcvTag.second.size());
4160#ifdef AMREX_USE_OMP
4161#pragma omp parallel for if (thecmd.m_threadsafe_rcv)
4162#endif
4163 for (int i = 0; i < N; ++i) {
4164 const CopyComTag& tag = RcvTag.second[i];
4165 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
4166 }
4167 }
4168 }
4169}
4170
4171template <class FAB>
4172template <class F>
4173requires (BaseFabType<F>)
4176{
4177 BL_PROFILE("FabArray::RecvLayoutMask()");
4178
4179 LayoutData<int> r(this->boxArray(), this->DistributionMap());
4180#ifdef AMREX_USE_OMP
4181#pragma omp parallel if (thecmd.m_threadsafe_rcv)
4182#endif
4183 for (MFIter mfi(r); mfi.isValid(); ++mfi) {
4184 r[mfi] = 0;
4185 }
4186
4187 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
4188 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
4189
4190 auto N_locs = static_cast<int>(LocTags.size());
4191 for (int i = 0; i < N_locs; ++i) {
4192 const CopyComTag& tag = LocTags[i];
4193 r[tag.dstIndex] = 1;
4194 }
4195
4196 for (const auto & RcvTag : RcvTags) {
4197 auto N = static_cast<int>(RcvTag.second.size());
4198 for (int i = 0; i < N; ++i) {
4199 const CopyComTag& tag = RcvTag.second[i];
4200 r[tag.dstIndex] = 1;
4201 }
4202 }
4203 return r;
4204}
4205
4206template <class FAB>
4207template <typename F>
4208requires (BaseFabType<F>)
4209typename F::value_type
4210FabArray<FAB>::norminf (int comp, int ncomp, IntVect const& nghost, bool local,
4211 [[maybe_unused]] bool ignore_covered) const
4212{
4213 BL_PROFILE("FabArray::norminf()");
4214
4215 using RT = typename F::value_type;
4216
4217 auto nm0 = RT(0.0);
4218 Math::detail::AbsNanToInf<RT> const absinf{};
4219
4220#ifdef AMREX_USE_EB
4221 if ( this->is_cell_centered() && this->hasEBFabFactory() && ignore_covered )
4222 {
4223 const auto& ebfactory = dynamic_cast<EBFArrayBoxFactory const&>(this->Factory());
4224 auto const& flags = ebfactory.getMultiEBCellFlagFab();
4225#ifdef AMREX_USE_GPU
4226 if (Gpu::inLaunchRegion())
4227#endif
4228 {
4229 auto const& flagsma = flags.const_arrays();
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#ifdef AMREX_USE_GPU
4235 return flagsma[box_no](i,j,k).isCovered() ? RT(0.0) : absinf(ma[box_no](i,j,k,comp+n));
4236#else // unconditional load so that the loop vectorizes; zero covered
4237 // values before any arithmetic
4238 RT v = ma[box_no](i,j,k,comp+n);
4239 v = flagsma[box_no](i,j,k).isCovered() ? RT(0.0) : v;
4240 return absinf(v);
4241#endif
4242 });
4243 }
4244#ifdef AMREX_USE_GPU
4245 else {
4246#ifdef AMREX_USE_OMP
4247#pragma omp parallel reduction(max:nm0)
4248#endif
4249 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
4250 Box const& bx = mfi.growntilebox(nghost);
4251 if (flags[mfi].getType(bx) != FabType::covered) {
4252 auto const& flag = flags.const_array(mfi);
4253 auto const& a = this->const_array(mfi);
4254 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
4255 {
4256 if (!flag(i,j,k).isCovered()) {
4257 nm0 = std::max(nm0, absinf(a(i,j,k,comp+n)));
4258 }
4259 });
4260 }
4261 }
4262 }
4263#endif
4264 }
4265 else
4266#endif
4267 {
4268#ifdef AMREX_USE_GPU
4269 if (Gpu::inLaunchRegion())
4270#endif
4271 {
4272 auto const& ma = this->const_arrays();
4273 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost, ncomp,
4274 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept -> GpuTuple<RT>
4275 {
4276 return absinf(ma[box_no](i,j,k,comp+n));
4277 });
4278 }
4279#ifdef AMREX_USE_GPU
4280 else {
4281#ifdef AMREX_USE_OMP
4282#pragma omp parallel reduction(max:nm0)
4283#endif
4284 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
4285 Box const& bx = mfi.growntilebox(nghost);
4286 auto const& a = this->const_array(mfi);
4287 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
4288 {
4289 nm0 = std::max(nm0, absinf(a(i,j,k,comp+n)));
4290 });
4291 }
4292 }
4293#endif
4294 }
4295
4296 nm0 = std::max(nm0, RT(0.0)); // ParReduce returns lowest() if this rank has no boxes
4297
4298 if (!local) {
4300 }
4301
4302 return nm0;
4303}
4304
4305template <class FAB>
4306template <typename IFAB, typename F>
4307requires (BaseFabType<F>)
4308typename F::value_type
4309FabArray<FAB>::norminf (FabArray<IFAB> const& mask, int comp, int ncomp,
4310 IntVect const& nghost, bool local) const
4311{
4312 BL_PROFILE("FabArray::norminf(mask)");
4313
4314 using RT = typename F::value_type;
4315
4316 auto nm0 = RT(0.0);
4317 Math::detail::AbsNanToInf<RT> const absinf{};
4318
4319#ifdef AMREX_USE_GPU
4320 if (Gpu::inLaunchRegion())
4321#endif
4322 {
4323 auto const& ma = this->const_arrays();
4324 auto const& maskma = mask.const_arrays();
4325 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, IntVect(nghost), ncomp,
4326 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept -> GpuTuple<RT>
4327 {
4328#ifdef AMREX_USE_GPU
4329 return maskma[box_no](i,j,k) ? absinf(ma[box_no](i,j,k,comp+n)) : RT(0.0);
4330#else // unconditional load so that the loop vectorizes; zero masked
4331 // values before any arithmetic, which could trap on garbage
4332 RT v = ma[box_no](i,j,k,comp+n);
4333 v = maskma[box_no](i,j,k) ? v : RT(0.0);
4334 return absinf(v);
4335#endif
4336 });
4337 }
4338#ifdef AMREX_USE_GPU
4339 else {
4340#ifdef AMREX_USE_OMP
4341#pragma omp parallel reduction(max:nm0)
4342#endif
4343 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
4344 Box const& bx = mfi.growntilebox(nghost);
4345 auto const& a = this->const_array(mfi);
4346 auto const& mskfab = mask.const_array(mfi);
4347 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
4348 {
4349 if (mskfab(i,j,k)) {
4350 nm0 = std::max(nm0, absinf(a(i,j,k,comp+n)));
4351 }
4352 });
4353 }
4354 }
4355#endif
4356
4357 nm0 = std::max(nm0, RT(0.0)); // ParReduce returns lowest() if this rank has no boxes
4358
4359 if (!local) {
4361 }
4362
4363 return nm0;
4364}
4365
4367
4368}
4369
4370#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:593
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.
Problem-domain geometry: maps between index space and physical space.
#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
Convenience header for the core AMReX GPU facilities.
#define AMREX_LOOP_3D(bx, i, j, k, block)
#define AMREX_LOOP_4D(bx, ncomp, i, j, k, n, block)
while parser_exe_t p
Definition AMReX_Parser_Exe_Body.H:33
Abstract base class for memory arenas.
Definition AMReX_Arena.H:154
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:681
__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:88
IntVect nGrowVect() const noexcept
Definition AMReX_FabArrayBase.H:85
void clearThisBD(bool no_assertion=false) const
clear BD count and caches associated with this BD, if no other is using this BD.
Definition AMReX_FabArrayBase.cpp:2569
void clear()
Clear this object's BoxArray, DistributionMapping, local index/ownership data, and BDKey so the conta...
Definition AMReX_FabArrayBase.cpp:208
friend class MFIter
Definition AMReX_FabArrayBase.H:48
Vector< int > indexArray
Definition AMReX_FabArrayBase.H:529
FabArrayBase()=default
static FabArrayStats m_FA_stats
Definition AMReX_FabArrayBase.H:881
static bool getAllocSingleChunk()
Query whether single-chunk allocation is enabled for new FabArrays.
Definition AMReX_FabArrayBase.H:886
void addThisBD()
add the current BD into BD count database
Definition AMReX_FabArrayBase.cpp:2599
int n_comp
Definition AMReX_FabArrayBase.H:532
const FB & getFB(const IntVect &nghost, const Periodicity &period, bool cross=false, bool enforce_periodicity_only=false, bool override_sync=false, IntVect const &sumboundary_src_nghost=IntVect(-1)) const
Retrieve (and cache) the FillBoundary metadata for the requested halo.
Definition AMReX_FabArrayBase.cpp:1295
bool isFusingCandidate() const noexcept
Is this a good candidate for kernel fusing?
Definition AMReX_FabArrayBase.cpp:2754
bool is_cell_centered() const noexcept
This tests on whether the FabArray is cell-centered.
Definition AMReX_FabArrayBase.cpp:2748
IndexType ixType() const noexcept
Return index type.
Definition AMReX_FabArrayBase.H:91
FabArrayBase & operator=(const FabArrayBase &rhs)=default
void define(const BoxArray &bxs, const DistributionMapping &dm, int nvar, int ngrow)
Definition AMReX_FabArrayBase.cpp:176
static void updateMemUsage(std::string const &tag, Long nbytes, Arena const *ar)
Accumulate memory usage statistics for diagnostics.
Definition AMReX_FabArrayBase.cpp:2676
CopyComTag::CopyComTagsContainer CopyComTagsContainer
Definition AMReX_FabArrayBase.H:236
CopyComTag::MapOfCopyComTagContainers MapOfCopyComTagContainers
Definition AMReX_FabArrayBase.H:237
int localindex(int K) const noexcept
Return local index in the vector of FABs.
Definition AMReX_FabArrayBase.H:124
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
IntVect n_grow
Definition AMReX_FabArrayBase.H:531
CpOp
parallel copy or add
Definition AMReX_FabArrayBase.H:424
@ ADD
Definition AMReX_FabArrayBase.H:424
@ COPY
Definition AMReX_FabArrayBase.H:424
Box box(int K) const noexcept
Return the Kth Box in the BoxArray. That is, the valid region of the Kth grid.
Definition AMReX_FabArrayBase.H:106
DistributionMapping distributionMap
Definition AMReX_FabArrayBase.H:528
Box fabbox(int K) const noexcept
Return the Kth FABs Box in the FabArray. That is, the region the Kth fab is actually defined on.
Definition AMReX_FabArrayBase.cpp:218
BoxArray boxarray
Definition AMReX_FabArrayBase.H:527
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 ParallelCopy(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const IntVect &snghost, const IntVect &dnghost, const IntVect &offset, const Periodicity &period)
This function copies data from src to this FabArray.
Definition AMReX_FabArrayCommI.H:343
void ParallelCopyToGhost_finish()
Finish the current ParallelCopyToGhost_nowait() operation.
Definition AMReX_FabArrayCommI.H:399
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:2673
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:3976
void mult(value_type val, int comp, int num_comp, int nghost=0)
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 * m_dp_arrays
Definition AMReX_FabArray.H:1772
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:2719
typename std::conditional_t< IsBaseFab< FAB >::value, FAB, FABType >::value_type value_type
Definition AMReX_FabArray.H:367
void capacityOfFabs(LayoutData< Int > &mem) const
std::unique_ptr< FabArray< BaseFab< GpuComplex< Real > > > > os_temp
Definition AMReX_FabArray.H:1917
static void Saxpy_Xpay(FabArray< BaseFab< GpuComplex< Real > > > &y, value_type a1, FabArray< BaseFab< GpuComplex< Real > > > const &x1, value_type a2, FabArray< BaseFab< GpuComplex< Real > > > const &x2, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
void FillBoundary(const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3762
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)
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:1000
LayoutData< int > RecvLayoutMask(const CommMetaData &thecmd)
void FillBoundary_nowait(const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3823
static void LinComb(FabArray< BaseFab< GpuComplex< Real > > > &dst, value_type a, const FabArray< BaseFab< GpuComplex< Real > > > &x, int xcomp, value_type b, const FabArray< BaseFab< GpuComplex< Real > > > &y, int ycomp, int dstcomp, int numcomp, const IntVect &nghost)
void shift(const IntVect &v)
Shift the boxarray by vector v.
Definition AMReX_FabArray.H:3405
FAB * release(int K)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:2177
bool ok() const
Return true if the FabArray is well-defined. That is, the FabArray has a BoxArray and DistributionMap...
Definition AMReX_FabArray.H:2454
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:2379
void ParallelCopy(const FabArray< FAB > &src, int scomp, int dcomp, int ncomp, const IntVect &snghost, const IntVect &dnghost, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY, const FabArrayBase::CPC *a_cpc=nullptr, bool deterministic=false)
Definition AMReX_FabArrayCommI.H:323
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:2343
bool defined(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:2052
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:3922
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:368
MultiArray4< typename FabArray< FAB >::value_type > arrays() noexcept
Build, if needed, and return mutable Array4 views for local FABs.
Definition AMReX_FabArray.H:713
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)
void ParallelCopy_finish()
Finish the current nowait ParallelCopy or ParallelAdd operation.
Definition AMReX_FabArrayCommI.H:690
FAB & get(int K) noexcept
Return a reference to the FAB associated with the Kth element.
Definition AMReX_FabArray.H:576
void ParallelAdd(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const IntVect &snghost, const IntVect &dnghost, const IntVect &offset, const Periodicity &period)
This function adds data from src to this FabArray.
Definition AMReX_FabArrayCommI.H:355
FAB const * fabPtr(int K) const noexcept
Definition AMReX_FabArray.H:2094
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:3969
static void Saxpy_Saxpy(FabArray< BaseFab< GpuComplex< Real > > > &y1, value_type a1, FabArray< BaseFab< GpuComplex< Real > > > const &x1, FabArray< BaseFab< GpuComplex< Real > > > &y2, value_type a2, FabArray< BaseFab< GpuComplex< Real > > > const &x2, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
void clear_arrays()
Free the cached Array4s so that they are rebuilt by the next arrays() call.
Definition AMReX_FabArray.H:2142
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:1759
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())
Split-phase version of OverrideSync.
Definition AMReX_FabArray.H:3915
std::unique_ptr< PCData< BaseFab< GpuComplex< Real > > > > pcd
Definition AMReX_FabArray.H:1914
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:2489
void setDomainBndry(value_type val, const Geometry &geom)
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< BaseFab< GpuComplex< Real > > > > fbd
Definition AMReX_FabArray.H:1913
std::unique_ptr< detail::SingleChunkArena > m_single_chunk_arena
Definition AMReX_FabArray.H:1758
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:3990
FabArray(const FabArray< FAB > &rhs, MakeType maketype, int scomp, int ncomp)
Construct a component alias of rhs.
Definition AMReX_FabArray.H:2357
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 ParallelCopy_nowait(const FabArray< FAB > &src, int scomp, int dcomp, int ncomp, const IntVect &snghost, const IntVect &dnghost, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY, const FabArrayBase::CPC *a_cpc=nullptr, bool to_ghost_cells_only=false, bool deterministic=false)
Asynchronous ParallelCopy with per-direction ghost-cell growth.
Definition AMReX_FabArrayCommI.H:407
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:1830
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:3831
Vector< std::string > m_tags
Definition AMReX_FabArray.H:1778
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:385
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)
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)
Arena * arena() const noexcept
Arena configured for allocations by this FabArray.
Definition AMReX_FabArray.H:480
DataAllocator m_dallocator
Definition AMReX_FabArray.H:1757
void copy(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:977
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:3885
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 ParallelCopy_nowait(const FabArray< FAB > &src, int scomp, int dcomp, int ncomp, const IntVect &snghost, const IntVect &dnghost, const IntVect &offset, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY, const FabArrayBase::CPC *a_cpc=nullptr, bool to_ghost_cells_only=false, bool deterministic=false)
Asynchronous ParallelCopy with per-direction ghost-cell growth and a spatial offset.
Definition AMReX_FabArrayCommI.H:425
void FillBoundary_nowait(bool cross=false)
Definition AMReX_FabArray.H:3815
void clear()
Releases FAB memory in the FabArray.
Definition AMReX_FabArray.H:2218
void FillBoundary_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:4054
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:3839
value_type * singleChunkPtr() noexcept
Definition AMReX_FabArray.H:504
std::vector< BaseFab< GpuComplex< Real > > * > m_fabs_v
Definition AMReX_FabArray.H:1769
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)
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
Definition AMReX_FabArray.H:1765
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:2318
void FillBoundary_test()
Definition AMReX_FabArrayCommI.H:1027
void plus(value_type val, int comp, int num_comp, int nghost=0)
bool defined(int K) const noexcept
Definition AMReX_FabArray.H:2039
FAB * fabPtr(int K) noexcept
Definition AMReX_FabArray.H:2085
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< BaseFab< GpuComplex< Real > > > > m_factory
Definition AMReX_FabArray.H:1756
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)
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:2979
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
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:4046
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:4003
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:3983
void FB_local_copy_cpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:396
void abs(int comp, int ncomp, int nghost=0)
static void Saxpy(FabArray< BaseFab< GpuComplex< Real > > > &y, value_type a, FabArray< BaseFab< GpuComplex< Real > > > const &x, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
MultiArray4< value_type > m_arrays
Definition AMReX_FabArray.H:1775
void FillBoundaryAndSync_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3869
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:3876
void BuildMask(const Box &phys_domain, const Periodicity &period, value_type covered, value_type notcovered, value_type physbnd, value_type interior)
void * m_hp_arrays
Definition AMReX_FabArray.H:1774
static void Saypy_Saxpy(FabArray< BaseFab< GpuComplex< Real > > > &y1, value_type a1, FabArray< BaseFab< GpuComplex< Real > > > &y2, value_type a2, FabArray< BaseFab< GpuComplex< Real > > > const &x, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
ShMem shmem
Definition AMReX_FabArray.H:1828
FabArray< FAB > & operator=(FabArray< FAB > &&rhs) noexcept
Definition AMReX_FabArray.H:2410
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:1776
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
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)
FAB * fabPtr(const MFIter &mfi) noexcept
Return pointer to FAB.
Definition AMReX_FabArray.H:2065
void copyTo(FAB &dest, int scomp, int dcomp, int ncomp, int nghost=0) const
Copy the values contained in the intersection of the num_comp component valid + nghost region of this...
Definition AMReX_FabArrayCommI.H:767
void OverrideSync_finish()
Definition AMReX_FabArray.H:3930
FAB * release(const MFIter &mfi)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:2198
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< BaseFab< GpuComplex< Real > > > &y, value_type a, FabArray< BaseFab< GpuComplex< Real > > > const &x, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
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:2501
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< BaseFab< GpuComplex< Real > > > const &src, int scomp, int dcomp, int ncomp, IntVect const &nghost)
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:2075
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:2482
value_type const * singleChunkPtr() const noexcept
Definition AMReX_FabArray.H:510
~FabArray()
The destructor – deletes all FABs in the array.
Definition AMReX_FabArray.H:2446
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
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:87
const Box & Domain() const noexcept
Returns our rectangular domain.
Definition AMReX_Geometry.H:246
bool isPeriodic(int dir) const noexcept
Is the domain periodic in the specified direction?
Definition AMReX_Geometry.H:399
GPU-compatible tuple.
Definition AMReX_Tuple.H:104
__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
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:457
const DistributionMapping & DistributionMap() const noexcept
Definition AMReX_MFIter.H:201
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:176
Box validbox() const noexcept
Return the valid Box in which the current tile resides.
Definition AMReX_MFIter.H:167
int index() const noexcept
The index into the underlying BoxArray of the current FAB.
Definition AMReX_MFIter.H:179
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:194
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
Checks if a type is derived from amrex::BaseFab.
Definition AMReX_Concepts.H:13
amrex_long Long
Definition AMReX_INT.H:30
ArrayND< T, 4, true > Array4
Convenient alias for a 4D ArrayND with three spatial dimensions plus a component dimension.
Definition AMReX_Array4.H:1340
@ covered
Every cell in the region is covered.
Definition AMReX_FabFactory.H:28
void EnforcePeriodicity(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Definition AMReX_FabArray.H:4033
void SumBoundary(int scomp, int ncomp, const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3945
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:3952
void OverrideSync(const Periodicity &period=Periodicity::NonPeriodic())
Synchronize nodal data.
Definition AMReX_FabArray.H:3893
void FillBoundary(bool cross=false)
Copy on intersection within a FabArray.
Definition AMReX_FabArray.H:3738
void OverrideSync(int scomp, int ncomp, const Periodicity &period)
Synchronize nodal data.
Definition AMReX_FabArray.H:3904
void FillBoundary(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3800
void FillBoundaryAndSync(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Fill ghost cells and synchronize nodal data.
Definition AMReX_FabArray.H:3857
void FillBoundary(const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3750
void FillBoundary(int scomp, int ncomp, bool cross=false)
Definition AMReX_FabArray.H:3776
void FillBoundaryAndSync(const Periodicity &period=Periodicity::NonPeriodic())
Fill ghost cells and synchronize nodal data.
Definition AMReX_FabArray.H:3846
void SumBoundary(const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Sum values in overlapped cells.
Definition AMReX_FabArray.H:3938
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:3959
F::value_type norminf(int comp, int ncomp, IntVect const &nghost, bool local=false, bool ignore_covered=false) const
void EnforcePeriodicity(const Periodicity &period)
Fill ghost cells with values from their corresponding cells across periodic boundaries,...
Definition AMReX_FabArray.H:4011
void FillBoundary(int scomp, int ncomp, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3788
void EnforcePeriodicity(int scomp, int ncomp, const Periodicity &period)
Definition AMReX_FabArray.H:4022
__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:1632
Arena * The_Comms_Arena()
Definition AMReX_Arena.cpp:899
Arena * The_Pinned_Arena()
Definition AMReX_Arena.cpp:879
Arena * The_Arena()
Definition AMReX_Arena.cpp:839
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:37
void Max(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:133
void freeAsync(Arena *arena, void *mem) noexcept
Definition AMReX_GpuDevice.H:364
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:329
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:440
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:273
void FillBoundary_finish(Vector< MF * > const &mf)
Wait for outstanding FillBoundary_nowait operations launched with the vector helper to complete.
Definition AMReX_FabArrayCommI.H:1134
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:1660
void Add(FabArray< FAB > &dst, FabArray< FAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Definition AMReX_FabArray.H:251
ReduceData< Ts... >::Type ParReduce(TypeList< Ops... > operation_list, TypeList< Ts... > type_list, FabArray< FAB > const &fa, IntVect const &nghost, F &&f)
Parallel reduce for MultiFab/FabArray. The reduce result is local and it's the user's responsibility ...
Definition AMReX_ParReduce.H:48
std::unique_ptr< char, TheFaArenaDeleter > TheFaArenaPointer
Definition AMReX_FabArray.H:118
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:2990
DistributionMapping const & DistributionMap(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.DistributionMap().
Definition AMReX_FabArrayBase.cpp:2995
void FillBoundary_nowait(Vector< MF * > const &mf, Vector< int > const &scomp, Vector< int > const &ncomp, Vector< IntVect > const &nghost, Vector< Periodicity > const &period, Vector< int > const &cross={})
Launch FillBoundary_nowait across a vector of FabArrays.
Definition AMReX_FabArrayCommI.H:1088
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:1157
void ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:202
FabArray< BaseFab< GpuComplex< Real > > > cMultiFab
Definition AMReX_FabArray.H:4366
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:256
int nComp(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.nComp().
Definition AMReX_FabArrayBase.cpp:2980
@ interior
Definition AMReX_LO_BCTYPES.H:28
@ y
Definition AMReX_Orientation.H:14
@ x
Definition AMReX_Orientation.H:14
__host__ __device__ T abs(const GpuComplex< T > &a_z) noexcept
Return the absolute value of a complex number.
Definition AMReX_GpuComplex.H:361
constexpr bool IsBaseFab_v
Definition AMReX_TypeTraits.H:25
void OverrideSync_finish(FabArray< FAB > &fa)
Finish the current masked OverrideSync_nowait() operation.
Definition AMReX_FabArrayUtility.H:1710
IntVect nGrowVect(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.nGrowVect().
Definition AMReX_FabArrayBase.cpp:2985
bool TilingIfNotGPU() noexcept
Definition AMReX_MFIter.H:12
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
void setBndry(MF &dst, typename MF::value_type val, int scomp, int ncomp)
dst = val in ghost cells.
Definition AMReX_FabArrayUtility.H:2173
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:244
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:1199
void setVal(MF &dst, typename MF::value_type val)
dst = val
Definition AMReX_FabArrayUtility.H:2166
__host__ __device__ constexpr int get(IntVectND< dim > const &iv) noexcept
Get the Idx-th element of IntVectND<dim>.
Definition AMReX_IntVect.H:1360
Definition AMReX_TagParallelFor.H:58
Lightweight allocator/deallocator backed by an Arena.
Definition AMReX_DataAllocator.H:21
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:643
Definition AMReX_FabArrayBase.H:555
std::unique_ptr< MapOfCopyComTagContainers > m_RcvTags
Definition AMReX_FabArrayBase.H:561
std::unique_ptr< CopyComTagsContainer > m_LocTags
Definition AMReX_FabArrayBase.H:559
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:580
Definition AMReX_FabArray.H:359
FAB value_type
Definition AMReX_FabArray.H:360
ShMem(ShMem &&rhs) noexcept
Definition AMReX_FabArray.H:1795
ShMem() noexcept=default
Long n_values
Definition AMReX_FabArray.H:1822
Long n_points
Definition AMReX_FabArray.H:1823
bool alloc
Definition AMReX_FabArray.H:1821
ShMem & operator=(ShMem &&rhs) noexcept
Definition AMReX_FabArray.H:1806
ShMem(const ShMem &)=delete
Construction hints passed to FabFactory::create.
Definition AMReX_FabFactory.H:41
FabInfo & SetShared(bool s) noexcept
Set the shared flag; returns *this for chaining.
Definition AMReX_FabFactory.H:53
FabInfo & SetAlloc(bool a) noexcept
Set the alloc flag; returns *this for chaining.
Definition AMReX_FabFactory.H:47
FabInfo & SetArena(Arena *ar) noexcept
Set the arena pointer; returns *this for chaining.
Definition AMReX_FabFactory.H:59
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