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
37#ifdef AMREX_USE_EB
38#include <AMReX_EBFabFactory.H>
39#endif
40
41#ifdef AMREX_USE_OMP
42#include <omp.h>
43#endif
44
45#include <algorithm>
46#include <cstring>
47#include <iterator>
48#include <limits>
49#include <map>
50#include <memory>
51#include <utility>
52#include <set>
53#include <string>
54#include <vector>
55
56namespace amrex {
57
58template <typename T>
59requires (!BaseFabType<T>)
60Long nBytesOwned (T const&) noexcept { return 0; }
61
62template <typename T>
63Long nBytesOwned (BaseFab<T> const& fab) noexcept { return fab.nBytesOwned(); }
64
68struct MFInfo {
69 // alloc: allocate memory or not
70 bool alloc = true;
72 Arena* arena = nullptr;
74
75 MFInfo& SetAlloc (bool a) noexcept { alloc = a; return *this; }
76
77 MFInfo& SetAllocSingleChunk (bool a) noexcept { alloc_single_chunk = a; return *this; }
78
79 MFInfo& SetArena (Arena* ar) noexcept { arena = ar; return *this; }
80
81 MFInfo& SetTag () noexcept { return *this; }
82
83 MFInfo& SetTag (const char* t) noexcept {
84 tags.emplace_back(t);
85 return *this;
86 }
87
88 MFInfo& SetTag (const std::string& t) noexcept {
89 tags.emplace_back(t);
90 return *this;
91 }
92
93 template <typename T, typename... Ts>
94 MFInfo& SetTag (T&& t, Ts&&... ts) noexcept {
95 tags.emplace_back(std::forward<T>(t));
96 return SetTag(std::forward<Ts>(ts)...);
97 }
98};
99
101 using pointer = char*;
102 void operator()(pointer p) const noexcept {
103 The_Comms_Arena()->free(p);
104 }
105};
106using TheFaArenaPointer = std::unique_ptr<char, TheFaArenaDeleter>;
107
108// Data used in non-blocking fill boundary.
109template <class FAB>
131
132// Data used in non-blocking parallel copy.
133template <class FAB>
153
154template <typename T>
156{
158 Array4<T> const& operator[] (int li) const noexcept {
159 AMREX_IF_ON_DEVICE((return dp[li];))
160 AMREX_IF_ON_HOST((return hp[li];))
161 }
162
164 explicit operator bool() const noexcept {
165 AMREX_IF_ON_DEVICE((return dp != nullptr;))
166 AMREX_IF_ON_HOST((return hp != nullptr;))
167 }
168
169#ifdef AMREX_USE_GPU
170 Array4<T> const* AMREX_RESTRICT dp = nullptr;
171#endif
172 Array4<T> const* AMREX_RESTRICT hp = nullptr;
173};
174
175template <class FAB> class FabArray;
176
177template <BaseFabType DFAB, BaseFabType SFAB>
178requires (std::is_convertible_v<typename SFAB::value_type, typename DFAB::value_type>)
179void
180Copy (FabArray<DFAB>& dst, FabArray<SFAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
181{
182 Copy(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
183}
184
185template <BaseFabType DFAB, BaseFabType SFAB>
186requires (std::is_convertible_v<typename SFAB::value_type, typename DFAB::value_type>)
187void
188Copy (FabArray<DFAB>& dst, FabArray<SFAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
189{
190 BL_PROFILE("amrex::Copy()");
191
192 using DT = typename DFAB::value_type;
193
194 if (dst.local_size() == 0) { return; }
195
196 // avoid self copy
197 if constexpr (std::is_same_v<typename SFAB::value_type, typename DFAB::value_type>) {
198 if (dst.atLocalIdx(0).dataPtr(dstcomp) == src.atLocalIdx(0).dataPtr(srccomp)) {
199 return;
200 }
201 }
202
203#ifdef AMREX_USE_GPU
204 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
205 auto const& srcarr = src.const_arrays();
206 auto const& dstarr = dst.arrays();
207 ParallelFor(dst, nghost, numcomp,
208 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
209 {
210 dstarr[box_no](i,j,k,dstcomp+n) = DT(srcarr[box_no](i,j,k,srccomp+n));
211 });
212 if (!Gpu::inNoSyncRegion()) {
214 }
215 } else
216#endif
217 {
218#ifdef AMREX_USE_OMP
219#pragma omp parallel if (Gpu::notInLaunchRegion())
220#endif
221 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
222 {
223 const Box& bx = mfi.growntilebox(nghost);
224 if (bx.ok())
225 {
226 auto const& srcFab = src.const_array(mfi);
227 auto const& dstFab = dst.array(mfi);
228 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
229 {
230 dstFab(i,j,k,dstcomp+n) = DT(srcFab(i,j,k,srccomp+n));
231 });
232 }
233 }
234 }
235}
236
237template <BaseFabType FAB>
238void
239Add (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
240{
241 Add(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
242}
243
244template <BaseFabType FAB>
245void
246Add (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
247{
248 BL_PROFILE("amrex::Add()");
249
250#ifdef AMREX_USE_GPU
251 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
252 auto const& dstfa = dst.arrays();
253 auto const& srcfa = src.const_arrays();
254 ParallelFor(dst, nghost, numcomp,
255 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
256 {
257 dstfa[box_no](i,j,k,n+dstcomp) += srcfa[box_no](i,j,k,n+srccomp);
258 });
259 if (!Gpu::inNoSyncRegion()) {
261 }
262 } else
263#endif
264 {
265#ifdef AMREX_USE_OMP
266#pragma omp parallel if (Gpu::notInLaunchRegion())
267#endif
268 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
269 {
270 const Box& bx = mfi.growntilebox(nghost);
271 if (bx.ok())
272 {
273 auto const srcFab = src.array(mfi);
274 auto dstFab = dst.array(mfi);
275 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
276 {
277 dstFab(i,j,k,n+dstcomp) += srcFab(i,j,k,n+srccomp);
278 });
279 }
280 }
281 }
282}
283
340template <class FAB>
342 :
343 public FabArrayBase
344{
345public:
346
347 struct FABType {
348 using value_type = FAB;
349 };
350
351 /*
352 * if FAB is a BaseFab or its child, value_type = FAB::value_type
353 * else value_type = FAB;
354 */
355 using value_type = typename std::conditional_t<IsBaseFab<FAB>::value, FAB, FABType>::value_type;
356
357 using fab_type = FAB;
358
359 //
361 FabArray () noexcept;
362
370 explicit FabArray (Arena* a) noexcept;
371
377 FabArray (const BoxArray& bxs,
378 const DistributionMapping& dm,
379 int nvar,
380 int ngrow,
381#ifdef AMREX_STRICT_MODE
382 const MFInfo& info,
383 const FabFactory<FAB>& factory);
384#else
385 const MFInfo& info = MFInfo(),
386 const FabFactory<FAB>& factory = DefaultFabFactory<FAB>());
387#endif
388
389 FabArray (const BoxArray& bxs,
390 const DistributionMapping& dm,
391 int nvar,
392 const IntVect& 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
401 FabArray (const FabArray<FAB>& rhs, MakeType maketype, int scomp, int ncomp);
402
405
406 FabArray (FabArray<FAB>&& rhs) noexcept;
408
409 FabArray (const FabArray<FAB>& rhs) = delete;
411
418 void define (const BoxArray& bxs,
419 const DistributionMapping& dm,
420 int nvar,
421 int ngrow,
422#ifdef AMREX_STRICT_MODE
423 const MFInfo& info,
424 const FabFactory<FAB>& factory);
425#else
426 const MFInfo& info = MFInfo(),
427 const FabFactory<FAB>& factory = DefaultFabFactory<FAB>());
428#endif
429
430 void define (const BoxArray& bxs,
431 const DistributionMapping& dm,
432 int nvar,
433 const IntVect& ngrow,
434#ifdef AMREX_STRICT_MODE
435 const MFInfo& info,
436 const FabFactory<FAB>& factory);
437#else
438 const MFInfo& info = MFInfo(),
439 const FabFactory<FAB>& factory = DefaultFabFactory<FAB>());
440#endif
441
442 const FabFactory<FAB>& Factory () const noexcept { return *m_factory; }
443
444 // Provides access to the Arena this FabArray was build with.
445 Arena* arena () const noexcept { return m_dallocator.arena(); }
446
447 const Vector<std::string>& tags () const noexcept { return m_tags; }
448
449 bool hasEBFabFactory () const noexcept {
450#ifdef AMREX_USE_EB
451 const auto *const f = dynamic_cast<EBFArrayBoxFactory const*>(m_factory.get());
452 return (f != nullptr);
453#else
454 return false;
455#endif
456 }
457
460 [[nodiscard]] value_type* singleChunkPtr () noexcept {
461 return m_single_chunk_arena ? (value_type*)m_single_chunk_arena->data() : nullptr;
462 }
463
466 [[nodiscard]] value_type const* singleChunkPtr () const noexcept {
467 return m_single_chunk_arena ? (value_type const*)m_single_chunk_arena->data() : nullptr;
468 }
469
472 [[nodiscard]] std::size_t singleChunkSize () const noexcept { return m_single_chunk_size; }
473
474 bool isAllRegular () const noexcept {
475#ifdef AMREX_USE_EB
476 const auto *const f = dynamic_cast<EBFArrayBoxFactory const*>(m_factory.get());
477 if (f) {
478 return f->isAllRegular();
479 } else {
480 return true;
481 }
482#else
483 return true;
484#endif
485 }
486
496 bool ok () const;
497
505 bool isDefined () const;
506
508 const FAB& operator[] (const MFIter& mfi) const noexcept { return *(this->fabPtr(mfi)); }
509
511 const FAB& get (const MFIter& mfi) const noexcept { return *(this->fabPtr(mfi)); }
512
514 FAB& operator[] (const MFIter& mfi) noexcept { return *(this->fabPtr(mfi)); }
515
517 FAB& get (const MFIter& mfi) noexcept { return *(this->fabPtr(mfi)); }
518
520 const FAB& operator[] (int K) const noexcept { return *(this->fabPtr(K)); }
521
523 const FAB& get (int K) const noexcept { return *(this->fabPtr(K)); }
524
526 FAB& operator[] (int K) noexcept { return *(this->fabPtr(K)); }
527
529 FAB& get (int K) noexcept { return *(this->fabPtr(K)); }
530
532 FAB& atLocalIdx (int L) noexcept { return *m_fabs_v[L]; }
533 const FAB& atLocalIdx (int L) const noexcept { return *m_fabs_v[L]; }
534
536 FAB * fabPtr (const MFIter& mfi) noexcept;
537 FAB const* fabPtr (const MFIter& mfi) const noexcept;
538 FAB * fabPtr (int K) noexcept; // Here K is global index
539 FAB const* fabPtr (int K) const noexcept;
540
541 void prefetchToHost (const MFIter& mfi) const noexcept
542 requires (BaseFabType<FAB>)
543 {
544#ifdef AMREX_USE_CUDA
545 this->fabPtr(mfi)->prefetchToHost();
546#else
548#endif
549 }
550
551 void prefetchToDevice (const MFIter& mfi) const noexcept
552 requires (BaseFabType<FAB>)
553 {
554#ifdef AMREX_USE_CUDA
555 this->fabPtr(mfi)->prefetchToDevice();
556#else
558#endif
559 }
560
561 Array4<typename FabArray<FAB>::value_type const> array (const MFIter& mfi) const noexcept
562 requires (BaseFabType<FAB>)
563 {
564 return fabPtr(mfi)->const_array();
565 }
566
568 requires (BaseFabType<FAB>)
569 {
570 return fabPtr(mfi)->array();
571 }
572
574 requires (BaseFabType<FAB>)
575 {
576 return fabPtr(K)->const_array();
577 }
578
580 requires (BaseFabType<FAB>)
581 {
582 return fabPtr(K)->array();
583 }
584
586 requires (BaseFabType<FAB>)
587 {
588 return fabPtr(mfi)->const_array();
589 }
590
592 requires (BaseFabType<FAB>)
593 {
594 return fabPtr(K)->const_array();
595 }
596
597 Array4<typename FabArray<FAB>::value_type const> array (const MFIter& mfi, int start_comp) const noexcept
598 requires (BaseFabType<FAB>)
599 {
600 return fabPtr(mfi)->const_array(start_comp);
601 }
602
603 Array4<typename FabArray<FAB>::value_type> array (const MFIter& mfi, int start_comp) noexcept
604 requires (BaseFabType<FAB>)
605 {
606 return fabPtr(mfi)->array(start_comp);
607 }
608
609 Array4<typename FabArray<FAB>::value_type const> array (int K, int start_comp) const noexcept
610 requires (BaseFabType<FAB>)
611 {
612 return fabPtr(K)->const_array(start_comp);
613 }
614
615 Array4<typename FabArray<FAB>::value_type> array (int K, int start_comp) noexcept
616 requires (BaseFabType<FAB>)
617 {
618 return fabPtr(K)->array(start_comp);
619 }
620
621 Array4<typename FabArray<FAB>::value_type const> const_array (const MFIter& mfi, int start_comp) const noexcept
622 requires (BaseFabType<FAB>)
623 {
624 return fabPtr(mfi)->const_array(start_comp);
625 }
626
627 Array4<typename FabArray<FAB>::value_type const> const_array (int K, int start_comp) const noexcept
628 requires (BaseFabType<FAB>)
629 {
630 return fabPtr(K)->const_array(start_comp);
631 }
632
634 requires (BaseFabType<FAB>)
635 {
636 build_arrays();
637 return m_arrays;
638 }
639
641 requires (BaseFabType<FAB>)
642 {
643 build_arrays();
644 return m_const_arrays;
645 }
646
648 requires (BaseFabType<FAB>)
649 {
650 build_arrays();
651 return m_const_arrays;
652 }
653
655 void setFab (int boxno, std::unique_ptr<FAB> elem);
656
658 template <class F=FAB>
659 requires (std::is_move_constructible_v<F>)
660 void setFab (int boxno, FAB&& elem);
661
663 void setFab (const MFIter&mfi, std::unique_ptr<FAB> elem);
664
666 template <class F=FAB>
667 requires (std::is_move_constructible_v<F>)
668 void setFab (const MFIter&mfi, FAB&& elem);
669
672 FAB* release (int K);
673
676 FAB* release (const MFIter& mfi);
677
679 void clear ();
680
695 template <BaseFabType SFAB, BaseFabType DFAB = FAB>
696 requires (std::is_convertible_v<typename SFAB::value_type,
697 typename DFAB::value_type>)
698 void LocalCopy (FabArray<SFAB> const& src, int scomp, int dcomp, int ncomp,
699 IntVect const& nghost);
700
713 template <class F=FAB>
714 requires (BaseFabType<F>)
715 void LocalAdd (FabArray<FAB> const& src, int scomp, int dcomp, int ncomp,
716 IntVect const& nghost);
717
719 template <class F=FAB>
720 requires (BaseFabType<F>)
721 void setVal (value_type val);
722
724 template <class F=FAB>
725 requires (BaseFabType<F>)
726 FabArray<FAB>& operator= (value_type val);
727
733 template <class F=FAB>
734 requires (BaseFabType<F>)
736 int comp,
737 int ncomp,
738 int nghost = 0);
739
740 template <class F=FAB>
741 requires (BaseFabType<F>)
743 int comp,
744 int ncomp,
745 const IntVect& nghost);
746
753 template <class F=FAB>
754 requires (BaseFabType<F>)
756 const Box& region,
757 int comp,
758 int ncomp,
759 int nghost = 0);
760
761 template <class F=FAB>
762 requires (BaseFabType<F>)
764 const Box& region,
765 int comp,
766 int ncomp,
767 const IntVect& nghost);
772 template <class F=FAB>
773 requires (BaseFabType<F>)
774 void setVal (value_type val, int nghost);
775
776 template <class F=FAB>
777 requires (BaseFabType<F>)
778 void setVal (value_type val, const IntVect& nghost);
779
785 template <class F=FAB>
786 requires (BaseFabType<F>)
787 void setVal (value_type val, const Box& region, int nghost);
788
789 template <class F=FAB>
790 requires (BaseFabType<F>)
791 void setVal (value_type val, const Box& region, const IntVect& nghost);
792
793 template <class F=FAB>
794 requires (BaseFabType<F>)
795 void abs (int comp, int ncomp, int nghost = 0);
796
797 template <class F=FAB>
798 requires (BaseFabType<F>)
799 void abs (int comp, int ncomp, const IntVect& nghost);
800
801 template <class F=FAB>
802 requires (BaseFabType<F>)
803 void plus (value_type val, int comp, int num_comp, int nghost = 0);
804
805 template <class F=FAB>
806 requires (BaseFabType<F>)
807 void plus (value_type val, const Box& region, int comp, int num_comp, int nghost = 0);
808
809 template <class F=FAB>
810 requires (BaseFabType<F>)
811 void mult (value_type val, int comp, int num_comp, int nghost = 0);
812
813 template <class F=FAB>
814 requires (BaseFabType<F>)
815 void mult (value_type val, const Box& region, int comp, int num_comp, int nghost = 0);
816
817 template <class F=FAB>
818 requires (BaseFabType<F>)
819 void invert (value_type numerator, int comp, int num_comp, int nghost = 0);
820
821 template <class F=FAB>
822 requires (BaseFabType<F>)
823 void invert (value_type numerator, const Box& region, int comp, int num_comp, int nghost = 0);
824
826 template <class F=FAB>
827 requires (BaseFabType<F>)
829
831 template <class F=FAB>
832 requires (BaseFabType<F>)
833 void setBndry (value_type val, int strt_comp, int ncomp);
834
836 template <class F=FAB>
837 requires (BaseFabType<F>)
838 void setDomainBndry (value_type val, const Geometry& geom);
839
841 template <class F=FAB>
842 requires (BaseFabType<F>)
843 void setDomainBndry (value_type val, int strt_comp, int ncomp, const Geometry& geom);
844
846 template <std::integral I>
847 requires (BaseFabType<FAB> && (sizeof(I) >= sizeof(Long)))
848 void capacityOfFabs (LayoutData<I>& mem) const;
849
859 template <typename F=FAB>
860 requires (BaseFabType<F>)
861 typename F::value_type
862 sum (int comp, IntVect const& nghost, bool local = false) const;
863
870 void ParallelAdd (const FabArray<FAB>& src,
871 const Periodicity& period = Periodicity::NonPeriodic())
872 { ParallelCopy(src,period,FabArray::ADD); }
873 void ParallelCopy (const FabArray<FAB>& src,
874 const Periodicity& period = Periodicity::NonPeriodic(),
876 { ParallelCopy(src,0,0,nComp(),0,0,period,op); }
877
878 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
879 void copy (const FabArray<FAB>& src,
880 const Periodicity& period = Periodicity::NonPeriodic(),
882 { ParallelCopy(src,period,op); }
883
885 const Periodicity& period = Periodicity::NonPeriodic())
886 { ParallelCopy_nowait(src,period,FabArray::ADD); }
888 const Periodicity& period = Periodicity::NonPeriodic(),
890 { ParallelCopy_nowait(src,0,0,nComp(),0,0,period,op); }
891
900 void ParallelAdd (const FabArray<FAB>& src,
901 int src_comp,
902 int dest_comp,
903 int num_comp,
904 const Periodicity& period = Periodicity::NonPeriodic())
905 { ParallelCopy(src,src_comp,dest_comp,num_comp, period, FabArrayBase::ADD); }
906 void ParallelCopy (const FabArray<FAB>& src,
907 int src_comp,
908 int dest_comp,
909 int num_comp,
910 const Periodicity& period = Periodicity::NonPeriodic(),
912 { ParallelCopy(src,src_comp,dest_comp,num_comp,0,0,period,op); }
913
914 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
915 void copy (const FabArray<FAB>& src,
916 int src_comp,
917 int dest_comp,
918 int num_comp,
919 const Periodicity& period = Periodicity::NonPeriodic(),
921 { ParallelCopy(src,src_comp,dest_comp,num_comp, period, op); }
922
924 int src_comp,
925 int dest_comp,
926 int num_comp,
927 const Periodicity& period = Periodicity::NonPeriodic())
928 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp, period, FabArrayBase::ADD); }
930 int src_comp,
931 int dest_comp,
932 int num_comp,
933 const Periodicity& period = Periodicity::NonPeriodic(),
935 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,0,0,period,op); }
936
938 void ParallelAdd (const FabArray<FAB>& src,
939 int src_comp,
940 int dest_comp,
941 int num_comp,
942 int src_nghost,
943 int dst_nghost,
944 const Periodicity& period = Periodicity::NonPeriodic())
945 { ParallelCopy(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),IntVect(dst_nghost),period,
947 void ParallelAdd (const FabArray<FAB>& src,
948 int src_comp,
949 int dest_comp,
950 int num_comp,
951 const IntVect& src_nghost,
952 const IntVect& dst_nghost,
953 const Periodicity& period = Periodicity::NonPeriodic())
954 { ParallelCopy(src,src_comp,dest_comp,num_comp,src_nghost,dst_nghost,period,FabArrayBase::ADD); }
955 void ParallelCopy (const FabArray<FAB>& src,
956 int src_comp,
957 int dest_comp,
958 int num_comp,
959 int src_nghost,
960 int dst_nghost,
961 const Periodicity& period = Periodicity::NonPeriodic(),
963 { ParallelCopy(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),IntVect(dst_nghost),period,op); }
964 void ParallelCopy (const FabArray<FAB>& src,
965 int scomp,
966 int dcomp,
967 int ncomp,
968 const IntVect& snghost,
969 const IntVect& dnghost,
970 const Periodicity& period = Periodicity::NonPeriodic(),
972 const FabArrayBase::CPC* a_cpc = nullptr,
973 bool deterministic = false);
974
976 int src_comp,
977 int dest_comp,
978 int num_comp,
979 int src_nghost,
980 int dst_nghost,
981 const Periodicity& period = Periodicity::NonPeriodic())
982 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),
983 IntVect(dst_nghost),period,FabArrayBase::ADD); }
984
986 int src_comp,
987 int dest_comp,
988 int num_comp,
989 const IntVect& src_nghost,
990 const IntVect& dst_nghost,
991 const Periodicity& period = Periodicity::NonPeriodic())
992 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,src_nghost,
993 dst_nghost,period,FabArrayBase::ADD); }
994
996 int src_comp,
997 int dest_comp,
998 int num_comp,
999 int src_nghost,
1000 int dst_nghost,
1001 const Periodicity& period = Periodicity::NonPeriodic(),
1003 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),
1004 IntVect(dst_nghost),period,op); }
1005
1006 void ParallelCopy_nowait (const FabArray<FAB>& src,
1007 int scomp,
1008 int dcomp,
1009 int ncomp,
1010 const IntVect& snghost,
1011 const IntVect& dnghost,
1012 const Periodicity& period = Periodicity::NonPeriodic(),
1014 const FabArrayBase::CPC* a_cpc = nullptr,
1015 bool to_ghost_cells_only = false,
1016 bool deterministic = false);
1017
1018 void ParallelCopy_nowait (const FabArray<FAB>& src,
1019 int scomp,
1020 int dcomp,
1021 int ncomp,
1022 const IntVect& snghost,
1023 const IntVect& dnghost,
1024 const IntVect& offset,
1025 const Periodicity& period = Periodicity::NonPeriodic(),
1027 const FabArrayBase::CPC* a_cpc = nullptr,
1028 bool to_ghost_cells_only = false,
1029 bool deterministic = false);
1030
1031 void ParallelCopy_finish ();
1032
1033 void ParallelCopyToGhost (const FabArray<FAB>& src,
1034 int scomp,
1035 int dcomp,
1036 int ncomp,
1037 const IntVect& snghost,
1038 const IntVect& dnghost,
1039 const Periodicity& period = Periodicity::NonPeriodic());
1040
1042 int scomp,
1043 int dcomp,
1044 int ncomp,
1045 const IntVect& snghost,
1046 const IntVect& dnghost,
1047 const Periodicity& period = Periodicity::NonPeriodic());
1048
1050
1063 void ParallelCopy (const FabArray<FAB>& src, int src_comp, int dest_comp, int num_comp,
1064 const IntVect& snghost, const IntVect& dnghost,
1065 const IntVect& offset, const Periodicity& period);
1066
1079 void ParallelAdd (const FabArray<FAB>& src, int src_comp, int dest_comp, int num_comp,
1080 const IntVect& snghost, const IntVect& dnghost,
1081 const IntVect& offset, const Periodicity& period);
1082
1083 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
1084 void copy (const FabArray<FAB>& src,
1085 int src_comp,
1086 int dest_comp,
1087 int num_comp,
1088 int src_nghost,
1089 int dst_nghost,
1090 const Periodicity& period = Periodicity::NonPeriodic(),
1092 { ParallelCopy(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),IntVect(dst_nghost),period,op); }
1093
1094 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
1095 void copy (const FabArray<FAB>& src,
1096 int src_comp,
1097 int dest_comp,
1098 int num_comp,
1099 const IntVect& src_nghost,
1100 const IntVect& dst_nghost,
1101 const Periodicity& period = Periodicity::NonPeriodic(),
1103 { ParallelCopy(src,src_comp,dest_comp,num_comp,src_nghost,dst_nghost,period,op); }
1104
1106 void Redistribute (const FabArray<FAB>& src,
1107 int scomp,
1108 int dcomp,
1109 int ncomp,
1110 const IntVect& nghost);
1111
1117 void copyTo (FAB& dest, int nghost = 0) const;
1118
1126 void copyTo (FAB& dest, int scomp, int dcomp, int ncomp, int nghost = 0) const;
1127
1129 void shift (const IntVect& v);
1130
1131 bool defined (int K) const noexcept;
1132 bool defined (const MFIter& mfi) const noexcept;
1133
1146 template <typename BUF=value_type>
1147 void FillBoundary (bool cross = false);
1148
1150 template <typename BUF=value_type>
1151 void FillBoundary (const Periodicity& period, bool cross = false);
1152
1153 template <typename BUF=value_type>
1154 void FillBoundary (const IntVect& nghost, const Periodicity& period, bool cross = false);
1155
1158 template <typename BUF=value_type>
1159 void FillBoundary (int scomp, int ncomp, bool cross = false);
1160
1162 template <typename BUF=value_type>
1163 void FillBoundary (int scomp, int ncomp, const Periodicity& period, bool cross = false);
1164
1166 template <typename BUF=value_type>
1167 void FillBoundary (int scomp, int ncomp, const IntVect& nghost, const Periodicity& period, bool cross = false);
1168
1169 template <typename BUF=value_type>
1170 void FillBoundary_nowait (bool cross = false);
1171
1172 template <typename BUF=value_type>
1173 void FillBoundary_nowait (const Periodicity& period, bool cross = false);
1174
1175 template <typename BUF=value_type>
1176 void FillBoundary_nowait (const IntVect& nghost, const Periodicity& period, bool cross = false);
1177
1178 template <typename BUF=value_type>
1179 void FillBoundary_nowait (int scomp, int ncomp, bool cross = false);
1180
1181 template <typename BUF=value_type>
1182 void FillBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool cross = false);
1183
1184 template <typename BUF=value_type>
1185 void FillBoundary_nowait (int scomp, int ncomp, const IntVect& nghost, const Periodicity& period, bool cross = false);
1186
1187 template <typename BUF=value_type, class F=FAB>
1188 requires (BaseFabType<F>)
1189 void FillBoundary_finish ();
1190
1191 void FillBoundary_test ();
1192
1223 void FillBoundaryAndSync (int scomp, int ncomp, const IntVect& nghost,
1224 const Periodicity& period);
1226 void FillBoundaryAndSync_nowait (int scomp, int ncomp, const IntVect& nghost,
1227 const Periodicity& period);
1229
1266 void OverrideSync (int scomp, int ncomp, const Periodicity& period);
1268 void OverrideSync_nowait (int scomp, int ncomp, const Periodicity& period);
1270
1282 bool deterministic = false);
1284 void SumBoundary (int scomp, int ncomp, const Periodicity& period = Periodicity::NonPeriodic(),
1285 bool deterministic = false);
1287 bool deterministic = false);
1288 void SumBoundary_nowait (int scomp, int ncomp, const Periodicity& period = Periodicity::NonPeriodic(),
1289 bool deterministic = false);
1290
1301 void SumBoundary (int scomp, int ncomp, IntVect const& nghost,
1302 const Periodicity& period = Periodicity::NonPeriodic(),
1303 bool deterministic = false);
1304 void SumBoundary_nowait (int scomp, int ncomp, IntVect const& nghost,
1305 const Periodicity& period = Periodicity::NonPeriodic(),
1306 bool deterministic = false);
1307
1319 void SumBoundary (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost,
1320 const Periodicity& period = Periodicity::NonPeriodic(),
1321 bool deterministic = false);
1322 void SumBoundary_nowait (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost,
1323 const Periodicity& period = Periodicity::NonPeriodic(),
1324 bool deterministic = false);
1326
1337 void EnforcePeriodicity (const Periodicity& period);
1339 void EnforcePeriodicity (int scomp, int ncomp, const Periodicity& period);
1341 void EnforcePeriodicity (int scomp, int ncomp, const IntVect& nghost,
1342 const Periodicity& period);
1343
1344 // covered : ghost cells covered by valid cells of this FabArray
1345 // (including periodically shifted valid cells)
1346 // notcovered: ghost cells not covered by valid cells
1347 // (including ghost cells outside periodic boundaries)
1348 // physbnd : boundary cells outside the domain (excluding periodic boundaries)
1349 // interior : interior cells (i.e., valid cells)
1350 template <class F=FAB>
1351 requires (BaseFabType<F>)
1352 void BuildMask (const Box& phys_domain, const Periodicity& period,
1353 value_type covered, value_type notcovered,
1354 value_type physbnd, value_type interior);
1355
1356 // The following are private functions. But we have to make them public for cuda.
1357
1358 template <typename BUF=value_type, class F=FAB>
1359 requires (BaseFabType<F>)
1360 void FBEP_nowait (int scomp, int ncomp, const IntVect& nghost,
1361 const Periodicity& period, bool cross,
1362 bool enforce_periodicity_only = false,
1363 bool override_sync = false,
1364 IntVect const& sumboundary_src_nghost = IntVect(-1),
1365 bool deterministic = false);
1366
1367 void FB_local_copy_cpu (const FB& TheFB, int scomp, int ncomp);
1368 void FB_local_add_cpu (const FB& TheFB, int scomp, int ncomp);
1369 void PC_local_cpu (const CPC& thecpc, FabArray<FAB> const& src,
1370 int scomp, int dcomp, int ncomp, CpOp op);
1371
1372 template <class F=FAB>
1373 requires (BaseFabType<F>)
1374 void setVal (value_type val, const CommMetaData& thecmd, int scomp, int ncomp);
1375
1376 template <class F=FAB>
1377 requires (BaseFabType<F>)
1379
1380#ifdef AMREX_USE_GPU
1381
1383 FB_get_local_copy_tag_vector (const FB& TheFB);
1384
1385 void FB_local_copy_gpu (const FB& TheFB, int scomp, int ncomp);
1386 void FB_local_add_gpu (const FB& TheFB, int scomp, int ncomp, bool deterministic);
1387 void PC_local_gpu (const CPC& thecpc, FabArray<FAB> const& src,
1388 int scomp, int dcomp, int ncomp, CpOp op, bool deterministic);
1389
1390 void CMD_local_setVal_gpu (value_type x, const CommMetaData& thecmd, int scomp, int ncomp);
1391 void CMD_remote_setVal_gpu (value_type x, const CommMetaData& thecmd, int scomp, int ncomp);
1392
1393#if defined(__CUDACC__)
1394
1395 void FB_local_copy_cuda_graph_1 (const FB& TheFB, int scomp, int ncomp);
1396 void FB_local_copy_cuda_graph_n (const FB& TheFB, int scomp, int ncomp);
1397
1398#endif
1399#endif
1400
1401#ifdef AMREX_USE_MPI
1402
1403#ifdef AMREX_USE_GPU
1404#if defined(__CUDACC__)
1405
1406 void FB_pack_send_buffer_cuda_graph (const FB& TheFB, int scomp, int ncomp,
1407 Vector<char*>& send_data,
1408 Vector<std::size_t> const& send_size,
1409 Vector<const CopyComTagsContainer*> const& send_cctc);
1410
1411 void FB_unpack_recv_buffer_cuda_graph (const FB& TheFB, int dcomp, int ncomp,
1412 Vector<char*> const& recv_data,
1413 Vector<std::size_t> const& recv_size,
1414 Vector<const CopyComTagsContainer*> const& recv_cctc,
1415 bool is_thread_safe);
1416
1417#endif
1418
1419 template <typename BUF = value_type>
1420 static void pack_send_buffer_gpu (FabArray<FAB> const& src, int scomp, int ncomp,
1421 Vector<char*> const& send_data,
1422 Vector<std::size_t> const& send_size,
1423 Vector<const CopyComTagsContainer*> const& send_cctc,
1424 std::uint64_t id);
1425
1426 template <typename BUF = value_type>
1427 static void unpack_recv_buffer_gpu (FabArray<FAB>& dst, int dcomp, int ncomp,
1428 Vector<char*> const& recv_data,
1429 Vector<std::size_t> const& recv_size,
1430 Vector<const CopyComTagsContainer*> const& recv_cctc,
1431 CpOp op, bool is_thread_safe,
1432 std::uint64_t id, bool deterministic);
1433
1434 template <typename BUF>
1437 Vector<std::size_t> const& recv_size,
1438 Vector<CopyComTagsContainer const*> const& recv_cctc,
1439 int ncomp, std::uint64_t id);
1440
1441 template <typename BUF>
1444 Vector<std::size_t> const& send_size,
1445 Vector<CopyComTagsContainer const*> const& send_cctc,
1446 int ncomp, std::uint64_t id) const;
1447
1448#endif
1449
1450 template <typename BUF = value_type>
1451 static void pack_send_buffer_cpu (FabArray<FAB> const& src, int scomp, int ncomp,
1452 Vector<char*> const& send_data,
1453 Vector<std::size_t> const& send_size,
1454 Vector<const CopyComTagsContainer*> const& send_cctc);
1455
1456 template <typename BUF = value_type>
1457 static void unpack_recv_buffer_cpu (FabArray<FAB>& dst, int dcomp, int ncomp,
1458 Vector<char*> const& recv_data,
1459 Vector<std::size_t> const& recv_size,
1460 Vector<const CopyComTagsContainer*> const& recv_cctc,
1461 CpOp op, bool is_thread_safe);
1462
1463#endif
1464
1477 template <typename F=FAB>
1478 requires (BaseFabType<F>)
1479 typename F::value_type
1480 norminf (int comp, int ncomp, IntVect const& nghost, bool local = false,
1481 [[maybe_unused]] bool ignore_covered = false) const;
1482
1495 template <typename IFAB, typename F=FAB>
1496 requires (BaseFabType<F>)
1497 typename F::value_type
1498 norminf (FabArray<IFAB> const& mask, int comp, int ncomp, IntVect const& nghost,
1499 bool local = false) const;
1500
1501protected:
1502
1503 std::unique_ptr<FabFactory<FAB> > m_factory;
1505 std::unique_ptr<detail::SingleChunkArena> m_single_chunk_arena;
1507
1510
1511 //
1513 std::vector<FAB*> m_fabs_v;
1514
1515#ifdef AMREX_USE_GPU
1516 mutable void* m_dp_arrays = nullptr;
1517#endif
1518 mutable void* m_hp_arrays = nullptr;
1521
1523
1525 struct ShMem {
1526
1527 ShMem () noexcept = default;
1528
1529 ~ShMem () { // NOLINT
1530#if defined(BL_USE_MPI3)
1531 if (win != MPI_WIN_NULL) { MPI_Win_free(&win); }
1532#endif
1533#ifdef BL_USE_TEAM
1534 if (alloc) {
1536 }
1537#endif
1538 }
1539 ShMem (ShMem&& rhs) noexcept
1540 : alloc(rhs.alloc), n_values(rhs.n_values), n_points(rhs.n_points)
1541#if defined(BL_USE_MPI3)
1542 , win(rhs.win)
1543#endif
1544 {
1545 rhs.alloc = false;
1546#if defined(BL_USE_MPI3)
1547 rhs.win = MPI_WIN_NULL;
1548#endif
1549 }
1550 ShMem& operator= (ShMem&& rhs) noexcept {
1551 if (&rhs != this) {
1552 alloc = rhs.alloc;
1553 n_values = rhs.n_values;
1554 n_points = rhs.n_points;
1555 rhs.alloc = false;
1556#if defined(BL_USE_MPI3)
1557 win = rhs.win;
1558 rhs.win = MPI_WIN_NULL;
1559#endif
1560 }
1561 return *this;
1562 }
1563 ShMem (const ShMem&) = delete;
1564 ShMem& operator= (const ShMem&) = delete;
1565 bool alloc{false};
1568#if defined(BL_USE_MPI3)
1569 MPI_Win win = MPI_WIN_NULL;
1570#endif
1571 };
1573
1574 bool SharedMemory () const noexcept { return shmem.alloc; }
1575
1576private:
1577 using Iterator = typename std::vector<FAB*>::iterator;
1578
1579 void AllocFabs (const FabFactory<FAB>& factory, Arena* ar,
1581 bool alloc_single_chunk);
1582
1583 void setFab_assert (int K, FAB const& fab) const;
1584
1585 template <class F=FAB>
1586 requires (BaseFabType<F>)
1587 void build_arrays () const;
1588
1589 void clear_arrays ();
1590
1591#ifdef AMREX_USE_GPU
1592 std::map<std::uint64_t,
1593 std::unique_ptr<TagVector<Array4CopyTag<value_type>>>>
1594 m_fb_local_copy_handler;
1595
1596 using RecvSendCopyHandlerKey = std::tuple<std::uint64_t,std::size_t,int>;
1597 std::map<RecvSendCopyHandlerKey,
1598 std::unique_ptr<TagVector<CommRecvBufTag<value_type>>>>
1599 m_recv_copy_handler;
1600 mutable std::map<RecvSendCopyHandlerKey,
1601 std::unique_ptr<TagVector<CommSendBufTag<value_type>>>>
1602 m_send_copy_handler;
1603#endif
1604
1605public:
1606
1607#ifdef BL_USE_MPI
1608
1610 template <typename BUF=value_type>
1611 static void PostRcvs (const MapOfCopyComTagContainers& RcvTags,
1612 char*& the_recv_data,
1613 Vector<char*>& recv_data,
1614 Vector<std::size_t>& recv_size,
1615 Vector<int>& recv_from,
1616 Vector<MPI_Request>& recv_reqs,
1617 int ncomp,
1618 int SeqNum);
1619
1620 template <typename BUF=value_type>
1622 static TheFaArenaPointer PostRcvs (const MapOfCopyComTagContainers& RcvTags,
1623 Vector<char*>& recv_data,
1624 Vector<std::size_t>& recv_size,
1625 Vector<int>& recv_from,
1626 Vector<MPI_Request>& recv_reqs,
1627 int ncomp,
1628 int SeqNum);
1629
1630 template <typename BUF=value_type>
1631 static void PrepareSendBuffers (const MapOfCopyComTagContainers& SndTags,
1632 char*& the_send_data,
1633 Vector<char*>& send_data,
1634 Vector<std::size_t>& send_size,
1635 Vector<int>& send_rank,
1636 Vector<MPI_Request>& send_reqs,
1638 int ncomp);
1639
1640 template <typename BUF=value_type>
1642 static TheFaArenaPointer PrepareSendBuffers (const MapOfCopyComTagContainers& SndTags,
1643 Vector<char*>& send_data,
1644 Vector<std::size_t>& send_size,
1645 Vector<int>& send_rank,
1646 Vector<MPI_Request>& send_reqs,
1648 int ncomp);
1649
1650 static void PostSnds (Vector<char*> const& send_data,
1651 Vector<std::size_t> const& send_size,
1652 Vector<int> const& send_rank,
1653 Vector<MPI_Request>& send_reqs,
1654 int SeqNum);
1655#endif
1656
1657 std::unique_ptr<FBData<FAB>> fbd;
1658 std::unique_ptr<PCData<FAB>> pcd;
1659
1660 // Pointer to temporary fab used in non-blocking amrex::OverrideSync
1661 std::unique_ptr< FabArray<FAB> > os_temp;
1662
1674 template <class F=FAB>
1675 requires (BaseFabType<F>)
1676 static void Saxpy (FabArray<FAB>& y, value_type a, FabArray<FAB> const& x,
1677 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1678
1690 template <class F=FAB>
1691 requires (BaseFabType<F>)
1692 static void Xpay (FabArray<FAB>& y, value_type a, FabArray<FAB> const& x,
1693 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1694
1709 template <class F=FAB>
1710 requires (BaseFabType<F>)
1711 static void LinComb (FabArray<FAB>& dst,
1712 value_type a, const FabArray<FAB>& x, int xcomp,
1713 value_type b, const FabArray<FAB>& y, int ycomp,
1714 int dstcomp, int numcomp, const IntVect& nghost);
1715
1729 template <class F=FAB>
1730 requires (BaseFabType<F>)
1731 static void Saxpy_Xpay (FabArray<FAB>& y, value_type a1, FabArray<FAB> const& x1,
1732 value_type a2, FabArray<FAB> const& x2,
1733 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1734
1749 template <class F=FAB>
1750 requires (BaseFabType<F>)
1751 static void Saxpy_Saxpy (FabArray<FAB>& y1, value_type a1, FabArray<FAB> const& x1,
1752 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x2,
1753 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1754
1768 template <class F=FAB>
1769 requires (BaseFabType<F>)
1771 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x,
1772 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1773};
1774
1775}
1776
1777#include <AMReX_FabArrayCommI.H>
1778
1779namespace amrex {
1780
1781template <class FAB>
1782bool
1783FabArray<FAB>::defined (int K) const noexcept
1784{
1785 int li = localindex(K);
1786 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != 0) {
1787 return true;
1788 }
1789 else {
1790 return false;
1791 }
1792}
1793
1794template <class FAB>
1795bool
1796FabArray<FAB>::defined (const MFIter& mfi) const noexcept
1797{
1798 int li = mfi.LocalIndex();
1799 if (li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
1800 return true;
1801 }
1802 else {
1803 return false;
1804 }
1805}
1806
1807template <class FAB>
1808FAB*
1809FabArray<FAB>::fabPtr (const MFIter& mfi) noexcept
1810{
1811 AMREX_ASSERT(mfi.LocalIndex() < indexArray.size());
1813 int li = mfi.LocalIndex();
1814 return m_fabs_v[li];
1815}
1816
1817template <class FAB>
1818FAB const*
1819FabArray<FAB>::fabPtr (const MFIter& mfi) const noexcept
1820{
1821 AMREX_ASSERT(mfi.LocalIndex() < indexArray.size());
1823 int li = mfi.LocalIndex();
1824 return m_fabs_v[li];
1825}
1826
1827template <class FAB>
1828FAB*
1830{
1831 int li = localindex(K);
1832 AMREX_ASSERT(li >=0 && li < indexArray.size());
1833 return m_fabs_v[li];
1834}
1835
1836template <class FAB>
1837FAB const*
1838FabArray<FAB>::fabPtr (int K) const noexcept
1839{
1840 int li = localindex(K);
1841 AMREX_ASSERT(li >=0 && li < indexArray.size());
1842 return m_fabs_v[li];
1843}
1844
1845template <class FAB>
1846template <class F>
1847requires (BaseFabType<F>)
1848void
1850{
1851 using A = Array4<value_type>;
1852 using AC = Array4<value_type const>;
1853 static_assert(sizeof(A) == sizeof(AC), "sizeof(Array4<T>) != sizeof(Array4<T const>)");
1854 if (!m_hp_arrays && local_size() > 0) {
1855 const int n = local_size();
1856#ifdef AMREX_USE_GPU
1857 m_hp_arrays = (void*)The_Pinned_Arena()->alloc(n*2*sizeof(A));
1858 m_dp_arrays = (void*)The_Arena()->alloc(n*2*sizeof(A));
1859#else
1860 m_hp_arrays = std::malloc(n*2*sizeof(A));
1861#endif
1862 for (int li = 0; li < n; ++li) {
1863 if (m_fabs_v[li]) {
1864 new ((A*)m_hp_arrays+li) A(m_fabs_v[li]->array());
1865 new ((AC*)m_hp_arrays+li+n) AC(m_fabs_v[li]->const_array());
1866 } else {
1867 new ((A*)m_hp_arrays+li) A{};
1868 new ((AC*)m_hp_arrays+li+n) AC{};
1869 }
1870 }
1871 m_arrays.hp = (A*)m_hp_arrays;
1872 m_const_arrays.hp = (AC*)m_hp_arrays + n;
1873#ifdef AMREX_USE_GPU
1874 m_arrays.dp = (A*)m_dp_arrays;
1875 m_const_arrays.dp = (AC*)m_dp_arrays + n;
1876 Gpu::htod_memcpy_async(m_dp_arrays, m_hp_arrays, n*2*sizeof(A));
1877 if (!Gpu::inNoSyncRegion()) {
1879 }
1880#endif
1881 }
1882}
1883
1884template <class FAB>
1885void
1886FabArray<FAB>::clear_arrays ()
1887{
1888#ifdef AMREX_USE_GPU
1889 The_Pinned_Arena()->free(m_hp_arrays);
1890 The_Arena()->free(m_dp_arrays);
1891 m_dp_arrays = nullptr;
1892#else
1893 std::free(m_hp_arrays);
1894#endif
1895 m_hp_arrays = nullptr;
1896 m_arrays.hp = nullptr;
1897 m_const_arrays.hp = nullptr;
1898}
1899
1900template <class FAB>
1902FAB*
1904{
1905 const int li = localindex(K);
1906 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
1907 AMREX_ASSERT(m_single_chunk_arena == nullptr);
1908 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
1909 if (nbytes > 0) {
1910 for (auto const& t : m_tags) {
1911 updateMemUsage(t, -nbytes, nullptr);
1912 }
1913 }
1914 return std::exchange(m_fabs_v[li], nullptr);
1915 } else {
1916 return nullptr;
1917 }
1918}
1919
1920template <class FAB>
1922FAB*
1924{
1925 const int li = mfi.LocalIndex();
1926 if (li >= 0 && li < std::ssize(m_fabs_v) && m_fabs_v[li] != nullptr) {
1927 AMREX_ASSERT(m_single_chunk_arena == nullptr);
1928 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
1929 if (nbytes > 0) {
1930 for (auto const& t : m_tags) {
1931 updateMemUsage(t, -nbytes, nullptr);
1932 }
1933 }
1934 return std::exchange(m_fabs_v[li], nullptr);
1935 } else {
1936 return nullptr;
1937 }
1938}
1939
1940template <class FAB>
1941void
1943{
1944 if (define_function_called)
1945 {
1946 define_function_called = false;
1947 clearThisBD();
1948 }
1949
1950 Long nbytes = 0L;
1951 for (auto *x : m_fabs_v) {
1952 if (x) {
1953 nbytes += amrex::nBytesOwned(*x);
1954 m_factory->destroy(x);
1955 }
1956 }
1957 m_fabs_v.clear();
1958 clear_arrays();
1959 m_factory.reset();
1960 m_dallocator.m_arena = nullptr;
1961 // no need to clear the non-blocking fillboundary stuff
1962
1963 if (nbytes > 0) {
1964 for (auto const& t : m_tags) {
1965 updateMemUsage(t, -nbytes, nullptr);
1966 }
1967 }
1968
1969 if (m_single_chunk_arena) {
1970 m_single_chunk_arena.reset();
1971 }
1972 m_single_chunk_size = 0;
1973
1974 m_tags.clear();
1975
1976#ifdef AMREX_USE_GPU
1977 m_fb_local_copy_handler.clear();
1978 m_recv_copy_handler.clear();
1979 m_send_copy_handler.clear();
1980#endif
1981
1983}
1984
1985template <class FAB>
1986template <BaseFabType SFAB, BaseFabType DFAB>
1987requires (std::is_convertible_v<typename SFAB::value_type, typename DFAB::value_type>)
1988void
1989FabArray<FAB>::LocalCopy (FabArray<SFAB> const& src, int scomp, int dcomp, int ncomp,
1990 IntVect const& nghost)
1991{
1992 amrex::Copy(*this, src, scomp, dcomp, ncomp, nghost);
1993}
1994
1995template <class FAB>
1996template <class F>
1997requires (BaseFabType<F>)
1998void
1999FabArray<FAB>::LocalAdd (FabArray<FAB> const& src, int scomp, int dcomp, int ncomp,
2000 IntVect const& nghost)
2001{
2002 amrex::Add(*this, src, scomp, dcomp, ncomp, nghost);
2003}
2004
2005template <class FAB>
2006template <class F>
2007requires (BaseFabType<F>)
2008void
2010{
2011 setVal(val,0,n_comp,IntVect(nghost));
2012}
2013
2014template <class FAB>
2015template <class F>
2016requires (BaseFabType<F>)
2017void
2019{
2020 setVal(val,0,n_comp,nghost);
2021}
2022
2023template <class FAB>
2024template <class F>
2025requires (BaseFabType<F>)
2026void
2027FabArray<FAB>::setVal (value_type val, const Box& region, int nghost)
2028{
2029 setVal(val,region,0,n_comp,IntVect(nghost));
2030}
2031
2032template <class FAB>
2033template <class F>
2034requires (BaseFabType<F>)
2035void
2036FabArray<FAB>::setVal (value_type val, const Box& region, const IntVect& nghost)
2037{
2038 setVal(val,region,0,n_comp,nghost);
2039}
2040
2041template <class FAB>
2043 : shmem()
2044{
2045 m_FA_stats.recordBuild();
2046}
2047
2048template <class FAB>
2050 : m_dallocator(a),
2051 shmem()
2052{
2053 m_FA_stats.recordBuild();
2054}
2055
2056template <class FAB>
2058 const DistributionMapping& dm,
2059 int nvar,
2060 int ngrow,
2061 const MFInfo& info,
2062 const FabFactory<FAB>& factory)
2063 : FabArray<FAB>(bxs,dm,nvar,IntVect(ngrow),info,factory)
2064{}
2065
2066template <class FAB>
2068 const DistributionMapping& dm,
2069 int nvar,
2070 const IntVect& ngrow,
2071 const MFInfo& info,
2072 const FabFactory<FAB>& factory)
2073 : m_factory(factory.clone()),
2074 shmem()
2075{
2077 define(bxs,dm,nvar,ngrow,info,*m_factory);
2078}
2079
2080template <class FAB>
2081FabArray<FAB>::FabArray (const FabArray<FAB>& rhs, MakeType maketype, int scomp, int ncomp)
2082 : m_factory(rhs.Factory().clone()),
2083 shmem()
2084{
2086 define(rhs.boxArray(), rhs.DistributionMap(), ncomp, rhs.nGrowVect(),
2087 MFInfo().SetAlloc(false), *m_factory);
2088
2089 if (maketype == amrex::make_alias)
2090 {
2091 for (int i = 0, n = indexArray.size(); i < n; ++i) {
2092 auto const& rhsfab = *(rhs.m_fabs_v[i]);
2093 m_fabs_v.push_back(m_factory->create_alias(rhsfab, scomp, ncomp));
2094 }
2095 }
2096 else
2097 {
2098 amrex::Abort("FabArray: unknown MakeType");
2099 }
2100}
2101
2102template <class FAB>
2104 : FabArrayBase (static_cast<FabArrayBase&&>(rhs))
2105 , m_factory (std::move(rhs.m_factory))
2106 , m_dallocator (rhs.m_dallocator)
2107 , m_single_chunk_arena(std::move(rhs.m_single_chunk_arena))
2108 , m_single_chunk_size(std::exchange(rhs.m_single_chunk_size,0))
2109 , define_function_called(rhs.define_function_called)
2110 , m_fabs_v (std::move(rhs.m_fabs_v))
2111#ifdef AMREX_USE_GPU
2112 , m_dp_arrays (std::exchange(rhs.m_dp_arrays, nullptr))
2113#endif
2114 , m_hp_arrays (std::exchange(rhs.m_hp_arrays, nullptr))
2115 , m_arrays (rhs.m_arrays)
2116 , m_const_arrays(rhs.m_const_arrays)
2117 , m_tags (std::move(rhs.m_tags))
2118 , shmem (std::move(rhs.shmem))
2119#ifdef AMREX_USE_GPU
2120 , m_fb_local_copy_handler(std::move(rhs.m_fb_local_copy_handler))
2121 , m_recv_copy_handler(std::move(rhs.m_recv_copy_handler))
2122 , m_send_copy_handler(std::move(rhs.m_send_copy_handler))
2123#endif
2124 // no need to worry about the data used in non-blocking FillBoundary.
2125{
2126 m_FA_stats.recordBuild();
2127 rhs.define_function_called = false; // the responsibility of clear BD has been transferred.
2128 rhs.m_fabs_v.clear(); // clear the data pointers so that rhs.clear does not delete them.
2129 rhs.clear();
2130}
2131
2132template <class FAB>
2135{
2136 if (&rhs != this)
2137 {
2138 clear();
2139
2140 FabArrayBase::operator=(static_cast<FabArrayBase&&>(rhs));
2141 m_factory = std::move(rhs.m_factory);
2142 m_dallocator = rhs.m_dallocator;
2143 m_single_chunk_arena = std::move(rhs.m_single_chunk_arena);
2144 std::swap(m_single_chunk_size, rhs.m_single_chunk_size);
2145 define_function_called = rhs.define_function_called;
2146 std::swap(m_fabs_v, rhs.m_fabs_v);
2147#ifdef AMREX_USE_GPU
2148 std::swap(m_dp_arrays, rhs.m_dp_arrays);
2149#endif
2150 std::swap(m_hp_arrays, rhs.m_hp_arrays);
2151 m_arrays = rhs.m_arrays;
2152 m_const_arrays = rhs.m_const_arrays;
2153 std::swap(m_tags, rhs.m_tags);
2154 shmem = std::move(rhs.shmem);
2155#ifdef AMREX_USE_GPU
2156 std::swap(m_fb_local_copy_handler, rhs.m_fb_local_copy_handler);
2157 std::swap(m_recv_copy_handler, rhs.m_recv_copy_handler);
2158 std::swap(m_send_copy_handler, rhs.m_send_copy_handler);
2159#endif
2160
2161 rhs.define_function_called = false;
2162 rhs.m_fabs_v.clear();
2163 rhs.m_tags.clear();
2164 rhs.clear();
2165 }
2166 return *this;
2167}
2168
2169template <class FAB>
2171{
2172 m_FA_stats.recordDelete();
2173 clear();
2174}
2175
2176template <class FAB>
2177bool
2179{
2180 if (!define_function_called) { return false; }
2181
2182 int isok = 1;
2183
2184 for (MFIter fai(*this); fai.isValid() && isok; ++fai)
2185 {
2186 if (defined(fai))
2187 {
2188 if (get(fai).box() != fabbox(fai.index()))
2189 {
2190 isok = 0;
2191 }
2192 }
2193 else
2194 {
2195 isok = 0;
2196 }
2197 }
2198
2200
2201 return isok == 1;
2202}
2203
2204template <class FAB>
2205bool
2207{
2208 return define_function_called;
2209}
2210
2211template <class FAB>
2212void
2214 const DistributionMapping& dm,
2215 int nvar,
2216 int ngrow,
2217 const MFInfo& info,
2218 const FabFactory<FAB>& a_factory)
2219{
2220 define(bxs,dm,nvar,IntVect(ngrow),info,a_factory);
2221}
2222
2223template <class FAB>
2224void
2226 const DistributionMapping& dm,
2227 int nvar,
2228 const IntVect& ngrow,
2229 const MFInfo& info,
2230 const FabFactory<FAB>& a_factory)
2231{
2232 std::unique_ptr<FabFactory<FAB> > factory(a_factory.clone());
2233
2234 auto *default_arena = m_dallocator.m_arena;
2235 clear();
2236
2237 m_factory = std::move(factory);
2238 m_dallocator.m_arena = info.arena ? info.arena : default_arena;
2239
2240 define_function_called = true;
2241
2242 AMREX_ASSERT(ngrow.allGE(0));
2243 AMREX_ASSERT(boxarray.empty());
2244 FabArrayBase::define(bxs, dm, nvar, ngrow);
2245
2246 addThisBD();
2247
2248 if(info.alloc) {
2249 AllocFabs(*m_factory, m_dallocator.m_arena, info.tags, info.alloc_single_chunk);
2250#ifdef BL_USE_TEAM
2252#endif
2253 }
2254}
2255
2256template <class FAB>
2257void
2259 const Vector<std::string>& tags, bool alloc_single_chunk)
2260{
2261 if (shmem.alloc) { alloc_single_chunk = false; }
2262 if constexpr (!IsBaseFab_v<FAB>) { alloc_single_chunk = false; }
2263
2264 const int n = indexArray.size();
2265 const int nworkers = ParallelDescriptor::TeamSize();
2266 shmem.alloc = (nworkers > 1);
2267
2268 bool alloc = !shmem.alloc;
2269
2270 FabInfo fab_info;
2271 fab_info.SetAlloc(alloc).SetShared(shmem.alloc).SetArena(ar);
2272
2273 if (alloc_single_chunk) {
2274 m_single_chunk_size = 0L;
2275 for (int i = 0; i < n; ++i) {
2276 int K = indexArray[i];
2277 const Box& tmpbox = fabbox(K);
2278 m_single_chunk_size += factory.nBytes(tmpbox, n_comp, K);
2279 }
2280 AMREX_ASSERT(m_single_chunk_size >= 0); // 0 is okay.
2281 m_single_chunk_arena = std::make_unique<detail::SingleChunkArena>(ar, m_single_chunk_size);
2282 fab_info.SetArena(m_single_chunk_arena.get());
2283 }
2284
2285 m_fabs_v.reserve(n);
2286
2287 Long nbytes = 0L;
2288 for (int i = 0; i < n; ++i)
2289 {
2290 int K = indexArray[i];
2291 const Box& tmpbox = fabbox(K);
2292 m_fabs_v.push_back(factory.create(tmpbox, n_comp, fab_info, K));
2293 nbytes += amrex::nBytesOwned(*m_fabs_v.back());
2294 }
2295
2296 m_tags.clear();
2297 m_tags.emplace_back("All");
2298 for (auto const& t : m_region_tag) {
2299 m_tags.push_back(t);
2300 }
2301 for (auto const& t : tags) {
2302 m_tags.push_back(t);
2303 }
2304 for (auto const& t: m_tags) {
2305 updateMemUsage(t, nbytes, ar);
2306 }
2307
2308#ifdef BL_USE_TEAM
2309 if (shmem.alloc)
2310 {
2311 const int teamlead = ParallelDescriptor::MyTeamLead();
2312
2313 shmem.n_values = 0;
2314 shmem.n_points = 0;
2315 Vector<Long> offset(n,0);
2316 Vector<Long> nextoffset(nworkers,-1);
2317 for (int i = 0; i < n; ++i) {
2318 int K = indexArray[i];
2319 int owner = distributionMap[K] - teamlead;
2320 Long s = m_fabs_v[i]->size();
2321 if (ownership[i]) {
2322 shmem.n_values += s;
2323 shmem.n_points += m_fabs_v[i]->numPts();
2324 }
2325 if (nextoffset[owner] < 0) {
2326 offset[i] = 0;
2327 nextoffset[owner] = s;
2328 } else {
2329 offset[i] = nextoffset[owner];
2330 nextoffset[owner] += s;
2331 }
2332 }
2333
2334 size_t bytes = shmem.n_values*sizeof(value_type);
2335
2336 value_type *mfp;
2337 Vector<value_type*> dps;
2338
2339#if defined (BL_USE_MPI3)
2340
2341 static MPI_Info info = MPI_INFO_NULL;
2342 if (info == MPI_INFO_NULL) {
2343 MPI_Info_create(&info);
2344 MPI_Info_set(info, "alloc_shared_noncontig", "true");
2345 }
2346
2347 const MPI_Comm& team_comm = ParallelDescriptor::MyTeam().get();
2348
2349 BL_MPI_REQUIRE( MPI_Win_allocate_shared(bytes, sizeof(value_type),
2350 info, team_comm, &mfp, &shmem.win) );
2351
2352 for (int w = 0; w < nworkers; ++w) {
2353 MPI_Aint sz;
2354 int disp;
2355 value_type *dptr = 0;
2356 BL_MPI_REQUIRE( MPI_Win_shared_query(shmem.win, w, &sz, &disp, &dptr) );
2357 // AMREX_ASSERT(disp == sizeof(value_type));
2358 dps.push_back(dptr);
2359 }
2360
2361#else
2362
2363 amrex::Abort("BaseFab::define: to allocate shared memory, USE_MPI3 must be true");
2364
2365#endif
2366
2367 for (int i = 0; i < n; ++i) {
2368 int K = indexArray[i];
2369 int owner = distributionMap[K] - teamlead;
2370 value_type *p = dps[owner] + offset[i];
2371 m_fabs_v[i]->setPtr(p, m_fabs_v[i]->size());
2372 }
2373
2374 for (Long i = 0; i < shmem.n_values; i++, mfp++) {
2375 new (mfp) value_type;
2376 }
2377
2378 amrex::update_fab_stats(shmem.n_points, shmem.n_values, sizeof(value_type));
2379 }
2380#endif
2381}
2382
2383template <class FAB>
2384void
2385FabArray<FAB>::setFab_assert (int K, FAB const& fab) const
2386{
2387 amrex::ignore_unused(K,fab);
2388 AMREX_ASSERT(n_comp == fab.nComp());
2389 AMREX_ASSERT(!boxarray.empty());
2390 AMREX_ASSERT(fab.box() == fabbox(K));
2391 AMREX_ASSERT(distributionMap[K] == ParallelDescriptor::MyProc());
2392 AMREX_ASSERT(m_single_chunk_arena == nullptr);
2393}
2394
2395template <class FAB>
2396void
2397FabArray<FAB>::setFab (int boxno, std::unique_ptr<FAB> elem)
2398{
2399 if (n_comp == 0) {
2400 n_comp = elem->nComp();
2401 }
2402
2403 setFab_assert(boxno, *elem);
2404
2405 if (m_fabs_v.empty()) {
2406 m_fabs_v.resize(indexArray.size(),nullptr);
2407 }
2408
2409 const int li = localindex(boxno);
2410 if (m_fabs_v[li]) {
2411 m_factory->destroy(m_fabs_v[li]);
2412 }
2413 m_fabs_v[li] = elem.release();
2414}
2415
2416template <class FAB>
2417template <class F>
2418requires (std::is_move_constructible_v<F>)
2419void
2420FabArray<FAB>::setFab (int boxno, FAB&& elem)
2421{
2422 if (n_comp == 0) {
2423 n_comp = elem.nComp();
2424 }
2425
2426 setFab_assert(boxno, elem);
2427
2428 if (m_fabs_v.empty()) {
2429 m_fabs_v.resize(indexArray.size(),nullptr);
2430 }
2431
2432 const int li = localindex(boxno);
2433 if (m_fabs_v[li]) {
2434 m_factory->destroy(m_fabs_v[li]);
2435 }
2436 m_fabs_v[li] = new FAB(std::move(elem));
2437}
2438
2439template <class FAB>
2440void
2441FabArray<FAB>::setFab (const MFIter& mfi, std::unique_ptr<FAB> elem)
2442{
2443 if (n_comp == 0) {
2444 n_comp = elem->nComp();
2445 }
2446
2447 setFab_assert(mfi.index(), *elem);
2448
2449 if (m_fabs_v.empty()) {
2450 m_fabs_v.resize(indexArray.size(),nullptr);
2451 }
2452
2453 const int li = mfi.LocalIndex();
2454 if (m_fabs_v[li]) {
2455 m_factory->destroy(m_fabs_v[li]);
2456 }
2457 m_fabs_v[li] = elem.release();
2458}
2459
2460template <class FAB>
2461template <class F>
2462requires (std::is_move_constructible_v<F>)
2463void
2464FabArray<FAB>::setFab (const MFIter& mfi, FAB&& elem)
2465{
2466 if (n_comp == 0) {
2467 n_comp = elem.nComp();
2468 }
2469
2470 setFab_assert(mfi.index(), elem);
2471
2472 if (m_fabs_v.empty()) {
2473 m_fabs_v.resize(indexArray.size(),nullptr);
2474 }
2475
2476 const int li = mfi.LocalIndex();
2477 if (m_fabs_v[li]) {
2478 m_factory->destroy(m_fabs_v[li]);
2479 }
2480 m_fabs_v[li] = new FAB(std::move(elem));
2481}
2482
2483template <class FAB>
2484template <class F>
2485requires (BaseFabType<F>)
2486void
2488{
2489 setBndry(val, 0, n_comp);
2490}
2491
2492template <class FAB>
2493template <class F>
2494requires (BaseFabType<F>)
2495void
2497 int strt_comp,
2498 int ncomp)
2499{
2500 if (n_grow.max() > 0)
2501 {
2502#ifdef AMREX_USE_GPU
2503 if (Gpu::inLaunchRegion()) {
2504 bool use_mfparfor = true;
2505 const int nboxes = local_size();
2506 if (nboxes == 1) {
2507 if (boxarray[indexArray[0]].numPts() > Long(65*65*65)) {
2508 use_mfparfor = false;
2509 }
2510 } else {
2511 for (int i = 0; i < nboxes; ++i) {
2512 const Long npts = boxarray[indexArray[i]].numPts();
2513 if (npts >= Long(64*64*64)) {
2514 use_mfparfor = false;
2515 break;
2516 } else if (npts <= Long(17*17*17)) {
2517 break;
2518 }
2519 }
2520 }
2521 const IntVect nghost = n_grow;
2522 if (use_mfparfor) {
2523 auto const& ma = this->arrays();
2524 ParallelFor(*this, nghost,
2525 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2526 {
2527 auto const& a = ma[box_no];
2528 Box vbx(a);
2529 vbx.grow(-nghost);
2530 if (!vbx.contains(i,j,k)) {
2531 for (int n = 0; n < ncomp; ++n) {
2532 a(i,j,k,strt_comp+n) = val;
2533 }
2534 }
2535 });
2536 if (!Gpu::inNoSyncRegion()) {
2538 }
2539 } else {
2540 using Tag = Array4BoxTag<value_type>;
2541 Vector<Tag> tags;
2542 for (MFIter mfi(*this); mfi.isValid(); ++mfi) {
2543 Box const& vbx = mfi.validbox();
2544 auto const& a = this->array(mfi);
2545
2546 Box b;
2547#if (AMREX_SPACEDIM == 3)
2548 if (nghost[2] > 0) {
2549 b = vbx;
2550 b.setRange(2, vbx.smallEnd(2)-nghost[2], nghost[2]);
2551 b.grow(IntVect(nghost[0],nghost[1],0));
2552 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2553 b.shift(2, vbx.length(2)+nghost[2]);
2554 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2555 }
2556#endif
2557#if (AMREX_SPACEDIM >= 2)
2558 if (nghost[1] > 0) {
2559 b = vbx;
2560 b.setRange(1, vbx.smallEnd(1)-nghost[1], nghost[1]);
2561 b.grow(0, nghost[0]);
2562 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2563 b.shift(1, vbx.length(1)+nghost[1]);
2564 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2565 }
2566#endif
2567 if (nghost[0] > 0) {
2568 b = vbx;
2569 b.setRange(0, vbx.smallEnd(0)-nghost[0], nghost[0]);
2570 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2571 b.shift(0, vbx.length(0)+nghost[0]);
2572 tags.emplace_back(Tag{.dfab = a, .dbox = b});
2573 }
2574 }
2575
2576 ParallelFor(tags, ncomp,
2577 [=] AMREX_GPU_DEVICE (int i, int j, int k, int n, Tag const& tag) noexcept
2578 {
2579 tag.dfab(i,j,k,strt_comp+n) = val;
2580 });
2581 }
2582 } else
2583#endif
2584 {
2585#ifdef AMREX_USE_OMP
2586#pragma omp parallel
2587#endif
2588 for (MFIter fai(*this); fai.isValid(); ++fai)
2589 {
2590 get(fai).template setComplement<RunOn::Host>(val, fai.validbox(), strt_comp, ncomp);
2591 }
2592 }
2593 }
2594}
2595
2596template <class FAB>
2597template <class F>
2598requires (BaseFabType<F>)
2599void
2601{
2602 setDomainBndry(val, 0, n_comp, geom);
2603}
2604
2605template <class FAB>
2606template <class F>
2607requires (BaseFabType<F>)
2608void
2610 int strt_comp,
2611 int ncomp,
2612 const Geometry& geom)
2613{
2614 BL_PROFILE("FabArray::setDomainBndry()");
2615
2616 Box domain_box = amrex::convert(geom.Domain(), boxArray().ixType());
2617 for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
2618 if (geom.isPeriodic(idim)) {
2619 int n = domain_box.length(idim);
2620 domain_box.grow(idim, n);
2621 }
2622 }
2623
2624#ifdef AMREX_USE_OMP
2625#pragma omp parallel if (Gpu::notInLaunchRegion())
2626#endif
2627 for (MFIter fai(*this); fai.isValid(); ++fai)
2628 {
2629 const Box& gbx = fai.fabbox();
2630 if (! domain_box.contains(gbx))
2631 {
2632 get(fai).template setComplement<RunOn::Device>(val, domain_box, strt_comp, ncomp);
2633 }
2634 }
2635}
2636
2637template <class FAB>
2638template <std::integral I>
2639requires (BaseFabType<FAB> && (sizeof(I) >= sizeof(Long)))
2640void
2642{
2643 AMREX_ASSERT(amrex::isMFIterSafe(*this, mem));
2644 for (MFIter mfi(*this, MFItInfo{}.DisableDeviceSync()); mfi.isValid(); ++mfi) {
2645 mem[mfi] += static_cast<I>((*this)[mfi].nBytesOwned());
2646 }
2647}
2648
2649template <class FAB>
2650template <class F>
2651requires (BaseFabType<F>)
2652typename F::value_type
2653FabArray<FAB>::sum (int comp, IntVect const& nghost, bool local) const
2654{
2655 BL_PROFILE("FabArray::sum()");
2656
2657 using T = typename FAB::value_type;
2658 auto sm = T(0.0);
2659#ifdef AMREX_USE_GPU
2660 if (Gpu::inLaunchRegion()) {
2661 auto const& ma = this->const_arrays();
2662 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, *this, nghost,
2663 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2664 -> GpuTuple<T>
2665 {
2666 return ma[box_no](i,j,k,comp);
2667 });
2668 } else
2669#endif
2670 {
2671#ifdef AMREX_USE_OMP
2672#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
2673#endif
2674 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi)
2675 {
2676 Box const& bx = mfi.growntilebox(nghost);
2677 auto const& a = this->const_array(mfi);
2678 auto tmp = T(0.0);
2679 AMREX_LOOP_3D(bx, i, j, k,
2680 {
2681 tmp += a(i,j,k,comp);
2682 });
2683 sm += tmp; // Do it this way so that it does not break regression tests.
2684 }
2685 }
2686
2687 if (!local) {
2689 }
2690
2691 return sm;
2692}
2693
2694template <class FAB>
2695void
2696FabArray<FAB>::copyTo (FAB& dest, int nghost) const
2697{
2698 copyTo(dest, 0, 0, dest.nComp(), nghost);
2699}
2700
2701template <class FAB>
2702template <class F>
2703requires (BaseFabType<F>)
2704void
2706{
2707 setVal(val,0,n_comp,n_grow);
2708}
2709
2710template <class FAB>
2711template <class F>
2712requires (BaseFabType<F>)
2715{
2716 setVal(val);
2717 return *this;
2718}
2719
2720template <class FAB>
2721template <class F>
2722requires (BaseFabType<F>)
2723void
2725 int comp,
2726 int ncomp,
2727 int nghost)
2728{
2729 setVal(val,comp,ncomp,IntVect(nghost));
2730}
2731
2732template <class FAB>
2733template <class F>
2734requires (BaseFabType<F>)
2735void
2737 int comp,
2738 int ncomp,
2739 const IntVect& nghost)
2740{
2741 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2742 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2743
2744 BL_PROFILE("FabArray::setVal()");
2745
2746#ifdef AMREX_USE_GPU
2747 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2748 auto const& fa = this->arrays();
2749 ParallelFor(*this, nghost, ncomp,
2750 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2751 {
2752 fa[box_no](i,j,k,n+comp) = val;
2753 });
2754 if (!Gpu::inNoSyncRegion()) {
2756 }
2757 } else
2758#endif
2759 {
2760#ifdef AMREX_USE_OMP
2761#pragma omp parallel if (Gpu::notInLaunchRegion())
2762#endif
2763 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
2764 {
2765 const Box& bx = fai.growntilebox(nghost);
2766 auto fab = this->array(fai);
2767 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
2768 {
2769 fab(i,j,k,n+comp) = val;
2770 });
2771 }
2772 }
2773}
2774
2775template <class FAB>
2776template <class F>
2777requires (BaseFabType<F>)
2778void
2780 const Box& region,
2781 int comp,
2782 int ncomp,
2783 int nghost)
2784{
2785 setVal(val,region,comp,ncomp,IntVect(nghost));
2786}
2787
2788template <class FAB>
2789template <class F>
2790requires (BaseFabType<F>)
2791void
2793 const Box& region,
2794 int comp,
2795 int ncomp,
2796 const IntVect& nghost)
2797{
2798 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2799 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2800
2801 BL_PROFILE("FabArray::setVal(val,region,comp,ncomp,nghost)");
2802
2803#ifdef AMREX_USE_GPU
2804 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2805 auto const& fa = this->arrays();
2806 ParallelFor(*this, nghost, ncomp,
2807 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2808 {
2809 if (region.contains(i,j,k)) {
2810 fa[box_no](i,j,k,n+comp) = val;
2811 }
2812 });
2813 if (!Gpu::inNoSyncRegion()) {
2815 }
2816 } else
2817#endif
2818 {
2819#ifdef AMREX_USE_OMP
2820 AMREX_ALWAYS_ASSERT(!omp_in_parallel());
2821#pragma omp parallel if (Gpu::notInLaunchRegion())
2822#endif
2823 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
2824 {
2825 Box b = fai.growntilebox(nghost) & region;
2826
2827 if (b.ok()) {
2828 auto fab = this->array(fai);
2829 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( b, ncomp, i, j, k, n,
2830 {
2831 fab(i,j,k,n+comp) = val;
2832 });
2833 }
2834 }
2835 }
2836}
2837
2838template <class FAB>
2839template <class F>
2840requires (BaseFabType<F>)
2841void
2842FabArray<FAB>::abs (int comp, int ncomp, int nghost)
2843{
2844 abs(comp, ncomp, IntVect(nghost));
2845}
2846
2847template <class FAB>
2848template <class F>
2849requires (BaseFabType<F>)
2850void
2851FabArray<FAB>::abs (int comp, int ncomp, const IntVect& nghost)
2852{
2853 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2854 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2855 BL_PROFILE("FabArray::abs()");
2856
2857#ifdef AMREX_USE_GPU
2858 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2859 auto const& fa = this->arrays();
2860 ParallelFor(*this, nghost, ncomp,
2861 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2862 {
2863 fa[box_no](i,j,k,n+comp) = std::abs(fa[box_no](i,j,k,n+comp));
2864 });
2865 if (!Gpu::inNoSyncRegion()) {
2867 }
2868 } else
2869#endif
2870 {
2871#ifdef AMREX_USE_OMP
2872#pragma omp parallel if (Gpu::notInLaunchRegion())
2873#endif
2874 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2875 {
2876 const Box& bx = mfi.growntilebox(nghost);
2877 auto fab = this->array(mfi);
2878 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
2879 {
2880 fab(i,j,k,n+comp) = std::abs(fab(i,j,k,n+comp));
2881 });
2882 }
2883 }
2884}
2885
2886template <class FAB>
2887template <class F>
2888requires (BaseFabType<F>)
2889void
2890FabArray<FAB>::plus (value_type val, int comp, int num_comp, int nghost)
2891{
2892 BL_PROFILE("FabArray::plus()");
2893
2894#ifdef AMREX_USE_GPU
2895 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2896 auto const& fa = this->arrays();
2897 ParallelFor(*this, IntVect(nghost), num_comp,
2898 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2899 {
2900 fa[box_no](i,j,k,n+comp) += val;
2901 });
2902 if (!Gpu::inNoSyncRegion()) {
2904 }
2905 } else
2906#endif
2907 {
2908#ifdef AMREX_USE_OMP
2909#pragma omp parallel if (Gpu::notInLaunchRegion())
2910#endif
2911 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2912 {
2913 const Box& bx = mfi.growntilebox(nghost);
2914 auto fab = this->array(mfi);
2915 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2916 {
2917 fab(i,j,k,n+comp) += val;
2918 });
2919 }
2920 }
2921}
2922
2923template <class FAB>
2924template <class F>
2925requires (BaseFabType<F>)
2926void
2927FabArray<FAB>::plus (value_type val, const Box& region, int comp, int num_comp, int nghost)
2928{
2929 BL_PROFILE("FabArray::plus(val, region, comp, num_comp, nghost)");
2930
2931#ifdef AMREX_USE_GPU
2932 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2933 auto const& fa = this->arrays();
2934 ParallelFor(*this, IntVect(nghost), num_comp,
2935 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2936 {
2937 if (region.contains(i,j,k)) {
2938 fa[box_no](i,j,k,n+comp) += val;
2939 }
2940 });
2941 if (!Gpu::inNoSyncRegion()) {
2943 }
2944 } else
2945#endif
2946 {
2947#ifdef AMREX_USE_OMP
2948#pragma omp parallel if (Gpu::notInLaunchRegion())
2949#endif
2950 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2951 {
2952 const Box& bx = mfi.growntilebox(nghost) & region;
2953 if (bx.ok()) {
2954 auto fab = this->array(mfi);
2955 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2956 {
2957 fab(i,j,k,n+comp) += val;
2958 });
2959 }
2960 }
2961 }
2962}
2963
2964template <class FAB>
2965template <class F>
2966requires (BaseFabType<F>)
2967void
2968FabArray<FAB>::mult (value_type val, int comp, int num_comp, int nghost)
2969{
2970 BL_PROFILE("FabArray::mult()");
2971
2972#ifdef AMREX_USE_GPU
2973 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2974 auto const& fa = this->arrays();
2975 ParallelFor(*this, IntVect(nghost), num_comp,
2976 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2977 {
2978 fa[box_no](i,j,k,n+comp) *= val;
2979 });
2980 if (!Gpu::inNoSyncRegion()) {
2982 }
2983 } else
2984#endif
2985 {
2986#ifdef AMREX_USE_OMP
2987#pragma omp parallel if (Gpu::notInLaunchRegion())
2988#endif
2989 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2990 {
2991 const Box& bx = mfi.growntilebox(nghost);
2992 auto fab = this->array(mfi);
2993 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2994 {
2995 fab(i,j,k,n+comp) *= val;
2996 });
2997 }
2998 }
2999}
3000
3001template <class FAB>
3002template <class F>
3003requires (BaseFabType<F>)
3004void
3005FabArray<FAB>::mult (value_type val, const Box& region, int comp, int num_comp, int nghost)
3006{
3007 BL_PROFILE("FabArray::mult(val, region, comp, num_comp, nghost)");
3008
3009#ifdef AMREX_USE_GPU
3010 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3011 auto const& fa = this->arrays();
3012 ParallelFor(*this, IntVect(nghost), num_comp,
3013 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3014 {
3015 if (region.contains(i,j,k)) {
3016 fa[box_no](i,j,k,n+comp) *= val;
3017 }
3018 });
3019 if (!Gpu::inNoSyncRegion()) {
3021 }
3022 } else
3023#endif
3024 {
3025#ifdef AMREX_USE_OMP
3026#pragma omp parallel if (Gpu::notInLaunchRegion())
3027#endif
3028 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3029 {
3030 const Box& bx = mfi.growntilebox(nghost) & region;
3031 if (bx.ok()) {
3032 auto fab = this->array(mfi);
3033 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3034 {
3035 fab(i,j,k,n+comp) *= val;
3036 });
3037 }
3038 }
3039 }
3040}
3041
3042template <class FAB>
3043template <class F>
3044requires (BaseFabType<F>)
3045void
3046FabArray<FAB>::invert (value_type numerator, int comp, int num_comp, int nghost)
3047{
3048 BL_PROFILE("FabArray::invert()");
3049
3050#ifdef AMREX_USE_GPU
3051 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3052 auto const& fa = this->arrays();
3053 ParallelFor(*this, IntVect(nghost), num_comp,
3054 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3055 {
3056 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
3057 });
3058 if (!Gpu::inNoSyncRegion()) {
3060 }
3061 } else
3062#endif
3063 {
3064#ifdef AMREX_USE_OMP
3065#pragma omp parallel if (Gpu::notInLaunchRegion())
3066#endif
3067 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3068 {
3069 const Box& bx = mfi.growntilebox(nghost);
3070 auto fab = this->array(mfi);
3071 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3072 {
3073 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
3074 });
3075 }
3076 }
3077}
3078
3079template <class FAB>
3080template <class F>
3081requires (BaseFabType<F>)
3082void
3083FabArray<FAB>::invert (value_type numerator, const Box& region, int comp, int num_comp, int nghost)
3084{
3085 BL_PROFILE("FabArray::invert(numerator, region, comp, num_comp, nghost)");
3086
3087#ifdef AMREX_USE_GPU
3088 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3089 auto const& fa = this->arrays();
3090 ParallelFor(*this, IntVect(nghost), num_comp,
3091 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3092 {
3093 if (region.contains(i,j,k)) {
3094 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
3095 }
3096 });
3097 if (!Gpu::inNoSyncRegion()) {
3099 }
3100 } else
3101#endif
3102 {
3103#ifdef AMREX_USE_OMP
3104#pragma omp parallel if (Gpu::notInLaunchRegion())
3105#endif
3106 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3107 {
3108 const Box& bx = mfi.growntilebox(nghost) & region;
3109 if (bx.ok()) {
3110 auto fab = this->array(mfi);
3111 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
3112 {
3113 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
3114 });
3115 }
3116 }
3117 }
3118}
3119
3120template <class FAB>
3121void
3123{
3124 clearThisBD(); // The new boxarray will have a different ID.
3125 boxarray.shift(v);
3126 addThisBD();
3127#ifdef AMREX_USE_OMP
3128#pragma omp parallel
3129#endif
3130 for (MFIter fai(*this); fai.isValid(); ++fai)
3131 {
3132 get(fai).shift(v);
3133 }
3134 clear_arrays();
3135}
3136
3137template <class FAB>
3138template <class F>
3139requires (BaseFabType<F>)
3141 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3142{
3143 AMREX_ASSERT(y.boxArray() == x.boxArray());
3144 AMREX_ASSERT(y.distributionMap == x.distributionMap);
3145 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
3146
3147 BL_PROFILE("FabArray::Saxpy()");
3148
3149#ifdef AMREX_USE_GPU
3150 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3151 auto const& yma = y.arrays();
3152 auto const& xma = x.const_arrays();
3153 ParallelFor(y, nghost, ncomp,
3154 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3155 {
3156 yma[box_no](i,j,k,ycomp+n) += a * xma[box_no](i,j,k,xcomp+n);
3157 });
3158 if (!Gpu::inNoSyncRegion()) {
3160 }
3161 } else
3162#endif
3163 {
3164#ifdef AMREX_USE_OMP
3165#pragma omp parallel if (Gpu::notInLaunchRegion())
3166#endif
3167 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3168 {
3169 const Box& bx = mfi.growntilebox(nghost);
3170
3171 if (bx.ok()) {
3172 auto const& xfab = x.const_array(mfi);
3173 auto const& yfab = y.array(mfi);
3174 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3175 {
3176 yfab(i,j,k,ycomp+n) += a * xfab(i,j,k,xcomp+n);
3177 });
3178 }
3179 }
3180 }
3181}
3182
3183template <class FAB>
3184template <class F>
3185requires (BaseFabType<F>)
3186void
3188 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3189{
3190 AMREX_ASSERT(y.boxArray() == x.boxArray());
3191 AMREX_ASSERT(y.distributionMap == x.distributionMap);
3192 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
3193
3194 BL_PROFILE("FabArray::Xpay()");
3195
3196#ifdef AMREX_USE_GPU
3197 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3198 auto const& yfa = y.arrays();
3199 auto const& xfa = x.const_arrays();
3200 ParallelFor(y, nghost, ncomp,
3201 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3202 {
3203 yfa[box_no](i,j,k,n+ycomp) = xfa[box_no](i,j,k,n+xcomp)
3204 + a * yfa[box_no](i,j,k,n+ycomp);
3205 });
3206 if (!Gpu::inNoSyncRegion()) {
3208 }
3209 } else
3210#endif
3211 {
3212#ifdef AMREX_USE_OMP
3213#pragma omp parallel if (Gpu::notInLaunchRegion())
3214#endif
3215 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3216 {
3217 const Box& bx = mfi.growntilebox(nghost);
3218 auto const& xFab = x.const_array(mfi);
3219 auto const& yFab = y.array(mfi);
3220 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3221 {
3222 yFab(i,j,k,n+ycomp) = xFab(i,j,k,n+xcomp)
3223 + a * yFab(i,j,k,n+ycomp);
3224 });
3225 }
3226 }
3227}
3228
3229template <class FAB>
3230template <class F>
3231requires (BaseFabType<F>)
3233 value_type a2, FabArray<FAB> const& x2,
3234 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3235{
3236 AMREX_ASSERT(y.boxArray() == x1.boxArray() &&
3237 y.boxArray() == x2.boxArray() &&
3238 y.distributionMap == x1.distributionMap &&
3239 y.distributionMap == x2.distributionMap &&
3240 y.nGrowVect().allGE(nghost) &&
3241 x1.nGrowVect().allGE(nghost) &&
3242 x2.nGrowVect().allGE(nghost));
3243
3244 BL_PROFILE("FabArray::Saxpy_Xpay()");
3245
3246#ifdef AMREX_USE_GPU
3247 if (Gpu::inLaunchRegion() && y.isFusingCandidate()) {
3248 auto const& yma = y.arrays();
3249 auto const& xma1 = x1.const_arrays();
3250 auto const& xma2 = x2.const_arrays();
3251 ParallelFor(y, nghost, ncomp,
3252 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3253 {
3254 yma[box_no](i,j,k,ycomp+n) = xma2[box_no](i,j,k,xcomp+n)
3255 + a2 * (yma [box_no](i,j,k,ycomp+n)
3256 + a1 * xma1[box_no](i,j,k,xcomp+n));
3257 });
3258 if (!Gpu::inNoSyncRegion()) {
3260 }
3261 } else
3262#endif
3263 {
3264#ifdef AMREX_USE_OMP
3265#pragma omp parallel if (Gpu::notInLaunchRegion())
3266#endif
3267 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3268 {
3269 const Box& bx = mfi.growntilebox(nghost);
3270
3271 if (bx.ok()) {
3272 auto const& xfab1 = x1.const_array(mfi);
3273 auto const& xfab2 = x2.const_array(mfi);
3274 auto const& yfab = y.array(mfi);
3275 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3276 {
3277 yfab(i,j,k,ycomp+n) = xfab2(i,j,k,xcomp+n)
3278 + a2 * (yfab (i,j,k,ycomp+n)
3279 + a1 * xfab1(i,j,k,xcomp+n));
3280 });
3281 }
3282 }
3283 }
3284}
3285
3286template <class FAB>
3287template <class F>
3288requires (BaseFabType<F>)
3290 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x2,
3291 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3292{
3293 AMREX_ASSERT(y1.boxArray() == y2.boxArray() &&
3294 y1.boxArray() == x1.boxArray() &&
3295 y1.boxArray() == x2.boxArray() &&
3299 y1.nGrowVect().allGE(nghost) &&
3300 y2.nGrowVect().allGE(nghost) &&
3301 x1.nGrowVect().allGE(nghost) &&
3302 x2.nGrowVect().allGE(nghost));
3303
3304 BL_PROFILE("FabArray::Saxpy_Saxpy()");
3305
3306#ifdef AMREX_USE_GPU
3307 if (Gpu::inLaunchRegion() && y1.isFusingCandidate()) {
3308 auto const& y1ma = y1.arrays();
3309 auto const& x1ma = x1.const_arrays();
3310 auto const& y2ma = y2.arrays();
3311 auto const& x2ma = x2.const_arrays();
3312 ParallelFor(y1, nghost, ncomp,
3313 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3314 {
3315 y1ma[box_no](i,j,k,ycomp+n) += a1 * x1ma[box_no](i,j,k,xcomp+n);
3316 y2ma[box_no](i,j,k,ycomp+n) += a2 * x2ma[box_no](i,j,k,xcomp+n);
3317 });
3318 if (!Gpu::inNoSyncRegion()) {
3320 }
3321 } else
3322#endif
3323 {
3324#ifdef AMREX_USE_OMP
3325#pragma omp parallel if (Gpu::notInLaunchRegion())
3326#endif
3327 for (MFIter mfi(y1,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3328 {
3329 const Box& bx = mfi.growntilebox(nghost);
3330
3331 if (bx.ok()) {
3332 auto const& x1fab = x1.const_array(mfi);
3333 auto const& y1fab = y1.array(mfi);
3334 auto const& x2fab = x2.const_array(mfi);
3335 auto const& y2fab = y2.array(mfi);
3336 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3337 {
3338 y1fab(i,j,k,ycomp+n) += a1 * x1fab(i,j,k,xcomp+n);
3339 y2fab(i,j,k,ycomp+n) += a2 * x2fab(i,j,k,xcomp+n);
3340 });
3341 }
3342 }
3343 }
3344}
3345
3346template <class FAB>
3347template <class F>
3348requires (BaseFabType<F>)
3350 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x,
3351 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3352{
3353 AMREX_ASSERT(y1.boxArray() == y2.boxArray() &&
3354 y1.boxArray() == x.boxArray() &&
3356 y1.distributionMap == x.distributionMap &&
3357 y1.nGrowVect().allGE(nghost) &&
3358 y2.nGrowVect().allGE(nghost) &&
3359 x.nGrowVect().allGE(nghost));
3360
3361 BL_PROFILE("FabArray::Saypy_Saxpy()");
3362
3363#ifdef AMREX_USE_GPU
3364 if (Gpu::inLaunchRegion() && y1.isFusingCandidate()) {
3365 auto const& y1ma = y1.arrays();
3366 auto const& y2ma = y2.arrays();
3367 auto const& xma = x.const_arrays();
3368 ParallelFor(y1, nghost, ncomp,
3369 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3370 {
3371 y1ma[box_no](i,j,k,ycomp+n) += a1 * y2ma[box_no](i,j,k,ycomp+n);
3372 y2ma[box_no](i,j,k,ycomp+n) += a2 * xma[box_no](i,j,k,xcomp+n);
3373 });
3374 if (!Gpu::inNoSyncRegion()) {
3376 }
3377 } else
3378#endif
3379 {
3380#ifdef AMREX_USE_OMP
3381#pragma omp parallel if (Gpu::notInLaunchRegion())
3382#endif
3383 for (MFIter mfi(y1,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3384 {
3385 const Box& bx = mfi.growntilebox(nghost);
3386
3387 if (bx.ok()) {
3388 auto const& xfab = x.const_array(mfi);
3389 auto const& y1fab = y1.array(mfi);
3390 auto const& y2fab = y2.array(mfi);
3391 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3392 {
3393 y1fab(i,j,k,ycomp+n) += a1 * y2fab(i,j,k,ycomp+n);
3394 y2fab(i,j,k,ycomp+n) += a2 * xfab(i,j,k,xcomp+n);
3395 });
3396 }
3397 }
3398 }
3399}
3400
3401template <class FAB>
3402template <class F>
3403requires (BaseFabType<F>)
3404void
3406 value_type a, const FabArray<FAB>& x, int xcomp,
3407 value_type b, const FabArray<FAB>& y, int ycomp,
3408 int dstcomp, int numcomp, const IntVect& nghost)
3409{
3410 AMREX_ASSERT(dst.boxArray() == x.boxArray());
3411 AMREX_ASSERT(dst.distributionMap == x.distributionMap);
3412 AMREX_ASSERT(dst.boxArray() == y.boxArray());
3413 AMREX_ASSERT(dst.distributionMap == y.distributionMap);
3414 AMREX_ASSERT(dst.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost) && y.nGrowVect().allGE(nghost));
3415
3416 BL_PROFILE("FabArray::LinComb()");
3417
3418#ifdef AMREX_USE_GPU
3419 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
3420 auto const& dstma = dst.arrays();
3421 auto const& xma = x.const_arrays();
3422 auto const& yma = y.const_arrays();
3423 ParallelFor(dst, nghost, numcomp,
3424 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3425 {
3426 dstma[box_no](i,j,k,dstcomp+n) = a*xma[box_no](i,j,k,xcomp+n)
3427 + b*yma[box_no](i,j,k,ycomp+n);
3428 });
3429 if (!Gpu::inNoSyncRegion()) {
3431 }
3432 } else
3433#endif
3434 {
3435#ifdef AMREX_USE_OMP
3436#pragma omp parallel if (Gpu::notInLaunchRegion())
3437#endif
3438 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3439 {
3440 const Box& bx = mfi.growntilebox(nghost);
3441 auto const& xfab = x.const_array(mfi);
3442 auto const& yfab = y.const_array(mfi);
3443 auto const& dfab = dst.array(mfi);
3444 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
3445 {
3446 dfab(i,j,k,dstcomp+n) = a*xfab(i,j,k,xcomp+n) + b*yfab(i,j,k,ycomp+n);
3447 });
3448 }
3449 }
3450}
3451
3452template <class FAB>
3453template <typename BUF>
3454void
3456{
3457 BL_PROFILE("FabArray::FillBoundary()");
3458 if ( n_grow.max() > 0 ) {
3459 FillBoundary_nowait<BUF>(0, nComp(), n_grow, Periodicity::NonPeriodic(), cross);
3460 FillBoundary_finish<BUF>();
3461 }
3462}
3463
3464template <class FAB>
3465template <typename BUF>
3466void
3467FabArray<FAB>::FillBoundary (const Periodicity& period, bool cross)
3468{
3469 BL_PROFILE("FabArray::FillBoundary()");
3470 if ( n_grow.max() > 0 ) {
3471 FillBoundary_nowait<BUF>(0, nComp(), n_grow, period, cross);
3472 FillBoundary_finish<BUF>();
3473 }
3474}
3475
3476template <class FAB>
3477template <typename BUF>
3478void
3479FabArray<FAB>::FillBoundary (const IntVect& nghost, const Periodicity& period, bool cross)
3480{
3481 BL_PROFILE("FabArray::FillBoundary()");
3483 "FillBoundary: asked to fill more ghost cells than we have");
3484 if ( nghost.max() > 0 ) {
3485 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3486 FillBoundary_finish<BUF>();
3487 }
3488}
3489
3490template <class FAB>
3491template <typename BUF>
3492void
3493FabArray<FAB>::FillBoundary (int scomp, int ncomp, bool cross)
3494{
3495 BL_PROFILE("FabArray::FillBoundary()");
3496 if ( n_grow.max() > 0 ) {
3497 FillBoundary_nowait<BUF>(scomp, ncomp, n_grow, Periodicity::NonPeriodic(), cross);
3498 FillBoundary_finish<BUF>();
3499 }
3500}
3501
3502template <class FAB>
3503template <typename BUF>
3504void
3505FabArray<FAB>::FillBoundary (int scomp, int ncomp, const Periodicity& period, bool cross)
3506{
3507 BL_PROFILE("FabArray::FillBoundary()");
3508 if ( n_grow.max() > 0 ) {
3509 FillBoundary_nowait<BUF>(scomp, ncomp, n_grow, period, cross);
3510 FillBoundary_finish<BUF>();
3511 }
3512}
3513
3514template <class FAB>
3515template <typename BUF>
3516void
3517FabArray<FAB>::FillBoundary (int scomp, int ncomp, const IntVect& nghost,
3518 const Periodicity& period, bool cross)
3519{
3520 BL_PROFILE("FabArray::FillBoundary()");
3522 "FillBoundary: asked to fill more ghost cells than we have");
3523 if ( nghost.max() > 0 ) {
3524 FillBoundary_nowait<BUF>(scomp, ncomp, nghost, period, cross);
3525 FillBoundary_finish<BUF>();
3526 }
3527}
3528
3529template <class FAB>
3530template <typename BUF>
3531void
3533{
3534 FillBoundary_nowait<BUF>(0, nComp(), nGrowVect(), Periodicity::NonPeriodic(), cross);
3535}
3536
3537template <class FAB>
3538template <typename BUF>
3539void
3541{
3542 FillBoundary_nowait<BUF>(0, nComp(), nGrowVect(), period, cross);
3543}
3544
3545template <class FAB>
3546template <typename BUF>
3547void
3548FabArray<FAB>::FillBoundary_nowait (const IntVect& nghost, const Periodicity& period, bool cross)
3549{
3550 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3551}
3552
3553template <class FAB>
3554template <typename BUF>
3555void
3556FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, bool cross)
3557{
3558 FillBoundary_nowait<BUF>(scomp, ncomp, nGrowVect(), Periodicity::NonPeriodic(), cross);
3559}
3560
3561template <class FAB>
3562void
3564{
3565 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3566 if (n_grow.max() > 0 || !is_cell_centered()) {
3567 FillBoundaryAndSync_nowait(0, nComp(), n_grow, period);
3569 }
3570}
3571
3572template <class FAB>
3573void
3574FabArray<FAB>::FillBoundaryAndSync (int scomp, int ncomp, const IntVect& nghost,
3575 const Periodicity& period)
3576{
3577 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3578 if (nghost.max() > 0 || !is_cell_centered()) {
3579 FillBoundaryAndSync_nowait(scomp, ncomp, nghost, period);
3581 }
3582}
3583
3584template <class FAB>
3585void
3590
3591template <class FAB>
3592void
3593FabArray<FAB>::FillBoundaryAndSync_nowait (int scomp, int ncomp, const IntVect& nghost,
3594 const Periodicity& period)
3595{
3596 BL_PROFILE("FillBoundaryAndSync_nowait()");
3597 FBEP_nowait(scomp, ncomp, nghost, period, false, false, true);
3598}
3599
3600template <class FAB>
3601void
3603{
3604 BL_PROFILE("FillBoundaryAndSync_finish()");
3606}
3607
3608template <class FAB>
3609void
3611{
3612 BL_PROFILE("FAbArray::OverrideSync()");
3613 if (!is_cell_centered()) {
3614 OverrideSync_nowait(0, nComp(), period);
3616 }
3617}
3618
3619template <class FAB>
3620void
3621FabArray<FAB>::OverrideSync (int scomp, int ncomp, const Periodicity& period)
3622{
3623 BL_PROFILE("FAbArray::OverrideSync()");
3624 if (!is_cell_centered()) {
3625 OverrideSync_nowait(scomp, ncomp, period);
3627 }
3628}
3629
3630template <class FAB>
3631void
3633{
3634 OverrideSync_nowait(0, nComp(), period);
3635}
3636
3637template <class FAB>
3638void
3639FabArray<FAB>::OverrideSync_nowait (int scomp, int ncomp, const Periodicity& period)
3640{
3641 BL_PROFILE("OverrideSync_nowait()");
3642 FBEP_nowait(scomp, ncomp, IntVect(0), period, false, false, true);
3643}
3644
3645template <class FAB>
3646void
3648{
3649 BL_PROFILE("OverrideSync_finish()");
3651}
3652
3653template <class FAB>
3654void
3655FabArray<FAB>::SumBoundary (const Periodicity& period, bool deterministic)
3656{
3657 SumBoundary(0, n_comp, IntVect(0), period, deterministic);
3658}
3659
3660template <class FAB>
3661void
3662FabArray<FAB>::SumBoundary (int scomp, int ncomp, const Periodicity& period, bool deterministic)
3663{
3664 SumBoundary(scomp, ncomp, IntVect(0), period, deterministic);
3665}
3666
3667template <class FAB>
3668void
3669FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period, bool deterministic)
3670{
3671 SumBoundary(scomp, ncomp, this->nGrowVect(), nghost, period, deterministic);
3672}
3673
3674template <class FAB>
3675void
3676FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period, bool deterministic)
3677{
3678 BL_PROFILE("FabArray<FAB>::SumBoundary()");
3679
3680 SumBoundary_nowait(scomp, ncomp, src_nghost, dst_nghost, period, deterministic);
3681 SumBoundary_finish();
3682}
3683
3684template <class FAB>
3685void
3686FabArray<FAB>::SumBoundary_nowait (const Periodicity& period, bool deterministic)
3687{
3688 SumBoundary_nowait(0, n_comp, IntVect(0), period, deterministic);
3689}
3690
3691template <class FAB>
3692void
3693FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool deterministic)
3694{
3695 SumBoundary_nowait(scomp, ncomp, IntVect(0), period, deterministic);
3696}
3697
3698template <class FAB>
3699void
3700FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period, bool deterministic)
3701{
3702 SumBoundary_nowait(scomp, ncomp, this->nGrowVect(), nghost, period, deterministic);
3703}
3704
3705template <class FAB>
3706void
3707FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period, bool deterministic)
3708{
3709 BL_PROFILE("FabArray<FAB>::SumBoundary_nowait()");
3710
3711 if ( n_grow == IntVect::TheZeroVector() && boxArray().ixType().cellCentered()) { return; }
3712
3713 AMREX_ALWAYS_ASSERT(src_nghost.allLE(n_grow) && dst_nghost.allLE(n_grow));
3714
3715 FBEP_nowait(scomp, ncomp, dst_nghost, period, false, false, false, src_nghost, deterministic);
3716}
3717
3718template <class FAB>
3719void
3721{
3722 BL_PROFILE("FabArray<FAB>::SumBoundary_finish()");
3724}
3725
3726template <class FAB>
3727void
3729{
3730 BL_PROFILE("FabArray::EnforcePeriodicity");
3731 if (period.isAnyPeriodic()) {
3732 FBEP_nowait(0, nComp(), nGrowVect(), period, false, true);
3733 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3734 }
3735}
3736
3737template <class FAB>
3738void
3739FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const Periodicity& period)
3740{
3741 BL_PROFILE("FabArray::EnforcePeriodicity");
3742 if (period.isAnyPeriodic()) {
3743 FBEP_nowait(scomp, ncomp, nGrowVect(), period, false, true);
3744 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3745 }
3746}
3747
3748template <class FAB>
3749void
3750FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const IntVect& nghost,
3751 const Periodicity& period)
3752{
3753 BL_PROFILE("FabArray::EnforcePeriodicity");
3754 if (period.isAnyPeriodic()) {
3755 FBEP_nowait(scomp, ncomp, nghost, period, false, true);
3756 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3757 }
3758}
3759
3760template <class FAB>
3761template <typename BUF>
3762void
3763FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool cross)
3764{
3765 FBEP_nowait<BUF>(scomp, ncomp, nGrowVect(), period, cross);
3766}
3767
3768template <class FAB>
3769template <typename BUF>
3770void
3771FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const IntVect& nghost,
3772 const Periodicity& period, bool cross)
3773{
3774 FBEP_nowait<BUF>(scomp, ncomp, nghost, period, cross);
3775}
3776
3777template <class FAB>
3778template <class F>
3779requires (BaseFabType<F>)
3780void
3781FabArray<FAB>::BuildMask (const Box& phys_domain, const Periodicity& period,
3782 value_type covered, value_type notcovered,
3784{
3785 BL_PROFILE("FabArray::BuildMask()");
3786
3787 int ncomp = this->nComp();
3788 const IntVect& ngrow = this->nGrowVect();
3789
3790 Box domain = amrex::convert(phys_domain, boxArray().ixType());
3791 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
3792 if (period.isPeriodic(i)) {
3793 domain.grow(i, ngrow[i]);
3794 }
3795 }
3796
3797#ifdef AMREX_USE_GPU
3798 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3799 auto const& fa = this->arrays();
3800 ParallelFor(*this, ngrow, ncomp,
3801 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3802 {
3803 auto const& fab = fa[box_no];
3804 Box vbx(fab);
3805 vbx.grow(-ngrow);
3806 if (vbx.contains(i,j,k)) {
3807 fab(i,j,k,n) = interior;
3808 } else if (domain.contains(i,j,k)) {
3809 fab(i,j,k,n) = notcovered;
3810 } else {
3811 fab(i,j,k,n) = physbnd;
3812 }
3813 });
3814 if (!Gpu::inNoSyncRegion()) {
3816 }
3817 } else
3818#endif
3819 {
3820#ifdef AMREX_USE_OMP
3821#pragma omp parallel if (Gpu::notInLaunchRegion())
3822#endif
3823 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3824 {
3825 auto const& fab = this->array(mfi);
3826 Box const& fbx = mfi.growntilebox();
3827 Box const& gbx = fbx & domain;
3828 Box const& vbx = mfi.validbox();
3829 AMREX_HOST_DEVICE_FOR_4D(fbx, ncomp, i, j, k, n,
3830 {
3831 if (vbx.contains(i,j,k)) {
3832 fab(i,j,k,n) = interior;
3833 } else if (gbx.contains(i,j,k)) {
3834 fab(i,j,k,n) = notcovered;
3835 } else {
3836 fab(i,j,k,n) = physbnd;
3837 }
3838 });
3839 }
3840 }
3841
3842 const FabArrayBase::FB& TheFB = this->getFB(ngrow,period);
3843 setVal(covered, TheFB, 0, ncomp);
3844}
3845
3846template <class FAB>
3847template <class F>
3848requires (BaseFabType<F>)
3849void
3850FabArray<FAB>::setVal (value_type val, const CommMetaData& thecmd, int scomp, int ncomp)
3851{
3852 BL_PROFILE("FabArray::setVal(val, thecmd, scomp, ncomp)");
3853
3854#ifdef AMREX_USE_GPU
3855 if (Gpu::inLaunchRegion())
3856 {
3857 CMD_local_setVal_gpu(val, thecmd, scomp, ncomp);
3858 CMD_remote_setVal_gpu(val, thecmd, scomp, ncomp);
3859 }
3860 else
3861#endif
3862 {
3863 AMREX_ASSERT(thecmd.m_LocTags && thecmd.m_RcvTags);
3864 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
3865 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
3866 auto N_locs = static_cast<int>(LocTags.size());
3867#ifdef AMREX_USE_OMP
3868#pragma omp parallel for if (thecmd.m_threadsafe_loc)
3869#endif
3870 for (int i = 0; i < N_locs; ++i) {
3871 const CopyComTag& tag = LocTags[i];
3872 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
3873 }
3874
3875 for (const auto & RcvTag : RcvTags) {
3876 auto N = static_cast<int>(RcvTag.second.size());
3877#ifdef AMREX_USE_OMP
3878#pragma omp parallel for if (thecmd.m_threadsafe_rcv)
3879#endif
3880 for (int i = 0; i < N; ++i) {
3881 const CopyComTag& tag = RcvTag.second[i];
3882 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
3883 }
3884 }
3885 }
3886}
3887
3888template <class FAB>
3889template <class F>
3890requires (BaseFabType<F>)
3893{
3894 BL_PROFILE("FabArray::RecvLayoutMask()");
3895
3896 LayoutData<int> r(this->boxArray(), this->DistributionMap());
3897#ifdef AMREX_USE_OMP
3898#pragma omp parallel if (thecmd.m_threadsafe_rcv)
3899#endif
3900 for (MFIter mfi(r); mfi.isValid(); ++mfi) {
3901 r[mfi] = 0;
3902 }
3903
3904 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
3905 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
3906
3907 auto N_locs = static_cast<int>(LocTags.size());
3908 for (int i = 0; i < N_locs; ++i) {
3909 const CopyComTag& tag = LocTags[i];
3910 r[tag.dstIndex] = 1;
3911 }
3912
3913 for (const auto & RcvTag : RcvTags) {
3914 auto N = static_cast<int>(RcvTag.second.size());
3915 for (int i = 0; i < N; ++i) {
3916 const CopyComTag& tag = RcvTag.second[i];
3917 r[tag.dstIndex] = 1;
3918 }
3919 }
3920 return r;
3921}
3922
3923template <class FAB>
3924template <typename F>
3925requires (BaseFabType<F>)
3926typename F::value_type
3927FabArray<FAB>::norminf (int comp, int ncomp, IntVect const& nghost, bool local,
3928 [[maybe_unused]] bool ignore_covered) const
3929{
3930 BL_PROFILE("FabArray::norminf()");
3931
3932 using RT = typename F::value_type;
3933
3934 auto nm0 = RT(0.0);
3935
3936#ifdef AMREX_USE_EB
3937 if ( this->is_cell_centered() && this->hasEBFabFactory() && ignore_covered )
3938 {
3939 const auto& ebfactory = dynamic_cast<EBFArrayBoxFactory const&>(this->Factory());
3940 auto const& flags = ebfactory.getMultiEBCellFlagFab();
3941#ifdef AMREX_USE_GPU
3942 if (Gpu::inLaunchRegion()) {
3943 auto const& flagsma = flags.const_arrays();
3944 auto const& ma = this->const_arrays();
3945 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost,
3946 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<RT>
3947 {
3948 if (flagsma[box_no](i,j,k).isCovered()) {
3949 return RT(0.0);
3950 } else {
3951 auto tmp = RT(0.0);
3952 auto const& a = ma[box_no];
3953 for (int n = 0; n < ncomp; ++n) {
3954 tmp = amrex::max(tmp, std::abs(a(i,j,k,comp+n)));
3955 }
3956 return tmp;
3957 }
3958 });
3959 } else
3960#endif
3961 {
3962#ifdef AMREX_USE_OMP
3963#pragma omp parallel reduction(max:nm0)
3964#endif
3965 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
3966 Box const& bx = mfi.growntilebox(nghost);
3967 if (flags[mfi].getType(bx) != FabType::covered) {
3968 auto const& flag = flags.const_array(mfi);
3969 auto const& a = this->const_array(mfi);
3970 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
3971 {
3972 if (!flag(i,j,k).isCovered()) {
3973 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
3974 }
3975 });
3976 }
3977 }
3978 }
3979 }
3980 else
3981#endif
3982 {
3983#ifdef AMREX_USE_GPU
3984 if (Gpu::inLaunchRegion()) {
3985 auto const& ma = this->const_arrays();
3986 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost, ncomp,
3987 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept -> GpuTuple<RT>
3988 {
3989 return std::abs(ma[box_no](i,j,k,comp+n));
3990 });
3991 } else
3992#endif
3993 {
3994#ifdef AMREX_USE_OMP
3995#pragma omp parallel reduction(max:nm0)
3996#endif
3997 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
3998 Box const& bx = mfi.growntilebox(nghost);
3999 auto const& a = this->const_array(mfi);
4000 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
4001 {
4002 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
4003 });
4004 }
4005 }
4006 }
4007
4008 if (!local) {
4010 }
4011
4012 return nm0;
4013}
4014
4015template <class FAB>
4016template <typename IFAB, typename F>
4017requires (BaseFabType<F>)
4018typename F::value_type
4019FabArray<FAB>::norminf (FabArray<IFAB> const& mask, int comp, int ncomp,
4020 IntVect const& nghost, bool local) const
4021{
4022 BL_PROFILE("FabArray::norminf(mask)");
4023
4024 using RT = typename F::value_type;
4025
4026 auto nm0 = RT(0.0);
4027
4028#ifdef AMREX_USE_GPU
4029 if (Gpu::inLaunchRegion()) {
4030 auto const& ma = this->const_arrays();
4031 auto const& maskma = mask.const_arrays();
4032 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, IntVect(nghost),
4033 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<RT>
4034 {
4035 if (maskma[box_no](i,j,k)) {
4036 auto tmp = RT(0.0);
4037 auto const& a = ma[box_no];
4038 for (int n = 0; n < ncomp; ++n) {
4039 tmp = amrex::max(tmp, std::abs(a(i,j,k,comp+n)));
4040 }
4041 return tmp;
4042 } else {
4043 return RT(0.0);
4044 }
4045 });
4046 } else
4047#endif
4048 {
4049#ifdef AMREX_USE_OMP
4050#pragma omp parallel reduction(max:nm0)
4051#endif
4052 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
4053 Box const& bx = mfi.growntilebox(nghost);
4054 auto const& a = this->const_array(mfi);
4055 auto const& mskfab = mask.const_array(mfi);
4056 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
4057 {
4058 if (mskfab(i,j,k)) {
4059 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
4060 }
4061 });
4062 }
4063 }
4064
4065 if (!local) {
4067 }
4068
4069 return nm0;
4070}
4071
4073
4074}
4075
4076#endif /*BL_FABARRAY_H*/
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#define AMREX_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:49
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
#define AMREX_NODISCARD
Definition AMReX_Extension.H:252
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_RESTRICT
Definition AMReX_Extension.H:32
#define AMREX_HOST_DEVICE_FOR_4D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:107
#define AMREX_HOST_DEVICE_PARALLEL_FOR_4D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:111
#define AMREX_IF_ON_DEVICE(CODE)
Definition AMReX_GpuQualifiers.H:56
#define AMREX_IF_ON_HOST(CODE)
Definition AMReX_GpuQualifiers.H:58
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
Array4< int const > offset
Definition AMReX_HypreMLABecLap.cpp:1139
Array4< int const > mask
Definition AMReX_InterpFaceRegister.cpp:93
#define AMREX_LOOP_3D(bx, i, j, k, block)
Definition AMReX_Loop.nolint.H:4
#define AMREX_LOOP_4D(bx, ncomp, i, j, k, n, block)
Definition AMReX_Loop.nolint.H:16
A virtual base class for objects that manage their own dynamic memory allocation.
Definition AMReX_Arena.H:132
virtual void free(void *pt)=0
A pure virtual function for deleting the arena pointed to by pt.
virtual void * alloc(std::size_t sz)=0
A FortranArrayBox(FAB)-like object.
Definition AMReX_BaseFab.H:194
A collection of Boxes stored in an Array.
Definition AMReX_BoxArray.H:564
__host__ __device__ BoxND & grow(int i) noexcept
Definition AMReX_Box.H:649
__host__ __device__ IntVectND< dim > length() const noexcept
Return the length of the BoxND.
Definition AMReX_Box.H:155
__host__ __device__ bool contains(const IntVectND< dim > &p) const noexcept
Return true if argument is contained within BoxND.
Definition AMReX_Box.H:216
__host__ __device__ BoxND & shift(int dir, int nzones) noexcept
Shift this BoxND nzones indexing positions in coordinate direction dir.
Definition AMReX_Box.H:517
__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:1117
__host__ __device__ bool ok() const noexcept
Checks if it is a proper BoxND (including a valid type).
Definition AMReX_Box.H:212
__host__ __device__ const IntVectND< dim > & smallEnd() const &noexcept
Return the inclusive lower bound of the box.
Definition AMReX_Box.H:112
Definition AMReX_FabFactory.H:76
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:43
Definition AMReX_EBFabFactory.H:32
const FabArray< EBCellFlagFab > & getMultiEBCellFlagFab() const noexcept
EB cell flags for all boxes.
Definition AMReX_EBFabFactory.H:73
bool isAllRegular() const noexcept
Definition AMReX_EBFabFactory.cpp:148
Base class for FabArray.
Definition AMReX_FabArrayBase.H:42
IntVect nGrowVect() const noexcept
Definition AMReX_FabArrayBase.H:80
void clear()
Definition AMReX_FabArrayBase.cpp:207
Vector< int > indexArray
Definition AMReX_FabArrayBase.H:446
static FabArrayStats m_FA_stats
Definition AMReX_FabArrayBase.H:726
static bool getAllocSingleChunk()
Definition AMReX_FabArrayBase.H:730
bool isFusingCandidate() const noexcept
Is this a good candidate for kernel fusing?
Definition AMReX_FabArrayBase.cpp:2705
int size() const noexcept
Return the number of FABs in the FabArray.
Definition AMReX_FabArrayBase.H:110
FabArrayBase & operator=(const FabArrayBase &rhs)=default
void define(const BoxArray &bxs, const DistributionMapping &dm, int nvar, int ngrow)
Definition AMReX_FabArrayBase.cpp:175
CopyComTag::CopyComTagsContainer CopyComTagsContainer
Definition AMReX_FabArrayBase.H:220
CopyComTag::MapOfCopyComTagContainers MapOfCopyComTagContainers
Definition AMReX_FabArrayBase.H:221
const DistributionMapping & DistributionMap() const noexcept
Return constant reference to associated DistributionMapping.
Definition AMReX_FabArrayBase.H:131
int local_size() const noexcept
Return the number of local FABs in the FabArray.
Definition AMReX_FabArrayBase.H:113
CpOp
parallel copy or add
Definition AMReX_FabArrayBase.H:394
@ ADD
Definition AMReX_FabArrayBase.H:394
@ COPY
Definition AMReX_FabArrayBase.H:394
DistributionMapping distributionMap
Definition AMReX_FabArrayBase.H:445
friend void FillBoundary(Vector< FabArray< FAB > * > const &mf, const Periodicity &period)
int nComp() const noexcept
Return number of variables (aka components) associated with each point.
Definition AMReX_FabArrayBase.H:83
const BoxArray & boxArray() const noexcept
Return a constant reference to the BoxArray that defines the valid region associated with this FabArr...
Definition AMReX_FabArrayBase.H:95
An Array of FortranArrayBox(FAB)-like Objects.
Definition AMReX_FabArray.H:344
void ParallelCopyToGhost_finish()
Definition AMReX_FabArrayCommI.H:383
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:2397
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:1084
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:3693
void mult(value_type val, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2968
void setBndry(value_type val)
Set all values in the boundary region to val.
Definition AMReX_FabArray.H:2487
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:1095
void FillBoundary_finish()
Definition AMReX_FabArrayCommI.H:221
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:1412
void * m_dp_arrays
Definition AMReX_FabArray.H:1516
void ParallelCopy(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:873
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:2441
typename std::conditional_t< IsBaseFab< FAB >::value, FAB, FABType >::value_type value_type
Definition AMReX_FabArray.H:355
std::unique_ptr< FabArray< FAB > > os_temp
Definition AMReX_FabArray.H:1661
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:3232
void FillBoundary(const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3479
const FabFactory< FAB > & Factory() const noexcept
Definition AMReX_FabArray.H:442
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:11
void CMD_remote_setVal_gpu(value_type x, const CommMetaData &thecmd, int scomp, int ncomp)
Definition AMReX_FBI.H:684
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:981
LayoutData< int > RecvLayoutMask(const CommMetaData &thecmd)
Definition AMReX_FabArray.H:3892
void FillBoundary_nowait(const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3540
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:3405
void shift(const IntVect &v)
Shift the boxarray by vector v.
Definition AMReX_FabArray.H:3122
FAB * release(int K)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:1903
bool ok() const
Return true if the FabArray is well-defined. That is, the FabArray has a BoxArray and DistributionMap...
Definition AMReX_FabArray.H:2178
const FAB & operator[](const MFIter &mfi) const noexcept
Return a constant reference to the FAB associated with mfi.
Definition AMReX_FabArray.H:508
void ParallelAdd_nowait(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:884
FabArray(FabArray< FAB > &&rhs) noexcept
Definition AMReX_FabArray.H:2103
FabArray(const BoxArray &bxs, const DistributionMapping &dm, int nvar, const IntVect &ngrow, const MFInfo &info=MFInfo(), const FabFactory< FAB > &factory=DefaultFabFactory< FAB >())
Definition AMReX_FabArray.H:2067
bool defined(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:1796
void prefetchToHost(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:541
void OverrideSync_nowait(int scomp, int ncomp, const Periodicity &period)
Definition AMReX_FabArray.H:3639
FabArray(const FabArray< FAB > &rhs)=delete
void ParallelCopyToGhost(const FabArray< FAB > &src, int scomp, int dcomp, int ncomp, const IntVect &snghost, const IntVect &dnghost, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArrayCommI.H:352
MultiArray4< typename FabArray< FAB >::value_type > arrays() noexcept
Definition AMReX_FabArray.H:633
void ParallelCopy_finish()
Definition AMReX_FabArrayCommI.H:671
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:1373
FAB & get(int K) noexcept
Return a reference to the FAB associated with the Kth element.
Definition AMReX_FabArray.H:529
FAB const * fabPtr(int K) const noexcept
Definition AMReX_FabArray.H:1838
Array4< typename FabArray< FAB >::value_type > array(const MFIter &mfi, int start_comp) noexcept
Definition AMReX_FabArray.H:603
void SumBoundary_nowait(const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3686
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:3289
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:955
Long m_single_chunk_size
Definition AMReX_FabArray.H:1506
FAB & get(const MFIter &mfi) noexcept
Returns a reference to the FAB associated mfi.
Definition AMReX_FabArray.H:517
void OverrideSync_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3632
std::unique_ptr< PCData< FAB > > pcd
Definition AMReX_FabArray.H:1658
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:2213
void setDomainBndry(value_type val, const Geometry &geom)
Set all values outside the Geometry domain to val.
Definition AMReX_FabArray.H:2600
void ParallelAdd_nowait(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const IntVect &src_nghost, const IntVect &dst_nghost, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:985
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:1657
std::unique_ptr< detail::SingleChunkArena > m_single_chunk_arena
Definition AMReX_FabArray.H:1505
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:3707
FabArray(const FabArray< FAB > &rhs, MakeType maketype, int scomp, int ncomp)
Definition AMReX_FabArray.H:2081
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:870
FAB fab_type
Definition AMReX_FabArray.H:357
void FB_local_add_cpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:443
Array4< typename FabArray< FAB >::value_type const > array(int K) const noexcept
Definition AMReX_FabArray.H:573
bool SharedMemory() const noexcept
Definition AMReX_FabArray.H:1574
Array4< typename FabArray< FAB >::value_type const > const_array(int K) const noexcept
Definition AMReX_FabArray.H:591
void prefetchToDevice(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:551
void FillBoundary_nowait(const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3548
Vector< std::string > m_tags
Definition AMReX_FabArray.H:1522
void ParallelCopyToGhost_nowait(const FabArray< FAB > &src, int scomp, int dcomp, int ncomp, const IntVect &snghost, const IntVect &dnghost, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArrayCommI.H:369
void ParallelAdd_nowait(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:923
void FB_local_add_gpu(const FB &TheFB, int scomp, int ncomp, bool deterministic)
Definition AMReX_FBI.H:606
void FB_local_copy_gpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:534
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:1989
Arena * arena() const noexcept
Definition AMReX_FabArray.H:445
DataAllocator m_dallocator
Definition AMReX_FabArray.H:1504
void copy(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:879
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:1211
Array4< typename FabArray< FAB >::value_type > array(const MFIter &mfi) noexcept
Definition AMReX_FabArray.H:567
void FillBoundaryAndSync_finish()
Definition AMReX_FabArray.H:3602
void ParallelCopy_nowait(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, int src_nghost, int dst_nghost, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:995
void FillBoundary_nowait(bool cross=false)
Definition AMReX_FabArray.H:3532
void clear()
Releases FAB memory in the FabArray.
Definition AMReX_FabArray.H:1942
void FillBoundary_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3771
const Vector< std::string > & tags() const noexcept
Definition AMReX_FabArray.H:447
void CMD_local_setVal_gpu(value_type x, const CommMetaData &thecmd, int scomp, int ncomp)
Definition AMReX_FBI.H:654
MultiArray4< typename FabArray< FAB >::value_type const > arrays() const noexcept
Definition AMReX_FabArray.H:640
void FillBoundary_nowait(int scomp, int ncomp, bool cross=false)
Definition AMReX_FabArray.H:3556
value_type * singleChunkPtr() noexcept
Definition AMReX_FabArray.H:460
std::vector< FAB * > m_fabs_v
The data.
Definition AMReX_FabArray.H:1513
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:947
bool define_function_called
has define() been called?
Definition AMReX_FabArray.H:1509
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:900
FabArray() noexcept
Constructs an empty FabArray<FAB>.
Definition AMReX_FabArray.H:2042
void FillBoundary_test()
Definition AMReX_FabArrayCommI.H:1008
void plus(value_type val, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2890
bool defined(int K) const noexcept
Definition AMReX_FabArray.H:1783
FAB * fabPtr(int K) noexcept
Definition AMReX_FabArray.H:1829
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:938
const FAB & atLocalIdx(int L) const noexcept
Definition AMReX_FabArray.H:533
MultiArray4< typename FabArray< FAB >::value_type const > const_arrays() const noexcept
Definition AMReX_FabArray.H:647
std::unique_ptr< FabFactory< FAB > > m_factory
Definition AMReX_FabArray.H:1503
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:915
void invert(value_type numerator, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:3046
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:2696
void ParallelAdd_nowait(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, int src_nghost, int dst_nghost, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:975
void setVal(value_type val)
Set all components in the entire region of each FAB to val.
Definition AMReX_FabArray.H:2705
Array4< typename FabArray< FAB >::value_type const > array(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:561
void FillBoundary_nowait(int scomp, int ncomp, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3763
const FAB & get(const MFIter &mfi) const noexcept
Return a constant reference to the FAB associated with mfi.
Definition AMReX_FabArray.H:511
void SumBoundary_finish()
Definition AMReX_FabArray.H:3720
std::size_t singleChunkSize() const noexcept
Definition AMReX_FabArray.H:472
void SumBoundary_nowait(int scomp, int ncomp, IntVect const &nghost, const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3700
void FB_local_copy_cpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:384
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:3140
MultiArray4< value_type > m_arrays
Definition AMReX_FabArray.H:1519
void FillBoundaryAndSync_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3586
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:3593
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:3781
void * m_hp_arrays
Definition AMReX_FabArray.H:1518
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:3349
ShMem shmem
Definition AMReX_FabArray.H:1572
FabArray< FAB > & operator=(FabArray< FAB > &&rhs) noexcept
Definition AMReX_FabArray.H:2134
Array4< typename FabArray< FAB >::value_type > array(int K, int start_comp) noexcept
Definition AMReX_FabArray.H:615
MultiArray4< value_type const > m_const_arrays
Definition AMReX_FabArray.H:1520
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:906
bool hasEBFabFactory() const noexcept
Definition AMReX_FabArray.H:449
TagVector< Array4CopyTag< value_type > > const * FB_get_local_copy_tag_vector(const FB &TheFB)
Definition AMReX_FBI.H:491
Array4< typename FabArray< FAB >::value_type const > array(int K, int start_comp) const noexcept
Definition AMReX_FabArray.H:609
bool isAllRegular() const noexcept
Definition AMReX_FabArray.H:474
Array4< typename FabArray< FAB >::value_type > array(int K) noexcept
Definition AMReX_FabArray.H:579
FAB * fabPtr(const MFIter &mfi) noexcept
Return pointer to FAB.
Definition AMReX_FabArray.H:1809
void OverrideSync_finish()
Definition AMReX_FabArray.H:3647
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:1113
FAB * release(const MFIter &mfi)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:1923
Array4< typename FabArray< FAB >::value_type const > const_array(const MFIter &mfi, int start_comp) const noexcept
Definition AMReX_FabArray.H:621
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:3187
void capacityOfFabs(LayoutData< I > &mem) const
Get capacity of the FabArray.
Definition AMReX_FabArray.H:2641
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:532
void define(const BoxArray &bxs, const DistributionMapping &dm, int nvar, const IntVect &ngrow, const MFInfo &info=MFInfo(), const FabFactory< FAB > &factory=DefaultFabFactory< FAB >())
Definition AMReX_FabArray.H:2225
void ParallelCopy_nowait(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:887
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:1999
Array4< typename FabArray< FAB >::value_type const > const_array(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:585
const FAB & get(int K) const noexcept
Return a constant reference to the FAB associated with the Kth element.
Definition AMReX_FabArray.H:523
FAB const * fabPtr(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:1819
void ParallelCopy_nowait(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:929
bool isDefined() const
Definition AMReX_FabArray.H:2206
value_type const * singleChunkPtr() const noexcept
Definition AMReX_FabArray.H:466
~FabArray()
The destructor – deletes all FABs in the array.
Definition AMReX_FabArray.H:2170
Array4< typename FabArray< FAB >::value_type const > array(const MFIter &mfi, int start_comp) const noexcept
Definition AMReX_FabArray.H:597
Array4< typename FabArray< FAB >::value_type const > const_array(int K, int start_comp) const noexcept
Definition AMReX_FabArray.H:627
F::value_type sum(int comp, IntVect const &nghost, bool local=false) const
Returns the sum of component "comp".
Definition AMReX_FabArray.H:2653
Definition AMReX_FabFactory.H:50
virtual Long nBytes(const Box &box, int ncomps, int) const
Definition AMReX_FabFactory.H:64
virtual FabFactory< FAB > * clone() const =0
virtual FAB * create(const Box &box, int ncomps, const FabInfo &info, int box_index) const =0
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:75
const Box & Domain() const noexcept
Returns our rectangular domain.
Definition AMReX_Geometry.H:216
bool isPeriodic(int dir) const noexcept
Is the domain periodic in the specified direction?
Definition AMReX_Geometry.H:337
GPU-compatible tuple.
Definition AMReX_Tuple.H:98
__host__ __device__ constexpr bool allGE(const IntVectND< dim > &rhs) const noexcept
Returns true if this is greater than or equal to argument for all components. NOTE: This is NOT a str...
Definition AMReX_IntVect.H:542
__host__ static __device__ constexpr IntVectND< dim > TheZeroVector() noexcept
This static member function returns a reference to a constant IntVectND object, all of whose dim argu...
Definition AMReX_IntVect.H:771
__host__ __device__ constexpr int max() const noexcept
maximum (no absolute values) value
Definition AMReX_IntVect.H:313
__host__ __device__ constexpr bool allLE(const IntVectND< dim > &rhs) const noexcept
Returns true if this is less than or equal to argument for all components. NOTE: This is NOT a strict...
Definition AMReX_IntVect.H:492
a one-thingy-per-box distributed object
Definition AMReX_LayoutData.H:13
Iterator for looping ever tiles and boxes of amrex::FabArray based containers.
Definition AMReX_MFIter.H:88
Box growntilebox(int ng=-1000000) const noexcept
Return the tile box at the current index grown to include ghost cells.
Definition AMReX_MFIter.cpp:476
const DistributionMapping & DistributionMap() const noexcept
Definition AMReX_MFIter.H:197
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:172
Box validbox() const noexcept
Return the valid Box in which the current tile resides.
Definition AMReX_MFIter.H:163
int index() const noexcept
The index into the underlying BoxArray of the current FAB.
Definition AMReX_MFIter.H:175
int LocalIndex() const noexcept
Return local index into the vector of fab pointers, m_fabs_v When AllBoxes is on, local_index_map is ...
Definition AMReX_MFIter.H:190
This provides length of period for periodic domains. 0 means it is not periodic in that direction....
Definition AMReX_Periodicity.H:17
static const Periodicity & NonPeriodic() noexcept
Definition AMReX_Periodicity.cpp:52
bool isAnyPeriodic() const noexcept
Definition AMReX_Periodicity.H:22
bool isPeriodic(int dir) const noexcept
Definition AMReX_Periodicity.H:26
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:29
Long size() const noexcept
Definition AMReX_Vector.H:54
Checks if a type is derived from amrex::BaseFab.
Definition AMReX_Concepts.H:13
amrex_long Long
Definition AMReX_INT.H:30
void EnforcePeriodicity(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Definition AMReX_FabArray.H:3750
void SumBoundary(int scomp, int ncomp, const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Definition AMReX_FabArray.H:3662
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:3669
void OverrideSync(const Periodicity &period=Periodicity::NonPeriodic())
Synchronize nodal data.
Definition AMReX_FabArray.H:3610
void FillBoundary(bool cross=false)
Copy on intersection within a FabArray.
Definition AMReX_FabArray.H:3455
void OverrideSync(int scomp, int ncomp, const Periodicity &period)
Synchronize nodal data.
Definition AMReX_FabArray.H:3621
void FillBoundary(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3517
void FillBoundaryAndSync(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Fill ghost cells and synchronize nodal data.
Definition AMReX_FabArray.H:3574
void FillBoundary(const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3467
void FillBoundary(int scomp, int ncomp, bool cross=false)
Definition AMReX_FabArray.H:3493
void FillBoundaryAndSync(const Periodicity &period=Periodicity::NonPeriodic())
Fill ghost cells and synchronize nodal data.
Definition AMReX_FabArray.H:3563
void SumBoundary(const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Sum values in overlapped cells.
Definition AMReX_FabArray.H:3655
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:3676
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:3927
void EnforcePeriodicity(const Periodicity &period)
Fill ghost cells with values from their corresponding cells across periodic boundaries,...
Definition AMReX_FabArray.H:3728
void FillBoundary(int scomp, int ncomp, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3505
void EnforcePeriodicity(int scomp, int ncomp, const Periodicity &period)
Definition AMReX_FabArray.H:3739
Arena * The_Comms_Arena()
Definition AMReX_Arena.cpp:880
Arena * The_Pinned_Arena()
Definition AMReX_Arena.cpp:860
Arena * The_Arena()
Definition AMReX_Arena.cpp:820
int MyProc() noexcept
Definition AMReX_ParallelDescriptor.H:128
void Min(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:161
void Sum(T &v, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:221
void Max(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:133
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H: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 &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:139
__host__ __device__ BoxND< dim > convert(const BoxND< dim > &b, const IntVectND< dim > &typ) noexcept
Return a BoxND with different type.
Definition AMReX_Box.H:1567
void FillBoundary_finish(Vector< MF * > const &mf)
Wait for outstanding FillBoundary_nowait operations launched with the vector helper to complete.
Definition AMReX_FabArrayCommI.H:1115
int nComp(FabArrayBase const &fa)
Definition AMReX_FabArrayBase.cpp:2852
void Copy(FabArray< DFAB > &dst, FabArray< SFAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Definition AMReX_FabArray.H:180
void OverrideSync_nowait(FabArray< FAB > &fa, FabArray< IFAB > const &msk, const Periodicity &period)
Definition AMReX_FabArrayUtility.H:1390
void Add(FabArray< FAB > &dst, FabArray< FAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Definition AMReX_FabArray.H:239
std::unique_ptr< char, TheFaArenaDeleter > TheFaArenaPointer
Definition AMReX_FabArray.H:106
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
DistributionMapping const & DistributionMap(FabArrayBase const &fa)
Definition AMReX_FabArrayBase.cpp:2867
Long nBytesOwned(T const &) noexcept
Definition AMReX_FabArray.H:60
IntVect nGrowVect(FabArrayBase const &fa)
Definition AMReX_FabArrayBase.cpp:2857
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:1138
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:30
bool isMFIterSafe(const FabArrayBase &x, const FabArrayBase &y)
Definition AMReX_MFIter.H:252
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:33
__host__ __device__ constexpr const T & max(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:45
__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)
Definition AMReX_FabArrayUtility.H:1437
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:1868
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:241
void update_fab_stats(Long n, Long s, size_t szt) noexcept
Definition AMReX_BaseFab.cpp:146
void FillBoundaryAndSync_finish(Vector< MF * > const &mf)
Wait for outstanding FillBoundaryAndSync_nowait operations launched with the vector helper to complet...
Definition AMReX_FabArrayCommI.H:1180
BoxArray const & boxArray(FabArrayBase const &fa)
Definition AMReX_FabArrayBase.cpp:2862
void setVal(MF &dst, typename MF::value_type val)
dst = val
Definition AMReX_FabArrayUtility.H:1861
__host__ __device__ constexpr int get(IntVectND< dim > const &iv) noexcept
Get I'th element of IntVectND<dim>
Definition AMReX_IntVect.H:1334
Definition AMReX_TagParallelFor.H:58
A multidimensional array accessor.
Definition AMReX_Array4.H:285
Definition AMReX_DataAllocator.H:9
Arena * arena() const noexcept
Definition AMReX_DataAllocator.H:24
Arena * m_arena
Definition AMReX_DataAllocator.H:10
Definition AMReX_FabArray.H:110
const FabArrayBase::FB * fb
Definition AMReX_FabArray.H:112
bool deterministic
Definition AMReX_FabArray.H:129
char * the_recv_data
Definition AMReX_FabArray.H:117
Vector< MPI_Request > recv_reqs
Definition AMReX_FabArray.H:122
Vector< char * > recv_data
Definition AMReX_FabArray.H:120
Vector< MPI_Status > recv_stat
Definition AMReX_FabArray.H:123
int scomp
Definition AMReX_FabArray.H:113
Vector< int > recv_from
Definition AMReX_FabArray.H:119
char * the_send_data
Definition AMReX_FabArray.H:118
Vector< MPI_Request > send_reqs
Definition AMReX_FabArray.H:126
Vector< char * > send_data
Definition AMReX_FabArray.H:125
Vector< std::size_t > recv_size
Definition AMReX_FabArray.H:121
int ncomp
Definition AMReX_FabArray.H:114
int tag
Definition AMReX_FabArray.H:127
parallel copy or add
Definition AMReX_FabArrayBase.H:538
Definition AMReX_FabArrayBase.H:472
std::unique_ptr< MapOfCopyComTagContainers > m_RcvTags
Definition AMReX_FabArrayBase.H:478
std::unique_ptr< CopyComTagsContainer > m_LocTags
Definition AMReX_FabArrayBase.H:476
Used by a bunch of routines when communicating via MPI.
Definition AMReX_FabArrayBase.H:195
Box dbox
Definition AMReX_FabArrayBase.H:196
int dstIndex
Definition AMReX_FabArrayBase.H:198
FillBoundary.
Definition AMReX_FabArrayBase.H:488
void recordBuild() noexcept
Definition AMReX_FabArrayBase.H:704
Definition AMReX_FabArray.H:347
FAB value_type
Definition AMReX_FabArray.H:348
for shared memory
Definition AMReX_FabArray.H:1525
ShMem(ShMem &&rhs) noexcept
Definition AMReX_FabArray.H:1539
ShMem() noexcept=default
Long n_values
Definition AMReX_FabArray.H:1566
Long n_points
Definition AMReX_FabArray.H:1567
bool alloc
Definition AMReX_FabArray.H:1565
ShMem & operator=(ShMem &&rhs) noexcept
Definition AMReX_FabArray.H:1550
ShMem(const ShMem &)=delete
FabArray memory allocation information.
Definition AMReX_FabArray.H:68
MFInfo & SetTag(T &&t, Ts &&... ts) noexcept
Definition AMReX_FabArray.H:94
MFInfo & SetTag(const std::string &t) noexcept
Definition AMReX_FabArray.H:88
Arena * arena
Definition AMReX_FabArray.H:72
MFInfo & SetArena(Arena *ar) noexcept
Definition AMReX_FabArray.H:79
MFInfo & SetTag() noexcept
Definition AMReX_FabArray.H:81
bool alloc
Definition AMReX_FabArray.H:70
MFInfo & SetAlloc(bool a) noexcept
Definition AMReX_FabArray.H:75
bool alloc_single_chunk
Definition AMReX_FabArray.H:71
MFInfo & SetAllocSingleChunk(bool a) noexcept
Definition AMReX_FabArray.H:77
Vector< std::string > tags
Definition AMReX_FabArray.H:73
MFInfo & SetTag(const char *t) noexcept
Definition AMReX_FabArray.H:83
Definition AMReX_MFIter.H:20
MFItInfo & DisableDeviceSync() noexcept
Definition AMReX_MFIter.H:47
Definition AMReX_FabArray.H:156
Array4< T > const *__restrict__ hp
Definition AMReX_FabArray.H:172
__host__ __device__ Array4< T > const & operator[](int li) const noexcept
Definition AMReX_FabArray.H:158
Array4< T > const *__restrict__ dp
Definition AMReX_FabArray.H:170
Definition AMReX_FabArray.H:134
int actual_n_rcvs
Definition AMReX_FabArray.H:140
Vector< std::size_t > recv_size
Definition AMReX_FabArray.H:147
int DC
Definition AMReX_FabArray.H:141
Vector< MPI_Request > send_reqs
Definition AMReX_FabArray.H:149
int tag
Definition AMReX_FabArray.H:139
const FabArray< FAB > * src
Definition AMReX_FabArray.H:137
char * the_recv_data
Definition AMReX_FabArray.H:143
FabArrayBase::CpOp op
Definition AMReX_FabArray.H:138
Vector< MPI_Request > recv_reqs
Definition AMReX_FabArray.H:148
char * the_send_data
Definition AMReX_FabArray.H:144
const FabArrayBase::CPC * cpc
Definition AMReX_FabArray.H:136
Vector< int > recv_from
Definition AMReX_FabArray.H:145
bool deterministic
Definition AMReX_FabArray.H:150
int NC
Definition AMReX_FabArray.H:141
int SC
Definition AMReX_FabArray.H:141
Vector< char * > recv_data
Definition AMReX_FabArray.H:146
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:100
char * pointer
Definition AMReX_FabArray.H:101
void operator()(pointer p) const noexcept
Definition AMReX_FabArray.H:102
Struct for holding types.
Definition AMReX_TypeList.H:13