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