Block-Structured AMR Software Framework
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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_LayoutData.H>
28#include <AMReX_BaseFab.H>
30#include <AMReX_MFParallelFor.H>
32#include <AMReX_ParReduce.H>
33
34#include <AMReX_Gpu.H>
35
36#ifdef AMREX_USE_EB
37#include <AMReX_EBFabFactory.H>
38#endif
39
40#ifdef AMREX_USE_OMP
41#include <omp.h>
42#endif
43
44#include <algorithm>
45#include <cstring>
46#include <limits>
47#include <map>
48#include <memory>
49#include <utility>
50#include <set>
51#include <string>
52#include <vector>
53
54
55namespace amrex {
56
57template <typename T, std::enable_if_t<!IsBaseFab<T>::value,int> = 0>
58Long nBytesOwned (T const&) noexcept { return 0; }
59
60template <typename T>
61Long nBytesOwned (BaseFab<T> const& fab) noexcept { return fab.nBytesOwned(); }
62
66struct MFInfo {
67 // alloc: allocate memory or not
68 bool alloc = true;
70 Arena* arena = nullptr;
72
73 MFInfo& SetAlloc (bool a) noexcept { alloc = a; return *this; }
74
75 MFInfo& SetAllocSingleChunk (bool a) noexcept { alloc_single_chunk = a; return *this; }
76
77 MFInfo& SetArena (Arena* ar) noexcept { arena = ar; return *this; }
78
79 MFInfo& SetTag () noexcept { return *this; }
80
81 MFInfo& SetTag (const char* t) noexcept {
82 tags.emplace_back(t);
83 return *this;
84 }
85
86 MFInfo& SetTag (const std::string& t) noexcept {
87 tags.emplace_back(t);
88 return *this;
89 }
90
91 template <typename T, typename... Ts>
92 MFInfo& SetTag (T&& t, Ts&&... ts) noexcept {
93 tags.emplace_back(std::forward<T>(t));
94 return SetTag(std::forward<Ts>(ts)...);
95 }
96};
97
99 using pointer = char*;
100 void operator()(pointer p) const noexcept {
101 The_Comms_Arena()->free(p);
102 }
103};
104using TheFaArenaPointer = std::unique_ptr<char, TheFaArenaDeleter>;
105
106// Data used in non-blocking fill boundary.
107template <class FAB>
128
129// Data used in non-blocking parallel copy.
130template <class FAB>
149
150template <typename T>
152{
154 Array4<T> const& operator[] (int li) const noexcept {
155 AMREX_IF_ON_DEVICE((return dp[li];))
156 AMREX_IF_ON_HOST((return hp[li];))
157 }
158
160 explicit operator bool() const noexcept {
161 AMREX_IF_ON_DEVICE((return dp != nullptr;))
162 AMREX_IF_ON_HOST((return hp != nullptr;))
163 }
164
165#ifdef AMREX_USE_GPU
166 Array4<T> const* AMREX_RESTRICT dp = nullptr;
167#endif
168 Array4<T> const* AMREX_RESTRICT hp = nullptr;
169};
170
171template <class FAB> class FabArray;
172
173template <class DFAB, class SFAB,
174 std::enable_if_t<std::conjunction_v<
176 std::is_convertible<typename SFAB::value_type,
177 typename DFAB::value_type>>, int> BAR = 0>
178void
179Copy (FabArray<DFAB>& dst, FabArray<SFAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
180{
181 Copy(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
182}
183
184template <class DFAB, class SFAB,
185 std::enable_if_t<std::conjunction_v<
186 IsBaseFab<DFAB>, IsBaseFab<SFAB>,
187 std::is_convertible<typename SFAB::value_type,
188 typename DFAB::value_type>>, int> BAR = 0>
189void
190Copy (FabArray<DFAB>& dst, FabArray<SFAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
191{
192 BL_PROFILE("amrex::Copy()");
193
194 using DT = typename DFAB::value_type;
195
196 if (dst.local_size() == 0) { return; }
197
198 // avoid self copy
199 if constexpr (std::is_same_v<typename SFAB::value_type, typename DFAB::value_type>) {
200 if (dst.atLocalIdx(0).dataPtr(dstcomp) == src.atLocalIdx(0).dataPtr(srccomp)) {
201 return;
202 }
203 }
204
205#ifdef AMREX_USE_GPU
206 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
207 auto const& srcarr = src.const_arrays();
208 auto const& dstarr = dst.arrays();
209 ParallelFor(dst, nghost, numcomp,
210 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
211 {
212 dstarr[box_no](i,j,k,dstcomp+n) = DT(srcarr[box_no](i,j,k,srccomp+n));
213 });
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 <class FAB,
238 class bar = std::enable_if_t<IsBaseFab<FAB>::value> >
239void
240Add (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, int nghost)
241{
242 Add(dst,src,srccomp,dstcomp,numcomp,IntVect(nghost));
243}
244
245template <class FAB,
246 class bar = std::enable_if_t<IsBaseFab<FAB>::value> >
247void
248Add (FabArray<FAB>& dst, FabArray<FAB> const& src, int srccomp, int dstcomp, int numcomp, const IntVect& nghost)
249{
250 BL_PROFILE("amrex::Add()");
251
252#ifdef AMREX_USE_GPU
253 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
254 auto const& dstfa = dst.arrays();
255 auto const& srcfa = src.const_arrays();
256 ParallelFor(dst, nghost, numcomp,
257 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
258 {
259 dstfa[box_no](i,j,k,n+dstcomp) += srcfa[box_no](i,j,k,n+srccomp);
260 });
261 if (!Gpu::inNoSyncRegion()) {
263 }
264 } else
265#endif
266 {
267#ifdef AMREX_USE_OMP
268#pragma omp parallel if (Gpu::notInLaunchRegion())
269#endif
270 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
271 {
272 const Box& bx = mfi.growntilebox(nghost);
273 if (bx.ok())
274 {
275 auto const srcFab = src.array(mfi);
276 auto dstFab = dst.array(mfi);
277 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
278 {
279 dstFab(i,j,k,n+dstcomp) += srcFab(i,j,k,n+srccomp);
280 });
281 }
282 }
283 }
284}
285
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
494 bool ok () const;
495
503 bool isDefined () const;
504
506 const FAB& operator[] (const MFIter& mfi) const noexcept { return *(this->fabPtr(mfi)); }
507
509 const FAB& get (const MFIter& mfi) const noexcept { return *(this->fabPtr(mfi)); }
510
512 FAB& operator[] (const MFIter& mfi) noexcept { return *(this->fabPtr(mfi)); }
513
515 FAB& get (const MFIter& mfi) noexcept { return *(this->fabPtr(mfi)); }
516
518 const FAB& operator[] (int K) const noexcept { return *(this->fabPtr(K)); }
519
521 const FAB& get (int K) const noexcept { return *(this->fabPtr(K)); }
522
524 FAB& operator[] (int K) noexcept { return *(this->fabPtr(K)); }
525
527 FAB& get (int K) noexcept { return *(this->fabPtr(K)); }
528
530 FAB& atLocalIdx (int L) noexcept { return *m_fabs_v[L]; }
531 const FAB& atLocalIdx (int L) const noexcept { return *m_fabs_v[L]; }
532
534 FAB * fabPtr (const MFIter& mfi) noexcept;
535 FAB const* fabPtr (const MFIter& mfi) const noexcept;
536 FAB * fabPtr (int K) noexcept; // Here K is global index
537 FAB const* fabPtr (int K) const noexcept;
538
539 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
540 void prefetchToHost (const MFIter& mfi) const noexcept
541 {
542#ifdef AMREX_USE_CUDA
543 this->fabPtr(mfi)->prefetchToHost();
544#else
546#endif
547 }
548
549 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
550 void prefetchToDevice (const MFIter& mfi) const noexcept
551 {
552#ifdef AMREX_USE_CUDA
553 this->fabPtr(mfi)->prefetchToDevice();
554#else
556#endif
557 }
558
559 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
560 Array4<typename FabArray<FAB>::value_type const> array (const MFIter& mfi) const noexcept
561 {
562 return fabPtr(mfi)->const_array();
563 }
564
565 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
567 {
568 return fabPtr(mfi)->array();
569 }
570
571 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
573 {
574 return fabPtr(K)->const_array();
575 }
576
577 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
579 {
580 return fabPtr(K)->array();
581 }
582
583 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
585 {
586 return fabPtr(mfi)->const_array();
587 }
588
589 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
591 {
592 return fabPtr(K)->const_array();
593 }
594
595 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
596 Array4<typename FabArray<FAB>::value_type const> array (const MFIter& mfi, int start_comp) const noexcept
597 {
598 return fabPtr(mfi)->const_array(start_comp);
599 }
600
601 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
602 Array4<typename FabArray<FAB>::value_type> array (const MFIter& mfi, int start_comp) noexcept
603 {
604 return fabPtr(mfi)->array(start_comp);
605 }
606
607 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
608 Array4<typename FabArray<FAB>::value_type const> array (int K, int start_comp) const noexcept
609 {
610 return fabPtr(K)->const_array(start_comp);
611 }
612
613 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
614 Array4<typename FabArray<FAB>::value_type> array (int K, int start_comp) noexcept
615 {
616 return fabPtr(K)->array(start_comp);
617 }
618
619 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
620 Array4<typename FabArray<FAB>::value_type const> const_array (const MFIter& mfi, int start_comp) const noexcept
621 {
622 return fabPtr(mfi)->const_array(start_comp);
623 }
624
625 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
626 Array4<typename FabArray<FAB>::value_type const> const_array (int K, int start_comp) const noexcept
627 {
628 return fabPtr(K)->const_array(start_comp);
629 }
630
631 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
637
638 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
640 {
641 build_arrays();
642 return m_const_arrays;
643 }
644
645 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
647 {
648 build_arrays();
649 return m_const_arrays;
650 }
651
653 void setFab (int boxno, std::unique_ptr<FAB> elem);
654
656 template <class F=FAB, std::enable_if_t<std::is_move_constructible_v<F>,int> = 0>
657 void setFab (int boxno, FAB&& elem);
658
660 void setFab (const MFIter&mfi, std::unique_ptr<FAB> elem);
661
663 template <class F=FAB, std::enable_if_t<std::is_move_constructible_v<F>,int> = 0>
664 void setFab (const MFIter&mfi, FAB&& elem);
665
668 FAB* release (int K);
669
672 FAB* release (const MFIter& mfi);
673
675 void clear ();
676
691 template <typename SFAB, typename DFAB = FAB,
692 std::enable_if_t<std::conjunction_v<
694 std::is_convertible<typename SFAB::value_type,
695 typename DFAB::value_type>>, int> = 0>
696 void LocalCopy (FabArray<SFAB> const& src, int scomp, int dcomp, int ncomp,
697 IntVect const& nghost);
698
711 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
712 void LocalAdd (FabArray<FAB> const& src, int scomp, int dcomp, int ncomp,
713 IntVect const& nghost);
714
716 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
717 void setVal (value_type val);
718
720 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
722
728 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
730 int comp,
731 int ncomp,
732 int nghost = 0);
733
734 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
736 int comp,
737 int ncomp,
738 const IntVect& nghost);
739
746 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
748 const Box& region,
749 int comp,
750 int ncomp,
751 int nghost = 0);
752
753 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
755 const Box& region,
756 int comp,
757 int ncomp,
758 const IntVect& nghost);
763 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
764 void setVal (value_type val, int nghost);
765
766 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
767 void setVal (value_type val, const IntVect& nghost);
768
774 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
775 void setVal (value_type val, const Box& region, int nghost);
776
777 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
778 void setVal (value_type val, const Box& region, const IntVect& nghost);
779
780 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
781 void abs (int comp, int ncomp, int nghost = 0);
782
783 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
784 void abs (int comp, int ncomp, const IntVect& nghost);
785
786 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
787 void plus (value_type val, int comp, int num_comp, int nghost = 0);
788
789 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
790 void plus (value_type val, const Box& region, int comp, int num_comp, int nghost = 0);
791
792 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
793 void mult (value_type val, int comp, int num_comp, int nghost = 0);
794
795 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
796 void mult (value_type val, const Box& region, int comp, int num_comp, int nghost = 0);
797
798 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
799 void invert (value_type numerator, int comp, int num_comp, int nghost = 0);
800
801 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
802 void invert (value_type numerator, const Box& region, int comp, int num_comp, int nghost = 0);
803
805 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
807
809 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
810 void setBndry (value_type val, int strt_comp, int ncomp);
811
813 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
814 void setDomainBndry (value_type val, const Geometry& geom);
815
817 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
818 void setDomainBndry (value_type val, int strt_comp, int ncomp, const Geometry& geom);
819
827 template <typename F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
828 typename F::value_type
829 sum (int comp, IntVect const& nghost, bool local = false) const;
830
837 void ParallelAdd (const FabArray<FAB>& src,
838 const Periodicity& period = Periodicity::NonPeriodic())
839 { ParallelCopy(src,period,FabArray::ADD); }
840 void ParallelCopy (const FabArray<FAB>& src,
841 const Periodicity& period = Periodicity::NonPeriodic(),
843 { ParallelCopy(src,0,0,nComp(),0,0,period,op); }
844
845 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
846 void copy (const FabArray<FAB>& src,
847 const Periodicity& period = Periodicity::NonPeriodic(),
849 { ParallelCopy(src,period,op); }
850
852 const Periodicity& period = Periodicity::NonPeriodic())
853 { ParallelCopy_nowait(src,period,FabArray::ADD); }
855 const Periodicity& period = Periodicity::NonPeriodic(),
857 { ParallelCopy_nowait(src,0,0,nComp(),0,0,period,op); }
858
867 void ParallelAdd (const FabArray<FAB>& src,
868 int src_comp,
869 int dest_comp,
870 int num_comp,
871 const Periodicity& period = Periodicity::NonPeriodic())
872 { ParallelCopy(src,src_comp,dest_comp,num_comp, period, FabArrayBase::ADD); }
873 void ParallelCopy (const FabArray<FAB>& src,
874 int src_comp,
875 int dest_comp,
876 int num_comp,
877 const Periodicity& period = Periodicity::NonPeriodic(),
879 { ParallelCopy(src,src_comp,dest_comp,num_comp,0,0,period,op); }
880
881 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
882 void copy (const FabArray<FAB>& src,
883 int src_comp,
884 int dest_comp,
885 int num_comp,
886 const Periodicity& period = Periodicity::NonPeriodic(),
888 { ParallelCopy(src,src_comp,dest_comp,num_comp, period, op); }
889
891 int src_comp,
892 int dest_comp,
893 int num_comp,
894 const Periodicity& period = Periodicity::NonPeriodic())
895 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp, period, FabArrayBase::ADD); }
897 int src_comp,
898 int dest_comp,
899 int num_comp,
900 const Periodicity& period = Periodicity::NonPeriodic(),
902 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,0,0,period,op); }
903
905 void ParallelAdd (const FabArray<FAB>& src,
906 int src_comp,
907 int dest_comp,
908 int num_comp,
909 int src_nghost,
910 int dst_nghost,
911 const Periodicity& period = Periodicity::NonPeriodic())
912 { ParallelCopy(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),IntVect(dst_nghost),period,
914 void ParallelAdd (const FabArray<FAB>& src,
915 int src_comp,
916 int dest_comp,
917 int num_comp,
918 const IntVect& src_nghost,
919 const IntVect& dst_nghost,
920 const Periodicity& period = Periodicity::NonPeriodic())
921 { ParallelCopy(src,src_comp,dest_comp,num_comp,src_nghost,dst_nghost,period,FabArrayBase::ADD); }
922 void ParallelCopy (const FabArray<FAB>& src,
923 int src_comp,
924 int dest_comp,
925 int num_comp,
926 int src_nghost,
927 int dst_nghost,
928 const Periodicity& period = Periodicity::NonPeriodic(),
930 { ParallelCopy(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),IntVect(dst_nghost),period,op); }
931 void ParallelCopy (const FabArray<FAB>& src,
932 int scomp,
933 int dcomp,
934 int ncomp,
935 const IntVect& snghost,
936 const IntVect& dnghost,
937 const Periodicity& period = Periodicity::NonPeriodic(),
939 const FabArrayBase::CPC* a_cpc = nullptr);
940
942 int src_comp,
943 int dest_comp,
944 int num_comp,
945 int src_nghost,
946 int dst_nghost,
947 const Periodicity& period = Periodicity::NonPeriodic())
948 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),
949 IntVect(dst_nghost),period,FabArrayBase::ADD); }
950
952 int src_comp,
953 int dest_comp,
954 int num_comp,
955 const IntVect& src_nghost,
956 const IntVect& dst_nghost,
957 const Periodicity& period = Periodicity::NonPeriodic())
958 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,src_nghost,
959 dst_nghost,period,FabArrayBase::ADD); }
960
962 int src_comp,
963 int dest_comp,
964 int num_comp,
965 int src_nghost,
966 int dst_nghost,
967 const Periodicity& period = Periodicity::NonPeriodic(),
969 { ParallelCopy_nowait(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),
970 IntVect(dst_nghost),period,op); }
971
973 int scomp,
974 int dcomp,
975 int ncomp,
976 const IntVect& snghost,
977 const IntVect& dnghost,
978 const Periodicity& period = Periodicity::NonPeriodic(),
980 const FabArrayBase::CPC* a_cpc = nullptr,
981 bool to_ghost_cells_only = false);
982
984
986 int scomp,
987 int dcomp,
988 int ncomp,
989 const IntVect& snghost,
990 const IntVect& dnghost,
991 const Periodicity& period = Periodicity::NonPeriodic());
992
994 int scomp,
995 int dcomp,
996 int ncomp,
997 const IntVect& snghost,
998 const IntVect& dnghost,
999 const Periodicity& period = Periodicity::NonPeriodic());
1000
1002
1003 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
1004 void copy (const FabArray<FAB>& src,
1005 int src_comp,
1006 int dest_comp,
1007 int num_comp,
1008 int src_nghost,
1009 int dst_nghost,
1010 const Periodicity& period = Periodicity::NonPeriodic(),
1012 { ParallelCopy(src,src_comp,dest_comp,num_comp,IntVect(src_nghost),IntVect(dst_nghost),period,op); }
1013
1014 [[deprecated("Use FabArray::ParallelCopy() instead.")]]
1015 void copy (const FabArray<FAB>& src,
1016 int src_comp,
1017 int dest_comp,
1018 int num_comp,
1019 const IntVect& src_nghost,
1020 const IntVect& dst_nghost,
1021 const Periodicity& period = Periodicity::NonPeriodic(),
1023 { ParallelCopy(src,src_comp,dest_comp,num_comp,src_nghost,dst_nghost,period,op); }
1024
1026 void Redistribute (const FabArray<FAB>& src,
1027 int scomp,
1028 int dcomp,
1029 int ncomp,
1030 const IntVect& nghost);
1031
1037 void copyTo (FAB& dest, int nghost = 0) const;
1038
1046 void copyTo (FAB& dest, int scomp, int dcomp, int ncomp, int nghost = 0) const;
1047
1049 void shift (const IntVect& v);
1050
1051 bool defined (int K) const noexcept;
1052 bool defined (const MFIter& mfi) const noexcept;
1053
1065 template <typename BUF=value_type>
1066 void FillBoundary (bool cross = false);
1067
1068 template <typename BUF=value_type>
1069 void FillBoundary (const Periodicity& period, bool cross = false);
1070
1071 template <typename BUF=value_type>
1072 void FillBoundary (const IntVect& nghost, const Periodicity& period, bool cross = false);
1073
1075 template <typename BUF=value_type>
1076 void FillBoundary (int scomp, int ncomp, bool cross = false);
1077
1078 template <typename BUF=value_type>
1079 void FillBoundary (int scomp, int ncomp, const Periodicity& period, bool cross = false);
1080
1081 template <typename BUF=value_type>
1082 void FillBoundary (int scomp, int ncomp, const IntVect& nghost, const Periodicity& period, bool cross = false);
1083
1084 template <typename BUF=value_type>
1085 void FillBoundary_nowait (bool cross = false);
1086
1087 template <typename BUF=value_type>
1088 void FillBoundary_nowait (const Periodicity& period, bool cross = false);
1089
1090 template <typename BUF=value_type>
1091 void FillBoundary_nowait (const IntVect& nghost, const Periodicity& period, bool cross = false);
1092
1093 template <typename BUF=value_type>
1094 void FillBoundary_nowait (int scomp, int ncomp, bool cross = false);
1095
1096 template <typename BUF=value_type>
1097 void FillBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool cross = false);
1098
1099 template <typename BUF=value_type>
1100 void FillBoundary_nowait (int scomp, int ncomp, const IntVect& nghost, const Periodicity& period, bool cross = false);
1101
1102 template <typename BUF=value_type,
1103 class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1105
1106 void FillBoundary_test ();
1107
1108
1135 void FillBoundaryAndSync (int scomp, int ncomp, const IntVect& nghost,
1136 const Periodicity& period);
1138 void FillBoundaryAndSync_nowait (int scomp, int ncomp, const IntVect& nghost,
1139 const Periodicity& period);
1141
1165 void OverrideSync (int scomp, int ncomp, const Periodicity& period);
1167 void OverrideSync_nowait (int scomp, int ncomp, const Periodicity& period);
1169
1174 void SumBoundary (int scomp, int ncomp, const Periodicity& period = Periodicity::NonPeriodic());
1176 void SumBoundary_nowait (int scomp, int ncomp, const Periodicity& period = Periodicity::NonPeriodic());
1177
1181 void SumBoundary (int scomp, int ncomp, IntVect const& nghost,
1182 const Periodicity& period = Periodicity::NonPeriodic());
1183 void SumBoundary_nowait (int scomp, int ncomp, IntVect const& nghost,
1184 const Periodicity& period = Periodicity::NonPeriodic());
1185
1190 void SumBoundary (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost,
1191 const Periodicity& period = Periodicity::NonPeriodic());
1192 void SumBoundary_nowait (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost,
1193 const Periodicity& period = Periodicity::NonPeriodic());
1195
1201 void EnforcePeriodicity (const Periodicity& period);
1202 void EnforcePeriodicity (int scomp, int ncomp, const Periodicity& period);
1203 void EnforcePeriodicity (int scomp, int ncomp, const IntVect& nghost,
1204 const Periodicity& period);
1205
1206 // covered : ghost cells covered by valid cells of this FabArray
1207 // (including periodically shifted valid cells)
1208 // notcovered: ghost cells not covered by valid cells
1209 // (including ghost cells outside periodic boundaries)
1210 // physbnd : boundary cells outside the domain (excluding periodic boundaries)
1211 // interior : interior cells (i.e., valid cells)
1212 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1213 void BuildMask (const Box& phys_domain, const Periodicity& period,
1214 value_type covered, value_type notcovered,
1215 value_type physbnd, value_type interior);
1216
1217 // The following are private functions. But we have to make them public for cuda.
1218
1219 template <typename BUF=value_type,
1220 class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1221 void FBEP_nowait (int scomp, int ncomp, const IntVect& nghost,
1222 const Periodicity& period, bool cross,
1223 bool enforce_periodicity_only = false,
1224 bool override_sync = false);
1225
1226 void FB_local_copy_cpu (const FB& TheFB, int scomp, int ncomp);
1227 void PC_local_cpu (const CPC& thecpc, FabArray<FAB> const& src,
1228 int scomp, int dcomp, int ncomp, CpOp op);
1229
1230 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1231 void setVal (value_type val, const CommMetaData& thecmd, int scomp, int ncomp);
1232
1233 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1235
1236#ifdef AMREX_USE_GPU
1237
1238 void FB_local_copy_gpu (const FB& TheFB, int scomp, int ncomp);
1239 void PC_local_gpu (const CPC& thecpc, FabArray<FAB> const& src,
1240 int scomp, int dcomp, int ncomp, CpOp op);
1241
1242 void CMD_local_setVal_gpu (value_type x, const CommMetaData& thecmd, int scomp, int ncomp);
1243 void CMD_remote_setVal_gpu (value_type x, const CommMetaData& thecmd, int scomp, int ncomp);
1244
1245#if defined(__CUDACC__)
1246
1247 void FB_local_copy_cuda_graph_1 (const FB& TheFB, int scomp, int ncomp);
1248 void FB_local_copy_cuda_graph_n (const FB& TheFB, int scomp, int ncomp);
1249
1250#endif
1251#endif
1252
1253#ifdef AMREX_USE_MPI
1254
1255#ifdef AMREX_USE_GPU
1256#if defined(__CUDACC__)
1257
1258 void FB_pack_send_buffer_cuda_graph (const FB& TheFB, int scomp, int ncomp,
1259 Vector<char*>& send_data,
1260 Vector<std::size_t> const& send_size,
1261 Vector<const CopyComTagsContainer*> const& send_cctc);
1262
1263 void FB_unpack_recv_buffer_cuda_graph (const FB& TheFB, int dcomp, int ncomp,
1264 Vector<char*> const& recv_data,
1265 Vector<std::size_t> const& recv_size,
1266 Vector<const CopyComTagsContainer*> const& recv_cctc,
1267 bool is_thread_safe);
1268
1269#endif
1270
1271 template <typename BUF = value_type>
1272 static void pack_send_buffer_gpu (FabArray<FAB> const& src, int scomp, int ncomp,
1273 Vector<char*> const& send_data,
1274 Vector<std::size_t> const& send_size,
1275 Vector<const CopyComTagsContainer*> const& send_cctc);
1276
1277 template <typename BUF = value_type>
1278 static void unpack_recv_buffer_gpu (FabArray<FAB>& dst, int dcomp, int ncomp,
1279 Vector<char*> const& recv_data,
1280 Vector<std::size_t> const& recv_size,
1281 Vector<const CopyComTagsContainer*> const& recv_cctc,
1282 CpOp op, bool is_thread_safe);
1283
1284#endif
1285
1286 template <typename BUF = value_type>
1287 static void pack_send_buffer_cpu (FabArray<FAB> const& src, int scomp, int ncomp,
1288 Vector<char*> const& send_data,
1289 Vector<std::size_t> const& send_size,
1290 Vector<const CopyComTagsContainer*> const& send_cctc);
1291
1292 template <typename BUF = value_type>
1293 static void unpack_recv_buffer_cpu (FabArray<FAB>& dst, int dcomp, int ncomp,
1294 Vector<char*> const& recv_data,
1295 Vector<std::size_t> const& recv_size,
1296 Vector<const CopyComTagsContainer*> const& recv_cctc,
1297 CpOp op, bool is_thread_safe);
1298
1299#endif
1300
1310 template <typename F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1311 typename F::value_type
1312 norminf (int comp, int ncomp, IntVect const& nghost, bool local = false,
1313 [[maybe_unused]] bool ignore_covered = false) const;
1314
1324 template <typename IFAB, typename F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1325 typename F::value_type
1326 norminf (FabArray<IFAB> const& mask, int comp, int ncomp, IntVect const& nghost,
1327 bool local = false) const;
1328
1329protected:
1330
1331 std::unique_ptr<FabFactory<FAB> > m_factory;
1333 std::unique_ptr<detail::SingleChunkArena> m_single_chunk_arena;
1335
1338
1339 //
1341 std::vector<FAB*> m_fabs_v;
1342
1343#ifdef AMREX_USE_GPU
1344 mutable void* m_dp_arrays = nullptr;
1345#endif
1346 mutable void* m_hp_arrays = nullptr;
1349
1351
1353 struct ShMem {
1354
1355 ShMem () noexcept = default;
1356
1357 ~ShMem () { // NOLINT
1358#if defined(BL_USE_MPI3)
1359 if (win != MPI_WIN_NULL) { MPI_Win_free(&win); }
1360#endif
1361#ifdef BL_USE_TEAM
1362 if (alloc) {
1364 }
1365#endif
1366 }
1367 ShMem (ShMem&& rhs) noexcept
1368 : alloc(rhs.alloc), n_values(rhs.n_values), n_points(rhs.n_points)
1369#if defined(BL_USE_MPI3)
1370 , win(rhs.win)
1371#endif
1372 {
1373 rhs.alloc = false;
1374#if defined(BL_USE_MPI3)
1375 rhs.win = MPI_WIN_NULL;
1376#endif
1377 }
1378 ShMem& operator= (ShMem&& rhs) noexcept {
1379 if (&rhs != this) {
1380 alloc = rhs.alloc;
1381 n_values = rhs.n_values;
1382 n_points = rhs.n_points;
1383 rhs.alloc = false;
1384#if defined(BL_USE_MPI3)
1385 win = rhs.win;
1386 rhs.win = MPI_WIN_NULL;
1387#endif
1388 }
1389 return *this;
1390 }
1391 ShMem (const ShMem&) = delete;
1392 ShMem& operator= (const ShMem&) = delete;
1393 bool alloc{false};
1394 Long n_values{0};
1395 Long n_points{0};
1396#if defined(BL_USE_MPI3)
1397 MPI_Win win = MPI_WIN_NULL;
1398#endif
1399 };
1401
1402 bool SharedMemory () const noexcept { return shmem.alloc; }
1403
1404private:
1405 using Iterator = typename std::vector<FAB*>::iterator;
1406
1407 void AllocFabs (const FabFactory<FAB>& factory, Arena* ar,
1409 bool alloc_single_chunk);
1410
1411 void setFab_assert (int K, FAB const& fab) const;
1412
1413 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1414 void build_arrays () const;
1415
1417
1418public:
1419
1420#ifdef BL_USE_MPI
1421
1423 template <typename BUF=value_type>
1424 static void PostRcvs (const MapOfCopyComTagContainers& RcvTags,
1425 char*& the_recv_data,
1426 Vector<char*>& recv_data,
1427 Vector<std::size_t>& recv_size,
1428 Vector<int>& recv_from,
1429 Vector<MPI_Request>& recv_reqs,
1430 int ncomp,
1431 int SeqNum);
1432
1433 template <typename BUF=value_type>
1435 static TheFaArenaPointer PostRcvs (const MapOfCopyComTagContainers& RcvTags,
1436 Vector<char*>& recv_data,
1437 Vector<std::size_t>& recv_size,
1438 Vector<int>& recv_from,
1439 Vector<MPI_Request>& recv_reqs,
1440 int ncomp,
1441 int SeqNum);
1442
1443 template <typename BUF=value_type>
1444 static void PrepareSendBuffers (const MapOfCopyComTagContainers& SndTags,
1445 char*& the_send_data,
1446 Vector<char*>& send_data,
1447 Vector<std::size_t>& send_size,
1448 Vector<int>& send_rank,
1449 Vector<MPI_Request>& send_reqs,
1451 int ncomp);
1452
1453 template <typename BUF=value_type>
1455 static TheFaArenaPointer PrepareSendBuffers (const MapOfCopyComTagContainers& SndTags,
1456 Vector<char*>& send_data,
1457 Vector<std::size_t>& send_size,
1458 Vector<int>& send_rank,
1459 Vector<MPI_Request>& send_reqs,
1461 int ncomp);
1462
1463 static void PostSnds (Vector<char*> const& send_data,
1464 Vector<std::size_t> const& send_size,
1465 Vector<int> const& send_rank,
1466 Vector<MPI_Request>& send_reqs,
1467 int SeqNum);
1468#endif
1469
1470 std::unique_ptr<FBData<FAB>> fbd;
1471 std::unique_ptr<PCData<FAB>> pcd;
1472
1473 // Pointer to temporary fab used in non-blocking amrex::OverrideSync
1474 std::unique_ptr< FabArray<FAB> > os_temp;
1475
1476
1477
1489 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1490 static void Saxpy (FabArray<FAB>& y, value_type a, FabArray<FAB> const& x,
1491 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1492
1504 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1505 static void Xpay (FabArray<FAB>& y, value_type a, FabArray<FAB> const& x,
1506 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1507
1522 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1523 static void LinComb (FabArray<FAB>& dst,
1524 value_type a, const FabArray<FAB>& x, int xcomp,
1525 value_type b, const FabArray<FAB>& y, int ycomp,
1526 int dstcomp, int numcomp, const IntVect& nghost);
1527};
1528
1529
1530#include <AMReX_FabArrayCommI.H>
1531
1532template <class FAB>
1533bool
1534FabArray<FAB>::defined (int K) const noexcept
1535{
1536 int li = localindex(K);
1537 if (li >= 0 && li < static_cast<int>(m_fabs_v.size()) && m_fabs_v[li] != 0) {
1538 return true;
1539 }
1540 else {
1541 return false;
1542 }
1543}
1544
1545template <class FAB>
1546bool
1547FabArray<FAB>::defined (const MFIter& mfi) const noexcept
1548{
1549 int li = mfi.LocalIndex();
1550 if (li < static_cast<int>(m_fabs_v.size()) && m_fabs_v[li] != nullptr) {
1551 return true;
1552 }
1553 else {
1554 return false;
1555 }
1556}
1557
1558template <class FAB>
1559FAB*
1560FabArray<FAB>::fabPtr (const MFIter& mfi) noexcept
1561{
1562 AMREX_ASSERT(mfi.LocalIndex() < indexArray.size());
1563 AMREX_ASSERT(DistributionMap() == mfi.DistributionMap());
1564 int li = mfi.LocalIndex();
1565 return m_fabs_v[li];
1566}
1567
1568template <class FAB>
1569FAB const*
1570FabArray<FAB>::fabPtr (const MFIter& mfi) const noexcept
1571{
1572 AMREX_ASSERT(mfi.LocalIndex() < indexArray.size());
1573 AMREX_ASSERT(DistributionMap() == mfi.DistributionMap());
1574 int li = mfi.LocalIndex();
1575 return m_fabs_v[li];
1576}
1577
1578template <class FAB>
1579FAB*
1581{
1582 int li = localindex(K);
1583 AMREX_ASSERT(li >=0 && li < indexArray.size());
1584 return m_fabs_v[li];
1585}
1586
1587template <class FAB>
1588FAB const*
1589FabArray<FAB>::fabPtr (int K) const noexcept
1590{
1591 int li = localindex(K);
1592 AMREX_ASSERT(li >=0 && li < indexArray.size());
1593 return m_fabs_v[li];
1594}
1595
1596template <class FAB>
1597template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1598void
1600{
1601 using A = Array4<value_type>;
1602 using AC = Array4<value_type const>;
1603 static_assert(sizeof(A) == sizeof(AC), "sizeof(Array4<T>) != sizeof(Array4<T const>)");
1604 if (!m_hp_arrays && local_size() > 0) {
1605 const int n = local_size();
1606#ifdef AMREX_USE_GPU
1607 m_hp_arrays = (void*)The_Pinned_Arena()->alloc(n*2*sizeof(A));
1608 m_dp_arrays = (void*)The_Arena()->alloc(n*2*sizeof(A));
1609#else
1610 m_hp_arrays = (void*)std::malloc(n*2*sizeof(A));
1611#endif
1612 for (int li = 0; li < n; ++li) {
1613 if (m_fabs_v[li]) {
1614 new ((A*)m_hp_arrays+li) A(m_fabs_v[li]->array());
1615 new ((AC*)m_hp_arrays+li+n) AC(m_fabs_v[li]->const_array());
1616 } else {
1617 new ((A*)m_hp_arrays+li) A{};
1618 new ((AC*)m_hp_arrays+li+n) AC{};
1619 }
1620 }
1621 m_arrays.hp = (A*)m_hp_arrays;
1622 m_const_arrays.hp = (AC*)m_hp_arrays + n;
1623#ifdef AMREX_USE_GPU
1624 m_arrays.dp = (A*)m_dp_arrays;
1625 m_const_arrays.dp = (AC*)m_dp_arrays + n;
1626 Gpu::htod_memcpy(m_dp_arrays, m_hp_arrays, n*2*sizeof(A));
1627#endif
1628 }
1629}
1630
1631template <class FAB>
1632void
1634{
1635#ifdef AMREX_USE_GPU
1636 The_Pinned_Arena()->free(m_hp_arrays);
1637 The_Arena()->free(m_dp_arrays);
1638 m_dp_arrays = nullptr;
1639#else
1640 std::free(m_hp_arrays);
1641#endif
1642 m_hp_arrays = nullptr;
1643 m_arrays.hp = nullptr;
1644 m_const_arrays.hp = nullptr;
1645}
1646
1647template <class FAB>
1649FAB*
1651{
1652 const int li = localindex(K);
1653 if (li >= 0 && li < static_cast<int>(m_fabs_v.size()) && m_fabs_v[li] != nullptr) {
1654 AMREX_ASSERT(m_single_chunk_arena == nullptr);
1655 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
1656 if (nbytes > 0) {
1657 for (auto const& t : m_tags) {
1658 updateMemUsage(t, -nbytes, nullptr);
1659 }
1660 }
1661 return std::exchange(m_fabs_v[li], nullptr);
1662 } else {
1663 return nullptr;
1664 }
1665}
1666
1667template <class FAB>
1669FAB*
1671{
1672 const int li = mfi.LocalIndex();
1673 if (li >= 0 && li < static_cast<int>(m_fabs_v.size()) && m_fabs_v[li] != nullptr) {
1674 AMREX_ASSERT(m_single_chunk_arena == nullptr);
1675 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
1676 if (nbytes > 0) {
1677 for (auto const& t : m_tags) {
1678 updateMemUsage(t, -nbytes, nullptr);
1679 }
1680 }
1681 return std::exchange(m_fabs_v[li], nullptr);
1682 } else {
1683 return nullptr;
1684 }
1685}
1686
1687template <class FAB>
1688void
1690{
1691 if (define_function_called)
1692 {
1693 define_function_called = false;
1694 clearThisBD();
1695 }
1696
1697 Long nbytes = 0L;
1698 for (auto *x : m_fabs_v) {
1699 if (x) {
1700 nbytes += amrex::nBytesOwned(*x);
1701 m_factory->destroy(x);
1702 }
1703 }
1704 m_fabs_v.clear();
1705 clear_arrays();
1706 m_factory.reset();
1707 m_dallocator.m_arena = nullptr;
1708 // no need to clear the non-blocking fillboundary stuff
1709
1710 if (nbytes > 0) {
1711 for (auto const& t : m_tags) {
1712 updateMemUsage(t, -nbytes, nullptr);
1713 }
1714 }
1715
1716 if (m_single_chunk_arena) {
1717 m_single_chunk_arena.reset();
1718 }
1719 m_single_chunk_size = 0;
1720
1721 m_tags.clear();
1722
1724}
1725
1726template <class FAB>
1727template <typename SFAB, typename DFAB,
1728 std::enable_if_t<std::conjunction_v<
1730 std::is_convertible<typename SFAB::value_type,
1731 typename DFAB::value_type>>, int>>
1732void
1733FabArray<FAB>::LocalCopy (FabArray<SFAB> const& src, int scomp, int dcomp, int ncomp,
1734 IntVect const& nghost)
1735{
1736 amrex::Copy(*this, src, scomp, dcomp, ncomp, nghost);
1737}
1738
1739template <class FAB>
1740template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1741void
1742FabArray<FAB>::LocalAdd (FabArray<FAB> const& src, int scomp, int dcomp, int ncomp,
1743 IntVect const& nghost)
1744{
1745 amrex::Add(*this, src, scomp, dcomp, ncomp, nghost);
1746}
1747
1748template <class FAB>
1749template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1750void
1752{
1753 setVal(val,0,n_comp,IntVect(nghost));
1754}
1755
1756template <class FAB>
1757template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1758void
1760{
1761 setVal(val,0,n_comp,nghost);
1762}
1763
1764template <class FAB>
1765template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1766void
1767FabArray<FAB>::setVal (value_type val, const Box& region, int nghost)
1768{
1769 setVal(val,region,0,n_comp,IntVect(nghost));
1770}
1771
1772template <class FAB>
1773template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1774void
1775FabArray<FAB>::setVal (value_type val, const Box& region, const IntVect& nghost)
1776{
1777 setVal(val,region,0,n_comp,nghost);
1778}
1779
1780template <class FAB>
1782 : shmem()
1783{
1784 m_FA_stats.recordBuild();
1785}
1786
1787template <class FAB>
1789 : m_dallocator(a),
1790 shmem()
1791{
1792 m_FA_stats.recordBuild();
1793}
1794
1795template <class FAB>
1797 const DistributionMapping& dm,
1798 int nvar,
1799 int ngrow,
1800 const MFInfo& info,
1801 const FabFactory<FAB>& factory)
1802 : FabArray<FAB>(bxs,dm,nvar,IntVect(ngrow),info,factory)
1803{}
1804
1805template <class FAB>
1807 const DistributionMapping& dm,
1808 int nvar,
1809 const IntVect& ngrow,
1810 const MFInfo& info,
1811 const FabFactory<FAB>& factory)
1812 : m_factory(factory.clone()),
1813 shmem()
1814{
1816 define(bxs,dm,nvar,ngrow,info,*m_factory);
1817}
1818
1819template <class FAB>
1820FabArray<FAB>::FabArray (const FabArray<FAB>& rhs, MakeType maketype, int scomp, int ncomp)
1821 : m_factory(rhs.Factory().clone()),
1822 shmem()
1823{
1825 define(rhs.boxArray(), rhs.DistributionMap(), ncomp, rhs.nGrowVect(),
1826 MFInfo().SetAlloc(false), *m_factory);
1827
1828 if (maketype == amrex::make_alias)
1829 {
1830 for (int i = 0, n = indexArray.size(); i < n; ++i) {
1831 auto const& rhsfab = *(rhs.m_fabs_v[i]);
1832 m_fabs_v.push_back(m_factory->create_alias(rhsfab, scomp, ncomp));
1833 }
1834 }
1835 else
1836 {
1837 amrex::Abort("FabArray: unknown MakeType");
1838 }
1839}
1840
1841template <class FAB>
1843 : FabArrayBase (static_cast<FabArrayBase&&>(rhs))
1844 , m_factory (std::move(rhs.m_factory))
1845 , m_dallocator (std::move(rhs.m_dallocator))
1846 , m_single_chunk_arena(std::move(rhs.m_single_chunk_arena))
1847 , m_single_chunk_size(std::exchange(rhs.m_single_chunk_size,0))
1848 , define_function_called(rhs.define_function_called)
1849 , m_fabs_v (std::move(rhs.m_fabs_v))
1850#ifdef AMREX_USE_GPU
1851 , m_dp_arrays (std::exchange(rhs.m_dp_arrays, nullptr))
1852#endif
1853 , m_hp_arrays (std::exchange(rhs.m_hp_arrays, nullptr))
1854 , m_arrays (rhs.m_arrays)
1855 , m_const_arrays(rhs.m_const_arrays)
1856 , m_tags (std::move(rhs.m_tags))
1857 , shmem (std::move(rhs.shmem))
1858 // no need to worry about the data used in non-blocking FillBoundary.
1859{
1860 m_FA_stats.recordBuild();
1861 rhs.define_function_called = false; // the responsibility of clear BD has been transferred.
1862 rhs.m_fabs_v.clear(); // clear the data pointers so that rhs.clear does delete them.
1863 rhs.clear();
1864}
1865
1866template <class FAB>
1869{
1870 if (&rhs != this)
1871 {
1872 clear();
1873
1874 FabArrayBase::operator=(static_cast<FabArrayBase&&>(rhs));
1875 m_factory = std::move(rhs.m_factory);
1876 m_dallocator = std::move(rhs.m_dallocator);
1877 m_single_chunk_arena = std::move(rhs.m_single_chunk_arena);
1878 std::swap(m_single_chunk_size, rhs.m_single_chunk_size);
1879 define_function_called = rhs.define_function_called;
1880 std::swap(m_fabs_v, rhs.m_fabs_v);
1881#ifdef AMREX_USE_GPU
1882 std::swap(m_dp_arrays, rhs.m_dp_arrays);
1883#endif
1884 std::swap(m_hp_arrays, rhs.m_hp_arrays);
1885 m_arrays = rhs.m_arrays;
1886 m_const_arrays = rhs.m_const_arrays;
1887 std::swap(m_tags, rhs.m_tags);
1888 shmem = std::move(rhs.shmem);
1889
1890 rhs.define_function_called = false;
1891 rhs.m_fabs_v.clear();
1892 rhs.m_tags.clear();
1893 rhs.clear();
1894 }
1895 return *this;
1896}
1897
1898template <class FAB>
1900{
1901 m_FA_stats.recordDelete();
1902 clear();
1903}
1904
1905template <class FAB>
1906bool
1908{
1909 if (!define_function_called) { return false; }
1910
1911 int isok = 1;
1912
1913 for (MFIter fai(*this); fai.isValid() && isok; ++fai)
1914 {
1915 if (defined(fai))
1916 {
1917 if (get(fai).box() != fabbox(fai.index()))
1918 {
1919 isok = 0;
1920 }
1921 }
1922 else
1923 {
1924 isok = 0;
1925 }
1926 }
1927
1929
1930 return isok == 1;
1931}
1932
1933template <class FAB>
1934bool
1936{
1937 return define_function_called;
1938}
1939
1940template <class FAB>
1941void
1943 const DistributionMapping& dm,
1944 int nvar,
1945 int ngrow,
1946 const MFInfo& info,
1947 const FabFactory<FAB>& a_factory)
1948{
1949 define(bxs,dm,nvar,IntVect(ngrow),info,a_factory);
1950}
1951
1952template <class FAB>
1953void
1955 const DistributionMapping& dm,
1956 int nvar,
1957 const IntVect& ngrow,
1958 const MFInfo& info,
1959 const FabFactory<FAB>& a_factory)
1960{
1961 std::unique_ptr<FabFactory<FAB> > factory(a_factory.clone());
1962
1963 auto *default_arena = m_dallocator.m_arena;
1964 clear();
1965
1966 m_factory = std::move(factory);
1967 m_dallocator.m_arena = info.arena ? info.arena : default_arena;
1968
1969 define_function_called = true;
1970
1971 AMREX_ASSERT(ngrow.allGE(0));
1972 AMREX_ASSERT(boxarray.empty());
1973 FabArrayBase::define(bxs, dm, nvar, ngrow);
1974
1975 addThisBD();
1976
1977 if(info.alloc) {
1978 AllocFabs(*m_factory, m_dallocator.m_arena, info.tags, info.alloc_single_chunk);
1979#ifdef BL_USE_TEAM
1981#endif
1982 }
1983}
1984
1985template <class FAB>
1986void
1988 const Vector<std::string>& tags, bool alloc_single_chunk)
1989{
1990 if (shmem.alloc) { alloc_single_chunk = false; }
1991 if constexpr (!IsBaseFab_v<FAB>) { alloc_single_chunk = false; }
1992
1993 const int n = indexArray.size();
1994 const int nworkers = ParallelDescriptor::TeamSize();
1995 shmem.alloc = (nworkers > 1);
1996
1997 bool alloc = !shmem.alloc;
1998
1999 FabInfo fab_info;
2000 fab_info.SetAlloc(alloc).SetShared(shmem.alloc).SetArena(ar);
2001
2002 if (alloc_single_chunk) {
2003 m_single_chunk_size = 0L;
2004 for (int i = 0; i < n; ++i) {
2005 int K = indexArray[i];
2006 const Box& tmpbox = fabbox(K);
2007 m_single_chunk_size += factory.nBytes(tmpbox, n_comp, K);
2008 }
2009 AMREX_ASSERT(m_single_chunk_size >= 0); // 0 is okay.
2010 m_single_chunk_arena = std::make_unique<detail::SingleChunkArena>(ar, m_single_chunk_size);
2011 fab_info.SetArena(m_single_chunk_arena.get());
2012 }
2013
2014 m_fabs_v.reserve(n);
2015
2016 Long nbytes = 0L;
2017 for (int i = 0; i < n; ++i)
2018 {
2019 int K = indexArray[i];
2020 const Box& tmpbox = fabbox(K);
2021 m_fabs_v.push_back(factory.create(tmpbox, n_comp, fab_info, K));
2022 nbytes += amrex::nBytesOwned(*m_fabs_v.back());
2023 }
2024
2025 m_tags.clear();
2026 m_tags.emplace_back("All");
2027 for (auto const& t : m_region_tag) {
2028 m_tags.push_back(t);
2029 }
2030 for (auto const& t : tags) {
2031 m_tags.push_back(t);
2032 }
2033 for (auto const& t: m_tags) {
2034 updateMemUsage(t, nbytes, ar);
2035 }
2036
2037#ifdef BL_USE_TEAM
2038 if (shmem.alloc)
2039 {
2040 const int teamlead = ParallelDescriptor::MyTeamLead();
2041
2042 shmem.n_values = 0;
2043 shmem.n_points = 0;
2044 Vector<Long> offset(n,0);
2045 Vector<Long> nextoffset(nworkers,-1);
2046 for (int i = 0; i < n; ++i) {
2047 int K = indexArray[i];
2048 int owner = distributionMap[K] - teamlead;
2049 Long s = m_fabs_v[i]->size();
2050 if (ownership[i]) {
2051 shmem.n_values += s;
2052 shmem.n_points += m_fabs_v[i]->numPts();
2053 }
2054 if (nextoffset[owner] < 0) {
2055 offset[i] = 0;
2056 nextoffset[owner] = s;
2057 } else {
2058 offset[i] = nextoffset[owner];
2059 nextoffset[owner] += s;
2060 }
2061 }
2062
2063 size_t bytes = shmem.n_values*sizeof(value_type);
2064
2065 value_type *mfp;
2067
2068#if defined (BL_USE_MPI3)
2069
2070 static MPI_Info info = MPI_INFO_NULL;
2071 if (info == MPI_INFO_NULL) {
2072 MPI_Info_create(&info);
2073 MPI_Info_set(info, "alloc_shared_noncontig", "true");
2074 }
2075
2076 const MPI_Comm& team_comm = ParallelDescriptor::MyTeam().get();
2077
2078 BL_MPI_REQUIRE( MPI_Win_allocate_shared(bytes, sizeof(value_type),
2079 info, team_comm, &mfp, &shmem.win) );
2080
2081 for (int w = 0; w < nworkers; ++w) {
2082 MPI_Aint sz;
2083 int disp;
2084 value_type *dptr = 0;
2085 BL_MPI_REQUIRE( MPI_Win_shared_query(shmem.win, w, &sz, &disp, &dptr) );
2086 // AMREX_ASSERT(disp == sizeof(value_type));
2087 dps.push_back(dptr);
2088 }
2089
2090#else
2091
2092 amrex::Abort("BaseFab::define: to allocate shared memory, USE_MPI3 must be true");
2093
2094#endif
2095
2096 for (int i = 0; i < n; ++i) {
2097 int K = indexArray[i];
2098 int owner = distributionMap[K] - teamlead;
2099 value_type *p = dps[owner] + offset[i];
2100 m_fabs_v[i]->setPtr(p, m_fabs_v[i]->size());
2101 }
2102
2103 for (Long i = 0; i < shmem.n_values; i++, mfp++) {
2104 new (mfp) value_type;
2105 }
2106
2107 amrex::update_fab_stats(shmem.n_points, shmem.n_values, sizeof(value_type));
2108 }
2109#endif
2110}
2111
2112template <class FAB>
2113void
2114FabArray<FAB>::setFab_assert (int K, FAB const& fab) const
2115{
2116 amrex::ignore_unused(K,fab);
2117 AMREX_ASSERT(n_comp == fab.nComp());
2118 AMREX_ASSERT(!boxarray.empty());
2119 AMREX_ASSERT(fab.box() == fabbox(K));
2120 AMREX_ASSERT(distributionMap[K] == ParallelDescriptor::MyProc());
2121 AMREX_ASSERT(m_single_chunk_arena == nullptr);
2122}
2123
2124template <class FAB>
2125void
2126FabArray<FAB>::setFab (int boxno, std::unique_ptr<FAB> elem)
2127{
2128 if (n_comp == 0) {
2129 n_comp = elem->nComp();
2130 }
2131
2132 setFab_assert(boxno, *elem);
2133
2134 if (m_fabs_v.empty()) {
2135 m_fabs_v.resize(indexArray.size(),nullptr);
2136 }
2137
2138 const int li = localindex(boxno);
2139 if (m_fabs_v[li]) {
2140 m_factory->destroy(m_fabs_v[li]);
2141 }
2142 m_fabs_v[li] = elem.release();
2143}
2144
2145template <class FAB>
2146template <class F, std::enable_if_t<std::is_move_constructible_v<F>,int> >
2147void
2148FabArray<FAB>::setFab (int boxno, FAB&& elem)
2149{
2150 if (n_comp == 0) {
2151 n_comp = elem.nComp();
2152 }
2153
2154 setFab_assert(boxno, elem);
2155
2156 if (m_fabs_v.empty()) {
2157 m_fabs_v.resize(indexArray.size(),nullptr);
2158 }
2159
2160 const int li = localindex(boxno);
2161 if (m_fabs_v[li]) {
2162 m_factory->destroy(m_fabs_v[li]);
2163 }
2164 m_fabs_v[li] = new FAB(std::move(elem));
2165}
2166
2167template <class FAB>
2168void
2169FabArray<FAB>::setFab (const MFIter& mfi, std::unique_ptr<FAB> elem)
2170{
2171 if (n_comp == 0) {
2172 n_comp = elem->nComp();
2173 }
2174
2175 setFab_assert(mfi.index(), *elem);
2176
2177 if (m_fabs_v.empty()) {
2178 m_fabs_v.resize(indexArray.size(),nullptr);
2179 }
2180
2181 const int li = mfi.LocalIndex();
2182 if (m_fabs_v[li]) {
2183 m_factory->destroy(m_fabs_v[li]);
2184 }
2185 m_fabs_v[li] = elem.release();
2186}
2187
2188template <class FAB>
2189template <class F, std::enable_if_t<std::is_move_constructible_v<F>,int> >
2190void
2191FabArray<FAB>::setFab (const MFIter& mfi, FAB&& elem)
2192{
2193 if (n_comp == 0) {
2194 n_comp = elem.nComp();
2195 }
2196
2197 setFab_assert(mfi.index(), elem);
2198
2199 if (m_fabs_v.empty()) {
2200 m_fabs_v.resize(indexArray.size(),nullptr);
2201 }
2202
2203 const int li = mfi.LocalIndex();
2204 if (m_fabs_v[li]) {
2205 m_factory->destroy(m_fabs_v[li]);
2206 }
2207 m_fabs_v[li] = new FAB(std::move(elem));
2208}
2209
2210template <class FAB>
2211template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2212void
2214{
2215 setBndry(val, 0, n_comp);
2216}
2217
2218template <class FAB>
2219template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2220void
2222 int strt_comp,
2223 int ncomp)
2224{
2225 if (n_grow.max() > 0)
2226 {
2227#ifdef AMREX_USE_GPU
2228 if (Gpu::inLaunchRegion()) {
2229 bool use_mfparfor = true;
2230 const int nboxes = local_size();
2231 if (nboxes == 1) {
2232 if (boxarray[indexArray[0]].numPts() > Long(65*65*65)) {
2233 use_mfparfor = false;
2234 }
2235 } else {
2236 for (int i = 0; i < nboxes; ++i) {
2237 const Long npts = boxarray[indexArray[i]].numPts();
2238 if (npts >= Long(64*64*64)) {
2239 use_mfparfor = false;
2240 break;
2241 } else if (npts <= Long(17*17*17)) {
2242 break;
2243 }
2244 }
2245 }
2246 const IntVect nghost = n_grow;
2247 if (use_mfparfor) {
2248 auto const& ma = this->arrays();
2249 ParallelFor(*this, nghost,
2250 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2251 {
2252 auto const& a = ma[box_no];
2253 Box vbx(a);
2254 vbx.grow(-nghost);
2255 if (!vbx.contains(i,j,k)) {
2256 for (int n = 0; n < ncomp; ++n) {
2257 a(i,j,k,strt_comp+n) = val;
2258 }
2259 }
2260 });
2262 } else {
2263 using Tag = Array4BoxTag<value_type>;
2264 Vector<Tag> tags;
2265 for (MFIter mfi(*this); mfi.isValid(); ++mfi) {
2266 Box const& vbx = mfi.validbox();
2267 auto const& a = this->array(mfi);
2268
2269 Box b;
2270#if (AMREX_SPACEDIM == 3)
2271 if (nghost[2] > 0) {
2272 b = vbx;
2273 b.setRange(2, vbx.smallEnd(2)-nghost[2], nghost[2]);
2274 b.grow(IntVect(nghost[0],nghost[1],0));
2275 tags.emplace_back(Tag{a, b});
2276 b.shift(2, vbx.length(2)+nghost[2]);
2277 tags.emplace_back(Tag{a, b});
2278 }
2279#endif
2280#if (AMREX_SPACEDIM >= 2)
2281 if (nghost[1] > 0) {
2282 b = vbx;
2283 b.setRange(1, vbx.smallEnd(1)-nghost[1], nghost[1]);
2284 b.grow(0, nghost[0]);
2285 tags.emplace_back(Tag{a, b});
2286 b.shift(1, vbx.length(1)+nghost[1]);
2287 tags.emplace_back(Tag{a, b});
2288 }
2289#endif
2290 if (nghost[0] > 0) {
2291 b = vbx;
2292 b.setRange(0, vbx.smallEnd(0)-nghost[0], nghost[0]);
2293 tags.emplace_back(Tag{a, b});
2294 b.shift(0, vbx.length(0)+nghost[0]);
2295 tags.emplace_back(Tag{a, b});
2296 }
2297 }
2298
2299 ParallelFor(tags, ncomp,
2300 [=] AMREX_GPU_DEVICE (int i, int j, int k, int n, Tag const& tag) noexcept
2301 {
2302 tag.dfab(i,j,k,strt_comp+n) = val;
2303 });
2304 }
2305 } else
2306#endif
2307 {
2308#ifdef AMREX_USE_OMP
2309#pragma omp parallel
2310#endif
2311 for (MFIter fai(*this); fai.isValid(); ++fai)
2312 {
2313 get(fai).template setComplement<RunOn::Host>(val, fai.validbox(), strt_comp, ncomp);
2314 }
2315 }
2316 }
2317}
2318
2319template <class FAB>
2320template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2321void
2323{
2324 setDomainBndry(val, 0, n_comp, geom);
2325}
2326
2327template <class FAB>
2328template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2329void
2331 int strt_comp,
2332 int ncomp,
2333 const Geometry& geom)
2334{
2335 BL_PROFILE("FabArray::setDomainBndry()");
2336
2337 Box domain_box = amrex::convert(geom.Domain(), boxArray().ixType());
2338 for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
2339 if (geom.isPeriodic(idim)) {
2340 int n = domain_box.length(idim);
2341 domain_box.grow(idim, n);
2342 }
2343 }
2344
2345#ifdef AMREX_USE_OMP
2346#pragma omp parallel if (Gpu::notInLaunchRegion())
2347#endif
2348 for (MFIter fai(*this); fai.isValid(); ++fai)
2349 {
2350 const Box& gbx = fai.fabbox();
2351 if (! domain_box.contains(gbx))
2352 {
2353 get(fai).template setComplement<RunOn::Device>(val, domain_box, strt_comp, ncomp);
2354 }
2355 }
2356}
2357
2358template <class FAB>
2359template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
2360typename F::value_type
2361FabArray<FAB>::sum (int comp, IntVect const& nghost, bool local) const
2362{
2363 BL_PROFILE("FabArray::sum()");
2364
2365 using T = typename FAB::value_type;
2366 auto sm = T(0.0);
2367#ifdef AMREX_USE_GPU
2368 if (Gpu::inLaunchRegion()) {
2369 auto const& ma = this->const_arrays();
2370 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, *this, nghost,
2371 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2372 -> GpuTuple<T>
2373 {
2374 return ma[box_no](i,j,k,comp);
2375 });
2376 } else
2377#endif
2378 {
2379#ifdef AMREX_USE_OMP
2380#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
2381#endif
2382 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi)
2383 {
2384 Box const& bx = mfi.growntilebox(nghost);
2385 auto const& a = this->const_array(mfi);
2386 auto tmp = T(0.0);
2387 AMREX_LOOP_3D(bx, i, j, k,
2388 {
2389 tmp += a(i,j,k,comp);
2390 });
2391 sm += tmp; // Do it this way so that it does not break regression tests.
2392 }
2393 }
2394
2395 if (!local) {
2397 }
2398
2399 return sm;
2400}
2401
2402template <class FAB>
2403void
2404FabArray<FAB>::copyTo (FAB& dest, int nghost) const
2405{
2406 copyTo(dest, 0, 0, dest.nComp(), nghost);
2407}
2408
2409template <class FAB>
2410template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2411void
2413{
2414 setVal(val,0,n_comp,n_grow);
2415}
2416
2417template <class FAB>
2418template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2421{
2422 setVal(val);
2423 return *this;
2424}
2425
2426template <class FAB>
2427template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2428void
2430 int comp,
2431 int ncomp,
2432 int nghost)
2433{
2434 setVal(val,comp,ncomp,IntVect(nghost));
2435}
2436
2437template <class FAB>
2438template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2439void
2441 int comp,
2442 int ncomp,
2443 const IntVect& nghost)
2444{
2445 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2446 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2447
2448 BL_PROFILE("FabArray::setVal()");
2449
2450#ifdef AMREX_USE_GPU
2451 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2452 auto const& fa = this->arrays();
2453 ParallelFor(*this, nghost, ncomp,
2454 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2455 {
2456 fa[box_no](i,j,k,n+comp) = val;
2457 });
2458 if (!Gpu::inNoSyncRegion()) {
2460 }
2461 } else
2462#endif
2463 {
2464#ifdef AMREX_USE_OMP
2465#pragma omp parallel if (Gpu::notInLaunchRegion())
2466#endif
2467 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
2468 {
2469 const Box& bx = fai.growntilebox(nghost);
2470 auto fab = this->array(fai);
2471 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
2472 {
2473 fab(i,j,k,n+comp) = val;
2474 });
2475 }
2476 }
2477}
2478
2479template <class FAB>
2480template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2481void
2483 const Box& region,
2484 int comp,
2485 int ncomp,
2486 int nghost)
2487{
2488 setVal(val,region,comp,ncomp,IntVect(nghost));
2489}
2490
2491template <class FAB>
2492template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2493void
2495 const Box& region,
2496 int comp,
2497 int ncomp,
2498 const IntVect& nghost)
2499{
2500 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2501 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2502
2503 BL_PROFILE("FabArray::setVal(val,region,comp,ncomp,nghost)");
2504
2505#ifdef AMREX_USE_GPU
2506 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2507 auto const& fa = this->arrays();
2508 ParallelFor(*this, nghost, ncomp,
2509 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2510 {
2511 if (region.contains(i,j,k)) {
2512 fa[box_no](i,j,k,n+comp) = val;
2513 }
2514 });
2515 if (!Gpu::inNoSyncRegion()) {
2517 }
2518 } else
2519#endif
2520 {
2521#ifdef AMREX_USE_OMP
2522 AMREX_ALWAYS_ASSERT(!omp_in_parallel());
2523#pragma omp parallel if (Gpu::notInLaunchRegion())
2524#endif
2525 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
2526 {
2527 Box b = fai.growntilebox(nghost) & region;
2528
2529 if (b.ok()) {
2530 auto fab = this->array(fai);
2531 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( b, ncomp, i, j, k, n,
2532 {
2533 fab(i,j,k,n+comp) = val;
2534 });
2535 }
2536 }
2537 }
2538}
2539
2540template <class FAB>
2541template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2542void
2543FabArray<FAB>::abs (int comp, int ncomp, int nghost)
2544{
2545 abs(comp, ncomp, IntVect(nghost));
2546}
2547
2548template <class FAB>
2549template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2550void
2551FabArray<FAB>::abs (int comp, int ncomp, const IntVect& nghost)
2552{
2553 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2554 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2555 BL_PROFILE("FabArray::abs()");
2556
2557#ifdef AMREX_USE_GPU
2558 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2559 auto const& fa = this->arrays();
2560 ParallelFor(*this, nghost, ncomp,
2561 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2562 {
2563 fa[box_no](i,j,k,n+comp) = std::abs(fa[box_no](i,j,k,n+comp));
2564 });
2565 if (!Gpu::inNoSyncRegion()) {
2567 }
2568 } else
2569#endif
2570 {
2571#ifdef AMREX_USE_OMP
2572#pragma omp parallel if (Gpu::notInLaunchRegion())
2573#endif
2574 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2575 {
2576 const Box& bx = mfi.growntilebox(nghost);
2577 auto fab = this->array(mfi);
2578 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
2579 {
2580 fab(i,j,k,n+comp) = std::abs(fab(i,j,k,n+comp));
2581 });
2582 }
2583 }
2584}
2585
2586template <class FAB>
2587template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2588void
2589FabArray<FAB>::plus (value_type val, int comp, int num_comp, int nghost)
2590{
2591 BL_PROFILE("FabArray::plus()");
2592
2593#ifdef AMREX_USE_GPU
2594 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2595 auto const& fa = this->arrays();
2596 ParallelFor(*this, IntVect(nghost), num_comp,
2597 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2598 {
2599 fa[box_no](i,j,k,n+comp) += val;
2600 });
2601 if (!Gpu::inNoSyncRegion()) {
2603 }
2604 } else
2605#endif
2606 {
2607#ifdef AMREX_USE_OMP
2608#pragma omp parallel if (Gpu::notInLaunchRegion())
2609#endif
2610 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2611 {
2612 const Box& bx = mfi.growntilebox(nghost);
2613 auto fab = this->array(mfi);
2614 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2615 {
2616 fab(i,j,k,n+comp) += val;
2617 });
2618 }
2619 }
2620}
2621
2622template <class FAB>
2623template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2624void
2625FabArray<FAB>::plus (value_type val, const Box& region, int comp, int num_comp, int nghost)
2626{
2627 BL_PROFILE("FabArray::plus(val, region, comp, num_comp, nghost)");
2628
2629#ifdef AMREX_USE_GPU
2630 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2631 auto const& fa = this->arrays();
2632 ParallelFor(*this, IntVect(nghost), num_comp,
2633 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2634 {
2635 if (region.contains(i,j,k)) {
2636 fa[box_no](i,j,k,n+comp) += val;
2637 }
2638 });
2639 if (!Gpu::inNoSyncRegion()) {
2641 }
2642 } else
2643#endif
2644 {
2645#ifdef AMREX_USE_OMP
2646#pragma omp parallel if (Gpu::notInLaunchRegion())
2647#endif
2648 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2649 {
2650 const Box& bx = mfi.growntilebox(nghost) & region;
2651 if (bx.ok()) {
2652 auto fab = this->array(mfi);
2653 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2654 {
2655 fab(i,j,k,n+comp) += val;
2656 });
2657 }
2658 }
2659 }
2660}
2661
2662template <class FAB>
2663template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2664void
2665FabArray<FAB>::mult (value_type val, int comp, int num_comp, int nghost)
2666{
2667 BL_PROFILE("FabArray::mult()");
2668
2669#ifdef AMREX_USE_GPU
2670 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2671 auto const& fa = this->arrays();
2672 ParallelFor(*this, IntVect(nghost), num_comp,
2673 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2674 {
2675 fa[box_no](i,j,k,n+comp) *= val;
2676 });
2677 if (!Gpu::inNoSyncRegion()) {
2679 }
2680 } else
2681#endif
2682 {
2683#ifdef AMREX_USE_OMP
2684#pragma omp parallel if (Gpu::notInLaunchRegion())
2685#endif
2686 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2687 {
2688 const Box& bx = mfi.growntilebox(nghost);
2689 auto fab = this->array(mfi);
2690 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2691 {
2692 fab(i,j,k,n+comp) *= val;
2693 });
2694 }
2695 }
2696}
2697
2698template <class FAB>
2699template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2700void
2701FabArray<FAB>::mult (value_type val, const Box& region, int comp, int num_comp, int nghost)
2702{
2703 BL_PROFILE("FabArray::mult(val, region, comp, num_comp, nghost)");
2704
2705#ifdef AMREX_USE_GPU
2706 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2707 auto const& fa = this->arrays();
2708 ParallelFor(*this, IntVect(nghost), num_comp,
2709 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2710 {
2711 if (region.contains(i,j,k)) {
2712 fa[box_no](i,j,k,n+comp) *= val;
2713 }
2714 });
2715 if (!Gpu::inNoSyncRegion()) {
2717 }
2718 } else
2719#endif
2720 {
2721#ifdef AMREX_USE_OMP
2722#pragma omp parallel if (Gpu::notInLaunchRegion())
2723#endif
2724 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2725 {
2726 const Box& bx = mfi.growntilebox(nghost) & region;
2727 if (bx.ok()) {
2728 auto fab = this->array(mfi);
2729 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2730 {
2731 fab(i,j,k,n+comp) *= val;
2732 });
2733 }
2734 }
2735 }
2736}
2737
2738template <class FAB>
2739template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2740void
2741FabArray<FAB>::invert (value_type numerator, int comp, int num_comp, int nghost)
2742{
2743 BL_PROFILE("FabArray::invert()");
2744
2745#ifdef AMREX_USE_GPU
2746 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2747 auto const& fa = this->arrays();
2748 ParallelFor(*this, IntVect(nghost), num_comp,
2749 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2750 {
2751 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
2752 });
2753 if (!Gpu::inNoSyncRegion()) {
2755 }
2756 } else
2757#endif
2758 {
2759#ifdef AMREX_USE_OMP
2760#pragma omp parallel if (Gpu::notInLaunchRegion())
2761#endif
2762 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2763 {
2764 const Box& bx = mfi.growntilebox(nghost);
2765 auto fab = this->array(mfi);
2766 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2767 {
2768 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
2769 });
2770 }
2771 }
2772}
2773
2774template <class FAB>
2775template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2776void
2777FabArray<FAB>::invert (value_type numerator, const Box& region, int comp, int num_comp, int nghost)
2778{
2779 BL_PROFILE("FabArray::invert(numerator, region, comp, num_comp, nghost)");
2780
2781#ifdef AMREX_USE_GPU
2782 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2783 auto const& fa = this->arrays();
2784 ParallelFor(*this, IntVect(nghost), num_comp,
2785 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2786 {
2787 if (region.contains(i,j,k)) {
2788 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
2789 }
2790 });
2791 if (!Gpu::inNoSyncRegion()) {
2793 }
2794 } else
2795#endif
2796 {
2797#ifdef AMREX_USE_OMP
2798#pragma omp parallel if (Gpu::notInLaunchRegion())
2799#endif
2800 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2801 {
2802 const Box& bx = mfi.growntilebox(nghost) & region;
2803 if (bx.ok()) {
2804 auto fab = this->array(mfi);
2805 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2806 {
2807 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
2808 });
2809 }
2810 }
2811 }
2812}
2813
2814template <class FAB>
2815void
2817{
2818 clearThisBD(); // The new boxarray will have a different ID.
2819 boxarray.shift(v);
2820 addThisBD();
2821#ifdef AMREX_USE_OMP
2822#pragma omp parallel
2823#endif
2824 for (MFIter fai(*this); fai.isValid(); ++fai)
2825 {
2826 get(fai).shift(v);
2827 }
2828 clear_arrays();
2829}
2830
2831template <class FAB>
2832template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
2834 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
2835{
2836 AMREX_ASSERT(y.boxArray() == x.boxArray());
2837 AMREX_ASSERT(y.distributionMap == x.distributionMap);
2838 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
2839
2840 BL_PROFILE("FabArray::Saxpy()");
2841
2842#ifdef AMREX_USE_GPU
2844 auto const& yma = y.arrays();
2845 auto const& xma = x.const_arrays();
2846 ParallelFor(y, nghost, ncomp,
2847 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2848 {
2849 yma[box_no](i,j,k,ycomp+n) += a * xma[box_no](i,j,k,xcomp+n);
2850 });
2851 if (!Gpu::inNoSyncRegion()) {
2853 }
2854 } else
2855#endif
2856 {
2857#ifdef AMREX_USE_OMP
2858#pragma omp parallel if (Gpu::notInLaunchRegion())
2859#endif
2860 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2861 {
2862 const Box& bx = mfi.growntilebox(nghost);
2863
2864 if (bx.ok()) {
2865 auto const& xfab = x.const_array(mfi);
2866 auto const& yfab = y.array(mfi);
2867 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
2868 {
2869 yfab(i,j,k,ycomp+n) += a * xfab(i,j,k,xcomp+n);
2870 });
2871 }
2872 }
2873 }
2874}
2875
2876template <class FAB>
2877template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
2878void
2880 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
2881{
2882 AMREX_ASSERT(y.boxArray() == x.boxArray());
2883 AMREX_ASSERT(y.distributionMap == x.distributionMap);
2884 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
2885
2886 BL_PROFILE("FabArray::Xpay()");
2887
2888#ifdef AMREX_USE_GPU
2890 auto const& yfa = y.arrays();
2891 auto const& xfa = x.const_arrays();
2892 ParallelFor(y, nghost, ncomp,
2893 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2894 {
2895 yfa[box_no](i,j,k,n+ycomp) = xfa[box_no](i,j,k,n+xcomp)
2896 + a * yfa[box_no](i,j,k,n+ycomp);
2897 });
2898 if (!Gpu::inNoSyncRegion()) {
2900 }
2901 } else
2902#endif
2903 {
2904#ifdef AMREX_USE_OMP
2905#pragma omp parallel if (Gpu::notInLaunchRegion())
2906#endif
2907 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2908 {
2909 const Box& bx = mfi.growntilebox(nghost);
2910 auto const& xFab = x.const_array(mfi);
2911 auto const& yFab = y.array(mfi);
2912 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
2913 {
2914 yFab(i,j,k,n+ycomp) = xFab(i,j,k,n+xcomp)
2915 + a * yFab(i,j,k,n+ycomp);
2916 });
2917 }
2918 }
2919}
2920
2921template <class FAB>
2922template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
2923void
2925 value_type a, const FabArray<FAB>& x, int xcomp,
2926 value_type b, const FabArray<FAB>& y, int ycomp,
2927 int dstcomp, int numcomp, const IntVect& nghost)
2928{
2929 AMREX_ASSERT(dst.boxArray() == x.boxArray());
2930 AMREX_ASSERT(dst.distributionMap == x.distributionMap);
2931 AMREX_ASSERT(dst.boxArray() == y.boxArray());
2933 AMREX_ASSERT(dst.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost) && y.nGrowVect().allGE(nghost));
2934
2935 BL_PROFILE("FabArray::LinComb()");
2936
2937#ifdef AMREX_USE_GPU
2938 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
2939 auto const& dstma = dst.arrays();
2940 auto const& xma = x.const_arrays();
2941 auto const& yma = y.const_arrays();
2942 ParallelFor(dst, nghost, numcomp,
2943 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2944 {
2945 dstma[box_no](i,j,k,dstcomp+n) = a*xma[box_no](i,j,k,xcomp+n)
2946 + b*yma[box_no](i,j,k,ycomp+n);
2947 });
2948 if (!Gpu::inNoSyncRegion()) {
2950 }
2951 } else
2952#endif
2953 {
2954#ifdef AMREX_USE_OMP
2955#pragma omp parallel if (Gpu::notInLaunchRegion())
2956#endif
2957 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2958 {
2959 const Box& bx = mfi.growntilebox(nghost);
2960 auto const& xfab = x.const_array(mfi);
2961 auto const& yfab = y.const_array(mfi);
2962 auto const& dfab = dst.array(mfi);
2963 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
2964 {
2965 dfab(i,j,k,dstcomp+n) = a*xfab(i,j,k,xcomp+n) + b*yfab(i,j,k,ycomp+n);
2966 });
2967 }
2968 }
2969}
2970
2971template <class FAB>
2972template <typename BUF>
2973void
2975{
2976 BL_PROFILE("FabArray::FillBoundary()");
2977 if ( n_grow.max() > 0 ) {
2978 FillBoundary_nowait<BUF>(0, nComp(), n_grow, Periodicity::NonPeriodic(), cross);
2979 FillBoundary_finish<BUF>();
2980 }
2981}
2982
2983template <class FAB>
2984template <typename BUF>
2985void
2986FabArray<FAB>::FillBoundary (const Periodicity& period, bool cross)
2987{
2988 BL_PROFILE("FabArray::FillBoundary()");
2989 if ( n_grow.max() > 0 ) {
2990 FillBoundary_nowait<BUF>(0, nComp(), n_grow, period, cross);
2991 FillBoundary_finish<BUF>();
2992 }
2993}
2994
2995template <class FAB>
2996template <typename BUF>
2997void
2998FabArray<FAB>::FillBoundary (const IntVect& nghost, const Periodicity& period, bool cross)
2999{
3000 BL_PROFILE("FabArray::FillBoundary()");
3002 "FillBoundary: asked to fill more ghost cells than we have");
3003 if ( nghost.max() > 0 ) {
3004 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3005 FillBoundary_finish<BUF>();
3006 }
3007}
3008
3009template <class FAB>
3010template <typename BUF>
3011void
3012FabArray<FAB>::FillBoundary (int scomp, int ncomp, bool cross)
3013{
3014 BL_PROFILE("FabArray::FillBoundary()");
3015 if ( n_grow.max() > 0 ) {
3016 FillBoundary_nowait<BUF>(scomp, ncomp, n_grow, Periodicity::NonPeriodic(), cross);
3017 FillBoundary_finish<BUF>();
3018 }
3019}
3020
3021template <class FAB>
3022template <typename BUF>
3023void
3024FabArray<FAB>::FillBoundary (int scomp, int ncomp, const Periodicity& period, bool cross)
3025{
3026 BL_PROFILE("FabArray::FillBoundary()");
3027 if ( n_grow.max() > 0 ) {
3028 FillBoundary_nowait<BUF>(scomp, ncomp, n_grow, period, cross);
3029 FillBoundary_finish<BUF>();
3030 }
3031}
3032
3033template <class FAB>
3034template <typename BUF>
3035void
3036FabArray<FAB>::FillBoundary (int scomp, int ncomp, const IntVect& nghost,
3037 const Periodicity& period, bool cross)
3038{
3039 BL_PROFILE("FabArray::FillBoundary()");
3041 "FillBoundary: asked to fill more ghost cells than we have");
3042 if ( nghost.max() > 0 ) {
3043 FillBoundary_nowait<BUF>(scomp, ncomp, nghost, period, cross);
3044 FillBoundary_finish<BUF>();
3045 }
3046}
3047
3048template <class FAB>
3049template <typename BUF>
3050void
3052{
3053 FillBoundary_nowait<BUF>(0, nComp(), nGrowVect(), Periodicity::NonPeriodic(), cross);
3054}
3055
3056template <class FAB>
3057template <typename BUF>
3058void
3060{
3061 FillBoundary_nowait<BUF>(0, nComp(), nGrowVect(), period, cross);
3062}
3063
3064template <class FAB>
3065template <typename BUF>
3066void
3067FabArray<FAB>::FillBoundary_nowait (const IntVect& nghost, const Periodicity& period, bool cross)
3068{
3069 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3070}
3071
3072template <class FAB>
3073template <typename BUF>
3074void
3075FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, bool cross)
3076{
3077 FillBoundary_nowait<BUF>(scomp, ncomp, nGrowVect(), Periodicity::NonPeriodic(), cross);
3078}
3079
3080template <class FAB>
3081void
3083{
3084 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3085 if (n_grow.max() > 0 || !is_cell_centered()) {
3086 FillBoundaryAndSync_nowait(0, nComp(), n_grow, period);
3087 FillBoundaryAndSync_finish();
3088 }
3089}
3090
3091template <class FAB>
3092void
3093FabArray<FAB>::FillBoundaryAndSync (int scomp, int ncomp, const IntVect& nghost,
3094 const Periodicity& period)
3095{
3096 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3097 if (nghost.max() > 0 || !is_cell_centered()) {
3098 FillBoundaryAndSync_nowait(scomp, ncomp, nghost, period);
3099 FillBoundaryAndSync_finish();
3100 }
3101}
3102
3103template <class FAB>
3104void
3106{
3107 FillBoundaryAndSync_nowait(0, nComp(), nGrowVect(), period);
3108}
3109
3110template <class FAB>
3111void
3112FabArray<FAB>::FillBoundaryAndSync_nowait (int scomp, int ncomp, const IntVect& nghost,
3113 const Periodicity& period)
3114{
3115 BL_PROFILE("FillBoundaryAndSync_nowait()");
3116 FBEP_nowait(scomp, ncomp, nghost, period, false, false, true);
3117}
3118
3119template <class FAB>
3120void
3122{
3123 BL_PROFILE("FillBoundaryAndSync_finish()");
3124 FillBoundary_finish();
3125}
3126
3127template <class FAB>
3128void
3130{
3131 BL_PROFILE("FAbArray::OverrideSync()");
3132 if (!is_cell_centered()) {
3133 OverrideSync_nowait(0, nComp(), period);
3135 }
3136}
3137
3138template <class FAB>
3139void
3140FabArray<FAB>::OverrideSync (int scomp, int ncomp, const Periodicity& period)
3141{
3142 BL_PROFILE("FAbArray::OverrideSync()");
3143 if (!is_cell_centered()) {
3144 OverrideSync_nowait(scomp, ncomp, period);
3146 }
3147}
3148
3149template <class FAB>
3150void
3152{
3153 OverrideSync_nowait(0, nComp(), period);
3154}
3155
3156template <class FAB>
3157void
3158FabArray<FAB>::OverrideSync_nowait (int scomp, int ncomp, const Periodicity& period)
3159{
3160 BL_PROFILE("OverrideSync_nowait()");
3161 FBEP_nowait(scomp, ncomp, IntVect(0), period, false, false, true);
3162}
3163
3164template <class FAB>
3165void
3167{
3168 BL_PROFILE("OverrideSync_finish()");
3169 FillBoundary_finish();
3170}
3171
3172template <class FAB>
3173void
3175{
3176 SumBoundary(0, n_comp, IntVect(0), period);
3177}
3178
3179template <class FAB>
3180void
3181FabArray<FAB>::SumBoundary (int scomp, int ncomp, const Periodicity& period)
3182{
3183 SumBoundary(scomp, ncomp, IntVect(0), period);
3184}
3185
3186template <class FAB>
3187void
3188FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period)
3189{
3190 SumBoundary(scomp, ncomp, this->nGrowVect(), nghost, period);
3191}
3192
3193template <class FAB>
3194void
3195FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period)
3196{
3197 BL_PROFILE("FabArray<FAB>::SumBoundary()");
3198
3199 SumBoundary_nowait(scomp, ncomp, src_nghost, dst_nghost, period);
3200 SumBoundary_finish();
3201}
3202
3203template <class FAB>
3204void
3206{
3207 SumBoundary_nowait(0, n_comp, IntVect(0), period);
3208}
3209
3210template <class FAB>
3211void
3212FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, const Periodicity& period)
3213{
3214 SumBoundary_nowait(scomp, ncomp, IntVect(0), period);
3215}
3216
3217template <class FAB>
3218void
3219FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period)
3220{
3221 SumBoundary_nowait(scomp, ncomp, this->nGrowVect(), nghost, period);
3222}
3223
3224template <class FAB>
3225void
3226FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period)
3227{
3228 BL_PROFILE("FabArray<FAB>::SumBoundary_nowait()");
3229
3230 if ( n_grow == IntVect::TheZeroVector() && boxArray().ixType().cellCentered()) { return; }
3231
3232 AMREX_ALWAYS_ASSERT(src_nghost.allLE(n_grow));
3233
3234 auto* tmp = new FabArray<FAB>( boxArray(), DistributionMap(), ncomp, src_nghost, MFInfo(), Factory() );
3235 amrex::Copy(*tmp, *this, scomp, 0, ncomp, src_nghost);
3236 this->setVal(typename FAB::value_type(0), scomp, ncomp, dst_nghost);
3237 this->ParallelCopy_nowait(*tmp,0,scomp,ncomp,src_nghost,dst_nghost,period,FabArrayBase::ADD);
3238
3239 // All local. Operation complete.
3240 if (!this->pcd) { delete tmp; }
3241}
3242
3243template <class FAB>
3244void
3246{
3247 BL_PROFILE("FabArray<FAB>::SumBoundary_finish()");
3248
3249 // If pcd doesn't exist, ParallelCopy was all local and operation was fully completed in "SumBoundary_nowait".
3250 if ( (n_grow == IntVect::TheZeroVector() && boxArray().ixType().cellCentered()) || !(this->pcd) ) { return; }
3251
3252 auto* tmp = const_cast<FabArray<FAB>*> (this->pcd->src);
3253 this->ParallelCopy_finish();
3254 delete tmp;
3255}
3256
3257template <class FAB>
3258void
3260{
3261 BL_PROFILE("FabArray::EnforcePeriodicity");
3262 if (period.isAnyPeriodic()) {
3263 FBEP_nowait(0, nComp(), nGrowVect(), period, false, true);
3264 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3265 }
3266}
3267
3268template <class FAB>
3269void
3270FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const Periodicity& period)
3271{
3272 BL_PROFILE("FabArray::EnforcePeriodicity");
3273 if (period.isAnyPeriodic()) {
3274 FBEP_nowait(scomp, ncomp, nGrowVect(), period, false, true);
3275 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3276 }
3277}
3278
3279template <class FAB>
3280void
3281FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const IntVect& nghost,
3282 const Periodicity& period)
3283{
3284 BL_PROFILE("FabArray::EnforcePeriodicity");
3285 if (period.isAnyPeriodic()) {
3286 FBEP_nowait(scomp, ncomp, nghost, period, false, true);
3287 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3288 }
3289}
3290
3291template <class FAB>
3292template <typename BUF>
3293void
3294FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool cross)
3295{
3296 FBEP_nowait<BUF>(scomp, ncomp, nGrowVect(), period, cross);
3297}
3298
3299template <class FAB>
3300template <typename BUF>
3301void
3302FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const IntVect& nghost,
3303 const Periodicity& period, bool cross)
3304{
3305 FBEP_nowait<BUF>(scomp, ncomp, nghost, period, cross);
3306}
3307
3308template <class FAB>
3309template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
3310void
3311FabArray<FAB>::BuildMask (const Box& phys_domain, const Periodicity& period,
3312 value_type covered, value_type notcovered,
3313 value_type physbnd, value_type interior)
3314{
3315 BL_PROFILE("FabArray::BuildMask()");
3316
3317 int ncomp = this->nComp();
3318 const IntVect& ngrow = this->nGrowVect();
3319
3320 Box domain = amrex::convert(phys_domain, boxArray().ixType());
3321 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
3322 if (period.isPeriodic(i)) {
3323 domain.grow(i, ngrow[i]);
3324 }
3325 }
3326
3327#ifdef AMREX_USE_GPU
3328 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3329 auto const& fa = this->arrays();
3330 ParallelFor(*this, ngrow, ncomp,
3331 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3332 {
3333 auto const& fab = fa[box_no];
3334 Box vbx(fab);
3335 vbx.grow(-ngrow);
3336 if (vbx.contains(i,j,k)) {
3337 fab(i,j,k,n) = interior;
3338 } else if (domain.contains(i,j,k)) {
3339 fab(i,j,k,n) = notcovered;
3340 } else {
3341 fab(i,j,k,n) = physbnd;
3342 }
3343 });
3344 if (!Gpu::inNoSyncRegion()) {
3346 }
3347 } else
3348#endif
3349 {
3350#ifdef AMREX_USE_OMP
3351#pragma omp parallel if (Gpu::notInLaunchRegion())
3352#endif
3353 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3354 {
3355 auto const& fab = this->array(mfi);
3356 Box const& fbx = mfi.growntilebox();
3357 Box const& gbx = fbx & domain;
3358 Box const& vbx = mfi.validbox();
3359 AMREX_HOST_DEVICE_FOR_4D(fbx, ncomp, i, j, k, n,
3360 {
3361 if (vbx.contains(i,j,k)) {
3362 fab(i,j,k,n) = interior;
3363 } else if (gbx.contains(i,j,k)) {
3364 fab(i,j,k,n) = notcovered;
3365 } else {
3366 fab(i,j,k,n) = physbnd;
3367 }
3368 });
3369 }
3370 }
3371
3372 const FabArrayBase::FB& TheFB = this->getFB(ngrow,period);
3373 setVal(covered, TheFB, 0, ncomp);
3374}
3375
3376template <class FAB>
3377template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
3378void
3379FabArray<FAB>::setVal (value_type val, const CommMetaData& thecmd, int scomp, int ncomp)
3380{
3381 BL_PROFILE("FabArray::setVal(val, thecmd, scomp, ncomp)");
3382
3383#ifdef AMREX_USE_GPU
3384 if (Gpu::inLaunchRegion())
3385 {
3386 CMD_local_setVal_gpu(val, thecmd, scomp, ncomp);
3387 CMD_remote_setVal_gpu(val, thecmd, scomp, ncomp);
3388 }
3389 else
3390#endif
3391 {
3392 AMREX_ASSERT(thecmd.m_LocTags && thecmd.m_RcvTags);
3393 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
3394 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
3395 auto N_locs = static_cast<int>(LocTags.size());
3396#ifdef AMREX_USE_OMP
3397#pragma omp parallel for if (thecmd.m_threadsafe_loc)
3398#endif
3399 for (int i = 0; i < N_locs; ++i) {
3400 const CopyComTag& tag = LocTags[i];
3401 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
3402 }
3403
3404 for (const auto & RcvTag : RcvTags) {
3405 auto N = static_cast<int>(RcvTag.second.size());
3406#ifdef AMREX_USE_OMP
3407#pragma omp parallel for if (thecmd.m_threadsafe_rcv)
3408#endif
3409 for (int i = 0; i < N; ++i) {
3410 const CopyComTag& tag = RcvTag.second[i];
3411 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
3412 }
3413 }
3414 }
3415}
3416
3417template <class FAB>
3418template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
3421{
3422 BL_PROFILE("FabArray::RecvLayoutMask()");
3423
3424 LayoutData<int> r(this->boxArray(), this->DistributionMap());
3425#ifdef AMREX_USE_OMP
3426#pragma omp parallel if (thecmd.m_threadsafe_rcv)
3427#endif
3428 for (MFIter mfi(r); mfi.isValid(); ++mfi) {
3429 r[mfi] = 0;
3430 }
3431
3432 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
3433 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
3434
3435 auto N_locs = static_cast<int>(LocTags.size());
3436 for (int i = 0; i < N_locs; ++i) {
3437 const CopyComTag& tag = LocTags[i];
3438 r[tag.dstIndex] = 1;
3439 }
3440
3441 for (const auto & RcvTag : RcvTags) {
3442 auto N = static_cast<int>(RcvTag.second.size());
3443 for (int i = 0; i < N; ++i) {
3444 const CopyComTag& tag = RcvTag.second[i];
3445 r[tag.dstIndex] = 1;
3446 }
3447 }
3448 return r;
3449}
3450
3451template <class FAB>
3452template <typename F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3453typename F::value_type
3454FabArray<FAB>::norminf (int comp, int ncomp, IntVect const& nghost, bool local,
3455 [[maybe_unused]] bool ignore_covered) const
3456{
3457 BL_PROFILE("FabArray::norminf()");
3458
3459 using RT = typename F::value_type;
3460
3461 auto nm0 = RT(0.0);
3462
3463#ifdef AMREX_USE_EB
3464 if ( this->is_cell_centered() && this->hasEBFabFactory() && ignore_covered )
3465 {
3466 const auto& ebfactory = dynamic_cast<EBFArrayBoxFactory const&>(this->Factory());
3467 auto const& flags = ebfactory.getMultiEBCellFlagFab();
3468#ifdef AMREX_USE_GPU
3469 if (Gpu::inLaunchRegion()) {
3470 auto const& flagsma = flags.const_arrays();
3471 auto const& ma = this->const_arrays();
3472 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost,
3473 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<RT>
3474 {
3475 if (flagsma[box_no](i,j,k).isCovered()) {
3476 return RT(0.0);
3477 } else {
3478 auto tmp = RT(0.0);
3479 auto const& a = ma[box_no];
3480 for (int n = 0; n < ncomp; ++n) {
3481 tmp = amrex::max(tmp, std::abs(a(i,j,k,comp+n)));
3482 }
3483 return tmp;
3484 }
3485 });
3486 } else
3487#endif
3488 {
3489#ifdef AMREX_USE_OMP
3490#pragma omp parallel reduction(max:nm0)
3491#endif
3492 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
3493 Box const& bx = mfi.growntilebox(nghost);
3494 if (flags[mfi].getType(bx) != FabType::covered) {
3495 auto const& flag = flags.const_array(mfi);
3496 auto const& a = this->const_array(mfi);
3497 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
3498 {
3499 if (!flag(i,j,k).isCovered()) {
3500 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
3501 }
3502 });
3503 }
3504 }
3505 }
3506 }
3507 else
3508#endif
3509 {
3510#ifdef AMREX_USE_GPU
3511 if (Gpu::inLaunchRegion()) {
3512 auto const& ma = this->const_arrays();
3513 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost, ncomp,
3514 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept -> GpuTuple<RT>
3515 {
3516 return std::abs(ma[box_no](i,j,k,comp+n));
3517 });
3518 } else
3519#endif
3520 {
3521#ifdef AMREX_USE_OMP
3522#pragma omp parallel reduction(max:nm0)
3523#endif
3524 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
3525 Box const& bx = mfi.growntilebox(nghost);
3526 auto const& a = this->const_array(mfi);
3527 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
3528 {
3529 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
3530 });
3531 }
3532 }
3533 }
3534
3535 if (!local) {
3537 }
3538
3539 return nm0;
3540}
3541
3542template <class FAB>
3543template <typename IFAB, typename F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3544typename F::value_type
3545FabArray<FAB>::norminf (FabArray<IFAB> const& mask, int comp, int ncomp,
3546 IntVect const& nghost, bool local) const
3547{
3548 BL_PROFILE("FabArray::norminf(mask)");
3549
3550 using RT = typename F::value_type;
3551
3552 auto nm0 = RT(0.0);
3553
3554#ifdef AMREX_USE_GPU
3555 if (Gpu::inLaunchRegion()) {
3556 auto const& ma = this->const_arrays();
3557 auto const& maskma = mask.const_arrays();
3558 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, IntVect(nghost),
3559 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<RT>
3560 {
3561 if (maskma[box_no](i,j,k)) {
3562 auto tmp = RT(0.0);
3563 auto const& a = ma[box_no];
3564 for (int n = 0; n < ncomp; ++n) {
3565 tmp = amrex::max(tmp, std::abs(a(i,j,k,comp+n)));
3566 }
3567 return tmp;
3568 } else {
3569 return RT(0.0);
3570 }
3571 });
3572 } else
3573#endif
3574 {
3575#ifdef AMREX_USE_OMP
3576#pragma omp parallel reduction(max:nm0)
3577#endif
3578 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
3579 Box const& bx = mfi.growntilebox(nghost);
3580 auto const& a = this->const_array(mfi);
3581 auto const& mskfab = mask.const_array(mfi);
3582 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
3583 {
3584 if (mskfab(i,j,k)) {
3585 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
3586 }
3587 });
3588 }
3589 }
3590
3591 if (!local) {
3593 }
3594
3595 return nm0;
3596}
3597
3599
3600}
3601
3602#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:251
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_RESTRICT
Definition AMReX_Extension.H:37
#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:1089
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
int MPI_Comm
Definition AMReX_ccse-mpi.H:47
if(!(yy_init))
Definition amrex_iparser.lex.nolint.H:935
A virtual base class for objects that manage their own dynamic memory allocation.
Definition AMReX_Arena.H:100
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:183
A collection of Boxes stored in an Array.
Definition AMReX_BoxArray.H:550
AMREX_GPU_HOST_DEVICE IntVectND< dim > length() const noexcept
Return the length of the BoxND.
Definition AMReX_Box.H:146
AMREX_GPU_HOST_DEVICE const IntVectND< dim > & smallEnd() const &noexcept
Get the smallend of the BoxND.
Definition AMReX_Box.H:105
AMREX_GPU_HOST_DEVICE BoxND & grow(int i) noexcept
Definition AMReX_Box.H:627
AMREX_GPU_HOST_DEVICE bool ok() const noexcept
Checks if it is a proper BoxND (including a valid type).
Definition AMReX_Box.H:200
AMREX_GPU_HOST_DEVICE bool contains(const IntVectND< dim > &p) const noexcept
Returns true if argument is contained within BoxND.
Definition AMReX_Box.H:204
AMREX_GPU_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:1046
Definition AMReX_FabFactory.H:76
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:41
Definition AMReX_EBFabFactory.H:24
const FabArray< EBCellFlagFab > & getMultiEBCellFlagFab() const noexcept
Definition AMReX_EBFabFactory.H:50
bool isAllRegular() const noexcept
Definition AMReX_EBFabFactory.cpp:148
Base class for FabArray.
Definition AMReX_FabArrayBase.H:41
IntVect nGrowVect() const noexcept
Definition AMReX_FabArrayBase.H:79
Vector< int > indexArray
Definition AMReX_FabArrayBase.H:445
static bool getAllocSingleChunk()
Definition AMReX_FabArrayBase.H:727
bool isFusingCandidate() const noexcept
Is this a good candidate for kernel fusing?
FabArrayBase & operator=(const FabArrayBase &rhs)=default
void define(const BoxArray &bxs, const DistributionMapping &dm, int nvar, int ngrow)
CopyComTag::CopyComTagsContainer CopyComTagsContainer
Definition AMReX_FabArrayBase.H:219
CopyComTag::MapOfCopyComTagContainers MapOfCopyComTagContainers
Definition AMReX_FabArrayBase.H:220
const DistributionMapping & DistributionMap() const noexcept
Return constant reference to associated DistributionMapping.
Definition AMReX_FabArrayBase.H:130
int local_size() const noexcept
Return the number of local FABs in the FabArray.
Definition AMReX_FabArrayBase.H:112
CpOp
parallel copy or add
Definition AMReX_FabArrayBase.H:393
@ ADD
Definition AMReX_FabArrayBase.H:393
@ COPY
Definition AMReX_FabArrayBase.H:393
DistributionMapping distributionMap
Definition AMReX_FabArrayBase.H:444
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:82
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:94
static AMREX_EXPORT FabArrayStats m_FA_stats
Definition AMReX_FabArrayBase.H:723
An Array of FortranArrayBox(FAB)-like Objects.
Definition AMReX_FabArray.H:344
void ParallelCopyToGhost_finish()
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:2126
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:1004
void setFab(const MFIter &mfi, FAB &&elem)
Explicitly set the FAB associated with mfi in the FabArray to point to elem.
Definition AMReX_FabArray.H:2191
F::value_type sum(int comp, IntVect const &nghost, bool local=false) const
Returns the sum of component "comp".
Definition AMReX_FabArray.H:2361
void EnforcePeriodicity(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Definition AMReX_FabArray.H:3281
void abs(int comp, int ncomp, int nghost=0)
Definition AMReX_FabArray.H:2543
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:1015
Array4< typename FabArray< FAB >::value_type const > const_array(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:584
void * m_dp_arrays
Definition AMReX_FabArray.H:1344
void FBEP_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross, bool enforce_periodicity_only=false, bool override_sync=false)
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)
void ParallelCopy(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:840
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:2169
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:1474
void FillBoundary(const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:2998
const FabFactory< FAB > & Factory() const noexcept
Definition AMReX_FabArray.H:442
void mult(value_type val, const Box &region, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2701
void invert(value_type numerator, const Box &region, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2777
void prefetchToDevice(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:550
void FillBoundary_nowait(const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3059
void shift(const IntVect &v)
Shift the boxarray by vector v.
Definition AMReX_FabArray.H:2816
bool ok() const
Return true if the FabArray is well-defined. That is, the FabArray has a BoxArray and DistributionMap...
Definition AMReX_FabArray.H:1907
Array4< typename FabArray< FAB >::value_type const > array(const MFIter &mfi, int start_comp) const noexcept
Definition AMReX_FabArray.H:596
const FAB & operator[](const MFIter &mfi) const noexcept
Return a constant reference to the FAB associated with mfi.
Definition AMReX_FabArray.H:506
void CMD_local_setVal_gpu(value_type x, const CommMetaData &thecmd, int scomp, int ncomp)
Definition AMReX_FBI.H:332
void CMD_remote_setVal_gpu(value_type x, const CommMetaData &thecmd, int scomp, int ncomp)
Definition AMReX_FBI.H:362
void ParallelAdd_nowait(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:851
void setDomainBndry(value_type val, int strt_comp, int ncomp, const Geometry &geom)
Set ncomp values outside the Geometry domain to val, starting at start_comp.
Definition AMReX_FabArray.H:2330
FabArray(FabArray< FAB > &&rhs) noexcept
Definition AMReX_FabArray.H:1842
Array4< typename FabArray< FAB >::value_type const > array(int K, int start_comp) const noexcept
Definition AMReX_FabArray.H:608
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:1806
bool defined(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:1547
void setVal(value_type val, const CommMetaData &thecmd, int scomp, int ncomp)
Definition AMReX_FabArray.H:3379
void setVal(value_type val, const Box &region, int comp, int ncomp, const IntVect &nghost)
Definition AMReX_FabArray.H:2494
void OverrideSync_nowait(int scomp, int ncomp, const Periodicity &period)
Definition AMReX_FabArray.H:3158
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())
void FillBoundary_test()
Definition AMReX_FabArrayCommI.H:886
void ParallelCopy_finish()
void setVal(value_type val, const Box &region, int comp, int ncomp, int nghost=0)
Set the value of num_comp components in the valid region of each FAB in the FabArray,...
Definition AMReX_FabArray.H:2482
FAB & get(int K) noexcept
Return a reference to the FAB associated with the Kth element.
Definition AMReX_FabArray.H:527
void setVal(value_type val, int comp, int ncomp, const IntVect &nghost)
Definition AMReX_FabArray.H:2440
void OverrideSync(const Periodicity &period=Periodicity::NonPeriodic())
Synchronize nodal data. The synchronization will override valid regions by the intersecting valid reg...
Definition AMReX_FabArray.H:3129
void FillBoundary(bool cross=false)
Copy on intersection within a FabArray. Data is copied from valid regions to intersecting regions of ...
Definition AMReX_FabArray.H:2974
FAB const * fabPtr(int K) const noexcept
Definition AMReX_FabArray.H:1589
void abs(int comp, int ncomp, const IntVect &nghost)
Definition AMReX_FabArray.H:2551
void clear_arrays()
Definition AMReX_FabArray.H:1633
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:922
void SumBoundary(const Periodicity &period=Periodicity::NonPeriodic())
Sum values in overlapped cells. The destination is limited to valid cells.
Definition AMReX_FabArray.H:3174
Long m_single_chunk_size
Definition AMReX_FabArray.H:1334
FAB & get(const MFIter &mfi) noexcept
Returns a reference to the FAB associated mfi.
Definition AMReX_FabArray.H:515
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:2924
void OverrideSync_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3151
AMREX_NODISCARD FAB * release(const MFIter &mfi)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:1670
AMREX_NODISCARD FAB * release(int K)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:1650
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:3454
void setDomainBndry(value_type val, const Geometry &geom)
Set all values outside the Geometry domain to val.
Definition AMReX_FabArray.H:2322
std::unique_ptr< PCData< FAB > > pcd
Definition AMReX_FabArray.H:1471
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:1942
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:951
std::unique_ptr< FBData< FAB > > fbd
Definition AMReX_FabArray.H:1470
std::unique_ptr< detail::SingleChunkArena > m_single_chunk_arena
Definition AMReX_FabArray.H:1333
FabArray(const FabArray< FAB > &rhs, MakeType maketype, int scomp, int ncomp)
Definition AMReX_FabArray.H:1820
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:837
FAB fab_type
Definition AMReX_FabArray.H:357
void setVal(value_type val, const IntVect &nghost)
Definition AMReX_FabArray.H:1759
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:3311
void OverrideSync(int scomp, int ncomp, const Periodicity &period)
Synchronize nodal data. The synchronization will override valid regions by the intersecting valid reg...
Definition AMReX_FabArray.H:3140
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:1733
bool SharedMemory() const noexcept
Definition AMReX_FabArray.H:1402
LayoutData< int > RecvLayoutMask(const CommMetaData &thecmd)
Definition AMReX_FabArray.H:3420
void FillBoundary(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3036
void FillBoundary_nowait(const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3067
Vector< std::string > m_tags
Definition AMReX_FabArray.H:1350
void ParallelCopyToGhost_nowait(const FabArray< FAB > &src, int scomp, int dcomp, int ncomp, const IntVect &snghost, const IntVect &dnghost, const Periodicity &period=Periodicity::NonPeriodic())
void FB_local_copy_cpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:211
void invert(value_type numerator, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2741
void FB_local_copy_gpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:272
static void unpack_recv_buffer_cpu(FabArray< FAB > &dst, int dcomp, int ncomp, Vector< char * > const &recv_data, Vector< std::size_t > const &recv_size, Vector< const CopyComTagsContainer * > const &recv_cctc, CpOp op, bool is_thread_safe)
void ParallelAdd_nowait(const FabArray< FAB > &src, int src_comp, int dest_comp, int num_comp, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:890
void PC_local_gpu(const CPC &thecpc, FabArray< FAB > const &src, int scomp, int dcomp, int ncomp, CpOp op)
Definition AMReX_PCI.H:88
Array4< typename FabArray< FAB >::value_type const > array(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:560
Arena * arena() const noexcept
Definition AMReX_FabArray.H:445
void setFab_assert(int K, FAB const &fab) const
Definition AMReX_FabArray.H:2114
Array4< typename FabArray< FAB >::value_type const > const_array(int K) const noexcept
Definition AMReX_FabArray.H:590
void plus(value_type val, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2589
DataAllocator m_dallocator
Definition AMReX_FabArray.H:1332
void FillBoundaryAndSync(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Fill ghost cells and synchronize nodal data. Ghost regions are filled with data from the intersecting...
Definition AMReX_FabArray.H:3093
void copy(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:846
void FillBoundaryAndSync_finish()
Definition AMReX_FabArray.H:3121
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:961
void SumBoundary_nowait(int scomp, int ncomp, IntVect const &src_nghost, IntVect const &dst_nghost, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3226
void SumBoundary_nowait(int scomp, int ncomp, IntVect const &nghost, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3219
void FillBoundary_nowait(bool cross=false)
Definition AMReX_FabArray.H:3051
void FillBoundary(const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:2986
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:2879
void clear()
Releases FAB memory in the FabArray.
Definition AMReX_FabArray.H:1689
void FillBoundary_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3302
const Vector< std::string > & tags() const noexcept
Definition AMReX_FabArray.H:447
void FillBoundary(int scomp, int ncomp, bool cross=false)
Same as FillBoundary(), but only copies ncomp components starting at scomp.
Definition AMReX_FabArray.H:3012
void FillBoundary_nowait(int scomp, int ncomp, bool cross=false)
Definition AMReX_FabArray.H:3075
Array4< typename FabArray< FAB >::value_type > array(const MFIter &mfi) noexcept
Definition AMReX_FabArray.H:566
value_type * singleChunkPtr() noexcept
Definition AMReX_FabArray.H:460
std::vector< FAB * > m_fabs_v
The data.
Definition AMReX_FabArray.H:1341
void setBndry(value_type val)
Set all values in the boundary region to val.
Definition AMReX_FabArray.H:2213
void SumBoundary(int scomp, int ncomp, IntVect const &nghost, const Periodicity &period=Periodicity::NonPeriodic())
Sum values in overlapped cells. The destination is limited to valid + ngrow cells.
Definition AMReX_FabArray.H:3188
void FillBoundaryAndSync(const Periodicity &period=Periodicity::NonPeriodic())
Fill ghost cells and synchronize nodal data. Ghost regions are filled with data from the intersecting...
Definition AMReX_FabArray.H:3082
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:914
bool define_function_called
has define() been called?
Definition AMReX_FabArray.H:1337
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:867
FabArray() noexcept
Constructs an empty FabArray<FAB>.
Definition AMReX_FabArray.H:1781
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)
bool defined(int K) const noexcept
Definition AMReX_FabArray.H:1534
FAB * fabPtr(int K) noexcept
Definition AMReX_FabArray.H:1580
void SumBoundary(int scomp, int ncomp, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3181
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:905
const FAB & atLocalIdx(int L) const noexcept
Definition AMReX_FabArray.H:531
std::unique_ptr< FabFactory< FAB > > m_factory
Definition AMReX_FabArray.H:1331
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:859
void setVal(value_type val)
Set all components in the entire region of each FAB to val.
Definition AMReX_FabArray.H:2412
void setVal(value_type val, int comp, int ncomp, int nghost=0)
Set the value of num_comp components in the valid region of each FAB in the FabArray,...
Definition AMReX_FabArray.H:2429
typename std::vector< FAB * >::iterator Iterator
Definition AMReX_FabArray.H:1405
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:882
MultiArray4< typename FabArray< FAB >::value_type > arrays() noexcept
Definition AMReX_FabArray.H:632
MultiArray4< typename FabArray< FAB >::value_type const > arrays() const noexcept
Definition AMReX_FabArray.H:639
void setVal(value_type val, int nghost)
Set all components in the valid region of each FAB in the FabArray to val, including nghost boundary ...
Definition AMReX_FabArray.H:1751
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:2404
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:941
void setBndry(value_type val, int strt_comp, int ncomp)
Set ncomp values in the boundary region, starting at start_comp to val.
Definition AMReX_FabArray.H:2221
void SumBoundary(int scomp, int ncomp, IntVect const &src_nghost, IntVect const &dst_nghost, const Periodicity &period=Periodicity::NonPeriodic())
Sum values in overlapped cells. For computing the overlap, the dst is grown by dst_ngrow,...
Definition AMReX_FabArray.H:3195
void setVal(value_type val, const Box &region, const IntVect &nghost)
Definition AMReX_FabArray.H:1775
void FillBoundary_nowait(int scomp, int ncomp, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3294
const FAB & get(const MFIter &mfi) const noexcept
Return a constant reference to the FAB associated with mfi.
Definition AMReX_FabArray.H:509
void SumBoundary_finish()
Definition AMReX_FabArray.H:3245
void SumBoundary_nowait(int scomp, int ncomp, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3212
std::size_t singleChunkSize() const noexcept
Definition AMReX_FabArray.H:472
void mult(value_type val, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2665
void ParallelCopy_nowait(const FabArray< FAB > &src, int scomp, int dcomp, int ncomp, const IntVect &snghost, const IntVect &dnghost, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY, const FabArrayBase::CPC *a_cpc=nullptr, bool to_ghost_cells_only=false)
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:2833
MultiArray4< value_type > m_arrays
Definition AMReX_FabArray.H:1347
void AllocFabs(const FabFactory< FAB > &factory, Arena *ar, const Vector< std::string > &tags, bool alloc_single_chunk)
Definition AMReX_FabArray.H:1987
void FillBoundaryAndSync_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3105
Array4< typename FabArray< FAB >::value_type const > const_array(int K, int start_comp) const noexcept
Definition AMReX_FabArray.H:626
void FillBoundaryAndSync_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Definition AMReX_FabArray.H:3112
Array4< typename FabArray< FAB >::value_type > array(int K) noexcept
Definition AMReX_FabArray.H:578
void * m_hp_arrays
Definition AMReX_FabArray.H:1346
ShMem shmem
Definition AMReX_FabArray.H:1400
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:1742
void setFab(int boxno, FAB &&elem)
Explicitly set the Kth FAB in the FabArray to point to elem.
Definition AMReX_FabArray.H:2148
FabArray< FAB > & operator=(FabArray< FAB > &&rhs) noexcept
Definition AMReX_FabArray.H:1868
MultiArray4< value_type const > m_const_arrays
Definition AMReX_FabArray.H:1348
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:873
bool hasEBFabFactory() const noexcept
Definition AMReX_FabArray.H:449
Array4< typename FabArray< FAB >::value_type const > array(int K) const noexcept
Definition AMReX_FabArray.H:572
bool isAllRegular() const noexcept
Definition AMReX_FabArray.H:474
Array4< typename FabArray< FAB >::value_type const > const_array(const MFIter &mfi, int start_comp) const noexcept
Definition AMReX_FabArray.H:620
void plus(value_type val, const Box &region, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2625
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)
void build_arrays() const
Definition AMReX_FabArray.H:1599
void SumBoundary_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3205
void ParallelCopy(const FabArray< FAB > &src, int scomp, int dcomp, int ncomp, const IntVect &snghost, const IntVect &dnghost, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY, const FabArrayBase::CPC *a_cpc=nullptr)
FAB * fabPtr(const MFIter &mfi) noexcept
Return pointer to FAB.
Definition AMReX_FabArray.H:1560
Array4< typename FabArray< FAB >::value_type > array(const MFIter &mfi, int start_comp) noexcept
Definition AMReX_FabArray.H:602
void copyTo(FAB &dest, int scomp, int dcomp, int ncomp, int nghost=0) const
Copy the values contained in the intersection of the num_comp component valid + nghost region of this...
void EnforcePeriodicity(const Periodicity &period)
Fill ghost cells with values from their corresponding cells across periodic boundaries,...
Definition AMReX_FabArray.H:3259
void OverrideSync_finish()
Definition AMReX_FabArray.H:3166
void FillBoundary(int scomp, int ncomp, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3024
MultiArray4< typename FabArray< FAB >::value_type const > const_arrays() const noexcept
Definition AMReX_FabArray.H:646
void prefetchToHost(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:540
FAB & atLocalIdx(int L) noexcept
Return a reference to the FAB associated with local index L.
Definition AMReX_FabArray.H:530
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:1954
F::value_type norminf(FabArray< IFAB > const &mask, int comp, int ncomp, IntVect const &nghost, bool local=false) const
Return infinity norm in masked region.
Definition AMReX_FabArray.H:3545
void ParallelCopy_nowait(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:854
void EnforcePeriodicity(int scomp, int ncomp, const Periodicity &period)
Definition AMReX_FabArray.H:3270
void PC_local_cpu(const CPC &thecpc, FabArray< FAB > const &src, int scomp, int dcomp, int ncomp, CpOp op)
Definition AMReX_PCI.H:6
const FAB & get(int K) const noexcept
Return a constant reference to the FAB associated with the Kth element.
Definition AMReX_FabArray.H:521
void FillBoundary_finish()
FAB const * fabPtr(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:1570
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:896
Array4< typename FabArray< FAB >::value_type > array(int K, int start_comp) noexcept
Definition AMReX_FabArray.H:614
bool isDefined() const
Definition AMReX_FabArray.H:1935
void setVal(value_type val, const Box &region, int nghost)
Set all components in the valid region of each FAB in the FabArray to val, including nghost boundary ...
Definition AMReX_FabArray.H:1767
value_type const * singleChunkPtr() const noexcept
Definition AMReX_FabArray.H:466
~FabArray()
The destructor – deletes all FABs in the array.
Definition AMReX_FabArray.H:1899
Definition AMReX_FabFactory.H:50
virtual AMREX_NODISCARD FabFactory< FAB > * clone() const =0
virtual AMREX_NODISCARD FAB * create(const Box &box, int ncomps, const FabInfo &info, int box_index) const =0
virtual AMREX_NODISCARD Long nBytes(const Box &box, int ncomps, int) const
Definition AMReX_FabFactory.H:64
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:73
const Box & Domain() const noexcept
Returns our rectangular domain.
Definition AMReX_Geometry.H:210
bool isPeriodic(int dir) const noexcept
Is the domain periodic in the specified direction?
Definition AMReX_Geometry.H:331
Definition AMReX_Tuple.H:93
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE 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:441
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE 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:391
AMREX_GPU_HOST_DEVICE static AMREX_FORCE_INLINE 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:670
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int max() const noexcept
maximum (no absolute values) value
Definition AMReX_IntVect.H:212
a one-thingy-per-box distributed object
Definition AMReX_LayoutData.H:13
Definition AMReX_MFIter.H:57
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:141
int index() const noexcept
The index into the underlying BoxArray of the current FAB.
Definition AMReX_MFIter.H:144
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:159
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:27
Long size() const noexcept
Definition AMReX_Vector.H:50
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:237
bool inLaunchRegion() noexcept
Definition AMReX_GpuControl.H:86
bool inNoSyncRegion() noexcept
Definition AMReX_GpuControl.H:146
void htod_memcpy(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:293
void Min(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:152
void Sum(T &v, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:204
void Max(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:126
MPI_Comm CommunicatorSub() noexcept
sub-communicator for current frame
Definition AMReX_ParallelContext.H:70
int MyProc() noexcept
return the rank number local to the current Parallel Context
Definition AMReX_ParallelDescriptor.H:125
int MyTeamLead() noexcept
Definition AMReX_ParallelDescriptor.H:309
int TeamSize() noexcept
Definition AMReX_ParallelDescriptor.H:294
const ProcessTeam & MyTeam() noexcept
Definition AMReX_ParallelDescriptor.H:349
Definition AMReX_Amr.cpp:49
MakeType
Definition AMReX_MakeType.H:7
@ make_alias
Definition AMReX_MakeType.H:7
int nComp(FabArrayBase const &fa)
std::enable_if_t< std::is_integral_v< T > > ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:191
std::unique_ptr< char, TheFaArenaDeleter > TheFaArenaPointer
Definition AMReX_FabArray.H:104
DistributionMapping const & DistributionMap(FabArrayBase const &fa)
IntVect nGrowVect(FabArrayBase const &fa)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE BoxND< dim > convert(const BoxND< dim > &b, const IntVectND< dim > &typ) noexcept
Returns a BoxND with different type.
Definition AMReX_Box.H:1435
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.
Definition AMReX_ParReduce.H:47
void Copy(FabArray< DFAB > &dst, FabArray< SFAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Definition AMReX_FabArray.H:179
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T abs(const GpuComplex< T > &a_z) noexcept
Return the absolute value of a complex number.
Definition AMReX_GpuComplex.H:356
Long nBytesOwned(T const &) noexcept
Definition AMReX_FabArray.H:58
Arena * The_Comms_Arena()
Definition AMReX_Arena.cpp:676
IntVectND< AMREX_SPACEDIM > IntVect
Definition AMReX_BaseFwd.H:30
AMREX_GPU_HOST_DEVICE constexpr GpuTupleElement< I, GpuTuple< Ts... > >::type & get(GpuTuple< Ts... > &tup) noexcept
Definition AMReX_Tuple.H:179
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:127
void setBndry(MF &dst, typename MF::value_type val, int scomp, int ncomp)
dst = val in ghost cells.
Definition AMReX_FabArrayUtility.H:1815
bool TilingIfNotGPU() noexcept
Definition AMReX_MFIter.H:12
void Add(FabArray< FAB > &dst, FabArray< FAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Definition AMReX_FabArray.H:240
Arena * The_Pinned_Arena()
Definition AMReX_Arena.cpp:656
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr const T & max(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:35
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:230
void OverrideSync_finish(FabArray< FAB > &fa)
Definition AMReX_FabArrayUtility.H:1382
void update_fab_stats(Long n, Long s, size_t szt) noexcept
Definition AMReX_BaseFab.cpp:144
void setVal(MF &dst, typename MF::value_type val)
dst = val
Definition AMReX_FabArrayUtility.H:1808
Arena * The_Arena()
Definition AMReX_Arena.cpp:616
BoxArray const & boxArray(FabArrayBase const &fa)
void OverrideSync_nowait(FabArray< FAB > &fa, FabArray< IFAB > const &msk, const Periodicity &period)
Definition AMReX_FabArrayUtility.H:1335
Definition AMReX_TagParallelFor.H:57
Definition AMReX_Array4.H:61
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:108
const FabArrayBase::FB * fb
Definition AMReX_FabArray.H:110
char * the_recv_data
Definition AMReX_FabArray.H:115
Vector< MPI_Request > recv_reqs
Definition AMReX_FabArray.H:120
Vector< char * > recv_data
Definition AMReX_FabArray.H:118
Vector< MPI_Status > recv_stat
Definition AMReX_FabArray.H:121
int scomp
Definition AMReX_FabArray.H:111
Vector< int > recv_from
Definition AMReX_FabArray.H:117
char * the_send_data
Definition AMReX_FabArray.H:116
Vector< MPI_Request > send_reqs
Definition AMReX_FabArray.H:124
Vector< char * > send_data
Definition AMReX_FabArray.H:123
Vector< std::size_t > recv_size
Definition AMReX_FabArray.H:119
int ncomp
Definition AMReX_FabArray.H:112
int tag
Definition AMReX_FabArray.H:125
parallel copy or add
Definition AMReX_FabArrayBase.H:536
Definition AMReX_FabArrayBase.H:471
std::unique_ptr< MapOfCopyComTagContainers > m_RcvTags
Definition AMReX_FabArrayBase.H:477
std::unique_ptr< CopyComTagsContainer > m_LocTags
Definition AMReX_FabArrayBase.H:475
Used by a bunch of routines when communicating via MPI.
Definition AMReX_FabArrayBase.H:194
Box dbox
Definition AMReX_FabArrayBase.H:195
int dstIndex
Definition AMReX_FabArrayBase.H:197
FillBoundary.
Definition AMReX_FabArrayBase.H:487
void recordBuild() noexcept
Definition AMReX_FabArrayBase.H:701
Definition AMReX_FabArray.H:347
FAB value_type
Definition AMReX_FabArray.H:348
for shared memory
Definition AMReX_FabArray.H:1353
ShMem(ShMem &&rhs) noexcept
Definition AMReX_FabArray.H:1367
ShMem() noexcept=default
Long n_values
Definition AMReX_FabArray.H:1394
Long n_points
Definition AMReX_FabArray.H:1395
bool alloc
Definition AMReX_FabArray.H:1393
ShMem & operator=(ShMem &&rhs) noexcept
Definition AMReX_FabArray.H:1378
ShMem(const ShMem &)=delete
Definition AMReX_FabFactory.H:27
FabInfo & SetShared(bool s) noexcept
Definition AMReX_FabFactory.H:37
FabInfo & SetAlloc(bool a) noexcept
Definition AMReX_FabFactory.H:32
FabInfo & SetArena(Arena *ar) noexcept
Definition AMReX_FabFactory.H:42
Definition AMReX_TypeTraits.H:18
FabArray memory allocation information.
Definition AMReX_FabArray.H:66
MFInfo & SetTag(T &&t, Ts &&... ts) noexcept
Definition AMReX_FabArray.H:92
MFInfo & SetTag(const std::string &t) noexcept
Definition AMReX_FabArray.H:86
Arena * arena
Definition AMReX_FabArray.H:70
MFInfo & SetArena(Arena *ar) noexcept
Definition AMReX_FabArray.H:77
MFInfo & SetTag() noexcept
Definition AMReX_FabArray.H:79
bool alloc
Definition AMReX_FabArray.H:68
MFInfo & SetAlloc(bool a) noexcept
Definition AMReX_FabArray.H:73
bool alloc_single_chunk
Definition AMReX_FabArray.H:69
MFInfo & SetAllocSingleChunk(bool a) noexcept
Definition AMReX_FabArray.H:75
Vector< std::string > tags
Definition AMReX_FabArray.H:71
MFInfo & SetTag(const char *t) noexcept
Definition AMReX_FabArray.H:81
Definition AMReX_FabArray.H:152
Array4< T > const *AMREX_RESTRICT dp
Definition AMReX_FabArray.H:166
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Array4< T > const & operator[](int li) const noexcept
Definition AMReX_FabArray.H:154
Array4< T > const *AMREX_RESTRICT hp
Definition AMReX_FabArray.H:168
Definition AMReX_FabArray.H:131
int actual_n_rcvs
Definition AMReX_FabArray.H:137
Vector< std::size_t > recv_size
Definition AMReX_FabArray.H:144
int DC
Definition AMReX_FabArray.H:138
Vector< MPI_Request > send_reqs
Definition AMReX_FabArray.H:146
int tag
Definition AMReX_FabArray.H:136
const FabArray< FAB > * src
Definition AMReX_FabArray.H:134
char * the_recv_data
Definition AMReX_FabArray.H:140
FabArrayBase::CpOp op
Definition AMReX_FabArray.H:135
Vector< MPI_Request > recv_reqs
Definition AMReX_FabArray.H:145
char * the_send_data
Definition AMReX_FabArray.H:141
const FabArrayBase::CPC * cpc
Definition AMReX_FabArray.H:133
Vector< int > recv_from
Definition AMReX_FabArray.H:142
int NC
Definition AMReX_FabArray.H:138
int SC
Definition AMReX_FabArray.H:138
Vector< char * > recv_data
Definition AMReX_FabArray.H:143
void MemoryBarrier() const
memory fence
Definition AMReX_ParallelDescriptor.H:157
const team_t & get() const
Definition AMReX_ParallelDescriptor.H:185
Definition AMReX_FabArray.H:98
char * pointer
Definition AMReX_FabArray.H:99
void operator()(pointer p) const noexcept
Definition AMReX_FabArray.H:100
Struct for holding types.
Definition AMReX_TypeList.H:12