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