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 // The pinned buffer is not modified after this point and is freed
2134 // in stream order by clear_arrays(), so kernels launched on the
2135 // current stream are correctly ordered after the copy without a
2136 // host sync. MFIter and StreamIter synchronize the current stream
2137 // before switching to other streams, so we only need to sync here
2138 // if we are already inside a multi-stream MFIter loop, where later
2139 // iterations may use the arrays on a different stream.
2140 if (!Gpu::inNoSyncRegion() && Gpu::numGpuStreams() > 1 &&
2142 {
2144 }
2145#endif
2146 }
2147}
2148
2149template <class FAB>
2150void
2152{
2153#ifdef AMREX_USE_GPU
2154 // The host-to-device copy of the Array4s issued in build_arrays() is
2155 // asynchronous and is not synchronized when we are in a NoSync region.
2156 // Use stream-ordered frees so that the pinned and device buffers are not
2157 // reused before the copy and any kernels using them have completed.
2158 if (m_hp_arrays) {
2161 }
2162 m_dp_arrays = nullptr;
2163#else
2164 std::free(m_hp_arrays);
2165#endif
2166 m_hp_arrays = nullptr;
2167 m_arrays.hp = nullptr;
2168 m_const_arrays.hp = nullptr;
2169}
2170
2171template <class FAB>
2172void
2173FabArray<FAB>::clear_fab_caches ()
2174{
2175 clear_arrays();
2176#ifdef AMREX_USE_GPU
2177 m_fb_local_copy_handler.clear();
2178 m_recv_copy_handler.clear();
2179 m_send_copy_handler.clear();
2180#endif
2181}
2182
2183template <class FAB>
2184[[nodiscard]]
2185FAB*
2187{
2188 const int li = localindex(K);
2189 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
2191 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
2192 if (nbytes > 0) {
2193 for (auto const& t : m_tags) {
2194 updateMemUsage(t, -nbytes, nullptr);
2195 }
2196 }
2197 clear_fab_caches();
2198 return std::exchange(m_fabs_v[li], nullptr);
2199 } else {
2200 return nullptr;
2201 }
2202}
2203
2204template <class FAB>
2205[[nodiscard]]
2206FAB*
2208{
2209 const int li = mfi.LocalIndex();
2210 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
2212 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
2213 if (nbytes > 0) {
2214 for (auto const& t : m_tags) {
2215 updateMemUsage(t, -nbytes, nullptr);
2216 }
2217 }
2218 clear_fab_caches();
2219 return std::exchange(m_fabs_v[li], nullptr);
2220 } else {
2221 return nullptr;
2222 }
2223}
2224
2225template <class FAB>
2226void
2228{
2230 {
2231 define_function_called = false;
2232 clearThisBD();
2233 }
2234
2235 Long nbytes = 0L;
2236 for (auto *x : m_fabs_v) {
2237 if (x) {
2238 nbytes += amrex::nBytesOwned(*x);
2239 m_factory->destroy(x);
2240 }
2241 }
2242 m_fabs_v.clear();
2243 clear_arrays();
2244 m_factory.reset();
2245 m_dallocator.m_arena = nullptr;
2246 // no need to clear the non-blocking fillboundary stuff
2247
2248 if (nbytes > 0) {
2249 for (auto const& t : m_tags) {
2250 updateMemUsage(t, -nbytes, nullptr);
2251 }
2252 }
2253
2255 m_single_chunk_arena.reset();
2256 }
2258
2259 m_tags.clear();
2260
2261#ifdef AMREX_USE_GPU
2262 m_fb_local_copy_handler.clear();
2263 m_recv_copy_handler.clear();
2264 m_send_copy_handler.clear();
2265#endif
2266
2268}
2269
2270template <class FAB>
2271template <BaseFabType SFAB, BaseFabType DFAB>
2272requires (std::is_convertible_v<typename SFAB::value_type, typename DFAB::value_type>)
2273void
2274FabArray<FAB>::LocalCopy (FabArray<SFAB> const& src, int scomp, int dcomp, int ncomp,
2275 IntVect const& nghost)
2276{
2277 amrex::Copy(*this, src, scomp, dcomp, ncomp, nghost);
2278}
2279
2280template <class FAB>
2281template <class F>
2282requires (BaseFabType<F>)
2283void
2284FabArray<FAB>::LocalAdd (FabArray<FAB> const& src, int scomp, int dcomp, int ncomp,
2285 IntVect const& nghost)
2286{
2287 amrex::Add(*this, src, scomp, dcomp, ncomp, nghost);
2288}
2289
2290template <class FAB>
2291template <class F>
2292requires (BaseFabType<F>)
2293void
2295{
2296 setVal(val,0,n_comp,IntVect(nghost));
2297}
2298
2299template <class FAB>
2300template <class F>
2301requires (BaseFabType<F>)
2302void
2304{
2305 setVal(val,0,n_comp,nghost);
2306}
2307
2308template <class FAB>
2309template <class F>
2310requires (BaseFabType<F>)
2311void
2312FabArray<FAB>::setVal (value_type val, const Box& region, int nghost)
2313{
2314 setVal(val,region,0,n_comp,IntVect(nghost));
2315}
2316
2317template <class FAB>
2318template <class F>
2319requires (BaseFabType<F>)
2320void
2321FabArray<FAB>::setVal (value_type val, const Box& region, const IntVect& nghost)
2322{
2323 setVal(val,region,0,n_comp,nghost);
2324}
2325
2326template <class FAB>
2328 : shmem()
2329{
2330 m_FA_stats.recordBuild();
2331}
2332
2333template <class FAB>
2335 : m_dallocator(a),
2336 shmem()
2337{
2338 m_FA_stats.recordBuild();
2339}
2340
2341template <class FAB>
2343 const DistributionMapping& dm,
2344 int nvar,
2345 int ngrow,
2346 const MFInfo& info,
2347 const FabFactory<FAB>& factory)
2348 : FabArray<FAB>(bxs,dm,nvar,IntVect(ngrow),info,factory)
2349{}
2350
2351template <class FAB>
2353 const DistributionMapping& dm,
2354 int nvar,
2355 const IntVect& ngrow,
2356 const MFInfo& info,
2357 const FabFactory<FAB>& factory)
2358 : m_factory(factory.clone()),
2359 shmem()
2360{
2361 m_FA_stats.recordBuild();
2362 define(bxs,dm,nvar,ngrow,info,*m_factory);
2363}
2364
2365template <class FAB>
2366FabArray<FAB>::FabArray (const FabArray<FAB>& rhs, MakeType maketype, int scomp, int ncomp)
2367 : m_factory(rhs.Factory().clone()),
2368 shmem()
2369{
2370 m_FA_stats.recordBuild();
2371 define(rhs.boxArray(), rhs.DistributionMap(), ncomp, rhs.nGrowVect(),
2372 MFInfo().SetAlloc(false), *m_factory);
2373
2374 if (maketype == amrex::make_alias)
2375 {
2376 for (int i = 0, n = indexArray.size(); i < n; ++i) {
2377 auto const& rhsfab = *(rhs.m_fabs_v[i]);
2378 m_fabs_v.push_back(m_factory->create_alias(rhsfab, scomp, ncomp));
2379 }
2380 }
2381 else
2382 {
2383 amrex::Abort("FabArray: unknown MakeType");
2384 }
2385}
2386
2387template <class FAB>
2389 : FabArrayBase (static_cast<FabArrayBase&&>(rhs))
2390 , m_factory (std::move(rhs.m_factory))
2391 , m_dallocator (rhs.m_dallocator)
2392 , m_single_chunk_arena(std::move(rhs.m_single_chunk_arena))
2393 , m_single_chunk_size(std::exchange(rhs.m_single_chunk_size,0))
2394 , define_function_called(rhs.define_function_called)
2395 , m_fabs_v (std::move(rhs.m_fabs_v))
2396#ifdef AMREX_USE_GPU
2397 , m_dp_arrays (std::exchange(rhs.m_dp_arrays, nullptr))
2398#endif
2399 , m_hp_arrays (std::exchange(rhs.m_hp_arrays, nullptr))
2400 , m_arrays (rhs.m_arrays)
2401 , m_const_arrays(rhs.m_const_arrays)
2402 , m_tags (std::move(rhs.m_tags))
2403 , shmem (std::move(rhs.shmem))
2404#ifdef AMREX_USE_GPU
2405 , m_fb_local_copy_handler(std::move(rhs.m_fb_local_copy_handler))
2406 , m_recv_copy_handler(std::move(rhs.m_recv_copy_handler))
2407 , m_send_copy_handler(std::move(rhs.m_send_copy_handler))
2408#endif
2409 // no need to worry about the data used in non-blocking FillBoundary.
2410{
2411 m_FA_stats.recordBuild();
2412 rhs.define_function_called = false; // the responsibility of clear BD has been transferred.
2413 rhs.m_fabs_v.clear(); // clear the data pointers so that rhs.clear does not delete them.
2414 rhs.clear();
2415}
2416
2417template <class FAB>
2420{
2421 if (&rhs != this)
2422 {
2423 clear();
2424
2425 FabArrayBase::operator=(static_cast<FabArrayBase&&>(rhs));
2426 m_factory = std::move(rhs.m_factory);
2427 m_dallocator = rhs.m_dallocator;
2428 m_single_chunk_arena = std::move(rhs.m_single_chunk_arena);
2429 std::swap(m_single_chunk_size, rhs.m_single_chunk_size);
2430 define_function_called = rhs.define_function_called;
2431 std::swap(m_fabs_v, rhs.m_fabs_v);
2432#ifdef AMREX_USE_GPU
2433 std::swap(m_dp_arrays, rhs.m_dp_arrays);
2434#endif
2435 std::swap(m_hp_arrays, rhs.m_hp_arrays);
2436 m_arrays = rhs.m_arrays;
2437 m_const_arrays = rhs.m_const_arrays;
2438 std::swap(m_tags, rhs.m_tags);
2439 shmem = std::move(rhs.shmem);
2440#ifdef AMREX_USE_GPU
2441 std::swap(m_fb_local_copy_handler, rhs.m_fb_local_copy_handler);
2442 std::swap(m_recv_copy_handler, rhs.m_recv_copy_handler);
2443 std::swap(m_send_copy_handler, rhs.m_send_copy_handler);
2444#endif
2445
2446 rhs.define_function_called = false;
2447 rhs.m_fabs_v.clear();
2448 rhs.m_tags.clear();
2449 rhs.clear();
2450 }
2451 return *this;
2452}
2453
2454template <class FAB>
2456{
2457 m_FA_stats.recordDelete();
2458 clear();
2459}
2460
2461template <class FAB>
2462bool
2464{
2465 if (!define_function_called) { return false; }
2466
2467 int isok = 1;
2468
2469 for (MFIter fai(*this); fai.isValid() && isok; ++fai)
2470 {
2471 if (defined(fai))
2472 {
2473 if (get(fai).box() != fabbox(fai.index()))
2474 {
2475 isok = 0;
2476 }
2477 }
2478 else
2479 {
2480 isok = 0;
2481 }
2482 }
2483
2485
2486 return isok == 1;
2487}
2488
2489template <class FAB>
2490bool
2492{
2494}
2495
2496template <class FAB>
2497void
2499 const DistributionMapping& dm,
2500 int nvar,
2501 int ngrow,
2502 const MFInfo& info,
2503 const FabFactory<FAB>& a_factory)
2504{
2505 define(bxs,dm,nvar,IntVect(ngrow),info,a_factory);
2506}
2507
2508template <class FAB>
2509void
2511 const DistributionMapping& dm,
2512 int nvar,
2513 const IntVect& ngrow,
2514 const MFInfo& info,
2515 const FabFactory<FAB>& a_factory)
2516{
2517 std::unique_ptr<FabFactory<FAB> > factory(a_factory.clone());
2518
2519 auto *default_arena = m_dallocator.m_arena;
2520 clear();
2521
2522 m_factory = std::move(factory);
2523 m_dallocator.m_arena = info.arena ? info.arena : default_arena;
2524
2526
2527 AMREX_ASSERT(ngrow.allGE(0));
2528 AMREX_ASSERT(boxarray.empty());
2529 FabArrayBase::define(bxs, dm, nvar, ngrow);
2530
2531 addThisBD();
2532
2533 if(info.alloc) {
2534 AllocFabs(*m_factory, m_dallocator.m_arena, info.tags, info.alloc_single_chunk);
2535#ifdef BL_USE_TEAM
2537#endif
2538 }
2539}
2540
2541template <class FAB>
2542void
2543FabArray<FAB>::AllocFabs (const FabFactory<FAB>& factory, Arena* ar,
2544 const Vector<std::string>& tags, bool alloc_single_chunk)
2545{
2546 if (shmem.alloc) { alloc_single_chunk = false; }
2547 if constexpr (!IsBaseFab_v<FAB>) { alloc_single_chunk = false; }
2548
2549 const int n = indexArray.size();
2550 const int nworkers = ParallelDescriptor::TeamSize();
2551 shmem.alloc = (nworkers > 1);
2552
2553 bool alloc = !shmem.alloc;
2554
2555 FabInfo fab_info;
2556 fab_info.SetAlloc(alloc).SetShared(shmem.alloc).SetArena(ar);
2557
2558 if (alloc_single_chunk) {
2559 m_single_chunk_size = 0L;
2560 for (int i = 0; i < n; ++i) {
2561 int K = indexArray[i];
2562 const Box& tmpbox = fabbox(K);
2563 m_single_chunk_size += factory.nBytes(tmpbox, n_comp, K);
2564 }
2565 AMREX_ASSERT(m_single_chunk_size >= 0); // 0 is okay.
2566 m_single_chunk_arena = std::make_unique<detail::SingleChunkArena>(ar, m_single_chunk_size);
2567 fab_info.SetArena(m_single_chunk_arena.get());
2568 }
2569
2570 m_fabs_v.reserve(n);
2571
2572 Long nbytes = 0L;
2573 for (int i = 0; i < n; ++i)
2574 {
2575 int K = indexArray[i];
2576 const Box& tmpbox = fabbox(K);
2577 m_fabs_v.push_back(factory.create(tmpbox, n_comp, fab_info, K));
2578 nbytes += amrex::nBytesOwned(*m_fabs_v.back());
2579 }
2580
2581 m_tags.clear();
2582 m_tags.emplace_back("All");
2583 for (auto const& t : m_region_tag) {
2584 m_tags.push_back(t);
2585 }
2586 for (auto const& t : tags) {
2587 m_tags.push_back(t);
2588 }
2589 for (auto const& t: m_tags) {
2590 updateMemUsage(t, nbytes, ar);
2591 }
2592
2593#ifdef BL_USE_TEAM
2594 if (shmem.alloc)
2595 {
2596 const int teamlead = ParallelDescriptor::MyTeamLead();
2597
2598 shmem.n_values = 0;
2599 shmem.n_points = 0;
2600 Vector<Long> offset(n,0);
2601 Vector<Long> nextoffset(nworkers,-1);
2602 for (int i = 0; i < n; ++i) {
2603 int K = indexArray[i];
2604 int owner = distributionMap[K] - teamlead;
2605 Long s = m_fabs_v[i]->size();
2606 if (ownership[i]) {
2607 shmem.n_values += s;
2608 shmem.n_points += m_fabs_v[i]->numPts();
2609 }
2610 if (nextoffset[owner] < 0) {
2611 offset[i] = 0;
2612 nextoffset[owner] = s;
2613 } else {
2614 offset[i] = nextoffset[owner];
2615 nextoffset[owner] += s;
2616 }
2617 }
2618
2619 size_t bytes = shmem.n_values*sizeof(value_type);
2620
2621 value_type *mfp;
2623
2624#if defined (BL_USE_MPI3)
2625
2626 static MPI_Info info = MPI_INFO_NULL;
2627 if (info == MPI_INFO_NULL) {
2628 MPI_Info_create(&info);
2629 MPI_Info_set(info, "alloc_shared_noncontig", "true");
2630 }
2631
2632 const MPI_Comm& team_comm = ParallelDescriptor::MyTeam().get();
2633
2634 BL_MPI_REQUIRE( MPI_Win_allocate_shared(bytes, sizeof(value_type),
2635 info, team_comm, &mfp, &shmem.win) );
2636
2637 for (int w = 0; w < nworkers; ++w) {
2638 MPI_Aint sz;
2639 int disp;
2640 value_type *dptr = 0;
2641 BL_MPI_REQUIRE( MPI_Win_shared_query(shmem.win, w, &sz, &disp, &dptr) );
2642 // AMREX_ASSERT(disp == sizeof(value_type));
2643 dps.push_back(dptr);
2644 }
2645
2646#else
2647
2648 amrex::Abort("BaseFab::define: to allocate shared memory, USE_MPI3 must be true");
2649
2650#endif
2651
2652 for (int i = 0; i < n; ++i) {
2653 int K = indexArray[i];
2654 int owner = distributionMap[K] - teamlead;
2655 value_type *p = dps[owner] + offset[i];
2656 m_fabs_v[i]->setPtr(p, m_fabs_v[i]->size());
2657 }
2658
2659 for (Long i = 0; i < shmem.n_values; i++, mfp++) {
2660 new (mfp) value_type;
2661 }
2662
2663 amrex::update_fab_stats(shmem.n_points, shmem.n_values, sizeof(value_type));
2664 }
2665#endif
2666}
2667
2668template <class FAB>
2669void
2670FabArray<FAB>::setFab_assert (int K, FAB const& fab) const
2671{
2672 amrex::ignore_unused(K,fab);
2673 AMREX_ASSERT(n_comp == fab.nComp());
2674 AMREX_ASSERT(!boxarray.empty());
2675 AMREX_ASSERT(fab.box() == fabbox(K));
2676 AMREX_ASSERT(distributionMap[K] == ParallelDescriptor::MyProc());
2677 AMREX_ASSERT(m_single_chunk_arena == nullptr);
2678}
2679
2680template <class FAB>
2681void
2682FabArray<FAB>::setFab (int boxno, std::unique_ptr<FAB> elem)
2683{
2684 if (n_comp == 0) {
2685 n_comp = elem->nComp();
2686 }
2687
2688 setFab_assert(boxno, *elem);
2689
2690 if (m_fabs_v.empty()) {
2691 m_fabs_v.resize(indexArray.size(),nullptr);
2692 }
2693
2694 const int li = localindex(boxno);
2695 if (m_fabs_v[li]) {
2696 m_factory->destroy(m_fabs_v[li]);
2697 }
2698 m_fabs_v[li] = elem.release();
2699 clear_fab_caches();
2700}
2701
2702template <class FAB>
2703template <class F>
2704requires (std::is_move_constructible_v<F>)
2705void
2706FabArray<FAB>::setFab (int boxno, FAB&& elem)
2707{
2708 if (n_comp == 0) {
2709 n_comp = elem.nComp();
2710 }
2711
2712 setFab_assert(boxno, elem);
2713
2714 if (m_fabs_v.empty()) {
2715 m_fabs_v.resize(indexArray.size(),nullptr);
2716 }
2717
2718 const int li = localindex(boxno);
2719 if (m_fabs_v[li]) {
2720 m_factory->destroy(m_fabs_v[li]);
2721 }
2722 m_fabs_v[li] = new FAB(std::move(elem));
2723 clear_fab_caches();
2724}
2725
2726template <class FAB>
2727void
2728FabArray<FAB>::setFab (const MFIter& mfi, std::unique_ptr<FAB> elem)
2729{
2730 if (n_comp == 0) {
2731 n_comp = elem->nComp();
2732 }
2733
2734 setFab_assert(mfi.index(), *elem);
2735
2736 if (m_fabs_v.empty()) {
2737 m_fabs_v.resize(indexArray.size(),nullptr);
2738 }
2739
2740 const int li = mfi.LocalIndex();
2741 if (m_fabs_v[li]) {
2742 m_factory->destroy(m_fabs_v[li]);
2743 }
2744 m_fabs_v[li] = elem.release();
2745 clear_fab_caches();
2746}
2747
2748template <class FAB>
2749template <class F>
2750requires (std::is_move_constructible_v<F>)
2751void
2752FabArray<FAB>::setFab (const MFIter& mfi, FAB&& elem)
2753{
2754 if (n_comp == 0) {
2755 n_comp = elem.nComp();
2756 }
2757
2758 setFab_assert(mfi.index(), elem);
2759
2760 if (m_fabs_v.empty()) {
2761 m_fabs_v.resize(indexArray.size(),nullptr);
2762 }
2763
2764 const int li = mfi.LocalIndex();
2765 if (m_fabs_v[li]) {
2766 m_factory->destroy(m_fabs_v[li]);
2767 }
2768 m_fabs_v[li] = new FAB(std::move(elem));
2769 clear_fab_caches();
2770}
2771
2772template <class FAB>
2773template <class F>
2774requires (BaseFabType<F>)
2775void
2777{
2778 setBndry(val, 0, n_comp);
2779}
2780
2781template <class FAB>
2782template <class F>
2783requires (BaseFabType<F>)
2784void
2786 int strt_comp,
2787 int ncomp)
2788{
2789 if (n_grow.max() > 0)
2790 {
2791#ifdef AMREX_USE_GPU
2792 if (Gpu::inLaunchRegion()) {
2793 bool use_mfparfor = true;
2794 const int nboxes = local_size();
2795 if (nboxes == 1) {
2796 if (boxarray[indexArray[0]].numPts() > Long(65*65*65)) {
2797 use_mfparfor = false;
2798 }
2799 } else {
2800 for (int i = 0; i < nboxes; ++i) {
2801 const Long npts = boxarray[indexArray[i]].numPts();
2802 if (npts >= Long(64*64*64)) {
2803 use_mfparfor = false;
2804 break;
2805 } else if (npts <= Long(17*17*17)) {
2806 break;
2807 }
2808 }
2809 }
2810 const IntVect nghost = n_grow;
2811 if (use_mfparfor) {
2812 auto const& ma = this->arrays();
2813 ParallelFor(*this, nghost,
2814 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2815 {
2816 auto const& a = ma[box_no];
2817 Box vbx(a);
2818 vbx.grow(-nghost);
2819 if (!vbx.contains(i,j,k)) {
2820 for (int n = 0; n < ncomp; ++n) {
2821 a(i,j,k,strt_comp+n) = val;
2822 }
2823 }
2824 });
2825 if (!Gpu::inNoSyncRegion()) {
2827 }
2828 } else {
2829 using Tag = Array4BoxTag<value_type>;
2831 for (MFIter mfi(*this); mfi.isValid(); ++mfi) {
2832 Box const& vbx = mfi.validbox();
2833 auto const& a = this->array(mfi);
2834
2835 Box b;
2836#if (AMREX_SPACEDIM == 3)
2837 if (nghost[2] > 0) {
2838 b = vbx;
2839 b.setRange(2, vbx.smallEnd(2)-nghost[2], nghost[2]);
2840 b.grow(IntVect(nghost[0],nghost[1],0));
2841 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2842 b.shift(2, vbx.length(2)+nghost[2]);
2843 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2844 }
2845#endif
2846#if (AMREX_SPACEDIM >= 2)
2847 if (nghost[1] > 0) {
2848 b = vbx;
2849 b.setRange(1, vbx.smallEnd(1)-nghost[1], nghost[1]);
2850 b.grow(0, nghost[0]);
2851 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2852 b.shift(1, vbx.length(1)+nghost[1]);
2853 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2854 }
2855#endif
2856 if (nghost[0] > 0) {
2857 b = vbx;
2858 b.setRange(0, vbx.smallEnd(0)-nghost[0], nghost[0]);
2859 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2860 b.shift(0, vbx.length(0)+nghost[0]);
2861 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2862 }
2863 }
2864
2865 ParallelFor(tags, ncomp,
2866 [=] AMREX_GPU_DEVICE (int i, int j, int k, int n, Tag const& tag) noexcept
2867 {
2868 tag.dfab(i,j,k,strt_comp+n) = val;
2869 });
2870 }
2871 } else
2872#endif
2873 {
2874#ifdef AMREX_USE_OMP
2875#pragma omp parallel
2876#endif
2877 for (MFIter fai(*this); fai.isValid(); ++fai)
2878 {
2879 get(fai).template setComplement<RunOn::Host>(val, fai.validbox(), strt_comp, ncomp);
2880 }
2881 }
2882 }
2883}
2884
2885template <class FAB>
2886template <class F>
2887requires (BaseFabType<F>)
2888void
2890{
2891 setDomainBndry(val, 0, n_comp, geom);
2892}
2893
2894template <class FAB>
2895template <class F>
2896requires (BaseFabType<F>)
2897void
2899 int strt_comp,
2900 int ncomp,
2901 const Geometry& geom)
2902{
2903 BL_PROFILE("FabArray::setDomainBndry()");
2904
2905 Box domain_box = amrex::convert(geom.Domain(), boxArray().ixType());
2906 for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
2907 if (geom.isPeriodic(idim)) {
2908 int n = domain_box.length(idim);
2909 domain_box.grow(idim, n);
2910 }
2911 }
2912
2913#ifdef AMREX_USE_OMP
2914#pragma omp parallel if (Gpu::notInLaunchRegion())
2915#endif
2916 for (MFIter fai(*this); fai.isValid(); ++fai)
2917 {
2918 const Box& gbx = fai.fabbox();
2919 if (! domain_box.contains(gbx))
2920 {
2921 get(fai).template setComplement<RunOn::Device>(val, domain_box, strt_comp, ncomp);
2922 }
2923 }
2924}
2925
2926template <class FAB>
2927template <std::integral Int>
2928requires (BaseFabType<FAB> && (sizeof(Int) >= sizeof(Long)))
2929void
2931{
2932 AMREX_ASSERT(amrex::isMFIterSafe(*this, mem));
2933 for (MFIter mfi(*this, MFItInfo{}.DisableDeviceSync()); mfi.isValid(); ++mfi) {
2934 mem[mfi] += static_cast<Int>((*this)[mfi].nBytesOwned());
2935 }
2936}
2937
2938template <class FAB>
2939template <class F>
2940requires (BaseFabType<F>)
2941typename F::value_type
2942FabArray<FAB>::sum (int comp, IntVect const& nghost, bool local) const
2943{
2944 BL_PROFILE("FabArray::sum()");
2945
2946 using T = typename FAB::value_type;
2947 auto sm = T(0.0);
2948#ifdef AMREX_USE_GPU
2949 if (Gpu::inLaunchRegion())
2950#endif
2951 {
2952 auto const& ma = this->const_arrays();
2953 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, *this, nghost,
2954 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2955 -> GpuTuple<T>
2956 {
2957 return ma[box_no](i,j,k,comp);
2958 });
2959 }
2960#ifdef AMREX_USE_GPU
2961 else {
2962#ifdef AMREX_USE_OMP
2963#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
2964#endif
2965 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi)
2966 {
2967 Box const& bx = mfi.growntilebox(nghost);
2968 auto const& a = this->const_array(mfi);
2969 auto tmp = T(0.0);
2970 AMREX_LOOP_3D(bx, i, j, k,
2971 {
2972 tmp += a(i,j,k,comp);
2973 });
2974 sm += tmp; // Do it this way so that it does not break regression tests.
2975 }
2976 }
2977#endif
2978
2979 if (!local) {
2981 }
2982
2983 return sm;
2984}
2985
2986template <class FAB>
2987void
2988FabArray<FAB>::copyTo (FAB& dest, int nghost) const
2989{
2990 copyTo(dest, 0, 0, dest.nComp(), nghost);
2991}
2992
2993template <class FAB>
2994template <class F>
2995requires (BaseFabType<F>)
2996void
2998{
2999 setVal(val,0,n_comp,n_grow);
3000}
3001
3002template <class FAB>
3003template <class F>
3004requires (BaseFabType<F>)
3007{
3008 setVal(val);
3009 return *this;
3010}
3011
3012template <class FAB>
3013template <class F>
3014requires (BaseFabType<F>)
3015void
3017 int comp,
3018 int ncomp,
3019 int nghost)
3020{
3021 setVal(val,comp,ncomp,IntVect(nghost));
3022}
3023
3024template <class FAB>
3025template <class F>
3026requires (BaseFabType<F>)
3027void
3029 int comp,
3030 int ncomp,
3031 const IntVect& nghost)
3032{
3033 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
3034 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
3035
3036 BL_PROFILE("FabArray::setVal()");
3037
3038#ifdef AMREX_USE_GPU
3039 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3040 auto const& fa = this->arrays();
3041 ParallelFor(*this, nghost, ncomp,
3042 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3043 {
3044 fa[box_no](i,j,k,n+comp) = val;
3045 });
3046 if (!Gpu::inNoSyncRegion()) {
3048 }
3049 } else
3050#endif
3051 {
3052#ifdef AMREX_USE_OMP
3053#pragma omp parallel if (Gpu::notInLaunchRegion())
3054#endif
3055 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
3056 {
3057 const Box& bx = fai.growntilebox(nghost);
3058 auto fab = this->array(fai);
3059 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3060 {
3061 fab(i,j,k,n+comp) = val;
3062 });
3063 }
3064 }
3065}
3066
3067template <class FAB>
3068template <class F>
3069requires (BaseFabType<F>)
3070void
3072 const Box& region,
3073 int comp,
3074 int ncomp,
3075 int nghost)
3076{
3077 setVal(val,region,comp,ncomp,IntVect(nghost));
3078}
3079
3080template <class FAB>
3081template <class F>
3082requires (BaseFabType<F>)
3083void
3085 const Box& region,
3086 int comp,
3087 int ncomp,
3088 const IntVect& nghost)
3089{
3090 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
3091 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
3092
3093 BL_PROFILE("FabArray::setVal(val,region,comp,ncomp,nghost)");
3094
3095#ifdef AMREX_USE_GPU
3096 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3097 auto const& fa = this->arrays();
3098 ParallelFor(*this, nghost, ncomp,
3099 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3100 {
3101 if (region.contains(i,j,k)) {
3102 fa[box_no](i,j,k,n+comp) = val;
3103 }
3104 });
3105 if (!Gpu::inNoSyncRegion()) {
3107 }
3108 } else
3109#endif
3110 {
3111#ifdef AMREX_USE_OMP
3112 AMREX_ALWAYS_ASSERT(!omp_in_parallel());
3113#pragma omp parallel if (Gpu::notInLaunchRegion())
3114#endif
3115 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
3116 {
3117 Box b = fai.growntilebox(nghost) & region;
3118
3119 if (b.ok()) {
3120 auto fab = this->array(fai);
3121 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( b, ncomp, i, j, k, n,
3122 {
3123 fab(i,j,k,n+comp) = val;
3124 });
3125 }
3126 }
3127 }
3128}
3129
3130template <class FAB>
3131template <class F>
3132requires (BaseFabType<F>)
3133void
3134FabArray<FAB>::abs (int comp, int ncomp, int nghost)
3135{
3136 abs(comp, ncomp, IntVect(nghost));
3137}
3138
3139template <class FAB>
3140template <class F>
3141requires (BaseFabType<F>)
3142void
3143FabArray<FAB>::abs (int comp, int ncomp, const IntVect& nghost)
3144{
3145 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
3146 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
3147 BL_PROFILE("FabArray::abs()");
3148
3149#ifdef AMREX_USE_GPU
3150 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3151 auto const& fa = this->arrays();
3152 ParallelFor(*this, nghost, ncomp,
3153 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3154 {
3155 fa[box_no](i,j,k,n+comp) = std::abs(fa[box_no](i,j,k,n+comp));
3156 });
3157 if (!Gpu::inNoSyncRegion()) {
3159 }
3160 } else
3161#endif
3162 {
3163#ifdef AMREX_USE_OMP
3164#pragma omp parallel if (Gpu::notInLaunchRegion())
3165#endif
3166 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3167 {
3168 const Box& bx = mfi.growntilebox(nghost);
3169 auto fab = this->array(mfi);
3170 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3171 {
3172 fab(i,j,k,n+comp) = std::abs(fab(i,j,k,n+comp));
3173 });
3174 }
3175 }
3176}
3177
3178template <class FAB>
3179template <class F>
3180requires (BaseFabType<F>)
3181void
3182FabArray<FAB>::plus (value_type val, int comp, int num_comp, int nghost)
3183{
3184 BL_PROFILE("FabArray::plus()");
3185
3186#ifdef AMREX_USE_GPU
3187 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3188 auto const& fa = this->arrays();
3189 ParallelFor(*this, IntVect(nghost), num_comp,
3190 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3191 {
3192 fa[box_no](i,j,k,n+comp) += val;
3193 });
3194 if (!Gpu::inNoSyncRegion()) {
3196 }
3197 } else
3198#endif
3199 {
3200#ifdef AMREX_USE_OMP
3201#pragma omp parallel if (Gpu::notInLaunchRegion())
3202#endif
3203 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3204 {
3205 const Box& bx = mfi.growntilebox(nghost);
3206 auto fab = this->array(mfi);
3207 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3208 {
3209 fab(i,j,k,n+comp) += val;
3210 });
3211 }
3212 }
3213}
3214
3215template <class FAB>
3216template <class F>
3217requires (BaseFabType<F>)
3218void
3219FabArray<FAB>::plus (value_type val, const Box& region, int comp, int num_comp, int nghost)
3220{
3221 BL_PROFILE("FabArray::plus(val, region, comp, num_comp, nghost)");
3222
3223#ifdef AMREX_USE_GPU
3224 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3225 auto const& fa = this->arrays();
3226 ParallelFor(*this, IntVect(nghost), num_comp,
3227 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3228 {
3229 if (region.contains(i,j,k)) {
3230 fa[box_no](i,j,k,n+comp) += val;
3231 }
3232 });
3233 if (!Gpu::inNoSyncRegion()) {
3235 }
3236 } else
3237#endif
3238 {
3239#ifdef AMREX_USE_OMP
3240#pragma omp parallel if (Gpu::notInLaunchRegion())
3241#endif
3242 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3243 {
3244 const Box& bx = mfi.growntilebox(nghost) & region;
3245 if (bx.ok()) {
3246 auto fab = this->array(mfi);
3247 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3248 {
3249 fab(i,j,k,n+comp) += val;
3250 });
3251 }
3252 }
3253 }
3254}
3255
3256template <class FAB>
3257template <class F>
3258requires (BaseFabType<F>)
3259void
3260FabArray<FAB>::mult (value_type val, int comp, int num_comp, int nghost)
3261{
3262 BL_PROFILE("FabArray::mult()");
3263
3264#ifdef AMREX_USE_GPU
3265 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3266 auto const& fa = this->arrays();
3267 ParallelFor(*this, IntVect(nghost), num_comp,
3268 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3269 {
3270 fa[box_no](i,j,k,n+comp) *= val;
3271 });
3272 if (!Gpu::inNoSyncRegion()) {
3274 }
3275 } else
3276#endif
3277 {
3278#ifdef AMREX_USE_OMP
3279#pragma omp parallel if (Gpu::notInLaunchRegion())
3280#endif
3281 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3282 {
3283 const Box& bx = mfi.growntilebox(nghost);
3284 auto fab = this->array(mfi);
3285 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3286 {
3287 fab(i,j,k,n+comp) *= val;
3288 });
3289 }
3290 }
3291}
3292
3293template <class FAB>
3294template <class F>
3295requires (BaseFabType<F>)
3296void
3297FabArray<FAB>::mult (value_type val, const Box& region, int comp, int num_comp, int nghost)
3298{
3299 BL_PROFILE("FabArray::mult(val, region, comp, num_comp, nghost)");
3300
3301#ifdef AMREX_USE_GPU
3302 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3303 auto const& fa = this->arrays();
3304 ParallelFor(*this, IntVect(nghost), num_comp,
3305 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3306 {
3307 if (region.contains(i,j,k)) {
3308 fa[box_no](i,j,k,n+comp) *= val;
3309 }
3310 });
3311 if (!Gpu::inNoSyncRegion()) {
3313 }
3314 } else
3315#endif
3316 {
3317#ifdef AMREX_USE_OMP
3318#pragma omp parallel if (Gpu::notInLaunchRegion())
3319#endif
3320 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3321 {
3322 const Box& bx = mfi.growntilebox(nghost) & region;
3323 if (bx.ok()) {
3324 auto fab = this->array(mfi);
3325 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3326 {
3327 fab(i,j,k,n+comp) *= val;
3328 });
3329 }
3330 }
3331 }
3332}
3333
3334template <class FAB>
3335template <class F>
3336requires (BaseFabType<F>)
3337void
3338FabArray<FAB>::invert (value_type numerator, int comp, int num_comp, int nghost)
3339{
3340 BL_PROFILE("FabArray::invert()");
3341
3342#ifdef AMREX_USE_GPU
3343 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3344 auto const& fa = this->arrays();
3345 ParallelFor(*this, IntVect(nghost), num_comp,
3346 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3347 {
3348 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
3349 });
3350 if (!Gpu::inNoSyncRegion()) {
3352 }
3353 } else
3354#endif
3355 {
3356#ifdef AMREX_USE_OMP
3357#pragma omp parallel if (Gpu::notInLaunchRegion())
3358#endif
3359 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3360 {
3361 const Box& bx = mfi.growntilebox(nghost);
3362 auto fab = this->array(mfi);
3363 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3364 {
3365 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
3366 });
3367 }
3368 }
3369}
3370
3371template <class FAB>
3372template <class F>
3373requires (BaseFabType<F>)
3374void
3375FabArray<FAB>::invert (value_type numerator, const Box& region, int comp, int num_comp, int nghost)
3376{
3377 BL_PROFILE("FabArray::invert(numerator, region, comp, num_comp, nghost)");
3378
3379#ifdef AMREX_USE_GPU
3380 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3381 auto const& fa = this->arrays();
3382 ParallelFor(*this, IntVect(nghost), num_comp,
3383 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3384 {
3385 if (region.contains(i,j,k)) {
3386 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
3387 }
3388 });
3389 if (!Gpu::inNoSyncRegion()) {
3391 }
3392 } else
3393#endif
3394 {
3395#ifdef AMREX_USE_OMP
3396#pragma omp parallel if (Gpu::notInLaunchRegion())
3397#endif
3398 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3399 {
3400 const Box& bx = mfi.growntilebox(nghost) & region;
3401 if (bx.ok()) {
3402 auto fab = this->array(mfi);
3403 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3404 {
3405 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
3406 });
3407 }
3408 }
3409 }
3410}
3411
3412template <class FAB>
3413void
3415{
3416 clearThisBD(); // The new boxarray will have a different ID.
3417 boxarray.shift(v);
3418 addThisBD();
3419#ifdef AMREX_USE_OMP
3420#pragma omp parallel
3421#endif
3422 for (MFIter fai(*this); fai.isValid(); ++fai)
3423 {
3424 get(fai).shift(v);
3425 }
3426 clear_arrays();
3427}
3428
3429template <class FAB>
3430template <class F>
3431requires (BaseFabType<F>)
3433 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3434{
3435 AMREX_ASSERT(y.boxArray() == x.boxArray());
3436 AMREX_ASSERT(y.distributionMap == x.distributionMap);
3437 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
3438
3439 BL_PROFILE("FabArray::Saxpy()");
3440
3441#ifdef AMREX_USE_GPU
3442 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3443 auto const& yma = y.arrays();
3444 auto const& xma = x.const_arrays();
3445 ParallelFor(y, nghost, ncomp,
3446 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3447 {
3448 yma[box_no](i,j,k,ycomp+n) += a * xma[box_no](i,j,k,xcomp+n);
3449 });
3450 if (!Gpu::inNoSyncRegion()) {
3452 }
3453 } else
3454#endif
3455 {
3456#ifdef AMREX_USE_OMP
3457#pragma omp parallel if (Gpu::notInLaunchRegion())
3458#endif
3459 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3460 {
3461 const Box& bx = mfi.growntilebox(nghost);
3462
3463 if (bx.ok()) {
3464 auto const& xfab = x.const_array(mfi);
3465 auto const& yfab = y.array(mfi);
3466 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3467 {
3468 yfab(i,j,k,ycomp+n) += a * xfab(i,j,k,xcomp+n);
3469 });
3470 }
3471 }
3472 }
3473}
3474
3475template <class FAB>
3476template <class F>
3477requires (BaseFabType<F>)
3478void
3480 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3481{
3482 AMREX_ASSERT(y.boxArray() == x.boxArray());
3483 AMREX_ASSERT(y.distributionMap == x.distributionMap);
3484 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
3485
3486 BL_PROFILE("FabArray::Xpay()");
3487
3488#ifdef AMREX_USE_GPU
3489 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3490 auto const& yfa = y.arrays();
3491 auto const& xfa = x.const_arrays();
3492 ParallelFor(y, nghost, ncomp,
3493 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3494 {
3495 yfa[box_no](i,j,k,n+ycomp) = xfa[box_no](i,j,k,n+xcomp)
3496 + a * yfa[box_no](i,j,k,n+ycomp);
3497 });
3498 if (!Gpu::inNoSyncRegion()) {
3500 }
3501 } else
3502#endif
3503 {
3504#ifdef AMREX_USE_OMP
3505#pragma omp parallel if (Gpu::notInLaunchRegion())
3506#endif
3507 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3508 {
3509 const Box& bx = mfi.growntilebox(nghost);
3510 auto const& xFab = x.const_array(mfi);
3511 auto const& yFab = y.array(mfi);
3512 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3513 {
3514 yFab(i,j,k,n+ycomp) = xFab(i,j,k,n+xcomp)
3515 + a * yFab(i,j,k,n+ycomp);
3516 });
3517 }
3518 }
3519}
3520
3521template <class FAB>
3522template <class F>
3523requires (BaseFabType<F>)
3525 value_type a2, FabArray<FAB> const& x2,
3526 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3527{
3528 AMREX_ASSERT(y.boxArray() == x1.boxArray() &&
3529 y.boxArray() == x2.boxArray() &&
3530 y.distributionMap == x1.distributionMap &&
3531 y.distributionMap == x2.distributionMap &&
3532 y.nGrowVect().allGE(nghost) &&
3533 x1.nGrowVect().allGE(nghost) &&
3534 x2.nGrowVect().allGE(nghost));
3535
3536 BL_PROFILE("FabArray::Saxpy_Xpay()");
3537
3538#ifdef AMREX_USE_GPU
3539 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3540 auto const& yma = y.arrays();
3541 auto const& xma1 = x1.const_arrays();
3542 auto const& xma2 = x2.const_arrays();
3543 ParallelFor(y, nghost, ncomp,
3544 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3545 {
3546 yma[box_no](i,j,k,ycomp+n) = xma2[box_no](i,j,k,xcomp+n)
3547 + a2 * (yma [box_no](i,j,k,ycomp+n)
3548 + a1 * xma1[box_no](i,j,k,xcomp+n));
3549 });
3550 if (!Gpu::inNoSyncRegion()) {
3552 }
3553 } else
3554#endif
3555 {
3556#ifdef AMREX_USE_OMP
3557#pragma omp parallel if (Gpu::notInLaunchRegion())
3558#endif
3559 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3560 {
3561 const Box& bx = mfi.growntilebox(nghost);
3562
3563 if (bx.ok()) {
3564 auto const& xfab1 = x1.const_array(mfi);
3565 auto const& xfab2 = x2.const_array(mfi);
3566 auto const& yfab = y.array(mfi);
3567 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3568 {
3569 yfab(i,j,k,ycomp+n) = xfab2(i,j,k,xcomp+n)
3570 + a2 * (yfab (i,j,k,ycomp+n)
3571 + a1 * xfab1(i,j,k,xcomp+n));
3572 });
3573 }
3574 }
3575 }
3576}
3577
3578template <class FAB>
3579template <class F>
3580requires (BaseFabType<F>)
3582 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x2,
3583 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3584{
3585 AMREX_ASSERT(y1.boxArray() == y2.boxArray() &&
3586 y1.boxArray() == x1.boxArray() &&
3587 y1.boxArray() == x2.boxArray() &&
3591 y1.nGrowVect().allGE(nghost) &&
3592 y2.nGrowVect().allGE(nghost) &&
3593 x1.nGrowVect().allGE(nghost) &&
3594 x2.nGrowVect().allGE(nghost));
3595
3596 BL_PROFILE("FabArray::Saxpy_Saxpy()");
3597
3598#ifdef AMREX_USE_GPU
3599 if (Gpu::inLaunchRegion() && y1.isFusingCandidate()) {
3600 auto const& y1ma = y1.arrays();
3601 auto const& x1ma = x1.const_arrays();
3602 auto const& y2ma = y2.arrays();
3603 auto const& x2ma = x2.const_arrays();
3604 ParallelFor(y1, nghost, ncomp,
3605 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3606 {
3607 y1ma[box_no](i,j,k,ycomp+n) += a1 * x1ma[box_no](i,j,k,xcomp+n);
3608 y2ma[box_no](i,j,k,ycomp+n) += a2 * x2ma[box_no](i,j,k,xcomp+n);
3609 });
3610 if (!Gpu::inNoSyncRegion()) {
3612 }
3613 } else
3614#endif
3615 {
3616#ifdef AMREX_USE_OMP
3617#pragma omp parallel if (Gpu::notInLaunchRegion())
3618#endif
3619 for (MFIter mfi(y1,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3620 {
3621 const Box& bx = mfi.growntilebox(nghost);
3622
3623 if (bx.ok()) {
3624 auto const& x1fab = x1.const_array(mfi);
3625 auto const& y1fab = y1.array(mfi);
3626 auto const& x2fab = x2.const_array(mfi);
3627 auto const& y2fab = y2.array(mfi);
3628 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3629 {
3630 y1fab(i,j,k,ycomp+n) += a1 * x1fab(i,j,k,xcomp+n);
3631 y2fab(i,j,k,ycomp+n) += a2 * x2fab(i,j,k,xcomp+n);
3632 });
3633 }
3634 }
3635 }
3636}
3637
3638template <class FAB>
3639template <class F>
3640requires (BaseFabType<F>)
3642 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x,
3643 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3644{
3645 AMREX_ASSERT(y1.boxArray() == y2.boxArray() &&
3646 y1.boxArray() == x.boxArray() &&
3648 y1.distributionMap == x.distributionMap &&
3649 y1.nGrowVect().allGE(nghost) &&
3650 y2.nGrowVect().allGE(nghost) &&
3651 x.nGrowVect().allGE(nghost));
3652
3653 BL_PROFILE("FabArray::Saypy_Saxpy()");
3654
3655#ifdef AMREX_USE_GPU
3656 if (Gpu::inLaunchRegion() && y1.isFusingCandidate()) {
3657 auto const& y1ma = y1.arrays();
3658 auto const& y2ma = y2.arrays();
3659 auto const& xma = x.const_arrays();
3660 ParallelFor(y1, nghost, ncomp,
3661 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3662 {
3663 y1ma[box_no](i,j,k,ycomp+n) += a1 * y2ma[box_no](i,j,k,ycomp+n);
3664 y2ma[box_no](i,j,k,ycomp+n) += a2 * xma[box_no](i,j,k,xcomp+n);
3665 });
3666 if (!Gpu::inNoSyncRegion()) {
3668 }
3669 } else
3670#endif
3671 {
3672#ifdef AMREX_USE_OMP
3673#pragma omp parallel if (Gpu::notInLaunchRegion())
3674#endif
3675 for (MFIter mfi(y1,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3676 {
3677 const Box& bx = mfi.growntilebox(nghost);
3678
3679 if (bx.ok()) {
3680 auto const& xfab = x.const_array(mfi);
3681 auto const& y1fab = y1.array(mfi);
3682 auto const& y2fab = y2.array(mfi);
3683 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3684 {
3685 y1fab(i,j,k,ycomp+n) += a1 * y2fab(i,j,k,ycomp+n);
3686 y2fab(i,j,k,ycomp+n) += a2 * xfab(i,j,k,xcomp+n);
3687 });
3688 }
3689 }
3690 }
3691}
3692
3693template <class FAB>
3694template <class F>
3695requires (BaseFabType<F>)
3696void
3698 value_type a, const FabArray<FAB>& x, int xcomp,
3699 value_type b, const FabArray<FAB>& y, int ycomp,
3700 int dstcomp, int numcomp, const IntVect& nghost)
3701{
3702 AMREX_ASSERT(dst.boxArray() == x.boxArray());
3703 AMREX_ASSERT(dst.distributionMap == x.distributionMap);
3704 AMREX_ASSERT(dst.boxArray() == y.boxArray());
3705 AMREX_ASSERT(dst.distributionMap == y.distributionMap);
3706 AMREX_ASSERT(dst.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost) && y.nGrowVect().allGE(nghost));
3707
3708 BL_PROFILE("FabArray::LinComb()");
3709
3710#ifdef AMREX_USE_GPU
3711 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
3712 auto const& dstma = dst.arrays();
3713 auto const& xma = x.const_arrays();
3714 auto const& yma = y.const_arrays();
3715 ParallelFor(dst, nghost, numcomp,
3716 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3717 {
3718 dstma[box_no](i,j,k,dstcomp+n) = a*xma[box_no](i,j,k,xcomp+n)
3719 + b*yma[box_no](i,j,k,ycomp+n);
3720 });
3721 if (!Gpu::inNoSyncRegion()) {
3723 }
3724 } else
3725#endif
3726 {
3727#ifdef AMREX_USE_OMP
3728#pragma omp parallel if (Gpu::notInLaunchRegion())
3729#endif
3730 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3731 {
3732 const Box& bx = mfi.growntilebox(nghost);
3733 auto const& xfab = x.const_array(mfi);
3734 auto const& yfab = y.const_array(mfi);
3735 auto const& dfab = dst.array(mfi);
3736 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
3737 {
3738 dfab(i,j,k,dstcomp+n) = a*xfab(i,j,k,xcomp+n) + b*yfab(i,j,k,ycomp+n);
3739 });
3740 }
3741 }
3742}
3743
3744template <class FAB>
3745template <typename BUF>
3746void
3748{
3749 BL_PROFILE("FabArray::FillBoundary()");
3750 if ( n_grow.max() > 0 ) {
3753 }
3754}
3755
3756template <class FAB>
3757template <typename BUF>
3758void
3759FabArray<FAB>::FillBoundary (const Periodicity& period, bool cross)
3760{
3761 BL_PROFILE("FabArray::FillBoundary()");
3762 if ( n_grow.max() > 0 ) {
3763 FillBoundary_nowait<BUF>(0, nComp(), n_grow, period, cross);
3765 }
3766}
3767
3768template <class FAB>
3769template <typename BUF>
3770void
3771FabArray<FAB>::FillBoundary (const IntVect& nghost, const Periodicity& period, bool cross)
3772{
3773 BL_PROFILE("FabArray::FillBoundary()");
3775 "FillBoundary: asked to fill more ghost cells than we have");
3776 if ( nghost.max() > 0 ) {
3777 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3779 }
3780}
3781
3782template <class FAB>
3783template <typename BUF>
3784void
3785FabArray<FAB>::FillBoundary (int scomp, int ncomp, bool cross)
3786{
3787 BL_PROFILE("FabArray::FillBoundary()");
3788 if ( n_grow.max() > 0 ) {
3791 }
3792}
3793
3794template <class FAB>
3795template <typename BUF>
3796void
3797FabArray<FAB>::FillBoundary (int scomp, int ncomp, const Periodicity& period, bool cross)
3798{
3799 BL_PROFILE("FabArray::FillBoundary()");
3800 if ( n_grow.max() > 0 ) {
3801 FillBoundary_nowait<BUF>(scomp, ncomp, n_grow, period, cross);
3803 }
3804}
3805
3806template <class FAB>
3807template <typename BUF>
3808void
3809FabArray<FAB>::FillBoundary (int scomp, int ncomp, const IntVect& nghost,
3810 const Periodicity& period, bool cross)
3811{
3812 BL_PROFILE("FabArray::FillBoundary()");
3814 "FillBoundary: asked to fill more ghost cells than we have");
3815 if ( nghost.max() > 0 ) {
3816 FillBoundary_nowait<BUF>(scomp, ncomp, nghost, period, cross);
3818 }
3819}
3820
3821template <class FAB>
3822template <typename BUF>
3823void
3828
3829template <class FAB>
3830template <typename BUF>
3831void
3833{
3834 FillBoundary_nowait<BUF>(0, nComp(), nGrowVect(), period, cross);
3835}
3836
3837template <class FAB>
3838template <typename BUF>
3839void
3840FabArray<FAB>::FillBoundary_nowait (const IntVect& nghost, const Periodicity& period, bool cross)
3841{
3842 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3843}
3844
3845template <class FAB>
3846template <typename BUF>
3847void
3848FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, bool cross)
3849{
3851}
3852
3853template <class FAB>
3854void
3856{
3857 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3858 if (n_grow.max() > 0 || !is_cell_centered()) {
3861 }
3862}
3863
3864template <class FAB>
3865void
3866FabArray<FAB>::FillBoundaryAndSync (int scomp, int ncomp, const IntVect& nghost,
3867 const Periodicity& period)
3868{
3869 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3870 if (nghost.max() > 0 || !is_cell_centered()) {
3871 FillBoundaryAndSync_nowait(scomp, ncomp, nghost, period);
3873 }
3874}
3875
3876template <class FAB>
3877void
3882
3883template <class FAB>
3884void
3885FabArray<FAB>::FillBoundaryAndSync_nowait (int scomp, int ncomp, const IntVect& nghost,
3886 const Periodicity& period)
3887{
3888 BL_PROFILE("FillBoundaryAndSync_nowait()");
3889 FBEP_nowait(scomp, ncomp, nghost, period, false, false, true);
3890}
3891
3892template <class FAB>
3893void
3895{
3896 BL_PROFILE("FillBoundaryAndSync_finish()");
3898}
3899
3900template <class FAB>
3901void
3903{
3904 BL_PROFILE("FAbArray::OverrideSync()");
3905 if (!is_cell_centered()) {
3906 OverrideSync_nowait(0, nComp(), period);
3908 }
3909}
3910
3911template <class FAB>
3912void
3913FabArray<FAB>::OverrideSync (int scomp, int ncomp, const Periodicity& period)
3914{
3915 BL_PROFILE("FAbArray::OverrideSync()");
3916 if (!is_cell_centered()) {
3917 OverrideSync_nowait(scomp, ncomp, period);
3919 }
3920}
3921
3922template <class FAB>
3923void
3925{
3926 OverrideSync_nowait(0, nComp(), period);
3927}
3928
3929template <class FAB>
3930void
3931FabArray<FAB>::OverrideSync_nowait (int scomp, int ncomp, const Periodicity& period)
3932{
3933 BL_PROFILE("OverrideSync_nowait()");
3934 FBEP_nowait(scomp, ncomp, IntVect(0), period, false, false, true);
3935}
3936
3937template <class FAB>
3938void
3940{
3941 BL_PROFILE("OverrideSync_finish()");
3943}
3944
3945template <class FAB>
3946void
3947FabArray<FAB>::SumBoundary (const Periodicity& period, bool deterministic)
3948{
3949 SumBoundary(0, n_comp, IntVect(0), period, deterministic);
3950}
3951
3952template <class FAB>
3953void
3954FabArray<FAB>::SumBoundary (int scomp, int ncomp, const Periodicity& period, bool deterministic)
3955{
3956 SumBoundary(scomp, ncomp, IntVect(0), period, deterministic);
3957}
3958
3959template <class FAB>
3960void
3961FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period, bool deterministic)
3962{
3963 SumBoundary(scomp, ncomp, this->nGrowVect(), nghost, period, deterministic);
3964}
3965
3966template <class FAB>
3967void
3968FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period, bool deterministic)
3969{
3970 BL_PROFILE("FabArray<FAB>::SumBoundary()");
3971
3972 SumBoundary_nowait(scomp, ncomp, src_nghost, dst_nghost, period, deterministic);
3974}
3975
3976template <class FAB>
3977void
3978FabArray<FAB>::SumBoundary_nowait (const Periodicity& period, bool deterministic)
3979{
3980 SumBoundary_nowait(0, n_comp, IntVect(0), period, deterministic);
3981}
3982
3983template <class FAB>
3984void
3985FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool deterministic)
3986{
3987 SumBoundary_nowait(scomp, ncomp, IntVect(0), period, deterministic);
3988}
3989
3990template <class FAB>
3991void
3992FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period, bool deterministic)
3993{
3994 SumBoundary_nowait(scomp, ncomp, this->nGrowVect(), nghost, period, deterministic);
3995}
3996
3997template <class FAB>
3998void
3999FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period, bool deterministic)
4000{
4001 BL_PROFILE("FabArray<FAB>::SumBoundary_nowait()");
4002
4003 if ( n_grow == IntVect::TheZeroVector() && boxArray().ixType().cellCentered()) { return; }
4004
4005 AMREX_ALWAYS_ASSERT(src_nghost.allLE(n_grow) && dst_nghost.allLE(n_grow));
4006
4007 FBEP_nowait(scomp, ncomp, dst_nghost, period, false, false, false, src_nghost, deterministic);
4008}
4009
4010template <class FAB>
4011void
4013{
4014 BL_PROFILE("FabArray<FAB>::SumBoundary_finish()");
4016}
4017
4018template <class FAB>
4019void
4021{
4022 BL_PROFILE("FabArray::EnforcePeriodicity");
4023 if (period.isAnyPeriodic()) {
4024 FBEP_nowait(0, nComp(), nGrowVect(), period, false, true);
4025 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
4026 }
4027}
4028
4029template <class FAB>
4030void
4031FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const Periodicity& period)
4032{
4033 BL_PROFILE("FabArray::EnforcePeriodicity");
4034 if (period.isAnyPeriodic()) {
4035 FBEP_nowait(scomp, ncomp, nGrowVect(), period, false, true);
4036 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
4037 }
4038}
4039
4040template <class FAB>
4041void
4042FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const IntVect& nghost,
4043 const Periodicity& period)
4044{
4045 BL_PROFILE("FabArray::EnforcePeriodicity");
4046 if (period.isAnyPeriodic()) {
4047 FBEP_nowait(scomp, ncomp, nghost, period, false, true);
4048 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
4049 }
4050}
4051
4052template <class FAB>
4053template <typename BUF>
4054void
4055FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool cross)
4056{
4057 FBEP_nowait<BUF>(scomp, ncomp, nGrowVect(), period, cross);
4058}
4059
4060template <class FAB>
4061template <typename BUF>
4062void
4063FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const IntVect& nghost,
4064 const Periodicity& period, bool cross)
4065{
4066 FBEP_nowait<BUF>(scomp, ncomp, nghost, period, cross);
4067}
4068
4069template <class FAB>
4070template <class F>
4071requires (BaseFabType<F>)
4072void
4073FabArray<FAB>::BuildMask (const Box& phys_domain, const Periodicity& period,
4074 value_type covered, value_type notcovered,
4076{
4077 BL_PROFILE("FabArray::BuildMask()");
4078
4079 int ncomp = this->nComp();
4080 const IntVect& ngrow = this->nGrowVect();
4081
4082 Box domain = amrex::convert(phys_domain, boxArray().ixType());
4083 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
4084 if (period.isPeriodic(i)) {
4085 domain.grow(i, ngrow[i]);
4086 }
4087 }
4088
4089#ifdef AMREX_USE_GPU
4090 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
4091 auto const& fa = this->arrays();
4092 ParallelFor(*this, ngrow, ncomp,
4093 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
4094 {
4095 auto const& fab = fa[box_no];
4096 Box vbx(fab);
4097 vbx.grow(-ngrow);
4098 if (vbx.contains(i,j,k)) {
4099 fab(i,j,k,n) = interior;
4100 } else if (domain.contains(i,j,k)) {
4101 fab(i,j,k,n) = notcovered;
4102 } else {
4103 fab(i,j,k,n) = physbnd;
4104 }
4105 });
4106 if (!Gpu::inNoSyncRegion()) {
4108 }
4109 } else
4110#endif
4111 {
4112#ifdef AMREX_USE_OMP
4113#pragma omp parallel if (Gpu::notInLaunchRegion())
4114#endif
4115 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
4116 {
4117 auto const& fab = this->array(mfi);
4118 Box const& fbx = mfi.growntilebox();
4119 Box const& gbx = fbx & domain;
4120 Box const& vbx = mfi.validbox();
4121 AMREX_HOST_DEVICE_FOR_4D(fbx, ncomp, i, j, k, n,
4122 {
4123 if (vbx.contains(i,j,k)) {
4124 fab(i,j,k,n) = interior;
4125 } else if (gbx.contains(i,j,k)) {
4126 fab(i,j,k,n) = notcovered;
4127 } else {
4128 fab(i,j,k,n) = physbnd;
4129 }
4130 });
4131 }
4132 }
4133
4134 const FabArrayBase::FB& TheFB = this->getFB(ngrow,period);
4135 setVal(covered, TheFB, 0, ncomp);
4136}
4137
4138template <class FAB>
4139template <class F>
4140requires (BaseFabType<F>)
4141void
4142FabArray<FAB>::setVal (value_type val, const CommMetaData& thecmd, int scomp, int ncomp)
4143{
4144 BL_PROFILE("FabArray::setVal(val, thecmd, scomp, ncomp)");
4145
4146#ifdef AMREX_USE_GPU
4147 if (Gpu::inLaunchRegion())
4148 {
4149 CMD_local_setVal_gpu(val, thecmd, scomp, ncomp);
4150 CMD_remote_setVal_gpu(val, thecmd, scomp, ncomp);
4151 }
4152 else
4153#endif
4154 {
4155 AMREX_ASSERT(thecmd.m_LocTags && thecmd.m_RcvTags);
4156 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
4157 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
4158 auto N_locs = static_cast<int>(LocTags.size());
4159#ifdef AMREX_USE_OMP
4160#pragma omp parallel for if (thecmd.m_threadsafe_loc)
4161#endif
4162 for (int i = 0; i < N_locs; ++i) {
4163 const CopyComTag& tag = LocTags[i];
4164 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
4165 }
4166
4167 for (const auto & RcvTag : RcvTags) {
4168 auto N = static_cast<int>(RcvTag.second.size());
4169#ifdef AMREX_USE_OMP
4170#pragma omp parallel for if (thecmd.m_threadsafe_rcv)
4171#endif
4172 for (int i = 0; i < N; ++i) {
4173 const CopyComTag& tag = RcvTag.second[i];
4174 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
4175 }
4176 }
4177 }
4178}
4179
4180template <class FAB>
4181template <class F>
4182requires (BaseFabType<F>)
4185{
4186 BL_PROFILE("FabArray::RecvLayoutMask()");
4187
4188 LayoutData<int> r(this->boxArray(), this->DistributionMap());
4189#ifdef AMREX_USE_OMP
4190#pragma omp parallel if (thecmd.m_threadsafe_rcv)
4191#endif
4192 for (MFIter mfi(r); mfi.isValid(); ++mfi) {
4193 r[mfi] = 0;
4194 }
4195
4196 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
4197 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
4198
4199 auto N_locs = static_cast<int>(LocTags.size());
4200 for (int i = 0; i < N_locs; ++i) {
4201 const CopyComTag& tag = LocTags[i];
4202 r[tag.dstIndex] = 1;
4203 }
4204
4205 for (const auto & RcvTag : RcvTags) {
4206 auto N = static_cast<int>(RcvTag.second.size());
4207 for (int i = 0; i < N; ++i) {
4208 const CopyComTag& tag = RcvTag.second[i];
4209 r[tag.dstIndex] = 1;
4210 }
4211 }
4212 return r;
4213}
4214
4215template <class FAB>
4216template <typename F>
4217requires (BaseFabType<F>)
4218typename F::value_type
4219FabArray<FAB>::norminf (int comp, int ncomp, IntVect const& nghost, bool local,
4220 [[maybe_unused]] bool ignore_covered) const
4221{
4222 BL_PROFILE("FabArray::norminf()");
4223
4224 using RT = typename F::value_type;
4225
4226 auto nm0 = RT(0.0);
4227 Math::detail::AbsNanToInf<RT> const absinf{};
4228
4229#ifdef AMREX_USE_EB
4230 if ( this->is_cell_centered() && this->hasEBFabFactory() && ignore_covered )
4231 {
4232 const auto& ebfactory = dynamic_cast<EBFArrayBoxFactory const&>(this->Factory());
4233 auto const& flags = ebfactory.getMultiEBCellFlagFab();
4234#ifdef AMREX_USE_GPU
4235 if (Gpu::inLaunchRegion())
4236#endif
4237 {
4238 auto const& flagsma = flags.const_arrays();
4239 auto const& ma = this->const_arrays();
4240 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost, ncomp,
4241 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept -> GpuTuple<RT>
4242 {
4243#ifdef AMREX_USE_GPU
4244 return flagsma[box_no](i,j,k).isCovered() ? RT(0.0) : absinf(ma[box_no](i,j,k,comp+n));
4245#else // unconditional load so that the loop vectorizes; zero covered
4246 // values before any arithmetic
4247 RT v = ma[box_no](i,j,k,comp+n);
4248 v = flagsma[box_no](i,j,k).isCovered() ? RT(0.0) : v;
4249 return absinf(v);
4250#endif
4251 });
4252 }
4253#ifdef AMREX_USE_GPU
4254 else {
4255#ifdef AMREX_USE_OMP
4256#pragma omp parallel reduction(max:nm0)
4257#endif
4258 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
4259 Box const& bx = mfi.growntilebox(nghost);
4260 if (flags[mfi].getType(bx) != FabType::covered) {
4261 auto const& flag = flags.const_array(mfi);
4262 auto const& a = this->const_array(mfi);
4263 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
4264 {
4265 if (!flag(i,j,k).isCovered()) {
4266 nm0 = std::max(nm0, absinf(a(i,j,k,comp+n)));
4267 }
4268 });
4269 }
4270 }
4271 }
4272#endif
4273 }
4274 else
4275#endif
4276 {
4277#ifdef AMREX_USE_GPU
4278 if (Gpu::inLaunchRegion())
4279#endif
4280 {
4281 auto const& ma = this->const_arrays();
4282 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost, ncomp,
4283 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept -> GpuTuple<RT>
4284 {
4285 return absinf(ma[box_no](i,j,k,comp+n));
4286 });
4287 }
4288#ifdef AMREX_USE_GPU
4289 else {
4290#ifdef AMREX_USE_OMP
4291#pragma omp parallel reduction(max:nm0)
4292#endif
4293 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
4294 Box const& bx = mfi.growntilebox(nghost);
4295 auto const& a = this->const_array(mfi);
4296 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
4297 {
4298 nm0 = std::max(nm0, absinf(a(i,j,k,comp+n)));
4299 });
4300 }
4301 }
4302#endif
4303 }
4304
4305 nm0 = std::max(nm0, RT(0.0)); // ParReduce returns lowest() if this rank has no boxes
4306
4307 if (!local) {
4309 }
4310
4311 return nm0;
4312}
4313
4314template <class FAB>
4315template <typename IFAB, typename F>
4316requires (BaseFabType<F>)
4317typename F::value_type
4318FabArray<FAB>::norminf (FabArray<IFAB> const& mask, int comp, int ncomp,
4319 IntVect const& nghost, bool local) const
4320{
4321 BL_PROFILE("FabArray::norminf(mask)");
4322
4323 using RT = typename F::value_type;
4324
4325 auto nm0 = RT(0.0);
4326 Math::detail::AbsNanToInf<RT> const absinf{};
4327
4328#ifdef AMREX_USE_GPU
4329 if (Gpu::inLaunchRegion())
4330#endif
4331 {
4332 auto const& ma = this->const_arrays();
4333 auto const& maskma = mask.const_arrays();
4334 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, IntVect(nghost), ncomp,
4335 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept -> GpuTuple<RT>
4336 {
4337#ifdef AMREX_USE_GPU
4338 return maskma[box_no](i,j,k) ? absinf(ma[box_no](i,j,k,comp+n)) : RT(0.0);
4339#else // unconditional load so that the loop vectorizes; zero masked
4340 // values before any arithmetic, which could trap on garbage
4341 RT v = ma[box_no](i,j,k,comp+n);
4342 v = maskma[box_no](i,j,k) ? v : RT(0.0);
4343 return absinf(v);
4344#endif
4345 });
4346 }
4347#ifdef AMREX_USE_GPU
4348 else {
4349#ifdef AMREX_USE_OMP
4350#pragma omp parallel reduction(max:nm0)
4351#endif
4352 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
4353 Box const& bx = mfi.growntilebox(nghost);
4354 auto const& a = this->const_array(mfi);
4355 auto const& mskfab = mask.const_array(mfi);
4356 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
4357 {
4358 if (mskfab(i,j,k)) {
4359 nm0 = std::max(nm0, absinf(a(i,j,k,comp+n)));
4360 }
4361 });
4362 }
4363 }
4364#endif
4365
4366 nm0 = std::max(nm0, RT(0.0)); // ParReduce returns lowest() if this rank has no boxes
4367
4368 if (!local) {
4370 }
4371
4372 return nm0;
4373}
4374
4376
4377}
4378
4379#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:2682
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:3985
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:2728
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:3771
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:708
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:3832
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:3414
FAB * release(int K)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:2186
bool ok() const
Return true if the FabArray is well-defined. That is, the FabArray has a BoxArray and DistributionMap...
Definition AMReX_FabArray.H:2463
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:2388
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:2352
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:3931
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:3978
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:2151
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:3924
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:2498
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:3999
FabArray(const FabArray< FAB > &rhs, MakeType maketype, int scomp, int ncomp)
Construct a component alias of rhs.
Definition AMReX_FabArray.H:2366
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:467
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:3840
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:630
void FB_local_copy_gpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:558
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:3894
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:3824
void clear()
Releases FAB memory in the FabArray.
Definition AMReX_FabArray.H:2227
void FillBoundary_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:4063
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:678
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:3848
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:2327
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:2988
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:4055
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:4012
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:3992
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:3878
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:98
void FillBoundaryAndSync_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Definition AMReX_FabArray.H:3885
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:2419
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:515
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:3939
FAB * release(const MFIter &mfi)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:2207
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:2510
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:2491
value_type const * singleChunkPtr() const noexcept
Definition AMReX_FabArray.H:510
~FabArray()
The destructor – deletes all FABs in the array.
Definition AMReX_FabArray.H:2455
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
static int currentDepth()
Definition AMReX_MFIter.cpp:21
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:4042
void SumBoundary(int scomp, int ncomp, const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3954
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:3961
void OverrideSync(const Periodicity &period=Periodicity::NonPeriodic())
Synchronize nodal data.
Definition AMReX_FabArray.H:3902
void FillBoundary(bool cross=false)
Copy on intersection within a FabArray.
Definition AMReX_FabArray.H:3747
void OverrideSync(int scomp, int ncomp, const Periodicity &period)
Synchronize nodal data.
Definition AMReX_FabArray.H:3913
void FillBoundary(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3809
void FillBoundaryAndSync(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Fill ghost cells and synchronize nodal data.
Definition AMReX_FabArray.H:3866
void FillBoundary(const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3759
void FillBoundary(int scomp, int ncomp, bool cross=false)
Definition AMReX_FabArray.H:3785
void FillBoundaryAndSync(const Periodicity &period=Periodicity::NonPeriodic())
Fill ghost cells and synchronize nodal data.
Definition AMReX_FabArray.H:3855
void SumBoundary(const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Sum values in overlapped cells.
Definition AMReX_FabArray.H:3947
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:3968
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:4020
void FillBoundary(int scomp, int ncomp, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3797
void EnforcePeriodicity(int scomp, int ncomp, const Periodicity &period)
Definition AMReX_FabArray.H:4031
__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
int numGpuStreams() noexcept
Definition AMReX_GpuDevice.H:317
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:4375
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