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