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
1541 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1542 static void Saxpy_Xpay (FabArray<FAB>& y, value_type a1, FabArray<FAB> const& x1,
1543 value_type a2, FabArray<FAB> const& x2,
1544 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1545
1560 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1561 static void Saxpy_Saxpy (FabArray<FAB>& y1, value_type a1, FabArray<FAB> const& x1,
1562 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x2,
1563 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1564
1578 template <class F=FAB, std::enable_if_t<IsBaseFab<F>::value,int> = 0>
1580 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x,
1581 int xcomp, int ycomp, int ncomp, IntVect const& nghost);
1582};
1583
1584
1585#include <AMReX_FabArrayCommI.H>
1586
1587template <class FAB>
1588bool
1589FabArray<FAB>::defined (int K) const noexcept
1590{
1591 int li = localindex(K);
1592 if (li >= 0 && li < static_cast<int>(m_fabs_v.size()) && m_fabs_v[li] != 0) {
1593 return true;
1594 }
1595 else {
1596 return false;
1597 }
1598}
1599
1600template <class FAB>
1601bool
1602FabArray<FAB>::defined (const MFIter& mfi) const noexcept
1603{
1604 int li = mfi.LocalIndex();
1605 if (li < static_cast<int>(m_fabs_v.size()) && m_fabs_v[li] != nullptr) {
1606 return true;
1607 }
1608 else {
1609 return false;
1610 }
1611}
1612
1613template <class FAB>
1614FAB*
1615FabArray<FAB>::fabPtr (const MFIter& mfi) noexcept
1616{
1617 AMREX_ASSERT(mfi.LocalIndex() < indexArray.size());
1618 AMREX_ASSERT(DistributionMap() == mfi.DistributionMap());
1619 int li = mfi.LocalIndex();
1620 return m_fabs_v[li];
1621}
1622
1623template <class FAB>
1624FAB const*
1625FabArray<FAB>::fabPtr (const MFIter& mfi) const noexcept
1626{
1627 AMREX_ASSERT(mfi.LocalIndex() < indexArray.size());
1628 AMREX_ASSERT(DistributionMap() == mfi.DistributionMap());
1629 int li = mfi.LocalIndex();
1630 return m_fabs_v[li];
1631}
1632
1633template <class FAB>
1634FAB*
1636{
1637 int li = localindex(K);
1638 AMREX_ASSERT(li >=0 && li < indexArray.size());
1639 return m_fabs_v[li];
1640}
1641
1642template <class FAB>
1643FAB const*
1644FabArray<FAB>::fabPtr (int K) const noexcept
1645{
1646 int li = localindex(K);
1647 AMREX_ASSERT(li >=0 && li < indexArray.size());
1648 return m_fabs_v[li];
1649}
1650
1651template <class FAB>
1652template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1653void
1655{
1656 using A = Array4<value_type>;
1657 using AC = Array4<value_type const>;
1658 static_assert(sizeof(A) == sizeof(AC), "sizeof(Array4<T>) != sizeof(Array4<T const>)");
1659 if (!m_hp_arrays && local_size() > 0) {
1660 const int n = local_size();
1661#ifdef AMREX_USE_GPU
1662 m_hp_arrays = (void*)The_Pinned_Arena()->alloc(n*2*sizeof(A));
1663 m_dp_arrays = (void*)The_Arena()->alloc(n*2*sizeof(A));
1664#else
1665 m_hp_arrays = (void*)std::malloc(n*2*sizeof(A));
1666#endif
1667 for (int li = 0; li < n; ++li) {
1668 if (m_fabs_v[li]) {
1669 new ((A*)m_hp_arrays+li) A(m_fabs_v[li]->array());
1670 new ((AC*)m_hp_arrays+li+n) AC(m_fabs_v[li]->const_array());
1671 } else {
1672 new ((A*)m_hp_arrays+li) A{};
1673 new ((AC*)m_hp_arrays+li+n) AC{};
1674 }
1675 }
1676 m_arrays.hp = (A*)m_hp_arrays;
1677 m_const_arrays.hp = (AC*)m_hp_arrays + n;
1678#ifdef AMREX_USE_GPU
1679 m_arrays.dp = (A*)m_dp_arrays;
1680 m_const_arrays.dp = (AC*)m_dp_arrays + n;
1681 Gpu::htod_memcpy_async(m_dp_arrays, m_hp_arrays, n*2*sizeof(A));
1682 if (!Gpu::inNoSyncRegion()) {
1684 }
1685#endif
1686 }
1687}
1688
1689template <class FAB>
1690void
1692{
1693#ifdef AMREX_USE_GPU
1694 The_Pinned_Arena()->free(m_hp_arrays);
1695 The_Arena()->free(m_dp_arrays);
1696 m_dp_arrays = nullptr;
1697#else
1698 std::free(m_hp_arrays);
1699#endif
1700 m_hp_arrays = nullptr;
1701 m_arrays.hp = nullptr;
1702 m_const_arrays.hp = nullptr;
1703}
1704
1705template <class FAB>
1707FAB*
1709{
1710 const int li = localindex(K);
1711 if (li >= 0 && li < static_cast<int>(m_fabs_v.size()) && m_fabs_v[li] != nullptr) {
1712 AMREX_ASSERT(m_single_chunk_arena == nullptr);
1713 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
1714 if (nbytes > 0) {
1715 for (auto const& t : m_tags) {
1716 updateMemUsage(t, -nbytes, nullptr);
1717 }
1718 }
1719 return std::exchange(m_fabs_v[li], nullptr);
1720 } else {
1721 return nullptr;
1722 }
1723}
1724
1725template <class FAB>
1727FAB*
1729{
1730 const int li = mfi.LocalIndex();
1731 if (li >= 0 && li < static_cast<int>(m_fabs_v.size()) && m_fabs_v[li] != nullptr) {
1732 AMREX_ASSERT(m_single_chunk_arena == nullptr);
1733 Long nbytes = amrex::nBytesOwned(*m_fabs_v[li]);
1734 if (nbytes > 0) {
1735 for (auto const& t : m_tags) {
1736 updateMemUsage(t, -nbytes, nullptr);
1737 }
1738 }
1739 return std::exchange(m_fabs_v[li], nullptr);
1740 } else {
1741 return nullptr;
1742 }
1743}
1744
1745template <class FAB>
1746void
1748{
1749 if (define_function_called)
1750 {
1751 define_function_called = false;
1752 clearThisBD();
1753 }
1754
1755 Long nbytes = 0L;
1756 for (auto *x : m_fabs_v) {
1757 if (x) {
1758 nbytes += amrex::nBytesOwned(*x);
1759 m_factory->destroy(x);
1760 }
1761 }
1762 m_fabs_v.clear();
1763 clear_arrays();
1764 m_factory.reset();
1765 m_dallocator.m_arena = nullptr;
1766 // no need to clear the non-blocking fillboundary stuff
1767
1768 if (nbytes > 0) {
1769 for (auto const& t : m_tags) {
1770 updateMemUsage(t, -nbytes, nullptr);
1771 }
1772 }
1773
1774 if (m_single_chunk_arena) {
1775 m_single_chunk_arena.reset();
1776 }
1777 m_single_chunk_size = 0;
1778
1779 m_tags.clear();
1780
1782}
1783
1784template <class FAB>
1785template <typename SFAB, typename DFAB,
1786 std::enable_if_t<std::conjunction_v<
1788 std::is_convertible<typename SFAB::value_type,
1789 typename DFAB::value_type>>, int>>
1790void
1791FabArray<FAB>::LocalCopy (FabArray<SFAB> const& src, int scomp, int dcomp, int ncomp,
1792 IntVect const& nghost)
1793{
1794 amrex::Copy(*this, src, scomp, dcomp, ncomp, nghost);
1795}
1796
1797template <class FAB>
1798template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1799void
1800FabArray<FAB>::LocalAdd (FabArray<FAB> const& src, int scomp, int dcomp, int ncomp,
1801 IntVect const& nghost)
1802{
1803 amrex::Add(*this, src, scomp, dcomp, ncomp, nghost);
1804}
1805
1806template <class FAB>
1807template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1808void
1810{
1811 setVal(val,0,n_comp,IntVect(nghost));
1812}
1813
1814template <class FAB>
1815template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1816void
1818{
1819 setVal(val,0,n_comp,nghost);
1820}
1821
1822template <class FAB>
1823template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1824void
1825FabArray<FAB>::setVal (value_type val, const Box& region, int nghost)
1826{
1827 setVal(val,region,0,n_comp,IntVect(nghost));
1828}
1829
1830template <class FAB>
1831template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
1832void
1833FabArray<FAB>::setVal (value_type val, const Box& region, const IntVect& nghost)
1834{
1835 setVal(val,region,0,n_comp,nghost);
1836}
1837
1838template <class FAB>
1840 : shmem()
1841{
1842 m_FA_stats.recordBuild();
1843}
1844
1845template <class FAB>
1847 : m_dallocator(a),
1848 shmem()
1849{
1850 m_FA_stats.recordBuild();
1851}
1852
1853template <class FAB>
1855 const DistributionMapping& dm,
1856 int nvar,
1857 int ngrow,
1858 const MFInfo& info,
1859 const FabFactory<FAB>& factory)
1860 : FabArray<FAB>(bxs,dm,nvar,IntVect(ngrow),info,factory)
1861{}
1862
1863template <class FAB>
1865 const DistributionMapping& dm,
1866 int nvar,
1867 const IntVect& ngrow,
1868 const MFInfo& info,
1869 const FabFactory<FAB>& factory)
1870 : m_factory(factory.clone()),
1871 shmem()
1872{
1874 define(bxs,dm,nvar,ngrow,info,*m_factory);
1875}
1876
1877template <class FAB>
1878FabArray<FAB>::FabArray (const FabArray<FAB>& rhs, MakeType maketype, int scomp, int ncomp)
1879 : m_factory(rhs.Factory().clone()),
1880 shmem()
1881{
1883 define(rhs.boxArray(), rhs.DistributionMap(), ncomp, rhs.nGrowVect(),
1884 MFInfo().SetAlloc(false), *m_factory);
1885
1886 if (maketype == amrex::make_alias)
1887 {
1888 for (int i = 0, n = indexArray.size(); i < n; ++i) {
1889 auto const& rhsfab = *(rhs.m_fabs_v[i]);
1890 m_fabs_v.push_back(m_factory->create_alias(rhsfab, scomp, ncomp));
1891 }
1892 }
1893 else
1894 {
1895 amrex::Abort("FabArray: unknown MakeType");
1896 }
1897}
1898
1899template <class FAB>
1901 : FabArrayBase (static_cast<FabArrayBase&&>(rhs))
1902 , m_factory (std::move(rhs.m_factory))
1903 , m_dallocator (std::move(rhs.m_dallocator))
1904 , m_single_chunk_arena(std::move(rhs.m_single_chunk_arena))
1905 , m_single_chunk_size(std::exchange(rhs.m_single_chunk_size,0))
1906 , define_function_called(rhs.define_function_called)
1907 , m_fabs_v (std::move(rhs.m_fabs_v))
1908#ifdef AMREX_USE_GPU
1909 , m_dp_arrays (std::exchange(rhs.m_dp_arrays, nullptr))
1910#endif
1911 , m_hp_arrays (std::exchange(rhs.m_hp_arrays, nullptr))
1912 , m_arrays (rhs.m_arrays)
1913 , m_const_arrays(rhs.m_const_arrays)
1914 , m_tags (std::move(rhs.m_tags))
1915 , shmem (std::move(rhs.shmem))
1916 // no need to worry about the data used in non-blocking FillBoundary.
1917{
1918 m_FA_stats.recordBuild();
1919 rhs.define_function_called = false; // the responsibility of clear BD has been transferred.
1920 rhs.m_fabs_v.clear(); // clear the data pointers so that rhs.clear does delete them.
1921 rhs.clear();
1922}
1923
1924template <class FAB>
1927{
1928 if (&rhs != this)
1929 {
1930 clear();
1931
1932 FabArrayBase::operator=(static_cast<FabArrayBase&&>(rhs));
1933 m_factory = std::move(rhs.m_factory);
1934 m_dallocator = std::move(rhs.m_dallocator);
1935 m_single_chunk_arena = std::move(rhs.m_single_chunk_arena);
1936 std::swap(m_single_chunk_size, rhs.m_single_chunk_size);
1937 define_function_called = rhs.define_function_called;
1938 std::swap(m_fabs_v, rhs.m_fabs_v);
1939#ifdef AMREX_USE_GPU
1940 std::swap(m_dp_arrays, rhs.m_dp_arrays);
1941#endif
1942 std::swap(m_hp_arrays, rhs.m_hp_arrays);
1943 m_arrays = rhs.m_arrays;
1944 m_const_arrays = rhs.m_const_arrays;
1945 std::swap(m_tags, rhs.m_tags);
1946 shmem = std::move(rhs.shmem);
1947
1948 rhs.define_function_called = false;
1949 rhs.m_fabs_v.clear();
1950 rhs.m_tags.clear();
1951 rhs.clear();
1952 }
1953 return *this;
1954}
1955
1956template <class FAB>
1958{
1959 m_FA_stats.recordDelete();
1960 clear();
1961}
1962
1963template <class FAB>
1964bool
1966{
1967 if (!define_function_called) { return false; }
1968
1969 int isok = 1;
1970
1971 for (MFIter fai(*this); fai.isValid() && isok; ++fai)
1972 {
1973 if (defined(fai))
1974 {
1975 if (get(fai).box() != fabbox(fai.index()))
1976 {
1977 isok = 0;
1978 }
1979 }
1980 else
1981 {
1982 isok = 0;
1983 }
1984 }
1985
1987
1988 return isok == 1;
1989}
1990
1991template <class FAB>
1992bool
1994{
1995 return define_function_called;
1996}
1997
1998template <class FAB>
1999void
2001 const DistributionMapping& dm,
2002 int nvar,
2003 int ngrow,
2004 const MFInfo& info,
2005 const FabFactory<FAB>& a_factory)
2006{
2007 define(bxs,dm,nvar,IntVect(ngrow),info,a_factory);
2008}
2009
2010template <class FAB>
2011void
2013 const DistributionMapping& dm,
2014 int nvar,
2015 const IntVect& ngrow,
2016 const MFInfo& info,
2017 const FabFactory<FAB>& a_factory)
2018{
2019 std::unique_ptr<FabFactory<FAB> > factory(a_factory.clone());
2020
2021 auto *default_arena = m_dallocator.m_arena;
2022 clear();
2023
2024 m_factory = std::move(factory);
2025 m_dallocator.m_arena = info.arena ? info.arena : default_arena;
2026
2027 define_function_called = true;
2028
2029 AMREX_ASSERT(ngrow.allGE(0));
2030 AMREX_ASSERT(boxarray.empty());
2031 FabArrayBase::define(bxs, dm, nvar, ngrow);
2032
2033 addThisBD();
2034
2035 if(info.alloc) {
2036 AllocFabs(*m_factory, m_dallocator.m_arena, info.tags, info.alloc_single_chunk);
2037#ifdef BL_USE_TEAM
2039#endif
2040 }
2041}
2042
2043template <class FAB>
2044void
2046 const Vector<std::string>& tags, bool alloc_single_chunk)
2047{
2048 if (shmem.alloc) { alloc_single_chunk = false; }
2049 if constexpr (!IsBaseFab_v<FAB>) { alloc_single_chunk = false; }
2050
2051 const int n = indexArray.size();
2052 const int nworkers = ParallelDescriptor::TeamSize();
2053 shmem.alloc = (nworkers > 1);
2054
2055 bool alloc = !shmem.alloc;
2056
2057 FabInfo fab_info;
2058 fab_info.SetAlloc(alloc).SetShared(shmem.alloc).SetArena(ar);
2059
2060 if (alloc_single_chunk) {
2061 m_single_chunk_size = 0L;
2062 for (int i = 0; i < n; ++i) {
2063 int K = indexArray[i];
2064 const Box& tmpbox = fabbox(K);
2065 m_single_chunk_size += factory.nBytes(tmpbox, n_comp, K);
2066 }
2067 AMREX_ASSERT(m_single_chunk_size >= 0); // 0 is okay.
2068 m_single_chunk_arena = std::make_unique<detail::SingleChunkArena>(ar, m_single_chunk_size);
2069 fab_info.SetArena(m_single_chunk_arena.get());
2070 }
2071
2072 m_fabs_v.reserve(n);
2073
2074 Long nbytes = 0L;
2075 for (int i = 0; i < n; ++i)
2076 {
2077 int K = indexArray[i];
2078 const Box& tmpbox = fabbox(K);
2079 m_fabs_v.push_back(factory.create(tmpbox, n_comp, fab_info, K));
2080 nbytes += amrex::nBytesOwned(*m_fabs_v.back());
2081 }
2082
2083 m_tags.clear();
2084 m_tags.emplace_back("All");
2085 for (auto const& t : m_region_tag) {
2086 m_tags.push_back(t);
2087 }
2088 for (auto const& t : tags) {
2089 m_tags.push_back(t);
2090 }
2091 for (auto const& t: m_tags) {
2092 updateMemUsage(t, nbytes, ar);
2093 }
2094
2095#ifdef BL_USE_TEAM
2096 if (shmem.alloc)
2097 {
2098 const int teamlead = ParallelDescriptor::MyTeamLead();
2099
2100 shmem.n_values = 0;
2101 shmem.n_points = 0;
2102 Vector<Long> offset(n,0);
2103 Vector<Long> nextoffset(nworkers,-1);
2104 for (int i = 0; i < n; ++i) {
2105 int K = indexArray[i];
2106 int owner = distributionMap[K] - teamlead;
2107 Long s = m_fabs_v[i]->size();
2108 if (ownership[i]) {
2109 shmem.n_values += s;
2110 shmem.n_points += m_fabs_v[i]->numPts();
2111 }
2112 if (nextoffset[owner] < 0) {
2113 offset[i] = 0;
2114 nextoffset[owner] = s;
2115 } else {
2116 offset[i] = nextoffset[owner];
2117 nextoffset[owner] += s;
2118 }
2119 }
2120
2121 size_t bytes = shmem.n_values*sizeof(value_type);
2122
2123 value_type *mfp;
2125
2126#if defined (BL_USE_MPI3)
2127
2128 static MPI_Info info = MPI_INFO_NULL;
2129 if (info == MPI_INFO_NULL) {
2130 MPI_Info_create(&info);
2131 MPI_Info_set(info, "alloc_shared_noncontig", "true");
2132 }
2133
2134 const MPI_Comm& team_comm = ParallelDescriptor::MyTeam().get();
2135
2136 BL_MPI_REQUIRE( MPI_Win_allocate_shared(bytes, sizeof(value_type),
2137 info, team_comm, &mfp, &shmem.win) );
2138
2139 for (int w = 0; w < nworkers; ++w) {
2140 MPI_Aint sz;
2141 int disp;
2142 value_type *dptr = 0;
2143 BL_MPI_REQUIRE( MPI_Win_shared_query(shmem.win, w, &sz, &disp, &dptr) );
2144 // AMREX_ASSERT(disp == sizeof(value_type));
2145 dps.push_back(dptr);
2146 }
2147
2148#else
2149
2150 amrex::Abort("BaseFab::define: to allocate shared memory, USE_MPI3 must be true");
2151
2152#endif
2153
2154 for (int i = 0; i < n; ++i) {
2155 int K = indexArray[i];
2156 int owner = distributionMap[K] - teamlead;
2157 value_type *p = dps[owner] + offset[i];
2158 m_fabs_v[i]->setPtr(p, m_fabs_v[i]->size());
2159 }
2160
2161 for (Long i = 0; i < shmem.n_values; i++, mfp++) {
2162 new (mfp) value_type;
2163 }
2164
2165 amrex::update_fab_stats(shmem.n_points, shmem.n_values, sizeof(value_type));
2166 }
2167#endif
2168}
2169
2170template <class FAB>
2171void
2172FabArray<FAB>::setFab_assert (int K, FAB const& fab) const
2173{
2174 amrex::ignore_unused(K,fab);
2175 AMREX_ASSERT(n_comp == fab.nComp());
2176 AMREX_ASSERT(!boxarray.empty());
2177 AMREX_ASSERT(fab.box() == fabbox(K));
2178 AMREX_ASSERT(distributionMap[K] == ParallelDescriptor::MyProc());
2179 AMREX_ASSERT(m_single_chunk_arena == nullptr);
2180}
2181
2182template <class FAB>
2183void
2184FabArray<FAB>::setFab (int boxno, std::unique_ptr<FAB> elem)
2185{
2186 if (n_comp == 0) {
2187 n_comp = elem->nComp();
2188 }
2189
2190 setFab_assert(boxno, *elem);
2191
2192 if (m_fabs_v.empty()) {
2193 m_fabs_v.resize(indexArray.size(),nullptr);
2194 }
2195
2196 const int li = localindex(boxno);
2197 if (m_fabs_v[li]) {
2198 m_factory->destroy(m_fabs_v[li]);
2199 }
2200 m_fabs_v[li] = elem.release();
2201}
2202
2203template <class FAB>
2204template <class F, std::enable_if_t<std::is_move_constructible_v<F>,int> >
2205void
2206FabArray<FAB>::setFab (int boxno, FAB&& elem)
2207{
2208 if (n_comp == 0) {
2209 n_comp = elem.nComp();
2210 }
2211
2212 setFab_assert(boxno, elem);
2213
2214 if (m_fabs_v.empty()) {
2215 m_fabs_v.resize(indexArray.size(),nullptr);
2216 }
2217
2218 const int li = localindex(boxno);
2219 if (m_fabs_v[li]) {
2220 m_factory->destroy(m_fabs_v[li]);
2221 }
2222 m_fabs_v[li] = new FAB(std::move(elem));
2223}
2224
2225template <class FAB>
2226void
2227FabArray<FAB>::setFab (const MFIter& mfi, std::unique_ptr<FAB> elem)
2228{
2229 if (n_comp == 0) {
2230 n_comp = elem->nComp();
2231 }
2232
2233 setFab_assert(mfi.index(), *elem);
2234
2235 if (m_fabs_v.empty()) {
2236 m_fabs_v.resize(indexArray.size(),nullptr);
2237 }
2238
2239 const int li = mfi.LocalIndex();
2240 if (m_fabs_v[li]) {
2241 m_factory->destroy(m_fabs_v[li]);
2242 }
2243 m_fabs_v[li] = elem.release();
2244}
2245
2246template <class FAB>
2247template <class F, std::enable_if_t<std::is_move_constructible_v<F>,int> >
2248void
2249FabArray<FAB>::setFab (const MFIter& mfi, FAB&& elem)
2250{
2251 if (n_comp == 0) {
2252 n_comp = elem.nComp();
2253 }
2254
2255 setFab_assert(mfi.index(), elem);
2256
2257 if (m_fabs_v.empty()) {
2258 m_fabs_v.resize(indexArray.size(),nullptr);
2259 }
2260
2261 const int li = mfi.LocalIndex();
2262 if (m_fabs_v[li]) {
2263 m_factory->destroy(m_fabs_v[li]);
2264 }
2265 m_fabs_v[li] = new FAB(std::move(elem));
2266}
2267
2268template <class FAB>
2269template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2270void
2272{
2273 setBndry(val, 0, n_comp);
2274}
2275
2276template <class FAB>
2277template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2278void
2280 int strt_comp,
2281 int ncomp)
2282{
2283 if (n_grow.max() > 0)
2284 {
2285#ifdef AMREX_USE_GPU
2286 if (Gpu::inLaunchRegion()) {
2287 bool use_mfparfor = true;
2288 const int nboxes = local_size();
2289 if (nboxes == 1) {
2290 if (boxarray[indexArray[0]].numPts() > Long(65*65*65)) {
2291 use_mfparfor = false;
2292 }
2293 } else {
2294 for (int i = 0; i < nboxes; ++i) {
2295 const Long npts = boxarray[indexArray[i]].numPts();
2296 if (npts >= Long(64*64*64)) {
2297 use_mfparfor = false;
2298 break;
2299 } else if (npts <= Long(17*17*17)) {
2300 break;
2301 }
2302 }
2303 }
2304 const IntVect nghost = n_grow;
2305 if (use_mfparfor) {
2306 auto const& ma = this->arrays();
2307 ParallelFor(*this, nghost,
2308 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2309 {
2310 auto const& a = ma[box_no];
2311 Box vbx(a);
2312 vbx.grow(-nghost);
2313 if (!vbx.contains(i,j,k)) {
2314 for (int n = 0; n < ncomp; ++n) {
2315 a(i,j,k,strt_comp+n) = val;
2316 }
2317 }
2318 });
2320 } else {
2321 using Tag = Array4BoxTag<value_type>;
2322 Vector<Tag> tags;
2323 for (MFIter mfi(*this); mfi.isValid(); ++mfi) {
2324 Box const& vbx = mfi.validbox();
2325 auto const& a = this->array(mfi);
2326
2327 Box b;
2328#if (AMREX_SPACEDIM == 3)
2329 if (nghost[2] > 0) {
2330 b = vbx;
2331 b.setRange(2, vbx.smallEnd(2)-nghost[2], nghost[2]);
2332 b.grow(IntVect(nghost[0],nghost[1],0));
2333 tags.emplace_back(Tag{a, b});
2334 b.shift(2, vbx.length(2)+nghost[2]);
2335 tags.emplace_back(Tag{a, b});
2336 }
2337#endif
2338#if (AMREX_SPACEDIM >= 2)
2339 if (nghost[1] > 0) {
2340 b = vbx;
2341 b.setRange(1, vbx.smallEnd(1)-nghost[1], nghost[1]);
2342 b.grow(0, nghost[0]);
2343 tags.emplace_back(Tag{a, b});
2344 b.shift(1, vbx.length(1)+nghost[1]);
2345 tags.emplace_back(Tag{a, b});
2346 }
2347#endif
2348 if (nghost[0] > 0) {
2349 b = vbx;
2350 b.setRange(0, vbx.smallEnd(0)-nghost[0], nghost[0]);
2351 tags.emplace_back(Tag{a, b});
2352 b.shift(0, vbx.length(0)+nghost[0]);
2353 tags.emplace_back(Tag{a, b});
2354 }
2355 }
2356
2357 ParallelFor(tags, ncomp,
2358 [=] AMREX_GPU_DEVICE (int i, int j, int k, int n, Tag const& tag) noexcept
2359 {
2360 tag.dfab(i,j,k,strt_comp+n) = val;
2361 });
2362 }
2363 } else
2364#endif
2365 {
2366#ifdef AMREX_USE_OMP
2367#pragma omp parallel
2368#endif
2369 for (MFIter fai(*this); fai.isValid(); ++fai)
2370 {
2371 get(fai).template setComplement<RunOn::Host>(val, fai.validbox(), strt_comp, ncomp);
2372 }
2373 }
2374 }
2375}
2376
2377template <class FAB>
2378template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2379void
2381{
2382 setDomainBndry(val, 0, n_comp, geom);
2383}
2384
2385template <class FAB>
2386template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2387void
2389 int strt_comp,
2390 int ncomp,
2391 const Geometry& geom)
2392{
2393 BL_PROFILE("FabArray::setDomainBndry()");
2394
2395 Box domain_box = amrex::convert(geom.Domain(), boxArray().ixType());
2396 for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
2397 if (geom.isPeriodic(idim)) {
2398 int n = domain_box.length(idim);
2399 domain_box.grow(idim, n);
2400 }
2401 }
2402
2403#ifdef AMREX_USE_OMP
2404#pragma omp parallel if (Gpu::notInLaunchRegion())
2405#endif
2406 for (MFIter fai(*this); fai.isValid(); ++fai)
2407 {
2408 const Box& gbx = fai.fabbox();
2409 if (! domain_box.contains(gbx))
2410 {
2411 get(fai).template setComplement<RunOn::Device>(val, domain_box, strt_comp, ncomp);
2412 }
2413 }
2414}
2415
2416template <class FAB>
2417template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
2418typename F::value_type
2419FabArray<FAB>::sum (int comp, IntVect const& nghost, bool local) const
2420{
2421 BL_PROFILE("FabArray::sum()");
2422
2423 using T = typename FAB::value_type;
2424 auto sm = T(0.0);
2425#ifdef AMREX_USE_GPU
2426 if (Gpu::inLaunchRegion()) {
2427 auto const& ma = this->const_arrays();
2428 sm = ParReduce(TypeList<ReduceOpSum>{}, TypeList<T>{}, *this, nghost,
2429 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
2430 -> GpuTuple<T>
2431 {
2432 return ma[box_no](i,j,k,comp);
2433 });
2434 } else
2435#endif
2436 {
2437#ifdef AMREX_USE_OMP
2438#pragma omp parallel if (!system::regtest_reduction) reduction(+:sm)
2439#endif
2440 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi)
2441 {
2442 Box const& bx = mfi.growntilebox(nghost);
2443 auto const& a = this->const_array(mfi);
2444 auto tmp = T(0.0);
2445 AMREX_LOOP_3D(bx, i, j, k,
2446 {
2447 tmp += a(i,j,k,comp);
2448 });
2449 sm += tmp; // Do it this way so that it does not break regression tests.
2450 }
2451 }
2452
2453 if (!local) {
2455 }
2456
2457 return sm;
2458}
2459
2460template <class FAB>
2461void
2462FabArray<FAB>::copyTo (FAB& dest, int nghost) const
2463{
2464 copyTo(dest, 0, 0, dest.nComp(), nghost);
2465}
2466
2467template <class FAB>
2468template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2469void
2471{
2472 setVal(val,0,n_comp,n_grow);
2473}
2474
2475template <class FAB>
2476template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2479{
2480 setVal(val);
2481 return *this;
2482}
2483
2484template <class FAB>
2485template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2486void
2488 int comp,
2489 int ncomp,
2490 int nghost)
2491{
2492 setVal(val,comp,ncomp,IntVect(nghost));
2493}
2494
2495template <class FAB>
2496template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2497void
2499 int comp,
2500 int ncomp,
2501 const IntVect& nghost)
2502{
2503 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2504 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2505
2506 BL_PROFILE("FabArray::setVal()");
2507
2508#ifdef AMREX_USE_GPU
2509 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2510 auto const& fa = this->arrays();
2511 ParallelFor(*this, nghost, ncomp,
2512 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2513 {
2514 fa[box_no](i,j,k,n+comp) = val;
2515 });
2516 if (!Gpu::inNoSyncRegion()) {
2518 }
2519 } else
2520#endif
2521 {
2522#ifdef AMREX_USE_OMP
2523#pragma omp parallel if (Gpu::notInLaunchRegion())
2524#endif
2525 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
2526 {
2527 const Box& bx = fai.growntilebox(nghost);
2528 auto fab = this->array(fai);
2529 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
2530 {
2531 fab(i,j,k,n+comp) = val;
2532 });
2533 }
2534 }
2535}
2536
2537template <class FAB>
2538template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2539void
2541 const Box& region,
2542 int comp,
2543 int ncomp,
2544 int nghost)
2545{
2546 setVal(val,region,comp,ncomp,IntVect(nghost));
2547}
2548
2549template <class FAB>
2550template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2551void
2553 const Box& region,
2554 int comp,
2555 int ncomp,
2556 const IntVect& nghost)
2557{
2558 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2559 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2560
2561 BL_PROFILE("FabArray::setVal(val,region,comp,ncomp,nghost)");
2562
2563#ifdef AMREX_USE_GPU
2564 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2565 auto const& fa = this->arrays();
2566 ParallelFor(*this, nghost, ncomp,
2567 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2568 {
2569 if (region.contains(i,j,k)) {
2570 fa[box_no](i,j,k,n+comp) = val;
2571 }
2572 });
2573 if (!Gpu::inNoSyncRegion()) {
2575 }
2576 } else
2577#endif
2578 {
2579#ifdef AMREX_USE_OMP
2580 AMREX_ALWAYS_ASSERT(!omp_in_parallel());
2581#pragma omp parallel if (Gpu::notInLaunchRegion())
2582#endif
2583 for (MFIter fai(*this,TilingIfNotGPU()); fai.isValid(); ++fai)
2584 {
2585 Box b = fai.growntilebox(nghost) & region;
2586
2587 if (b.ok()) {
2588 auto fab = this->array(fai);
2589 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( b, ncomp, i, j, k, n,
2590 {
2591 fab(i,j,k,n+comp) = val;
2592 });
2593 }
2594 }
2595 }
2596}
2597
2598template <class FAB>
2599template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
2600void
2601FabArray<FAB>::abs (int comp, int ncomp, int nghost)
2602{
2603 abs(comp, ncomp, IntVect(nghost));
2604}
2605
2606template <class FAB>
2607template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2608void
2609FabArray<FAB>::abs (int comp, int ncomp, const IntVect& nghost)
2610{
2611 AMREX_ASSERT(nghost.allGE(0) && nghost.allLE(n_grow));
2612 AMREX_ALWAYS_ASSERT(comp+ncomp <= n_comp);
2613 BL_PROFILE("FabArray::abs()");
2614
2615#ifdef AMREX_USE_GPU
2616 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2617 auto const& fa = this->arrays();
2618 ParallelFor(*this, nghost, ncomp,
2619 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2620 {
2621 fa[box_no](i,j,k,n+comp) = std::abs(fa[box_no](i,j,k,n+comp));
2622 });
2623 if (!Gpu::inNoSyncRegion()) {
2625 }
2626 } else
2627#endif
2628 {
2629#ifdef AMREX_USE_OMP
2630#pragma omp parallel if (Gpu::notInLaunchRegion())
2631#endif
2632 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2633 {
2634 const Box& bx = mfi.growntilebox(nghost);
2635 auto fab = this->array(mfi);
2636 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
2637 {
2638 fab(i,j,k,n+comp) = std::abs(fab(i,j,k,n+comp));
2639 });
2640 }
2641 }
2642}
2643
2644template <class FAB>
2645template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2646void
2647FabArray<FAB>::plus (value_type val, int comp, int num_comp, int nghost)
2648{
2649 BL_PROFILE("FabArray::plus()");
2650
2651#ifdef AMREX_USE_GPU
2652 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2653 auto const& fa = this->arrays();
2654 ParallelFor(*this, IntVect(nghost), num_comp,
2655 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2656 {
2657 fa[box_no](i,j,k,n+comp) += val;
2658 });
2659 if (!Gpu::inNoSyncRegion()) {
2661 }
2662 } else
2663#endif
2664 {
2665#ifdef AMREX_USE_OMP
2666#pragma omp parallel if (Gpu::notInLaunchRegion())
2667#endif
2668 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2669 {
2670 const Box& bx = mfi.growntilebox(nghost);
2671 auto fab = this->array(mfi);
2672 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2673 {
2674 fab(i,j,k,n+comp) += val;
2675 });
2676 }
2677 }
2678}
2679
2680template <class FAB>
2681template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2682void
2683FabArray<FAB>::plus (value_type val, const Box& region, int comp, int num_comp, int nghost)
2684{
2685 BL_PROFILE("FabArray::plus(val, region, comp, num_comp, nghost)");
2686
2687#ifdef AMREX_USE_GPU
2688 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2689 auto const& fa = this->arrays();
2690 ParallelFor(*this, IntVect(nghost), num_comp,
2691 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2692 {
2693 if (region.contains(i,j,k)) {
2694 fa[box_no](i,j,k,n+comp) += val;
2695 }
2696 });
2697 if (!Gpu::inNoSyncRegion()) {
2699 }
2700 } else
2701#endif
2702 {
2703#ifdef AMREX_USE_OMP
2704#pragma omp parallel if (Gpu::notInLaunchRegion())
2705#endif
2706 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2707 {
2708 const Box& bx = mfi.growntilebox(nghost) & region;
2709 if (bx.ok()) {
2710 auto fab = this->array(mfi);
2711 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2712 {
2713 fab(i,j,k,n+comp) += val;
2714 });
2715 }
2716 }
2717 }
2718}
2719
2720template <class FAB>
2721template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2722void
2723FabArray<FAB>::mult (value_type val, int comp, int num_comp, int nghost)
2724{
2725 BL_PROFILE("FabArray::mult()");
2726
2727#ifdef AMREX_USE_GPU
2728 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2729 auto const& fa = this->arrays();
2730 ParallelFor(*this, IntVect(nghost), num_comp,
2731 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2732 {
2733 fa[box_no](i,j,k,n+comp) *= val;
2734 });
2735 if (!Gpu::inNoSyncRegion()) {
2737 }
2738 } else
2739#endif
2740 {
2741#ifdef AMREX_USE_OMP
2742#pragma omp parallel if (Gpu::notInLaunchRegion())
2743#endif
2744 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2745 {
2746 const Box& bx = mfi.growntilebox(nghost);
2747 auto fab = this->array(mfi);
2748 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2749 {
2750 fab(i,j,k,n+comp) *= val;
2751 });
2752 }
2753 }
2754}
2755
2756template <class FAB>
2757template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2758void
2759FabArray<FAB>::mult (value_type val, const Box& region, int comp, int num_comp, int nghost)
2760{
2761 BL_PROFILE("FabArray::mult(val, region, comp, num_comp, nghost)");
2762
2763#ifdef AMREX_USE_GPU
2764 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2765 auto const& fa = this->arrays();
2766 ParallelFor(*this, IntVect(nghost), num_comp,
2767 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2768 {
2769 if (region.contains(i,j,k)) {
2770 fa[box_no](i,j,k,n+comp) *= val;
2771 }
2772 });
2773 if (!Gpu::inNoSyncRegion()) {
2775 }
2776 } else
2777#endif
2778 {
2779#ifdef AMREX_USE_OMP
2780#pragma omp parallel if (Gpu::notInLaunchRegion())
2781#endif
2782 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2783 {
2784 const Box& bx = mfi.growntilebox(nghost) & region;
2785 if (bx.ok()) {
2786 auto fab = this->array(mfi);
2787 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2788 {
2789 fab(i,j,k,n+comp) *= val;
2790 });
2791 }
2792 }
2793 }
2794}
2795
2796template <class FAB>
2797template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2798void
2799FabArray<FAB>::invert (value_type numerator, int comp, int num_comp, int nghost)
2800{
2801 BL_PROFILE("FabArray::invert()");
2802
2803#ifdef AMREX_USE_GPU
2804 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2805 auto const& fa = this->arrays();
2806 ParallelFor(*this, IntVect(nghost), num_comp,
2807 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2808 {
2809 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
2810 });
2811 if (!Gpu::inNoSyncRegion()) {
2813 }
2814 } else
2815#endif
2816 {
2817#ifdef AMREX_USE_OMP
2818#pragma omp parallel if (Gpu::notInLaunchRegion())
2819#endif
2820 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2821 {
2822 const Box& bx = mfi.growntilebox(nghost);
2823 auto fab = this->array(mfi);
2824 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2825 {
2826 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
2827 });
2828 }
2829 }
2830}
2831
2832template <class FAB>
2833template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
2834void
2835FabArray<FAB>::invert (value_type numerator, const Box& region, int comp, int num_comp, int nghost)
2836{
2837 BL_PROFILE("FabArray::invert(numerator, region, comp, num_comp, nghost)");
2838
2839#ifdef AMREX_USE_GPU
2840 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
2841 auto const& fa = this->arrays();
2842 ParallelFor(*this, IntVect(nghost), num_comp,
2843 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2844 {
2845 if (region.contains(i,j,k)) {
2846 fa[box_no](i,j,k,n+comp) = numerator / fa[box_no](i,j,k,n+comp);
2847 }
2848 });
2849 if (!Gpu::inNoSyncRegion()) {
2851 }
2852 } else
2853#endif
2854 {
2855#ifdef AMREX_USE_OMP
2856#pragma omp parallel if (Gpu::notInLaunchRegion())
2857#endif
2858 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2859 {
2860 const Box& bx = mfi.growntilebox(nghost) & region;
2861 if (bx.ok()) {
2862 auto fab = this->array(mfi);
2863 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, num_comp, i, j, k, n,
2864 {
2865 fab(i,j,k,n+comp) = numerator / fab(i,j,k,n+comp);
2866 });
2867 }
2868 }
2869 }
2870}
2871
2872template <class FAB>
2873void
2875{
2876 clearThisBD(); // The new boxarray will have a different ID.
2877 boxarray.shift(v);
2878 addThisBD();
2879#ifdef AMREX_USE_OMP
2880#pragma omp parallel
2881#endif
2882 for (MFIter fai(*this); fai.isValid(); ++fai)
2883 {
2884 get(fai).shift(v);
2885 }
2886 clear_arrays();
2887}
2888
2889template <class FAB>
2890template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
2892 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
2893{
2894 AMREX_ASSERT(y.boxArray() == x.boxArray());
2895 AMREX_ASSERT(y.distributionMap == x.distributionMap);
2896 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
2897
2898 BL_PROFILE("FabArray::Saxpy()");
2899
2900#ifdef AMREX_USE_GPU
2902 auto const& yma = y.arrays();
2903 auto const& xma = x.const_arrays();
2904 ParallelFor(y, nghost, ncomp,
2905 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2906 {
2907 yma[box_no](i,j,k,ycomp+n) += a * xma[box_no](i,j,k,xcomp+n);
2908 });
2909 if (!Gpu::inNoSyncRegion()) {
2911 }
2912 } else
2913#endif
2914 {
2915#ifdef AMREX_USE_OMP
2916#pragma omp parallel if (Gpu::notInLaunchRegion())
2917#endif
2918 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2919 {
2920 const Box& bx = mfi.growntilebox(nghost);
2921
2922 if (bx.ok()) {
2923 auto const& xfab = x.const_array(mfi);
2924 auto const& yfab = y.array(mfi);
2925 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
2926 {
2927 yfab(i,j,k,ycomp+n) += a * xfab(i,j,k,xcomp+n);
2928 });
2929 }
2930 }
2931 }
2932}
2933
2934template <class FAB>
2935template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
2936void
2938 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
2939{
2940 AMREX_ASSERT(y.boxArray() == x.boxArray());
2941 AMREX_ASSERT(y.distributionMap == x.distributionMap);
2942 AMREX_ASSERT(y.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost));
2943
2944 BL_PROFILE("FabArray::Xpay()");
2945
2946#ifdef AMREX_USE_GPU
2948 auto const& yfa = y.arrays();
2949 auto const& xfa = x.const_arrays();
2950 ParallelFor(y, nghost, ncomp,
2951 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
2952 {
2953 yfa[box_no](i,j,k,n+ycomp) = xfa[box_no](i,j,k,n+xcomp)
2954 + a * yfa[box_no](i,j,k,n+ycomp);
2955 });
2956 if (!Gpu::inNoSyncRegion()) {
2958 }
2959 } else
2960#endif
2961 {
2962#ifdef AMREX_USE_OMP
2963#pragma omp parallel if (Gpu::notInLaunchRegion())
2964#endif
2965 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
2966 {
2967 const Box& bx = mfi.growntilebox(nghost);
2968 auto const& xFab = x.const_array(mfi);
2969 auto const& yFab = y.array(mfi);
2970 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
2971 {
2972 yFab(i,j,k,n+ycomp) = xFab(i,j,k,n+xcomp)
2973 + a * yFab(i,j,k,n+ycomp);
2974 });
2975 }
2976 }
2977}
2978
2979template <class FAB>
2980template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
2982 value_type a2, FabArray<FAB> const& x2,
2983 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
2984{
2985 AMREX_ASSERT(y.boxArray() == x1.boxArray() &&
2986 y.boxArray() == x2.boxArray() &&
2989 y.nGrowVect().allGE(nghost) &&
2990 x1.nGrowVect().allGE(nghost) &&
2991 x2.nGrowVect().allGE(nghost));
2992
2993 BL_PROFILE("FabArray::Saxpy_Xpay()");
2994
2995#ifdef AMREX_USE_GPU
2997 auto const& yma = y.arrays();
2998 auto const& xma1 = x1.const_arrays();
2999 auto const& xma2 = x2.const_arrays();
3000 ParallelFor(y, nghost, ncomp,
3001 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3002 {
3003 yma[box_no](i,j,k,ycomp+n) = xma2[box_no](i,j,k,xcomp+n)
3004 + a2 * (yma [box_no](i,j,k,ycomp+n)
3005 + a1 * xma1[box_no](i,j,k,xcomp+n));
3006 });
3007 if (!Gpu::inNoSyncRegion()) {
3009 }
3010 } else
3011#endif
3012 {
3013#ifdef AMREX_USE_OMP
3014#pragma omp parallel if (Gpu::notInLaunchRegion())
3015#endif
3016 for (MFIter mfi(y,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3017 {
3018 const Box& bx = mfi.growntilebox(nghost);
3019
3020 if (bx.ok()) {
3021 auto const& xfab1 = x1.const_array(mfi);
3022 auto const& xfab2 = x2.const_array(mfi);
3023 auto const& yfab = y.array(mfi);
3024 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3025 {
3026 yfab(i,j,k,ycomp+n) = xfab2(i,j,k,xcomp+n)
3027 + a2 * (yfab (i,j,k,ycomp+n)
3028 + a1 * xfab1(i,j,k,xcomp+n));
3029 });
3030 }
3031 }
3032 }
3033}
3034
3035template <class FAB>
3036template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3038 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x2,
3039 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3040{
3041 AMREX_ASSERT(y1.boxArray() == y2.boxArray() &&
3042 y1.boxArray() == x1.boxArray() &&
3043 y1.boxArray() == x2.boxArray() &&
3047 y1.nGrowVect().allGE(nghost) &&
3048 y2.nGrowVect().allGE(nghost) &&
3049 x1.nGrowVect().allGE(nghost) &&
3050 x2.nGrowVect().allGE(nghost));
3051
3052 BL_PROFILE("FabArray::Saxpy_Saxpy()");
3053
3054#ifdef AMREX_USE_GPU
3055 if (Gpu::inLaunchRegion() && y1.isFusingCandidate()) {
3056 auto const& y1ma = y1.arrays();
3057 auto const& x1ma = x1.const_arrays();
3058 auto const& y2ma = y2.arrays();
3059 auto const& x2ma = x2.const_arrays();
3060 ParallelFor(y1, nghost, ncomp,
3061 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3062 {
3063 y1ma[box_no](i,j,k,ycomp+n) += a1 * x1ma[box_no](i,j,k,xcomp+n);
3064 y2ma[box_no](i,j,k,ycomp+n) += a2 * x2ma[box_no](i,j,k,xcomp+n);
3065 });
3066 if (!Gpu::inNoSyncRegion()) {
3068 }
3069 } else
3070#endif
3071 {
3072#ifdef AMREX_USE_OMP
3073#pragma omp parallel if (Gpu::notInLaunchRegion())
3074#endif
3075 for (MFIter mfi(y1,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3076 {
3077 const Box& bx = mfi.growntilebox(nghost);
3078
3079 if (bx.ok()) {
3080 auto const& x1fab = x1.const_array(mfi);
3081 auto const& y1fab = y1.array(mfi);
3082 auto const& x2fab = x2.const_array(mfi);
3083 auto const& y2fab = y2.array(mfi);
3084 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3085 {
3086 y1fab(i,j,k,ycomp+n) += a1 * x1fab(i,j,k,xcomp+n);
3087 y2fab(i,j,k,ycomp+n) += a2 * x2fab(i,j,k,xcomp+n);
3088 });
3089 }
3090 }
3091 }
3092}
3093
3094template <class FAB>
3095template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3097 FabArray<FAB>& y2, value_type a2, FabArray<FAB> const& x,
3098 int xcomp, int ycomp, int ncomp, IntVect const& nghost)
3099{
3100 AMREX_ASSERT(y1.boxArray() == y2.boxArray() &&
3101 y1.boxArray() == x.boxArray() &&
3103 y1.distributionMap == x.distributionMap &&
3104 y1.nGrowVect().allGE(nghost) &&
3105 y2.nGrowVect().allGE(nghost) &&
3106 x.nGrowVect().allGE(nghost));
3107
3108 BL_PROFILE("FabArray::Saypy_Saxpy()");
3109
3110#ifdef AMREX_USE_GPU
3111 if (Gpu::inLaunchRegion() && y1.isFusingCandidate()) {
3112 auto const& y1ma = y1.arrays();
3113 auto const& y2ma = y2.arrays();
3114 auto const& xma = x.const_arrays();
3115 ParallelFor(y1, nghost, ncomp,
3116 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3117 {
3118 y1ma[box_no](i,j,k,ycomp+n) += a1 * y2ma[box_no](i,j,k,ycomp+n);
3119 y2ma[box_no](i,j,k,ycomp+n) += a2 * xma[box_no](i,j,k,xcomp+n);
3120 });
3121 if (!Gpu::inNoSyncRegion()) {
3123 }
3124 } else
3125#endif
3126 {
3127#ifdef AMREX_USE_OMP
3128#pragma omp parallel if (Gpu::notInLaunchRegion())
3129#endif
3130 for (MFIter mfi(y1,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3131 {
3132 const Box& bx = mfi.growntilebox(nghost);
3133
3134 if (bx.ok()) {
3135 auto const& xfab = x.const_array(mfi);
3136 auto const& y1fab = y1.array(mfi);
3137 auto const& y2fab = y2.array(mfi);
3138 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, ncomp, i, j, k, n,
3139 {
3140 y1fab(i,j,k,ycomp+n) += a1 * y2fab(i,j,k,ycomp+n);
3141 y2fab(i,j,k,ycomp+n) += a2 * xfab(i,j,k,xcomp+n);
3142 });
3143 }
3144 }
3145 }
3146}
3147
3148template <class FAB>
3149template <class F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3150void
3152 value_type a, const FabArray<FAB>& x, int xcomp,
3153 value_type b, const FabArray<FAB>& y, int ycomp,
3154 int dstcomp, int numcomp, const IntVect& nghost)
3155{
3156 AMREX_ASSERT(dst.boxArray() == x.boxArray());
3157 AMREX_ASSERT(dst.distributionMap == x.distributionMap);
3158 AMREX_ASSERT(dst.boxArray() == y.boxArray());
3160 AMREX_ASSERT(dst.nGrowVect().allGE(nghost) && x.nGrowVect().allGE(nghost) && y.nGrowVect().allGE(nghost));
3161
3162 BL_PROFILE("FabArray::LinComb()");
3163
3164#ifdef AMREX_USE_GPU
3165 if (Gpu::inLaunchRegion() && dst.isFusingCandidate()) {
3166 auto const& dstma = dst.arrays();
3167 auto const& xma = x.const_arrays();
3168 auto const& yma = y.const_arrays();
3169 ParallelFor(dst, nghost, numcomp,
3170 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3171 {
3172 dstma[box_no](i,j,k,dstcomp+n) = a*xma[box_no](i,j,k,xcomp+n)
3173 + b*yma[box_no](i,j,k,ycomp+n);
3174 });
3175 if (!Gpu::inNoSyncRegion()) {
3177 }
3178 } else
3179#endif
3180 {
3181#ifdef AMREX_USE_OMP
3182#pragma omp parallel if (Gpu::notInLaunchRegion())
3183#endif
3184 for (MFIter mfi(dst,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3185 {
3186 const Box& bx = mfi.growntilebox(nghost);
3187 auto const& xfab = x.const_array(mfi);
3188 auto const& yfab = y.const_array(mfi);
3189 auto const& dfab = dst.array(mfi);
3190 AMREX_HOST_DEVICE_PARALLEL_FOR_4D( bx, numcomp, i, j, k, n,
3191 {
3192 dfab(i,j,k,dstcomp+n) = a*xfab(i,j,k,xcomp+n) + b*yfab(i,j,k,ycomp+n);
3193 });
3194 }
3195 }
3196}
3197
3198template <class FAB>
3199template <typename BUF>
3200void
3202{
3203 BL_PROFILE("FabArray::FillBoundary()");
3204 if ( n_grow.max() > 0 ) {
3205 FillBoundary_nowait<BUF>(0, nComp(), n_grow, Periodicity::NonPeriodic(), cross);
3206 FillBoundary_finish<BUF>();
3207 }
3208}
3209
3210template <class FAB>
3211template <typename BUF>
3212void
3213FabArray<FAB>::FillBoundary (const Periodicity& period, bool cross)
3214{
3215 BL_PROFILE("FabArray::FillBoundary()");
3216 if ( n_grow.max() > 0 ) {
3217 FillBoundary_nowait<BUF>(0, nComp(), n_grow, period, cross);
3218 FillBoundary_finish<BUF>();
3219 }
3220}
3221
3222template <class FAB>
3223template <typename BUF>
3224void
3225FabArray<FAB>::FillBoundary (const IntVect& nghost, const Periodicity& period, bool cross)
3226{
3227 BL_PROFILE("FabArray::FillBoundary()");
3229 "FillBoundary: asked to fill more ghost cells than we have");
3230 if ( nghost.max() > 0 ) {
3231 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3232 FillBoundary_finish<BUF>();
3233 }
3234}
3235
3236template <class FAB>
3237template <typename BUF>
3238void
3239FabArray<FAB>::FillBoundary (int scomp, int ncomp, bool cross)
3240{
3241 BL_PROFILE("FabArray::FillBoundary()");
3242 if ( n_grow.max() > 0 ) {
3243 FillBoundary_nowait<BUF>(scomp, ncomp, n_grow, Periodicity::NonPeriodic(), cross);
3244 FillBoundary_finish<BUF>();
3245 }
3246}
3247
3248template <class FAB>
3249template <typename BUF>
3250void
3251FabArray<FAB>::FillBoundary (int scomp, int ncomp, const Periodicity& period, bool cross)
3252{
3253 BL_PROFILE("FabArray::FillBoundary()");
3254 if ( n_grow.max() > 0 ) {
3255 FillBoundary_nowait<BUF>(scomp, ncomp, n_grow, period, cross);
3256 FillBoundary_finish<BUF>();
3257 }
3258}
3259
3260template <class FAB>
3261template <typename BUF>
3262void
3263FabArray<FAB>::FillBoundary (int scomp, int ncomp, const IntVect& nghost,
3264 const Periodicity& period, bool cross)
3265{
3266 BL_PROFILE("FabArray::FillBoundary()");
3268 "FillBoundary: asked to fill more ghost cells than we have");
3269 if ( nghost.max() > 0 ) {
3270 FillBoundary_nowait<BUF>(scomp, ncomp, nghost, period, cross);
3271 FillBoundary_finish<BUF>();
3272 }
3273}
3274
3275template <class FAB>
3276template <typename BUF>
3277void
3279{
3280 FillBoundary_nowait<BUF>(0, nComp(), nGrowVect(), Periodicity::NonPeriodic(), cross);
3281}
3282
3283template <class FAB>
3284template <typename BUF>
3285void
3287{
3288 FillBoundary_nowait<BUF>(0, nComp(), nGrowVect(), period, cross);
3289}
3290
3291template <class FAB>
3292template <typename BUF>
3293void
3294FabArray<FAB>::FillBoundary_nowait (const IntVect& nghost, const Periodicity& period, bool cross)
3295{
3296 FillBoundary_nowait<BUF>(0, nComp(), nghost, period, cross);
3297}
3298
3299template <class FAB>
3300template <typename BUF>
3301void
3302FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, bool cross)
3303{
3304 FillBoundary_nowait<BUF>(scomp, ncomp, nGrowVect(), Periodicity::NonPeriodic(), cross);
3305}
3306
3307template <class FAB>
3308void
3310{
3311 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3312 if (n_grow.max() > 0 || !is_cell_centered()) {
3313 FillBoundaryAndSync_nowait(0, nComp(), n_grow, period);
3314 FillBoundaryAndSync_finish();
3315 }
3316}
3317
3318template <class FAB>
3319void
3320FabArray<FAB>::FillBoundaryAndSync (int scomp, int ncomp, const IntVect& nghost,
3321 const Periodicity& period)
3322{
3323 BL_PROFILE("FabArray::FillBoundaryAndSync()");
3324 if (nghost.max() > 0 || !is_cell_centered()) {
3325 FillBoundaryAndSync_nowait(scomp, ncomp, nghost, period);
3326 FillBoundaryAndSync_finish();
3327 }
3328}
3329
3330template <class FAB>
3331void
3333{
3334 FillBoundaryAndSync_nowait(0, nComp(), nGrowVect(), period);
3335}
3336
3337template <class FAB>
3338void
3339FabArray<FAB>::FillBoundaryAndSync_nowait (int scomp, int ncomp, const IntVect& nghost,
3340 const Periodicity& period)
3341{
3342 BL_PROFILE("FillBoundaryAndSync_nowait()");
3343 FBEP_nowait(scomp, ncomp, nghost, period, false, false, true);
3344}
3345
3346template <class FAB>
3347void
3349{
3350 BL_PROFILE("FillBoundaryAndSync_finish()");
3351 FillBoundary_finish();
3352}
3353
3354template <class FAB>
3355void
3357{
3358 BL_PROFILE("FAbArray::OverrideSync()");
3359 if (!is_cell_centered()) {
3360 OverrideSync_nowait(0, nComp(), period);
3362 }
3363}
3364
3365template <class FAB>
3366void
3367FabArray<FAB>::OverrideSync (int scomp, int ncomp, const Periodicity& period)
3368{
3369 BL_PROFILE("FAbArray::OverrideSync()");
3370 if (!is_cell_centered()) {
3371 OverrideSync_nowait(scomp, ncomp, period);
3373 }
3374}
3375
3376template <class FAB>
3377void
3379{
3380 OverrideSync_nowait(0, nComp(), period);
3381}
3382
3383template <class FAB>
3384void
3385FabArray<FAB>::OverrideSync_nowait (int scomp, int ncomp, const Periodicity& period)
3386{
3387 BL_PROFILE("OverrideSync_nowait()");
3388 FBEP_nowait(scomp, ncomp, IntVect(0), period, false, false, true);
3389}
3390
3391template <class FAB>
3392void
3394{
3395 BL_PROFILE("OverrideSync_finish()");
3396 FillBoundary_finish();
3397}
3398
3399template <class FAB>
3400void
3402{
3403 SumBoundary(0, n_comp, IntVect(0), period);
3404}
3405
3406template <class FAB>
3407void
3408FabArray<FAB>::SumBoundary (int scomp, int ncomp, const Periodicity& period)
3409{
3410 SumBoundary(scomp, ncomp, IntVect(0), period);
3411}
3412
3413template <class FAB>
3414void
3415FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period)
3416{
3417 SumBoundary(scomp, ncomp, this->nGrowVect(), nghost, period);
3418}
3419
3420template <class FAB>
3421void
3422FabArray<FAB>::SumBoundary (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period)
3423{
3424 BL_PROFILE("FabArray<FAB>::SumBoundary()");
3425
3426 SumBoundary_nowait(scomp, ncomp, src_nghost, dst_nghost, period);
3427 SumBoundary_finish();
3428}
3429
3430template <class FAB>
3431void
3433{
3434 SumBoundary_nowait(0, n_comp, IntVect(0), period);
3435}
3436
3437template <class FAB>
3438void
3439FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, const Periodicity& period)
3440{
3441 SumBoundary_nowait(scomp, ncomp, IntVect(0), period);
3442}
3443
3444template <class FAB>
3445void
3446FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& nghost, const Periodicity& period)
3447{
3448 SumBoundary_nowait(scomp, ncomp, this->nGrowVect(), nghost, period);
3449}
3450
3451template <class FAB>
3452void
3453FabArray<FAB>::SumBoundary_nowait (int scomp, int ncomp, IntVect const& src_nghost, IntVect const& dst_nghost, const Periodicity& period)
3454{
3455 BL_PROFILE("FabArray<FAB>::SumBoundary_nowait()");
3456
3457 if ( n_grow == IntVect::TheZeroVector() && boxArray().ixType().cellCentered()) { return; }
3458
3459 AMREX_ALWAYS_ASSERT(src_nghost.allLE(n_grow));
3460
3461 auto* tmp = new FabArray<FAB>( boxArray(), DistributionMap(), ncomp, src_nghost, MFInfo(), Factory() );
3462 amrex::Copy(*tmp, *this, scomp, 0, ncomp, src_nghost);
3463 this->setVal(typename FAB::value_type(0), scomp, ncomp, dst_nghost);
3464 this->ParallelCopy_nowait(*tmp,0,scomp,ncomp,src_nghost,dst_nghost,period,FabArrayBase::ADD);
3465
3466 // All local. Operation complete.
3467 if (!this->pcd) { delete tmp; }
3468}
3469
3470template <class FAB>
3471void
3473{
3474 BL_PROFILE("FabArray<FAB>::SumBoundary_finish()");
3475
3476 // If pcd doesn't exist, ParallelCopy was all local and operation was fully completed in "SumBoundary_nowait".
3477 if ( (n_grow == IntVect::TheZeroVector() && boxArray().ixType().cellCentered()) || !(this->pcd) ) { return; }
3478
3479 auto* tmp = const_cast<FabArray<FAB>*> (this->pcd->src);
3480 this->ParallelCopy_finish();
3481 delete tmp;
3482}
3483
3484template <class FAB>
3485void
3487{
3488 BL_PROFILE("FabArray::EnforcePeriodicity");
3489 if (period.isAnyPeriodic()) {
3490 FBEP_nowait(0, nComp(), nGrowVect(), period, false, true);
3491 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3492 }
3493}
3494
3495template <class FAB>
3496void
3497FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const Periodicity& period)
3498{
3499 BL_PROFILE("FabArray::EnforcePeriodicity");
3500 if (period.isAnyPeriodic()) {
3501 FBEP_nowait(scomp, ncomp, nGrowVect(), period, false, true);
3502 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3503 }
3504}
3505
3506template <class FAB>
3507void
3508FabArray<FAB>::EnforcePeriodicity (int scomp, int ncomp, const IntVect& nghost,
3509 const Periodicity& period)
3510{
3511 BL_PROFILE("FabArray::EnforcePeriodicity");
3512 if (period.isAnyPeriodic()) {
3513 FBEP_nowait(scomp, ncomp, nghost, period, false, true);
3514 FillBoundary_finish(); // unsafe unless isAnyPeriodic()
3515 }
3516}
3517
3518template <class FAB>
3519template <typename BUF>
3520void
3521FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const Periodicity& period, bool cross)
3522{
3523 FBEP_nowait<BUF>(scomp, ncomp, nGrowVect(), period, cross);
3524}
3525
3526template <class FAB>
3527template <typename BUF>
3528void
3529FabArray<FAB>::FillBoundary_nowait (int scomp, int ncomp, const IntVect& nghost,
3530 const Periodicity& period, bool cross)
3531{
3532 FBEP_nowait<BUF>(scomp, ncomp, nghost, period, cross);
3533}
3534
3535template <class FAB>
3536template <class F, std::enable_if_t<IsBaseFab<F>::value,int>Z>
3537void
3538FabArray<FAB>::BuildMask (const Box& phys_domain, const Periodicity& period,
3539 value_type covered, value_type notcovered,
3540 value_type physbnd, value_type interior)
3541{
3542 BL_PROFILE("FabArray::BuildMask()");
3543
3544 int ncomp = this->nComp();
3545 const IntVect& ngrow = this->nGrowVect();
3546
3547 Box domain = amrex::convert(phys_domain, boxArray().ixType());
3548 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
3549 if (period.isPeriodic(i)) {
3550 domain.grow(i, ngrow[i]);
3551 }
3552 }
3553
3554#ifdef AMREX_USE_GPU
3555 if (Gpu::inLaunchRegion() && this->isFusingCandidate()) {
3556 auto const& fa = this->arrays();
3557 ParallelFor(*this, ngrow, ncomp,
3558 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept
3559 {
3560 auto const& fab = fa[box_no];
3561 Box vbx(fab);
3562 vbx.grow(-ngrow);
3563 if (vbx.contains(i,j,k)) {
3564 fab(i,j,k,n) = interior;
3565 } else if (domain.contains(i,j,k)) {
3566 fab(i,j,k,n) = notcovered;
3567 } else {
3568 fab(i,j,k,n) = physbnd;
3569 }
3570 });
3571 if (!Gpu::inNoSyncRegion()) {
3573 }
3574 } else
3575#endif
3576 {
3577#ifdef AMREX_USE_OMP
3578#pragma omp parallel if (Gpu::notInLaunchRegion())
3579#endif
3580 for (MFIter mfi(*this,TilingIfNotGPU()); mfi.isValid(); ++mfi)
3581 {
3582 auto const& fab = this->array(mfi);
3583 Box const& fbx = mfi.growntilebox();
3584 Box const& gbx = fbx & domain;
3585 Box const& vbx = mfi.validbox();
3586 AMREX_HOST_DEVICE_FOR_4D(fbx, ncomp, i, j, k, n,
3587 {
3588 if (vbx.contains(i,j,k)) {
3589 fab(i,j,k,n) = interior;
3590 } else if (gbx.contains(i,j,k)) {
3591 fab(i,j,k,n) = notcovered;
3592 } else {
3593 fab(i,j,k,n) = physbnd;
3594 }
3595 });
3596 }
3597 }
3598
3599 const FabArrayBase::FB& TheFB = this->getFB(ngrow,period);
3600 setVal(covered, TheFB, 0, ncomp);
3601}
3602
3603template <class FAB>
3604template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
3605void
3606FabArray<FAB>::setVal (value_type val, const CommMetaData& thecmd, int scomp, int ncomp)
3607{
3608 BL_PROFILE("FabArray::setVal(val, thecmd, scomp, ncomp)");
3609
3610#ifdef AMREX_USE_GPU
3611 if (Gpu::inLaunchRegion())
3612 {
3613 CMD_local_setVal_gpu(val, thecmd, scomp, ncomp);
3614 CMD_remote_setVal_gpu(val, thecmd, scomp, ncomp);
3615 }
3616 else
3617#endif
3618 {
3619 AMREX_ASSERT(thecmd.m_LocTags && thecmd.m_RcvTags);
3620 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
3621 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
3622 auto N_locs = static_cast<int>(LocTags.size());
3623#ifdef AMREX_USE_OMP
3624#pragma omp parallel for if (thecmd.m_threadsafe_loc)
3625#endif
3626 for (int i = 0; i < N_locs; ++i) {
3627 const CopyComTag& tag = LocTags[i];
3628 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
3629 }
3630
3631 for (const auto & RcvTag : RcvTags) {
3632 auto N = static_cast<int>(RcvTag.second.size());
3633#ifdef AMREX_USE_OMP
3634#pragma omp parallel for if (thecmd.m_threadsafe_rcv)
3635#endif
3636 for (int i = 0; i < N; ++i) {
3637 const CopyComTag& tag = RcvTag.second[i];
3638 (*this)[tag.dstIndex].template setVal<RunOn::Host>(val, tag.dbox, scomp, ncomp);
3639 }
3640 }
3641 }
3642}
3643
3644template <class FAB>
3645template <class F, std::enable_if_t<IsBaseFab<F>::value,int>>
3648{
3649 BL_PROFILE("FabArray::RecvLayoutMask()");
3650
3651 LayoutData<int> r(this->boxArray(), this->DistributionMap());
3652#ifdef AMREX_USE_OMP
3653#pragma omp parallel if (thecmd.m_threadsafe_rcv)
3654#endif
3655 for (MFIter mfi(r); mfi.isValid(); ++mfi) {
3656 r[mfi] = 0;
3657 }
3658
3659 const CopyComTagsContainer& LocTags = *(thecmd.m_LocTags);
3660 const MapOfCopyComTagContainers& RcvTags = *(thecmd.m_RcvTags);
3661
3662 auto N_locs = static_cast<int>(LocTags.size());
3663 for (int i = 0; i < N_locs; ++i) {
3664 const CopyComTag& tag = LocTags[i];
3665 r[tag.dstIndex] = 1;
3666 }
3667
3668 for (const auto & RcvTag : RcvTags) {
3669 auto N = static_cast<int>(RcvTag.second.size());
3670 for (int i = 0; i < N; ++i) {
3671 const CopyComTag& tag = RcvTag.second[i];
3672 r[tag.dstIndex] = 1;
3673 }
3674 }
3675 return r;
3676}
3677
3678template <class FAB>
3679template <typename F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3680typename F::value_type
3681FabArray<FAB>::norminf (int comp, int ncomp, IntVect const& nghost, bool local,
3682 [[maybe_unused]] bool ignore_covered) const
3683{
3684 BL_PROFILE("FabArray::norminf()");
3685
3686 using RT = typename F::value_type;
3687
3688 auto nm0 = RT(0.0);
3689
3690#ifdef AMREX_USE_EB
3691 if ( this->is_cell_centered() && this->hasEBFabFactory() && ignore_covered )
3692 {
3693 const auto& ebfactory = dynamic_cast<EBFArrayBoxFactory const&>(this->Factory());
3694 auto const& flags = ebfactory.getMultiEBCellFlagFab();
3695#ifdef AMREX_USE_GPU
3696 if (Gpu::inLaunchRegion()) {
3697 auto const& flagsma = flags.const_arrays();
3698 auto const& ma = this->const_arrays();
3699 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost,
3700 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<RT>
3701 {
3702 if (flagsma[box_no](i,j,k).isCovered()) {
3703 return RT(0.0);
3704 } else {
3705 auto tmp = RT(0.0);
3706 auto const& a = ma[box_no];
3707 for (int n = 0; n < ncomp; ++n) {
3708 tmp = amrex::max(tmp, std::abs(a(i,j,k,comp+n)));
3709 }
3710 return tmp;
3711 }
3712 });
3713 } else
3714#endif
3715 {
3716#ifdef AMREX_USE_OMP
3717#pragma omp parallel reduction(max:nm0)
3718#endif
3719 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
3720 Box const& bx = mfi.growntilebox(nghost);
3721 if (flags[mfi].getType(bx) != FabType::covered) {
3722 auto const& flag = flags.const_array(mfi);
3723 auto const& a = this->const_array(mfi);
3724 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
3725 {
3726 if (!flag(i,j,k).isCovered()) {
3727 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
3728 }
3729 });
3730 }
3731 }
3732 }
3733 }
3734 else
3735#endif
3736 {
3737#ifdef AMREX_USE_GPU
3738 if (Gpu::inLaunchRegion()) {
3739 auto const& ma = this->const_arrays();
3740 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, nghost, ncomp,
3741 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k, int n) noexcept -> GpuTuple<RT>
3742 {
3743 return std::abs(ma[box_no](i,j,k,comp+n));
3744 });
3745 } else
3746#endif
3747 {
3748#ifdef AMREX_USE_OMP
3749#pragma omp parallel reduction(max:nm0)
3750#endif
3751 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
3752 Box const& bx = mfi.growntilebox(nghost);
3753 auto const& a = this->const_array(mfi);
3754 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
3755 {
3756 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
3757 });
3758 }
3759 }
3760 }
3761
3762 if (!local) {
3764 }
3765
3766 return nm0;
3767}
3768
3769template <class FAB>
3770template <typename IFAB, typename F, std::enable_if_t<IsBaseFab<F>::value,int> FOO>
3771typename F::value_type
3772FabArray<FAB>::norminf (FabArray<IFAB> const& mask, int comp, int ncomp,
3773 IntVect const& nghost, bool local) const
3774{
3775 BL_PROFILE("FabArray::norminf(mask)");
3776
3777 using RT = typename F::value_type;
3778
3779 auto nm0 = RT(0.0);
3780
3781#ifdef AMREX_USE_GPU
3782 if (Gpu::inLaunchRegion()) {
3783 auto const& ma = this->const_arrays();
3784 auto const& maskma = mask.const_arrays();
3785 nm0 = ParReduce(TypeList<ReduceOpMax>{}, TypeList<RT>{}, *this, IntVect(nghost),
3786 [=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept -> GpuTuple<RT>
3787 {
3788 if (maskma[box_no](i,j,k)) {
3789 auto tmp = RT(0.0);
3790 auto const& a = ma[box_no];
3791 for (int n = 0; n < ncomp; ++n) {
3792 tmp = amrex::max(tmp, std::abs(a(i,j,k,comp+n)));
3793 }
3794 return tmp;
3795 } else {
3796 return RT(0.0);
3797 }
3798 });
3799 } else
3800#endif
3801 {
3802#ifdef AMREX_USE_OMP
3803#pragma omp parallel reduction(max:nm0)
3804#endif
3805 for (MFIter mfi(*this,true); mfi.isValid(); ++mfi) {
3806 Box const& bx = mfi.growntilebox(nghost);
3807 auto const& a = this->const_array(mfi);
3808 auto const& mskfab = mask.const_array(mfi);
3809 AMREX_LOOP_4D(bx, ncomp, i, j, k, n,
3810 {
3811 if (mskfab(i,j,k)) {
3812 nm0 = std::max(nm0, std::abs(a(i,j,k,comp+n)));
3813 }
3814 });
3815 }
3816 }
3817
3818 if (!local) {
3820 }
3821
3822 return nm0;
3823}
3824
3826
3827}
3828
3829#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:2184
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:2249
F::value_type sum(int comp, IntVect const &nghost, bool local=false) const
Returns the sum of component "comp".
Definition AMReX_FabArray.H:2419
void EnforcePeriodicity(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period)
Definition AMReX_FabArray.H:3508
void abs(int comp, int ncomp, int nghost=0)
Definition AMReX_FabArray.H:2601
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:2227
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:3225
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:2759
void invert(value_type numerator, const Box &region, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2835
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:3286
void shift(const IntVect &v)
Shift the boxarray by vector v.
Definition AMReX_FabArray.H:2874
bool ok() const
Return true if the FabArray is well-defined. That is, the FabArray has a BoxArray and DistributionMap...
Definition AMReX_FabArray.H:1965
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:336
void CMD_remote_setVal_gpu(value_type x, const CommMetaData &thecmd, int scomp, int ncomp)
Definition AMReX_FBI.H:366
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:2388
FabArray(FabArray< FAB > &&rhs) noexcept
Definition AMReX_FabArray.H:1900
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:1864
bool defined(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:1602
void setVal(value_type val, const CommMetaData &thecmd, int scomp, int ncomp)
Definition AMReX_FabArray.H:3606
void setVal(value_type val, const Box &region, int comp, int ncomp, const IntVect &nghost)
Definition AMReX_FabArray.H:2552
void OverrideSync_nowait(int scomp, int ncomp, const Periodicity &period)
Definition AMReX_FabArray.H:3385
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:2540
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:2498
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:3356
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:3201
static void Saypy_Saxpy(FabArray< FAB > &y1, value_type a1, FabArray< FAB > &y2, value_type a2, FabArray< FAB > const &x, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
y1 += a1*y2; y2 += a2*x;
Definition AMReX_FabArray.H:3096
FAB const * fabPtr(int K) const noexcept
Definition AMReX_FabArray.H:1644
void abs(int comp, int ncomp, const IntVect &nghost)
Definition AMReX_FabArray.H:2609
void clear_arrays()
Definition AMReX_FabArray.H:1691
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:3401
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:3151
void OverrideSync_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3378
AMREX_NODISCARD FAB * release(const MFIter &mfi)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:1728
AMREX_NODISCARD FAB * release(int K)
Release ownership of the FAB. This function is not thread safe.
Definition AMReX_FabArray.H:1708
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:3681
void setDomainBndry(value_type val, const Geometry &geom)
Set all values outside the Geometry domain to val.
Definition AMReX_FabArray.H:2380
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:2000
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:1878
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:1817
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:3538
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:3367
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:1791
bool SharedMemory() const noexcept
Definition AMReX_FabArray.H:1402
LayoutData< int > RecvLayoutMask(const CommMetaData &thecmd)
Definition AMReX_FabArray.H:3647
void FillBoundary(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3263
void FillBoundary_nowait(const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3294
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:215
void invert(value_type numerator, int comp, int num_comp, int nghost=0)
Definition AMReX_FabArray.H:2799
void FB_local_copy_gpu(const FB &TheFB, int scomp, int ncomp)
Definition AMReX_FBI.H:276
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:2172
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:2647
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:3320
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:3348
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:3453
void SumBoundary_nowait(int scomp, int ncomp, IntVect const &nghost, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3446
static void Saxpy_Saxpy(FabArray< FAB > &y1, value_type a1, FabArray< FAB > const &x1, FabArray< FAB > &y2, value_type a2, FabArray< FAB > const &x2, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
y1 += a1*x1; y2 += a2*x2;
Definition AMReX_FabArray.H:3037
void FillBoundary_nowait(bool cross=false)
Definition AMReX_FabArray.H:3278
static void Saxpy_Xpay(FabArray< FAB > &y, value_type a1, FabArray< FAB > const &x1, value_type a2, FabArray< FAB > const &x2, int xcomp, int ycomp, int ncomp, IntVect const &nghost)
y = x2+a2*(y+a1*x1)
Definition AMReX_FabArray.H:2981
void FillBoundary(const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3213
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:2937
void clear()
Releases FAB memory in the FabArray.
Definition AMReX_FabArray.H:1747
void FillBoundary_nowait(int scomp, int ncomp, const IntVect &nghost, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3529
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:3239
void FillBoundary_nowait(int scomp, int ncomp, bool cross=false)
Definition AMReX_FabArray.H:3302
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:2271
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:3415
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:3309
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:1839
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:1589
FAB * fabPtr(int K) noexcept
Definition AMReX_FabArray.H:1635
void SumBoundary(int scomp, int ncomp, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3408
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:2470
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:2487
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:1809
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:2462
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:2279
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:3422
void setVal(value_type val, const Box &region, const IntVect &nghost)
Definition AMReX_FabArray.H:1833
void FillBoundary_nowait(int scomp, int ncomp, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3521
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:3472
void SumBoundary_nowait(int scomp, int ncomp, const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3439
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:2723
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:2891
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:2045
void FillBoundaryAndSync_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3332
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:3339
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:1800
void setFab(int boxno, FAB &&elem)
Explicitly set the Kth FAB in the FabArray to point to elem.
Definition AMReX_FabArray.H:2206
FabArray< FAB > & operator=(FabArray< FAB > &&rhs) noexcept
Definition AMReX_FabArray.H:1926
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:2683
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:1654
void SumBoundary_nowait(const Periodicity &period=Periodicity::NonPeriodic())
Definition AMReX_FabArray.H:3432
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:1615
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:3486
void OverrideSync_finish()
Definition AMReX_FabArray.H:3393
void FillBoundary(int scomp, int ncomp, const Periodicity &period, bool cross=false)
Definition AMReX_FabArray.H:3251
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:2012
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:3772
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:3497
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:1625
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:1993
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:1825
value_type const * singleChunkPtr() const noexcept
Definition AMReX_FabArray.H:466
~FabArray()
The destructor – deletes all FABs in the array.
Definition AMReX_FabArray.H:1957
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_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:251
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:1882
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:1449
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:1875
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:1402
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