Block-Structured AMR Software Framework
 
Loading...
Searching...
No Matches
AMReX_BaseFab.H
Go to the documentation of this file.
1#ifndef AMREX_BASEFAB_H_
2#define AMREX_BASEFAB_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_Algorithm.H>
6#include <AMReX_Extension.H>
7#include <AMReX_BLassert.H>
8#include <AMReX_Array.H>
9#include <AMReX_Box.H>
10#include <AMReX_Loop.H>
11#include <AMReX_BoxList.H>
12#include <AMReX_BArena.H>
13#include <AMReX_CArena.H>
14#include <AMReX_DataAllocator.H>
15#include <AMReX_REAL.H>
16#include <AMReX_BLProfiler.H>
17#include <AMReX_BoxIterator.H>
18#include <AMReX_MakeType.H>
19#include <AMReX_Utility.H>
20#include <AMReX_Reduce.H>
21#include <AMReX_Gpu.H>
22#include <AMReX_Scan.H>
23#include <AMReX_Math.H>
24#include <AMReX_OpenMP.H>
25#include <AMReX_MemPool.H>
26
27#include <cmath>
28#include <cstdlib>
29#include <algorithm>
30#include <limits>
31#include <climits>
32#include <array>
33#include <type_traits>
34#include <memory>
35#include <atomic>
36#include <utility>
37
38namespace amrex
39{
40
41extern std::atomic<Long> atomic_total_bytes_allocated_in_fabs;
42extern std::atomic<Long> atomic_total_bytes_allocated_in_fabs_hwm;
43extern std::atomic<Long> atomic_total_cells_allocated_in_fabs;
44extern std::atomic<Long> atomic_total_cells_allocated_in_fabs_hwm;
49#ifdef AMREX_USE_OMP
50#pragma omp threadprivate(private_total_bytes_allocated_in_fabs)
51#pragma omp threadprivate(private_total_bytes_allocated_in_fabs_hwm)
52#pragma omp threadprivate(private_total_cells_allocated_in_fabs)
53#pragma omp threadprivate(private_total_cells_allocated_in_fabs_hwm)
54#endif
55
56Long TotalBytesAllocatedInFabs () noexcept;
57Long TotalBytesAllocatedInFabsHWM () noexcept;
58Long TotalCellsAllocatedInFabs () noexcept;
59Long TotalCellsAllocatedInFabsHWM () noexcept;
61void update_fab_stats (Long n, Long s, std::size_t szt) noexcept;
62
63void BaseFab_Initialize ();
64void BaseFab_Finalize ();
65
66struct SrcComp {
68 explicit SrcComp (int ai) noexcept : i(ai) {}
69 int i;
70};
71
72struct DestComp {
74 explicit DestComp (int ai) noexcept : i(ai) {}
75 int i;
76};
77
78struct NumComps {
80 explicit NumComps (int an) noexcept : n(an) {}
81 int n;
82};
83
84template <typename T>
87makeArray4 (T* p, Box const& bx, int ncomp) noexcept
88{
89 return Array4<T>{p, amrex::begin(bx), amrex::end(bx), ncomp};
90}
91
92template <typename T>
93std::enable_if_t<std::is_arithmetic_v<T>>
94placementNew (T* const /*ptr*/, Long /*n*/)
95{}
96
97template <typename T>
98std::enable_if_t<std::is_trivially_default_constructible_v<T>
99 && !std::is_arithmetic_v<T>>
100placementNew (T* const ptr, Long n)
101{
102 for (Long i = 0; i < n; ++i) {
103 new (ptr+i) T;
104 }
105}
106
107template <typename T>
108std::enable_if_t<!std::is_trivially_default_constructible_v<T>>
109placementNew (T* const ptr, Long n)
110{
112 {
113 new (ptr+i) T;
114 });
115}
116
117template <typename T>
118std::enable_if_t<std::is_trivially_destructible_v<T>>
119placementDelete (T* const /*ptr*/, Long /*n*/)
120{}
121
122template <typename T>
123std::enable_if_t<!std::is_trivially_destructible_v<T>>
124placementDelete (T* const ptr, Long n)
125{
127 {
128 (ptr+i)->~T();
129 });
130}
131
180template <class T>
182 : public DataAllocator
183{
184public:
185
186 template <class U> friend class BaseFab;
187
188 using value_type = T;
189
191 BaseFab () noexcept = default;
192
193 explicit BaseFab (Arena* ar) noexcept;
194
195 BaseFab (const Box& bx, int n, Arena* ar);
196
198 explicit BaseFab (const Box& bx, int n = 1, bool alloc = true,
199 bool shared = false, Arena* ar = nullptr);
200
201 BaseFab (const BaseFab<T>& rhs, MakeType make_type, int scomp, int ncomp);
202
208 BaseFab (const Box& bx, int ncomp, T* p);
209 BaseFab (const Box& bx, int ncomp, T const* p);
210
211 explicit BaseFab (Array4<T> const& a) noexcept;
212
213 explicit BaseFab (Array4<T> const& a, IndexType t) noexcept;
214
215 explicit BaseFab (Array4<T const> const& a) noexcept;
216
217 explicit BaseFab (Array4<T const> const& a, IndexType t) noexcept;
218
220 virtual ~BaseFab () noexcept;
221
222 BaseFab (const BaseFab<T>& rhs) = delete;
223 BaseFab<T>& operator= (const BaseFab<T>& rhs) = delete;
224
225 BaseFab (BaseFab<T>&& rhs) noexcept;
226 BaseFab<T>& operator= (BaseFab<T>&& rhs) noexcept;
227
228#if defined(AMREX_USE_GPU)
229 template <RunOn run_on>
230#else
231 template <RunOn run_on=RunOn::Host>
232#endif
233 BaseFab& operator= (T const&) noexcept;
234
235 static void Initialize();
236 static void Finalize();
237
251 void resize (const Box& b, int N = 1, Arena* ar = nullptr);
252
253 template <class U=T, std::enable_if_t<std::is_trivially_destructible_v<U>,int> = 0>
254 [[nodiscard]] Elixir elixir () noexcept;
255
260 void clear () noexcept;
261
263 [[nodiscard]] std::unique_ptr<T,DataDeleter> release () noexcept;
264
266 [[nodiscard]] std::size_t nBytes () const noexcept { return this->truesize*sizeof(T); }
267
268 [[nodiscard]] std::size_t nBytesOwned () const noexcept {
269 return (this->ptr_owner) ? nBytes() : 0;
270 }
271
273 [[nodiscard]] std::size_t nBytes (const Box& bx, int ncomps) const noexcept
274 { return bx.numPts() * sizeof(T) * ncomps; }
275
277 [[nodiscard]] int nComp () const noexcept { return this->nvar; }
278
280 [[nodiscard]] const int* nCompPtr() const noexcept {
281 return &(this->nvar);
282 }
283
285 [[nodiscard]] Long numPts () const noexcept { return this->domain.numPts(); }
286
288 [[nodiscard]] Long size () const noexcept { return this->nvar*this->domain.numPts(); }
289
291 [[nodiscard]] const Box& box () const noexcept { return this->domain; }
292
297 [[nodiscard]] IntVect length () const noexcept { return this->domain.length(); }
298
303 [[nodiscard]] const IntVect& smallEnd () const noexcept { return this->domain.smallEnd(); }
304
306 [[nodiscard]] const IntVect& bigEnd () const noexcept { return this->domain.bigEnd(); }
307
316 [[nodiscard]] const int* loVect () const noexcept { return this->domain.loVect(); }
317
326 [[nodiscard]] const int* hiVect () const noexcept { return this->domain.hiVect(); }
327
332 [[nodiscard]] bool contains (const BaseFab<T>& fab) const noexcept
333 {
334 return box().contains(fab.box()) && this->nvar <= fab.nvar;
335 }
336
341 [[nodiscard]] bool contains (const Box& bx) const noexcept { return box().contains(bx); }
342
352 [[nodiscard]] T* dataPtr (int n = 0) noexcept {
353 if (this->dptr) {
354 return &(this->dptr[n*this->domain.numPts()]);
355 } else {
356 return nullptr;
357 }
358 }
359
361 [[nodiscard]] const T* dataPtr (int n = 0) const noexcept {
362 if (this->dptr) {
363 return &(this->dptr[n*this->domain.numPts()]);
364 } else {
365 return nullptr;
366 }
367 }
368
369 [[nodiscard]] T* dataPtr (const IntVect& p, int n = 0) noexcept;
370
371 [[nodiscard]] const T* dataPtr (const IntVect& p, int n = 0) const noexcept;
372
373 void setPtr (T* p, Long sz) noexcept { AMREX_ASSERT(this->dptr == nullptr && this->truesize == 0); this->dptr = p; this->truesize = sz; }
374
375 void prefetchToHost () const noexcept;
376 void prefetchToDevice () const noexcept;
377
378 [[nodiscard]] AMREX_FORCE_INLINE
379 Array4<T const> array () const noexcept
380 {
381 return makeArray4<T const>(this->dptr, this->domain, this->nvar);
382 }
383
384 [[nodiscard]] AMREX_FORCE_INLINE
385 Array4<T const> array (int start_comp) const noexcept
386 {
387 return Array4<T const>(makeArray4<T const>(this->dptr, this->domain, this->nvar),start_comp);
388 }
389
390 [[nodiscard]] AMREX_FORCE_INLINE
391 Array4<T const> array (int start_comp, int num_comps) const noexcept
392 {
393 return Array4<T const>(makeArray4<T const>(this->dptr, this->domain, this->nvar), start_comp, num_comps);
394 }
395
396 [[nodiscard]] AMREX_FORCE_INLINE
397 Array4<T> array () noexcept
398 {
399 return makeArray4<T>(this->dptr, this->domain, this->nvar);
400 }
401
402 [[nodiscard]] AMREX_FORCE_INLINE
403 Array4<T> array (int start_comp) noexcept
404 {
405 return Array4<T>(makeArray4<T>(this->dptr, this->domain, this->nvar),start_comp);
406 }
407
408 [[nodiscard]] AMREX_FORCE_INLINE
409 Array4<T> array (int start_comp, int num_comps) noexcept
410 {
411 return Array4<T>(makeArray4<T>(this->dptr, this->domain, this->nvar), start_comp, num_comps);
412 }
413
414 [[nodiscard]] AMREX_FORCE_INLINE
415 Array4<T const> const_array () const noexcept
416 {
417 return makeArray4<T const>(this->dptr, this->domain, this->nvar);
418 }
419
420 [[nodiscard]] AMREX_FORCE_INLINE
421 Array4<T const> const_array (int start_comp) const noexcept
422 {
423 return Array4<T const>(makeArray4<T const>(this->dptr, this->domain, this->nvar),start_comp);
424 }
425
426 [[nodiscard]] AMREX_FORCE_INLINE
427 Array4<T const> const_array (int start_comp, int num_comps) const noexcept
428 {
429 return Array4<T const>(makeArray4<T const>(this->dptr, this->domain, this->nvar), start_comp, num_comps);
430 }
431
433 [[nodiscard]] bool isAllocated () const noexcept { return this->dptr != nullptr; }
434
441 [[nodiscard]] T& operator() (const IntVect& p, int N) noexcept;
442
444 [[nodiscard]] T& operator() (const IntVect& p) noexcept;
445
447 [[nodiscard]] const T& operator() (const IntVect& p, int N) const noexcept;
448
450 [[nodiscard]] const T& operator() (const IntVect& p) const noexcept;
451
457 void getVal (T* data, const IntVect& pos, int N, int numcomp) const noexcept;
459 void getVal (T* data, const IntVect& pos) const noexcept;
460
461#if defined(AMREX_USE_GPU)
462 template <RunOn run_on,
463#else
464 template <RunOn run_on=RunOn::Host,
465#endif
466 class U=T, std::enable_if_t<std::is_same_v<U,float> || std::is_same_v<U,double>,int> FOO = 0>
467 void fill_snan () noexcept;
468
475#if defined(AMREX_USE_GPU)
476 template <RunOn run_on>
477#else
478 template <RunOn run_on=RunOn::Host>
479#endif
480 void setVal (T const& x, const Box& bx, int dcomp, int ncomp) noexcept;
482#if defined(AMREX_USE_GPU)
483 template <RunOn run_on>
484#else
485 template <RunOn run_on=RunOn::Host>
486#endif
487 void setVal (T const& x, const Box& bx, int N = 0) noexcept;
489#if defined(AMREX_USE_GPU)
490 template <RunOn run_on>
491#else
492 template <RunOn run_on=RunOn::Host>
493#endif
494 void setVal (T const& x, int N) noexcept;
495
496#if defined(AMREX_USE_GPU)
497 template <RunOn run_on>
498#else
499 template <RunOn run_on=RunOn::Host>
500#endif
501 void setValIfNot (T const& val, const Box& bx, const BaseFab<int>& mask, int nstart, int num) noexcept;
502
508#if defined(AMREX_USE_GPU)
509 template <RunOn run_on>
510#else
511 template <RunOn run_on=RunOn::Host>
512#endif
513 void setComplement (T const& x, const Box& b, int ns, int num) noexcept;
514
531#if defined(AMREX_USE_GPU)
532 template <RunOn run_on>
533#else
534 template <RunOn run_on=RunOn::Host>
535#endif
536 BaseFab<T>& copy (const BaseFab<T>& src, const Box& srcbox, int srccomp,
537 const Box& destbox, int destcomp, int numcomp) noexcept;
538
545#if defined(AMREX_USE_GPU)
546 template <RunOn run_on>
547#else
548 template <RunOn run_on=RunOn::Host>
549#endif
550 BaseFab<T>& copy (const BaseFab<T>& src, int srccomp, int destcomp,
551 int numcomp = 1) noexcept;
558#if defined(AMREX_USE_GPU)
559 template <RunOn run_on>
560#else
561 template <RunOn run_on=RunOn::Host>
562#endif
563 BaseFab<T>& copy (const BaseFab<T>& src, const Box& destbox) noexcept;
564
566#if defined(AMREX_USE_GPU)
567 template <RunOn run_on>
568#else
569 template <RunOn run_on=RunOn::Host>
570#endif
571 std::size_t copyToMem (const Box& srcbox, int srccomp,
572 int numcomp, void* dst) const noexcept;
573
575#if defined(AMREX_USE_GPU)
576 template <RunOn run_on, typename BUF = T>
577#else
578 template <RunOn run_on=RunOn::Host, typename BUF = T>
579#endif
580 std::size_t copyFromMem (const Box& dstbox, int dstcomp,
581 int numcomp, const void* src) noexcept;
582
584#if defined(AMREX_USE_GPU)
585 template <RunOn run_on, typename BUF = T>
586#else
587 template <RunOn run_on=RunOn::Host, typename BUF = T>
588#endif
589 std::size_t addFromMem (const Box& dstbox, int dstcomp,
590 int numcomp, const void* src) noexcept;
591
597 BaseFab<T>& shift (const IntVect& v) noexcept;
603 BaseFab<T>& shift (int idir, int n_cell) noexcept;
609 BaseFab<T>& shiftHalf (int dir, int n_cell) noexcept;
615 BaseFab<T>& shiftHalf (const IntVect& v) noexcept;
616
617#if defined(AMREX_USE_GPU)
618 template <RunOn run_on>
619#else
620 template <RunOn run_on=RunOn::Host>
621#endif
622 [[nodiscard]] Real norminfmask (const Box& subbox, const BaseFab<int>& mask, int scomp=0, int ncomp=1) const noexcept;
623
630#if defined(AMREX_USE_GPU)
631 template <RunOn run_on>
632#else
633 template <RunOn run_on=RunOn::Host>
634#endif
635 [[nodiscard]] Real norm (int p, int scomp = 0, int numcomp = 1) const noexcept;
636
638#if defined(AMREX_USE_GPU)
639 template <RunOn run_on>
640#else
641 template <RunOn run_on=RunOn::Host>
642#endif
643 [[nodiscard]] Real norm (const Box& subbox, int p, int scomp = 0, int numcomp = 1) const noexcept;
645#if defined(AMREX_USE_GPU)
646 template <RunOn run_on>
647#else
648 template <RunOn run_on=RunOn::Host>
649#endif
650 void abs () noexcept;
652#if defined(AMREX_USE_GPU)
653 template <RunOn run_on>
654#else
655 template <RunOn run_on=RunOn::Host>
656#endif
657 void abs (int comp, int numcomp=1) noexcept;
661#if defined(AMREX_USE_GPU)
662 template <RunOn run_on>
663#else
664 template <RunOn run_on=RunOn::Host>
665#endif
666 void abs (const Box& subbox, int comp = 0, int numcomp=1) noexcept;
670#if defined(AMREX_USE_GPU)
671 template <RunOn run_on>
672#else
673 template <RunOn run_on=RunOn::Host>
674#endif
675 [[nodiscard]] T min (int comp = 0) const noexcept;
679#if defined(AMREX_USE_GPU)
680 template <RunOn run_on>
681#else
682 template <RunOn run_on=RunOn::Host>
683#endif
684 [[nodiscard]] T min (const Box& subbox, int comp = 0) const noexcept;
688#if defined(AMREX_USE_GPU)
689 template <RunOn run_on>
690#else
691 template <RunOn run_on=RunOn::Host>
692#endif
693 [[nodiscard]] T max (int comp = 0) const noexcept;
697#if defined(AMREX_USE_GPU)
698 template <RunOn run_on>
699#else
700 template <RunOn run_on=RunOn::Host>
701#endif
702 [[nodiscard]] T max (const Box& subbox, int comp = 0) const noexcept;
706#if defined(AMREX_USE_GPU)
707 template <RunOn run_on>
708#else
709 template <RunOn run_on=RunOn::Host>
710#endif
711 [[nodiscard]] std::pair<T,T> minmax (int comp = 0) const noexcept;
715#if defined(AMREX_USE_GPU)
716 template <RunOn run_on>
717#else
718 template <RunOn run_on=RunOn::Host>
719#endif
720 [[nodiscard]] std::pair<T,T> minmax (const Box& subbox, int comp = 0) const noexcept;
724#if defined(AMREX_USE_GPU)
725 template <RunOn run_on>
726#else
727 template <RunOn run_on=RunOn::Host>
728#endif
729 [[nodiscard]] T maxabs (int comp = 0) const noexcept;
733#if defined(AMREX_USE_GPU)
734 template <RunOn run_on>
735#else
736 template <RunOn run_on=RunOn::Host>
737#endif
738 [[nodiscard]] T maxabs (const Box& subbox, int comp = 0) const noexcept;
739
740 /*(
741 * \return location of given value
742 */
743#if defined(AMREX_USE_GPU)
744 template <RunOn run_on>
745#else
746 template <RunOn run_on=RunOn::Host>
747#endif
748 [[nodiscard]] IntVect indexFromValue (const Box& subbox, int comp, T const& value) const noexcept;
749
753#if defined(AMREX_USE_GPU)
754 template <RunOn run_on>
755#else
756 template <RunOn run_on=RunOn::Host>
757#endif
758 [[nodiscard]] IntVect minIndex (int comp = 0) const noexcept;
763#if defined(AMREX_USE_GPU)
764 template <RunOn run_on>
765#else
766 template <RunOn run_on=RunOn::Host>
767#endif
768 [[nodiscard]] IntVect minIndex (const Box& subbox, int comp = 0) const noexcept;
773#if defined(AMREX_USE_GPU)
774 template <RunOn run_on>
775#else
776 template <RunOn run_on=RunOn::Host>
777#endif
778 void minIndex (const Box& subbox, Real& min_val, IntVect& min_idx, int comp = 0) const noexcept;
779
783#if defined(AMREX_USE_GPU)
784 template <RunOn run_on>
785#else
786 template <RunOn run_on=RunOn::Host>
787#endif
788 [[nodiscard]] IntVect maxIndex (int comp = 0) const noexcept;
793#if defined(AMREX_USE_GPU)
794 template <RunOn run_on>
795#else
796 template <RunOn run_on=RunOn::Host>
797#endif
798 [[nodiscard]] IntVect maxIndex (const Box& subbox, int comp = 0) const noexcept;
803#if defined(AMREX_USE_GPU)
804 template <RunOn run_on>
805#else
806 template <RunOn run_on=RunOn::Host>
807#endif
808 void maxIndex (const Box& subbox, Real& max_value, IntVect& max_idx, int comp = 0) const noexcept;
809
816#if defined(AMREX_USE_GPU)
817 template <RunOn run_on>
818#else
819 template <RunOn run_on=RunOn::Host>
820#endif
821 int maskLT (BaseFab<int>& mask, T const& val, int comp = 0) const noexcept;
823#if defined(AMREX_USE_GPU)
824 template <RunOn run_on>
825#else
826 template <RunOn run_on=RunOn::Host>
827#endif
828 int maskLE (BaseFab<int>& mask, T const& val, int comp = 0) const noexcept;
829
831#if defined(AMREX_USE_GPU)
832 template <RunOn run_on>
833#else
834 template <RunOn run_on=RunOn::Host>
835#endif
836 int maskEQ (BaseFab<int>& mask, T const& val, int comp = 0) const noexcept;
838#if defined(AMREX_USE_GPU)
839 template <RunOn run_on>
840#else
841 template <RunOn run_on=RunOn::Host>
842#endif
843 int maskGT (BaseFab<int>& mask, T const& val, int comp = 0) const noexcept;
845#if defined(AMREX_USE_GPU)
846 template <RunOn run_on>
847#else
848 template <RunOn run_on=RunOn::Host>
849#endif
850 int maskGE (BaseFab<int>& mask, T const& val, int comp = 0) const noexcept;
851
853#if defined(AMREX_USE_GPU)
854 template <RunOn run_on>
855#else
856 template <RunOn run_on=RunOn::Host>
857#endif
858 [[nodiscard]] T sum (int comp, int numcomp = 1) const noexcept;
860#if defined(AMREX_USE_GPU)
861 template <RunOn run_on>
862#else
863 template <RunOn run_on=RunOn::Host>
864#endif
865 [[nodiscard]] T sum (const Box& subbox, int comp, int numcomp = 1) const noexcept;
866
868#if defined(AMREX_USE_GPU)
869 template <RunOn run_on>
870#else
871 template <RunOn run_on=RunOn::Host>
872#endif
873 BaseFab<T>& invert (T const& r, const Box& b, int comp=0, int numcomp=1) noexcept;
875#if defined(AMREX_USE_GPU)
876 template <RunOn run_on>
877#else
878 template <RunOn run_on=RunOn::Host>
879#endif
880 BaseFab<T>& invert (T const& r, int comp, int numcomp=1) noexcept;
881
883#if defined(AMREX_USE_GPU)
884 template <RunOn run_on>
885#else
886 template <RunOn run_on=RunOn::Host>
887#endif
888 BaseFab<T>& negate (const Box& b, int comp=0, int numcomp=1) noexcept;
890#if defined(AMREX_USE_GPU)
891 template <RunOn run_on>
892#else
893 template <RunOn run_on=RunOn::Host>
894#endif
895 BaseFab<T>& negate (int comp, int numcomp=1) noexcept;
896
898#if defined(AMREX_USE_GPU)
899 template <RunOn run_on>
900#else
901 template <RunOn run_on=RunOn::Host>
902#endif
903 BaseFab<T>& plus (T const& r, const Box& b, int comp=0, int numcomp=1) noexcept;
904
906#if defined(AMREX_USE_GPU)
907 template <RunOn run_on>
908#else
909 template <RunOn run_on=RunOn::Host>
910#endif
911 BaseFab<T>& plus (T const& r, int comp, int numcomp=1) noexcept;
912
918#if defined(AMREX_USE_GPU)
919 template <RunOn run_on>
920#else
921 template <RunOn run_on=RunOn::Host>
922#endif
923 BaseFab<T>& plus (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp=1) noexcept;
929#if defined(AMREX_USE_GPU)
930 template <RunOn run_on>
931#else
932 template <RunOn run_on=RunOn::Host>
933#endif
934 BaseFab<T>& plus (const BaseFab<T>& src, const Box& subbox, int srccomp, int destcomp, int numcomp=1) noexcept;
939#if defined(AMREX_USE_GPU)
940 template <RunOn run_on>
941#else
942 template <RunOn run_on=RunOn::Host>
943#endif
944 BaseFab<T>& plus (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
945 int srccomp, int destcomp, int numcomp=1) noexcept;
946
948#if defined(AMREX_USE_GPU)
949 template <RunOn run_on>
950#else
951 template <RunOn run_on=RunOn::Host>
952#endif
953 BaseFab<T>& atomicAdd (const BaseFab<T>& x) noexcept;
954
960#if defined(AMREX_USE_GPU)
961 template <RunOn run_on>
962#else
963 template <RunOn run_on=RunOn::Host>
964#endif
965 BaseFab<T>& atomicAdd (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp=1) noexcept;
971#if defined(AMREX_USE_GPU)
972 template <RunOn run_on>
973#else
974 template <RunOn run_on=RunOn::Host>
975#endif
976 BaseFab<T>& atomicAdd (const BaseFab<T>& src, const Box& subbox, int srccomp, int destcomp,
977 int numcomp=1) noexcept;
982#if defined(AMREX_USE_GPU)
983 template <RunOn run_on>
984#else
985 template <RunOn run_on=RunOn::Host>
986#endif
987 BaseFab<T>& atomicAdd (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
988 int srccomp, int destcomp, int numcomp=1) noexcept;
989
995#if defined(AMREX_USE_GPU)
996 template <RunOn run_on>
997#else
998 template <RunOn run_on=RunOn::Host>
999#endif
1000 BaseFab<T>& lockAdd (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
1001 int srccomp, int destcomp, int numcomp) noexcept;
1002
1004#if defined(AMREX_USE_GPU)
1005 template <RunOn run_on>
1006#else
1007 template <RunOn run_on=RunOn::Host>
1008#endif
1009 BaseFab<T>& saxpy (T a, const BaseFab<T>& x, const Box& srcbox, const Box& destbox,
1010 int srccomp, int destcomp, int numcomp=1) noexcept;
1012#if defined(AMREX_USE_GPU)
1013 template <RunOn run_on>
1014#else
1015 template <RunOn run_on=RunOn::Host>
1016#endif
1017 BaseFab<T>& saxpy (T a, const BaseFab<T>& x) noexcept;
1018
1020#if defined(AMREX_USE_GPU)
1021 template <RunOn run_on>
1022#else
1023 template <RunOn run_on=RunOn::Host>
1024#endif
1025 BaseFab<T>& xpay (T a, const BaseFab<T>& x, const Box& srcbox, const Box& destbox,
1026 int srccomp, int destcomp, int numcomp=1) noexcept;
1027
1029#if defined(AMREX_USE_GPU)
1030 template <RunOn run_on>
1031#else
1032 template <RunOn run_on=RunOn::Host>
1033#endif
1034 BaseFab<T>& addproduct (const Box& destbox, int destcomp, int numcomp,
1035 const BaseFab<T>& src1, int comp1,
1036 const BaseFab<T>& src2, int comp2) noexcept;
1037
1043#if defined(AMREX_USE_GPU)
1044 template <RunOn run_on>
1045#else
1046 template <RunOn run_on=RunOn::Host>
1047#endif
1048 BaseFab<T>& minus (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp=1) noexcept;
1054#if defined(AMREX_USE_GPU)
1055 template <RunOn run_on>
1056#else
1057 template <RunOn run_on=RunOn::Host>
1058#endif
1059 BaseFab<T>& minus (const BaseFab<T>& src, const Box& subbox, int srccomp, int destcomp,
1060 int numcomp=1) noexcept;
1065#if defined(AMREX_USE_GPU)
1066 template <RunOn run_on>
1067#else
1068 template <RunOn run_on=RunOn::Host>
1069#endif
1070 BaseFab<T>& minus (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
1071 int srccomp, int destcomp, int numcomp=1) noexcept;
1072
1074#if defined(AMREX_USE_GPU)
1075 template <RunOn run_on>
1076#else
1077 template <RunOn run_on=RunOn::Host>
1078#endif
1079 BaseFab<T>& mult (T const& r, int comp, int numcomp=1) noexcept;
1083#if defined(AMREX_USE_GPU)
1084 template <RunOn run_on>
1085#else
1086 template <RunOn run_on=RunOn::Host>
1087#endif
1088 BaseFab<T>& mult (T const& r, const Box& b, int comp=0, int numcomp=1) noexcept;
1089
1095#if defined(AMREX_USE_GPU)
1096 template <RunOn run_on>
1097#else
1098 template <RunOn run_on=RunOn::Host>
1099#endif
1100 BaseFab<T>& mult (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp=1) noexcept;
1101
1107#if defined(AMREX_USE_GPU)
1108 template <RunOn run_on>
1109#else
1110 template <RunOn run_on=RunOn::Host>
1111#endif
1112 BaseFab<T>& mult (const BaseFab<T>& src, const Box& subbox, int srccomp, int destcomp,
1113 int numcomp=1) noexcept;
1114
1119#if defined(AMREX_USE_GPU)
1120 template <RunOn run_on>
1121#else
1122 template <RunOn run_on=RunOn::Host>
1123#endif
1124 BaseFab<T>& mult (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
1125 int srccomp, int destcomp, int numcomp=1) noexcept;
1126
1128#if defined(AMREX_USE_GPU)
1129 template <RunOn run_on>
1130#else
1131 template <RunOn run_on=RunOn::Host>
1132#endif
1133 BaseFab<T>& divide (T const& r, int comp, int numcomp=1) noexcept;
1134
1136#if defined(AMREX_USE_GPU)
1137 template <RunOn run_on>
1138#else
1139 template <RunOn run_on=RunOn::Host>
1140#endif
1141 BaseFab<T>& divide (T const& r, const Box& b, int comp=0, int numcomp=1) noexcept;
1142
1149#if defined(AMREX_USE_GPU)
1150 template <RunOn run_on>
1151#else
1152 template <RunOn run_on=RunOn::Host>
1153#endif
1154 BaseFab<T>& divide (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp=1) noexcept;
1160#if defined(AMREX_USE_GPU)
1161 template <RunOn run_on>
1162#else
1163 template <RunOn run_on=RunOn::Host>
1164#endif
1165 BaseFab<T>& divide (const BaseFab<T>& src, const Box& subbox, int srccomp, int destcomp,
1166 int numcomp=1) noexcept;
1171#if defined(AMREX_USE_GPU)
1172 template <RunOn run_on>
1173#else
1174 template <RunOn run_on=RunOn::Host>
1175#endif
1176 BaseFab<T>& divide (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
1177 int srccomp, int destcomp, int numcomp=1) noexcept;
1181#if defined(AMREX_USE_GPU)
1182 template <RunOn run_on>
1183#else
1184 template <RunOn run_on=RunOn::Host>
1185#endif
1187
1195#if defined(AMREX_USE_GPU)
1196 template <RunOn run_on>
1197#else
1198 template <RunOn run_on=RunOn::Host>
1199#endif
1200 BaseFab<T>& protected_divide (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp=1) noexcept;
1201
1208#if defined(AMREX_USE_GPU)
1209 template <RunOn run_on>
1210#else
1211 template <RunOn run_on=RunOn::Host>
1212#endif
1213 BaseFab<T>& protected_divide (const BaseFab<T>& src, const Box& subbox, int srccomp, int destcomp,
1214 int numcomp=1) noexcept;
1215
1221#if defined(AMREX_USE_GPU)
1222 template <RunOn run_on>
1223#else
1224 template <RunOn run_on=RunOn::Host>
1225#endif
1226 BaseFab<T>& protected_divide (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
1227 int srccomp, int destcomp, int numcomp=1) noexcept;
1228
1239#if defined(AMREX_USE_GPU)
1240 template <RunOn run_on>
1241#else
1242 template <RunOn run_on=RunOn::Host>
1243#endif
1244 BaseFab<T>& linInterp (const BaseFab<T>& f1, const Box& b1, int comp1,
1245 const BaseFab<T>& f2, const Box& b2, int comp2,
1246 Real t1, Real t2, Real t,
1247 const Box& b, int comp, int numcomp = 1) noexcept;
1248
1250#if defined(AMREX_USE_GPU)
1251 template <RunOn run_on>
1252#else
1253 template <RunOn run_on=RunOn::Host>
1254#endif
1255 BaseFab<T>& linInterp (const BaseFab<T>& f1, int comp1,
1256 const BaseFab<T>& f2, int comp2,
1257 Real t1, Real t2, Real t,
1258 const Box& b, int comp, int numcomp = 1) noexcept;
1259
1269#if defined(AMREX_USE_GPU)
1270 template <RunOn run_on>
1271#else
1272 template <RunOn run_on=RunOn::Host>
1273#endif
1274 BaseFab<T>& linComb (const BaseFab<T>& f1, const Box& b1, int comp1,
1275 const BaseFab<T>& f2, const Box& b2, int comp2,
1276 Real alpha, Real beta, const Box& b,
1277 int comp, int numcomp = 1) noexcept;
1278
1280#if defined(AMREX_USE_GPU)
1281 template <RunOn run_on>
1282#else
1283 template <RunOn run_on=RunOn::Host>
1284#endif
1285 [[nodiscard]] T dot (const Box& xbx, int xcomp, const BaseFab<T>& y, const Box& ybx, int ycomp,
1286 int numcomp = 1) const noexcept;
1287
1288#if defined(AMREX_USE_GPU)
1289 template <RunOn run_on>
1290#else
1291 template <RunOn run_on=RunOn::Host>
1292#endif
1293 [[nodiscard]] T dotmask (const BaseFab<int>& mask, const Box& xbx, int xcomp,
1294 const BaseFab<T>& y, const Box& ybx, int ycomp,
1295 int numcomp) const noexcept;
1296
1298 void SetBoxType (const IndexType& typ) noexcept { this->domain.setType(typ); }
1299
1300 //
1301 // New interfaces
1302 //
1303
1305#if defined(AMREX_USE_GPU)
1306 template <RunOn run_on>
1307#else
1308 template <RunOn run_on=RunOn::Host>
1309#endif
1310 void setVal (T const& val) noexcept;
1311 //
1313#if defined(AMREX_USE_GPU)
1314 template <RunOn run_on>
1315#else
1316 template <RunOn run_on=RunOn::Host>
1317#endif
1318 void setVal (T const& x, Box const& bx, DestComp dcomp, NumComps ncomp) noexcept;
1319
1320#if defined(AMREX_USE_GPU)
1321 template <RunOn run_on>
1322#else
1323 template <RunOn run_on=RunOn::Host>
1324#endif
1325 void setValIf (T const& val, const BaseFab<int>& mask) noexcept;
1326 //
1328#if defined(AMREX_USE_GPU)
1329 template <RunOn run_on>
1330#else
1331 template <RunOn run_on=RunOn::Host>
1332#endif
1333 void setValIf (T const& val, Box const& bx, const BaseFab<int>& mask, DestComp dcomp, NumComps ncomp) noexcept;
1334
1335#if defined(AMREX_USE_GPU)
1336 template <RunOn run_on>
1337#else
1338 template <RunOn run_on=RunOn::Host>
1339#endif
1340 void setValIfNot (T const& val, const BaseFab<int>& mask) noexcept;
1341 //
1343#if defined(AMREX_USE_GPU)
1344 template <RunOn run_on>
1345#else
1346 template <RunOn run_on=RunOn::Host>
1347#endif
1348 void setValIfNot (T const& val, Box const& bx, const BaseFab<int>& mask, DestComp dcomp, NumComps ncomp) noexcept;
1349
1351#if defined(AMREX_USE_GPU)
1352 template <RunOn run_on>
1353#else
1354 template <RunOn run_on=RunOn::Host>
1355#endif
1356 void setComplement (T const& x, Box const& bx, DestComp dcomp, NumComps ncomp) noexcept;
1357
1363#if defined(AMREX_USE_GPU)
1364 template <RunOn run_on>
1365#else
1366 template <RunOn run_on=RunOn::Host>
1367#endif
1368 BaseFab<T>& copy (const BaseFab<T>& src) noexcept;
1369 //
1371#if defined(AMREX_USE_GPU)
1372 template <RunOn run_on>
1373#else
1374 template <RunOn run_on=RunOn::Host>
1375#endif
1376 BaseFab<T>& copy (const BaseFab<T>& src, Box bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept;
1377
1379#if defined(AMREX_USE_GPU)
1380 template <RunOn run_on>
1381#else
1382 template <RunOn run_on=RunOn::Host>
1383#endif
1384 BaseFab<T>& plus (T const& val) noexcept;
1385 //
1386#if defined(AMREX_USE_GPU)
1387 template <RunOn run_on>
1388#else
1389 template <RunOn run_on=RunOn::Host>
1390#endif
1391 BaseFab<T>& operator+= (T const& val) noexcept;
1392 //
1394#if defined(AMREX_USE_GPU)
1395 template <RunOn run_on>
1396#else
1397 template <RunOn run_on=RunOn::Host>
1398#endif
1399 BaseFab<T>& plus (T const& val, Box const& bx, DestComp dcomp, NumComps ncomp) noexcept;
1405#if defined(AMREX_USE_GPU)
1406 template <RunOn run_on>
1407#else
1408 template <RunOn run_on=RunOn::Host>
1409#endif
1410 BaseFab<T>& plus (const BaseFab<T>& src) noexcept;
1411 //
1412#if defined(AMREX_USE_GPU)
1413 template <RunOn run_on>
1414#else
1415 template <RunOn run_on=RunOn::Host>
1416#endif
1417 BaseFab<T>& operator+= (const BaseFab<T>& src) noexcept;
1418 //
1420#if defined(AMREX_USE_GPU)
1421 template <RunOn run_on>
1422#else
1423 template <RunOn run_on=RunOn::Host>
1424#endif
1425 BaseFab<T>& plus (const BaseFab<T>& src, Box bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept;
1426
1428#if defined(AMREX_USE_GPU)
1429 template <RunOn run_on>
1430#else
1431 template <RunOn run_on=RunOn::Host>
1432#endif
1433 BaseFab<T>& minus (T const& val) noexcept;
1434 //
1435#if defined(AMREX_USE_GPU)
1436 template <RunOn run_on>
1437#else
1438 template <RunOn run_on=RunOn::Host>
1439#endif
1440 BaseFab<T>& operator-= (T const& val) noexcept;
1441 //
1443#if defined(AMREX_USE_GPU)
1444 template <RunOn run_on>
1445#else
1446 template <RunOn run_on=RunOn::Host>
1447#endif
1448 BaseFab<T>& minus (T const& val, Box const& bx, DestComp dcomp, NumComps ncomp) noexcept;
1454#if defined(AMREX_USE_GPU)
1455 template <RunOn run_on>
1456#else
1457 template <RunOn run_on=RunOn::Host>
1458#endif
1459 BaseFab<T>& minus (const BaseFab<T>& src) noexcept;
1460 //
1461#if defined(AMREX_USE_GPU)
1462 template <RunOn run_on>
1463#else
1464 template <RunOn run_on=RunOn::Host>
1465#endif
1466 BaseFab<T>& operator-= (const BaseFab<T>& src) noexcept;
1467 //
1469#if defined(AMREX_USE_GPU)
1470 template <RunOn run_on>
1471#else
1472 template <RunOn run_on=RunOn::Host>
1473#endif
1474 BaseFab<T>& minus (const BaseFab<T>& src, Box bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept;
1475
1477#if defined(AMREX_USE_GPU)
1478 template <RunOn run_on>
1479#else
1480 template <RunOn run_on=RunOn::Host>
1481#endif
1482 BaseFab<T>& mult (T const& val) noexcept;
1483 //
1484#if defined(AMREX_USE_GPU)
1485 template <RunOn run_on>
1486#else
1487 template <RunOn run_on=RunOn::Host>
1488#endif
1489 BaseFab<T>& operator*= (T const& val) noexcept;
1490 //
1492#if defined(AMREX_USE_GPU)
1493 template <RunOn run_on>
1494#else
1495 template <RunOn run_on=RunOn::Host>
1496#endif
1497 BaseFab<T>& mult (T const& val, Box const& bx, DestComp dcomp, NumComps ncomp) noexcept;
1503#if defined(AMREX_USE_GPU)
1504 template <RunOn run_on>
1505#else
1506 template <RunOn run_on=RunOn::Host>
1507#endif
1508 BaseFab<T>& mult (const BaseFab<T>& src) noexcept;
1509 //
1510#if defined(AMREX_USE_GPU)
1511 template <RunOn run_on>
1512#else
1513 template <RunOn run_on=RunOn::Host>
1514#endif
1515 BaseFab<T>& operator*= (const BaseFab<T>& src) noexcept;
1516 //
1518#if defined(AMREX_USE_GPU)
1519 template <RunOn run_on>
1520#else
1521 template <RunOn run_on=RunOn::Host>
1522#endif
1523 BaseFab<T>& mult (const BaseFab<T>& src, Box bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept;
1524
1526#if defined(AMREX_USE_GPU)
1527 template <RunOn run_on>
1528#else
1529 template <RunOn run_on=RunOn::Host>
1530#endif
1531 BaseFab<T>& divide (T const& val) noexcept;
1532 //
1533#if defined(AMREX_USE_GPU)
1534 template <RunOn run_on>
1535#else
1536 template <RunOn run_on=RunOn::Host>
1537#endif
1538 BaseFab<T>& operator/= (T const& val) noexcept;
1539 //
1541#if defined(AMREX_USE_GPU)
1542 template <RunOn run_on>
1543#else
1544 template <RunOn run_on=RunOn::Host>
1545#endif
1546 BaseFab<T>& divide (T const& val, Box const& bx, DestComp dcomp, NumComps ncomp) noexcept;
1552#if defined(AMREX_USE_GPU)
1553 template <RunOn run_on>
1554#else
1555 template <RunOn run_on=RunOn::Host>
1556#endif
1557 BaseFab<T>& divide (const BaseFab<T>& src) noexcept;
1558 //
1559#if defined(AMREX_USE_GPU)
1560 template <RunOn run_on>
1561#else
1562 template <RunOn run_on=RunOn::Host>
1563#endif
1564 BaseFab<T>& operator/= (const BaseFab<T>& src) noexcept;
1565 //
1567#if defined(AMREX_USE_GPU)
1568 template <RunOn run_on>
1569#else
1570 template <RunOn run_on=RunOn::Host>
1571#endif
1572 BaseFab<T>& divide (const BaseFab<T>& src, Box bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept;
1573
1575#if defined(AMREX_USE_GPU)
1576 template <RunOn run_on>
1577#else
1578 template <RunOn run_on=RunOn::Host>
1579#endif
1580 BaseFab<T>& negate () noexcept;
1581 //
1582#if defined(AMREX_USE_GPU)
1583 template <RunOn run_on>
1584#else
1585 template <RunOn run_on=RunOn::Host>
1586#endif
1587 BaseFab<T>& negate (const Box& bx, DestComp dcomp, NumComps ncomp) noexcept;
1588
1590#if defined(AMREX_USE_GPU)
1591 template <RunOn run_on>
1592#else
1593 template <RunOn run_on=RunOn::Host>
1594#endif
1595 BaseFab<T>& invert (T const& r) noexcept;
1596 //
1597#if defined(AMREX_USE_GPU)
1598 template <RunOn run_on>
1599#else
1600 template <RunOn run_on=RunOn::Host>
1601#endif
1602 BaseFab<T>& invert (T const& r, const Box& bx, DestComp dcomp, NumComps ncomp) noexcept;
1603
1605#if defined(AMREX_USE_GPU)
1606 template <RunOn run_on>
1607#else
1608 template <RunOn run_on=RunOn::Host>
1609#endif
1610 [[nodiscard]] T sum (const Box& bx, DestComp dcomp, NumComps ncomp) const noexcept;
1611
1613#if defined(AMREX_USE_GPU)
1614 template <RunOn run_on>
1615#else
1616 template <RunOn run_on=RunOn::Host>
1617#endif
1618 [[nodiscard]] T dot (const BaseFab<T>& src, const Box& bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) const noexcept;
1619
1621#if defined(AMREX_USE_GPU)
1622 template <RunOn run_on>
1623#else
1624 template <RunOn run_on=RunOn::Host>
1625#endif
1626 [[nodiscard]] T dot (const Box& bx, int destcomp, int numcomp) const noexcept;
1627
1629#if defined(AMREX_USE_GPU)
1630 template <RunOn run_on>
1631#else
1632 template <RunOn run_on=RunOn::Host>
1633#endif
1634 [[nodiscard]] T dot (const Box& bx, DestComp dcomp, NumComps ncomp) const noexcept;
1635
1637#if defined(AMREX_USE_GPU)
1638 template <RunOn run_on>
1639#else
1640 template <RunOn run_on=RunOn::Host>
1641#endif
1642 [[nodiscard]] T dotmask (const BaseFab<T>& src, const Box& bx, const BaseFab<int>& mask,
1643 SrcComp scomp, DestComp dcomp, NumComps ncomp) const noexcept;
1644
1645protected:
1647 void define ();
1648
1649 T* dptr = nullptr;
1651 int nvar = 0;
1652 Long truesize = 0L;
1653 bool ptr_owner = false;
1654 bool shared_memory = false;
1655#ifdef AMREX_USE_GPU
1657#endif
1658};
1659
1660template <class T>
1662T*
1663BaseFab<T>::dataPtr (const IntVect& p, int n) noexcept
1664{
1665 AMREX_ASSERT(n >= 0);
1666 AMREX_ASSERT(n < this->nvar);
1667 AMREX_ASSERT(!(this->dptr == nullptr));
1668 AMREX_ASSERT(this->domain.contains(p));
1669
1670 return this->dptr + (this->domain.index(p)+n*this->domain.numPts());
1671}
1672
1673template <class T>
1675const T*
1676BaseFab<T>::dataPtr (const IntVect& p, int n) const noexcept
1677{
1678 AMREX_ASSERT(n >= 0);
1679 AMREX_ASSERT(n < this->nvar);
1680 AMREX_ASSERT(!(this->dptr == nullptr));
1681 AMREX_ASSERT(this->domain.contains(p));
1682
1683 return this->dptr + (this->domain.index(p)+n*this->domain.numPts());
1684}
1685
1686template <class T>
1687void
1689{
1690#ifdef AMREX_USE_GPU
1691 if (this->arena()->isManaged()) {
1692#if defined(AMREX_USE_SYCL)
1693 // xxxxx SYCL todo: prefetchToHost
1694 // std::size_t s = sizeof(T)*this->nvar*this->domain.numPts();
1695 // auto& q = Gpu::Device::streamQueue();
1696 // q.submit([&] (sycl::handler& h) { h.prefetch(this->dptr, s); });
1697#elif defined(AMREX_USE_CUDA) && !defined(_WIN32)
1698 if (Gpu::Device::devicePropMajor() >= 6) {
1699 std::size_t s = sizeof(T)*this->nvar*this->domain.numPts();
1700 AMREX_CUDA_SAFE_CALL(cudaMemPrefetchAsync(this->dptr, s,
1701 cudaCpuDeviceId,
1702 Gpu::gpuStream()));
1703 }
1704#elif defined(AMREX_USE_HIP)
1705 // xxxxx HIP FIX HERE after managed memory is supported
1706#endif
1707 }
1708#endif
1709}
1710
1711template <class T>
1712void
1714{
1715#ifdef AMREX_USE_GPU
1716 if (this->arena()->isManaged()) {
1717#if defined(AMREX_USE_SYCL)
1718 std::size_t s = sizeof(T)*this->nvar*this->domain.numPts();
1719 auto& q = Gpu::Device::streamQueue();
1720 q.submit([&] (sycl::handler& h) { h.prefetch(this->dptr, s); });
1721#elif defined(AMREX_USE_CUDA) && !defined(_WIN32)
1722 if (Gpu::Device::devicePropMajor() >= 6) {
1723 std::size_t s = sizeof(T)*this->nvar*this->domain.numPts();
1724 AMREX_CUDA_SAFE_CALL(cudaMemPrefetchAsync(this->dptr, s,
1726 Gpu::gpuStream()));
1727 }
1728#elif defined(AMREX_USE_HIP)
1729 // xxxxx HIP FIX HERE after managed memory is supported
1730#endif
1731 }
1732#endif
1733}
1734
1735template <class T>
1737T&
1738BaseFab<T>::operator() (const IntVect& p, int n) noexcept
1739{
1740 AMREX_ASSERT(n >= 0);
1741 AMREX_ASSERT(n < this->nvar);
1742 AMREX_ASSERT(!(this->dptr == nullptr));
1743 AMREX_ASSERT(this->domain.contains(p));
1744
1745 return this->dptr[this->domain.index(p)+n*this->domain.numPts()];
1746}
1747
1748template <class T>
1750T&
1752{
1753 AMREX_ASSERT(!(this->dptr == nullptr));
1754 AMREX_ASSERT(this->domain.contains(p));
1755
1756 return this->dptr[this->domain.index(p)];
1757}
1758
1759template <class T>
1761const T&
1762BaseFab<T>::operator() (const IntVect& p, int n) const noexcept
1763{
1764 AMREX_ASSERT(n >= 0);
1765 AMREX_ASSERT(n < this->nvar);
1766 AMREX_ASSERT(!(this->dptr == nullptr));
1767 AMREX_ASSERT(this->domain.contains(p));
1768
1769 return this->dptr[this->domain.index(p)+n*this->domain.numPts()];
1770}
1771
1772template <class T>
1774const T&
1775BaseFab<T>::operator() (const IntVect& p) const noexcept
1776{
1777 AMREX_ASSERT(!(this->dptr == nullptr));
1778 AMREX_ASSERT(this->domain.contains(p));
1779
1780 return this->dptr[this->domain.index(p)];
1781}
1782
1783template <class T>
1784void
1786 const IntVect& pos,
1787 int n,
1788 int numcomp) const noexcept
1789{
1790 const int loc = this->domain.index(pos);
1791 const Long sz = this->domain.numPts();
1792
1793 AMREX_ASSERT(!(this->dptr == nullptr));
1794 AMREX_ASSERT(n >= 0 && n + numcomp <= this->nvar);
1795
1796 for (int k = 0; k < numcomp; k++) {
1797 data[k] = this->dptr[loc+(n+k)*sz];
1798 }
1799}
1800
1801template <class T>
1802void
1804 const IntVect& pos) const noexcept
1805{
1806 getVal(data,pos,0,this->nvar);
1807}
1808
1809template <class T>
1811BaseFab<T>::shift (const IntVect& v) noexcept
1812{
1813 this->domain += v;
1814 return *this;
1815}
1816
1817template <class T>
1819BaseFab<T>::shift (int idir, int n_cell) noexcept
1820{
1821 this->domain.shift(idir,n_cell);
1822 return *this;
1823}
1824
1825template <class T>
1826BaseFab<T> &
1828{
1829 this->domain.shiftHalf(v);
1830 return *this;
1831}
1832
1833template <class T>
1834BaseFab<T> &
1835BaseFab<T>::shiftHalf (int idir, int n_cell) noexcept
1836{
1837 this->domain.shiftHalf(idir,n_cell);
1838 return *this;
1839}
1840
1841template <class T>
1842template <RunOn run_on, class U,
1843 std::enable_if_t<std::is_same_v<U,float> || std::is_same_v<U,double>, int> FOO>
1844void
1846{
1847 amrex::fill_snan<run_on>(this->dptr, this->truesize);
1848}
1849
1850template <class T>
1851template <RunOn run_on>
1852void
1853BaseFab<T>::setVal (T const& x, const Box& bx, int n) noexcept
1854{
1855 this->setVal<run_on>(x, bx, DestComp{n}, NumComps{1});
1856}
1857
1858template <class T>
1859template <RunOn run_on>
1860void
1861BaseFab<T>::setVal (T const& x, int n) noexcept
1862{
1863 this->setVal<run_on>(x, this->domain, DestComp{n}, NumComps{1});
1864}
1865
1866template <class T>
1867template <RunOn run_on>
1868void
1869BaseFab<T>::setVal (T const& x, const Box& bx, int dcomp, int ncomp) noexcept
1870{
1871 this->setVal<run_on>(x, bx, DestComp{dcomp}, NumComps{ncomp});
1872}
1873
1874template <class T>
1875template <RunOn run_on>
1876void
1877BaseFab<T>::setValIfNot (T const& val, const Box& bx, const BaseFab<int>& mask, int ns, int num) noexcept
1878{
1879 this->setValIfNot<run_on>(val, bx, mask, DestComp{ns}, NumComps{num});
1880}
1881
1882template <class T>
1883template <RunOn run_on>
1885BaseFab<T>::copy (const BaseFab<T>& src, const Box& srcbox, int srccomp,
1886 const Box& destbox, int destcomp, int numcomp) noexcept
1887{
1888 AMREX_ASSERT(destbox.ok());
1889 AMREX_ASSERT(srcbox.sameSize(destbox));
1890 AMREX_ASSERT(src.box().contains(srcbox));
1891 AMREX_ASSERT(this->domain.contains(destbox));
1892 AMREX_ASSERT(srccomp >= 0 && srccomp+numcomp <= src.nComp());
1893 AMREX_ASSERT(destcomp >= 0 && destcomp+numcomp <= this->nvar);
1894
1895 Array4<T> const& d = this->array();
1896 Array4<T const> const& s = src.const_array();
1897 const auto dlo = amrex::lbound(destbox);
1898 const auto slo = amrex::lbound(srcbox);
1899 const Dim3 offset{slo.x-dlo.x,slo.y-dlo.y,slo.z-dlo.z};
1900
1901 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, destbox, numcomp, i, j, k, n,
1902 {
1903 d(i,j,k,n+destcomp) = s(i+offset.x,j+offset.y,k+offset.z,n+srccomp);
1904 });
1905
1906 return *this;
1907}
1908
1909template <class T>
1910template <RunOn run_on>
1912BaseFab<T>::copy (const BaseFab<T>& src, const Box& destbox) noexcept
1913{
1914 return this->copy<run_on>(src, destbox, SrcComp{0}, DestComp{0}, NumComps{this->nvar});
1915}
1916
1917template <class T>
1918template <RunOn run_on>
1920BaseFab<T>::copy (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp) noexcept
1921{
1922 return copy<run_on>(src, this->domain, SrcComp{srccomp}, DestComp{destcomp}, NumComps{numcomp});
1923}
1924
1925template <class T>
1926void
1928{
1929 AMREX_ASSERT(this->dptr == nullptr);
1930 AMREX_ASSERT(this->domain.numPts() > 0);
1931 AMREX_ASSERT(this->nvar >= 0);
1932 if (this->nvar == 0) { return; }
1933 AMREX_ASSERT(std::numeric_limits<Long>::max()/this->nvar > this->domain.numPts());
1934
1935 this->truesize = this->nvar*this->domain.numPts();
1936 this->ptr_owner = true;
1937 this->dptr = static_cast<T*>(this->alloc(this->truesize*sizeof(T)));
1938#ifdef AMREX_USE_GPU
1939 this->alloc_stream = Gpu::gpuStream();
1940#endif
1941
1942 placementNew(this->dptr, this->truesize);
1943
1944 amrex::update_fab_stats(this->domain.numPts(), this->truesize, sizeof(T));
1945
1946 if constexpr (std::is_same_v<T,float> || std::is_same_v<T,double>) {
1947 if (amrex::InitSNaN() && this->truesize > 0) {
1948#ifdef AMREX_USE_GPU
1949 if (Gpu::inLaunchRegion() && arena()->isDeviceAccessible()) {
1950 this->template fill_snan<RunOn::Device>();
1952 } else
1953#endif
1954 {
1955 this->template fill_snan<RunOn::Host>();
1956 }
1957 }
1958 }
1959}
1960
1961template <class T>
1963 : DataAllocator{ar}
1964{}
1965
1966template <class T>
1967BaseFab<T>::BaseFab (const Box& bx, int n, Arena* ar)
1968 : DataAllocator{ar}, domain(bx), nvar(n)
1969{
1970 define();
1971}
1972
1973template <class T>
1974BaseFab<T>::BaseFab (const Box& bx, int n, bool alloc, bool shared, Arena* ar)
1975 : DataAllocator{ar}, domain(bx), nvar(n), shared_memory(shared)
1976{
1977 if (!this->shared_memory && alloc) { define(); }
1978}
1979
1980template <class T>
1981BaseFab<T>::BaseFab (const BaseFab<T>& rhs, MakeType make_type, int scomp, int ncomp)
1982 : DataAllocator{rhs.arena()},
1983 dptr(const_cast<T*>(rhs.dataPtr(scomp))),
1984 domain(rhs.domain), nvar(ncomp),
1985 truesize(ncomp*rhs.domain.numPts())
1986{
1987 AMREX_ASSERT(scomp+ncomp <= rhs.nComp());
1988 if (make_type == amrex::make_deep_copy)
1989 {
1990 this->dptr = nullptr;
1991 define();
1992 this->copy<RunOn::Device>(rhs, this->domain, scomp, this->domain, 0, ncomp);
1993 } else if (make_type == amrex::make_alias) {
1994 ; // nothing to do
1995 } else {
1996 amrex::Abort("BaseFab: unknown MakeType");
1997 }
1998}
1999
2000template<class T>
2001BaseFab<T>::BaseFab (const Box& bx, int ncomp, T* p)
2002 : dptr(p), domain(bx), nvar(ncomp), truesize(bx.numPts()*ncomp)
2003{
2004}
2005
2006template<class T>
2007BaseFab<T>::BaseFab (const Box& bx, int ncomp, T const* p)
2008 : dptr(const_cast<T*>(p)), domain(bx), nvar(ncomp), truesize(bx.numPts()*ncomp)
2009{
2010}
2011
2012template<class T>
2014 : dptr(a.p),
2015 domain(IntVect(AMREX_D_DECL(a.begin.x,a.begin.y,a.begin.z)),
2016 IntVect(AMREX_D_DECL(a.end.x-1,a.end.y-1,a.end.z-1))),
2017 nvar(a.ncomp), truesize(a.ncomp*a.nstride)
2018{}
2019
2020template<class T>
2022 : dptr(a.p),
2023 domain(IntVect(AMREX_D_DECL(a.begin.x,a.begin.y,a.begin.z)),
2024 IntVect(AMREX_D_DECL(a.end.x-1,a.end.y-1,a.end.z-1)), t),
2025 nvar(a.ncomp), truesize(a.ncomp*a.nstride)
2026{}
2027
2028template<class T>
2030 : dptr(const_cast<T*>(a.p)),
2031 domain(IntVect(AMREX_D_DECL(a.begin.x,a.begin.y,a.begin.z)),
2032 IntVect(AMREX_D_DECL(a.end.x-1,a.end.y-1,a.end.z-1))),
2033 nvar(a.ncomp), truesize(a.ncomp*a.nstride)
2034{}
2035
2036template<class T>
2038 : dptr(const_cast<T*>(a.p)),
2039 domain(IntVect(AMREX_D_DECL(a.begin.x,a.begin.y,a.begin.z)),
2040 IntVect(AMREX_D_DECL(a.end.x-1,a.end.y-1,a.end.z-1)), t),
2041 nvar(a.ncomp), truesize(a.ncomp*a.nstride)
2042{}
2043
2044template <class T>
2046{
2047 clear();
2048}
2049
2050template <class T>
2052 : DataAllocator{rhs.arena()},
2053 dptr(rhs.dptr), domain(rhs.domain),
2054 nvar(rhs.nvar), truesize(rhs.truesize),
2055 ptr_owner(rhs.ptr_owner), shared_memory(rhs.shared_memory)
2056#ifdef AMREX_USE_GPU
2057 , alloc_stream(rhs.alloc_stream)
2058#endif
2059{
2060 rhs.dptr = nullptr;
2061 rhs.ptr_owner = false;
2062}
2063
2064template <class T>
2065BaseFab<T>&
2067{
2068 if (this != &rhs) {
2069 clear();
2070 DataAllocator::operator=(rhs);
2071 dptr = rhs.dptr;
2072 domain = rhs.domain;
2073 nvar = rhs.nvar;
2074 truesize = rhs.truesize;
2075 ptr_owner = rhs.ptr_owner;
2076 shared_memory = rhs.shared_memory;
2077#ifdef AMREX_USE_GPU
2078 alloc_stream = rhs.alloc_stream;
2079#endif
2080
2081 rhs.dptr = nullptr;
2082 rhs.ptr_owner = false;
2083 }
2084 return *this;
2085}
2086
2087template <class T>
2088template <RunOn run_on>
2090BaseFab<T>::operator= (T const& t) noexcept
2091{
2092 setVal<run_on>(t);
2093 return *this;
2094}
2095
2096template <class T>
2097void
2098BaseFab<T>::resize (const Box& b, int n, Arena* ar)
2099{
2100 this->nvar = n;
2101 this->domain = b;
2102
2103 if (ar == nullptr) {
2104 ar = m_arena;
2105 }
2106
2107 if (arena() != DataAllocator(ar).arena()) {
2108 clear();
2109 m_arena = ar;
2110 define();
2111 }
2112 else if (this->dptr == nullptr || !this->ptr_owner)
2113 {
2114 if (this->shared_memory) {
2115 amrex::Abort("BaseFab::resize: BaseFab in shared memory cannot increase size");
2116 }
2117
2118 this->dptr = nullptr;
2119 define();
2120 }
2121 else if (this->nvar*this->domain.numPts() > this->truesize
2122#ifdef AMREX_USE_GPU
2123 || (arena()->isStreamOrderedArena() && alloc_stream != Gpu::gpuStream())
2124#endif
2125 )
2126 {
2127 if (this->shared_memory) {
2128 amrex::Abort("BaseFab::resize: BaseFab in shared memory cannot increase size");
2129 }
2130
2131 clear();
2132
2133 define();
2134 }
2135}
2136
2137template <class T>
2138template <class U, std::enable_if_t<std::is_trivially_destructible_v<U>,int>>
2139Elixir
2141{
2142 bool o;
2143 if (Gpu::inLaunchRegion()) {
2144 o = this->ptr_owner;
2145 this->ptr_owner = false;
2146 if (o && this->dptr) {
2147 if (this->nvar > 1) {
2148 amrex::update_fab_stats(-this->truesize/this->nvar, -this->truesize, sizeof(T));
2149 } else {
2150 amrex::update_fab_stats(0, -this->truesize, sizeof(T));
2151 }
2152 }
2153 } else {
2154 o = false;
2155 }
2156 return Elixir((o ? this->dptr : nullptr), this->arena());
2157}
2158
2159template <class T>
2160void
2162{
2163 if (this->dptr)
2164 {
2165 //
2166 // Call T::~T() on the to-be-destroyed memory.
2167 //
2168 if (this->ptr_owner)
2169 {
2170 if (this->shared_memory)
2171 {
2172 amrex::Abort("BaseFab::clear: BaseFab cannot be owner of shared memory");
2173 }
2174
2175 placementDelete(this->dptr, this->truesize);
2176
2177#ifdef AMREX_USE_GPU
2178 auto current_stream = Gpu::Device::gpuStream();
2179 Gpu::Device::setStream(alloc_stream);
2180#endif
2181 this->free(this->dptr);
2182#ifdef AMREX_USE_GPU
2183 Gpu::Device::setStream(current_stream);
2184#endif
2185
2186 if (this->nvar > 1) {
2187 amrex::update_fab_stats(-this->truesize/this->nvar, -this->truesize, sizeof(T));
2188 } else {
2189 amrex::update_fab_stats(0, -this->truesize, sizeof(T));
2190 }
2191 }
2192
2193 this->dptr = nullptr;
2194 this->truesize = 0;
2195 }
2196}
2197
2198template <class T>
2199std::unique_ptr<T,DataDeleter>
2201{
2202 std::unique_ptr<T,DataDeleter> r(nullptr, DataDeleter{this->arena()});
2203 if (this->dptr && this->ptr_owner) {
2204 r.reset(this->dptr);
2205 this->ptr_owner = false;
2206 if (this->nvar > 1) {
2207 amrex::update_fab_stats(-this->truesize/this->nvar, -this->truesize, sizeof(T));
2208 } else {
2209 amrex::update_fab_stats(0, -this->truesize, sizeof(T));
2210 }
2211 }
2212 return r;
2213}
2214
2215template <class T>
2216template <RunOn run_on>
2217std::size_t
2219 int srccomp,
2220 int numcomp,
2221 void* dst) const noexcept
2222{
2223 BL_ASSERT(box().contains(srcbox));
2224 BL_ASSERT(srccomp >= 0 && srccomp+numcomp <= nComp());
2225
2226 if (srcbox.ok())
2227 {
2228 Array4<T> d(static_cast<T*>(dst),amrex::begin(srcbox),amrex::end(srcbox),numcomp);
2229 Array4<T const> const& s = this->const_array();
2230 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, srcbox, numcomp, i, j, k, n,
2231 {
2232 d(i,j,k,n) = s(i,j,k,n+srccomp);
2233 });
2234 return sizeof(T)*d.size();
2235 }
2236 else
2237 {
2238 return 0;
2239 }
2240}
2241
2242template <class T>
2243template <RunOn run_on, typename BUF>
2244std::size_t
2246 int dstcomp,
2247 int numcomp,
2248 const void* src) noexcept
2249{
2250 BL_ASSERT(box().contains(dstbox));
2251 BL_ASSERT(dstcomp >= 0 && dstcomp+numcomp <= nComp());
2252
2253 if (dstbox.ok())
2254 {
2255 Array4<BUF const> s(static_cast<BUF const*>(src), amrex::begin(dstbox),
2256 amrex::end(dstbox), numcomp);
2257 Array4<T> const& d = this->array();
2258 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, dstbox, numcomp, i, j, k, n,
2259 {
2260 d(i,j,k,n+dstcomp) = static_cast<T>(s(i,j,k,n));
2261 });
2262 return sizeof(BUF)*s.size();
2263 }
2264 else
2265 {
2266 return 0;
2267 }
2268}
2269
2270template <class T>
2271template <RunOn run_on, typename BUF>
2272std::size_t
2274 int dstcomp,
2275 int numcomp,
2276 const void* src) noexcept
2277{
2278 BL_ASSERT(box().contains(dstbox));
2279 BL_ASSERT(dstcomp >= 0 && dstcomp+numcomp <= nComp());
2280
2281 if (dstbox.ok())
2282 {
2283 Array4<BUF const> s(static_cast<BUF const*>(src), amrex::begin(dstbox),
2284 amrex::end(dstbox), numcomp);
2285 Array4<T> const& d = this->array();
2286 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, dstbox, numcomp, i, j, k, n,
2287 {
2288 d(i,j,k,n+dstcomp) += static_cast<T>(s(i,j,k,n));
2289 });
2290 return sizeof(BUF)*s.size();
2291 }
2292 else
2293 {
2294 return 0;
2295 }
2296}
2297
2298template <class T>
2299template <RunOn run_on>
2300void
2301BaseFab<T>::setComplement (T const& x, const Box& b, int ns, int num) noexcept
2302{
2303 this->setComplement<run_on>(x, b, DestComp{ns}, NumComps{num});
2304}
2305
2306template <class T>
2307template <RunOn run_on>
2308void
2310{
2311 this->abs<run_on>(this->domain,0,this->nvar);
2312}
2313
2314template <class T>
2315template <RunOn run_on>
2316void
2317BaseFab<T>::abs (int comp, int numcomp) noexcept
2318{
2319 this->abs<run_on>(this->domain,comp,numcomp);
2320}
2321
2322template <class T>
2323template <RunOn run_on>
2324void
2325BaseFab<T>::abs (const Box& subbox, int comp, int numcomp) noexcept
2326{
2327 Array4<T> const& a = this->array();
2328 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG (run_on, subbox, numcomp, i, j, k, n,
2329 {
2330 a(i,j,k,n+comp) = std::abs(a(i,j,k,n+comp));
2331 });
2332}
2333
2334template <class T>
2335template <RunOn run_on>
2336Real
2338 int scomp, int ncomp) const noexcept
2339{
2340 BL_ASSERT(this->domain.contains(subbox));
2341 BL_ASSERT(scomp >= 0 && scomp + ncomp <= this->nvar);
2342
2343 Array4<T const> const& a = this->const_array();
2344 Array4<int const> const& m = mask.const_array();
2345 Real r = 0.0;
2346#ifdef AMREX_USE_GPU
2347 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
2348 ReduceOps<ReduceOpMax> reduce_op;
2349 ReduceData<Real> reduce_data(reduce_op);
2350 using ReduceTuple = ReduceData<Real>::Type;
2351 reduce_op.eval(subbox, reduce_data,
2352 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2353 {
2354 Real t = 0.0;
2355 if (m(i,j,k)) {
2356 for (int n = 0; n < ncomp; ++n) {
2357 t = amrex::max(t,static_cast<Real>(std::abs(a(i,j,k,n+scomp))));
2358 }
2359 }
2360 return {t};
2361 });
2362 ReduceTuple hv = reduce_data.value(reduce_op);
2363 r = amrex::get<0>(hv);
2364 } else
2365#endif
2366 {
2367 amrex::LoopOnCpu(subbox, ncomp, [=,&r] (int i, int j, int k, int n) noexcept
2368 {
2369 if (m(i,j,k)) {
2370 Real t = static_cast<Real>(std::abs(a(i,j,k,n+scomp)));
2371 r = amrex::max(r,t);
2372 }
2373 });
2374 }
2375 return r;
2376}
2377
2378template <class T>
2379template <RunOn run_on>
2380Real
2381BaseFab<T>::norm (int p, int comp, int numcomp) const noexcept
2382{
2383 return norm<run_on>(this->domain,p,comp,numcomp);
2384}
2385
2386template <class T>
2387template <RunOn run_on>
2388Real
2389BaseFab<T>::norm (const Box& subbox, int p, int comp, int numcomp) const noexcept
2390{
2391 BL_ASSERT(this->domain.contains(subbox));
2392 BL_ASSERT(comp >= 0 && comp + numcomp <= this->nvar);
2393
2394 Array4<T const> const& a = this->const_array();
2395 Real nrm = 0.;
2396#ifdef AMREX_USE_GPU
2397 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
2398 if (p == 0) {
2399 ReduceOps<ReduceOpMax> reduce_op;
2400 ReduceData<Real> reduce_data(reduce_op);
2401 using ReduceTuple = ReduceData<Real>::Type;
2402 reduce_op.eval(subbox, reduce_data,
2403 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2404 {
2405 Real t = 0.0;
2406 for (int n = 0; n < numcomp; ++n) {
2407 t = amrex::max(t, static_cast<Real>(std::abs(a(i,j,k,n+comp))));
2408 }
2409 return {t};
2410 });
2411 ReduceTuple hv = reduce_data.value(reduce_op);
2412 nrm = amrex::get<0>(hv);
2413 } else if (p == 1) {
2414 ReduceOps<ReduceOpSum> reduce_op;
2415 ReduceData<Real> reduce_data(reduce_op);
2416 using ReduceTuple = ReduceData<Real>::Type;
2417 reduce_op.eval(subbox, reduce_data,
2418 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2419 {
2420 Real t = 0.0;
2421 for (int n = 0; n < numcomp; ++n) {
2422 t += static_cast<Real>(std::abs(a(i,j,k,n+comp)));
2423 }
2424 return {t};
2425 });
2426 ReduceTuple hv = reduce_data.value(reduce_op);
2427 nrm = amrex::get<0>(hv);
2428 } else if (p == 2) {
2429 ReduceOps<ReduceOpSum> reduce_op;
2430 ReduceData<Real> reduce_data(reduce_op);
2431 using ReduceTuple = ReduceData<Real>::Type;
2432 reduce_op.eval(subbox, reduce_data,
2433 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2434 {
2435 Real t = 0.0;
2436 for (int n = 0; n < numcomp; ++n) {
2437 t += static_cast<Real>(a(i,j,k,n+comp)*a(i,j,k,n+comp));
2438 }
2439 return {t};
2440 });
2441 ReduceTuple hv = reduce_data.value(reduce_op);
2442 nrm = amrex::get<0>(hv);
2443 } else {
2444 amrex::Error("BaseFab<T>::norm: wrong p");
2445 }
2446 } else
2447#endif
2448 {
2449 if (p == 0) {
2450 amrex::LoopOnCpu(subbox, numcomp, [=,&nrm] (int i, int j, int k, int n) noexcept
2451 {
2452 Real t = static_cast<Real>(std::abs(a(i,j,k,n+comp)));
2453 nrm = amrex::max(nrm,t);
2454 });
2455 } else if (p == 1) {
2456 amrex::LoopOnCpu(subbox, numcomp, [=,&nrm] (int i, int j, int k, int n) noexcept
2457 {
2458 nrm += std::abs(a(i,j,k,n+comp));
2459 });
2460 } else if (p == 2) {
2461 amrex::LoopOnCpu(subbox, numcomp, [=,&nrm] (int i, int j, int k, int n) noexcept
2462 {
2463 nrm += a(i,j,k,n+comp)*a(i,j,k,n+comp);
2464 });
2465 } else {
2466 amrex::Error("BaseFab<T>::norm: wrong p");
2467 }
2468 }
2469
2470 return nrm;
2471}
2472
2473template <class T>
2474template <RunOn run_on>
2475T
2476BaseFab<T>::min (int comp) const noexcept
2477{
2478 return this->min<run_on>(this->domain,comp);
2479}
2480
2481template <class T>
2482template <RunOn run_on>
2483T
2484BaseFab<T>::min (const Box& subbox, int comp) const noexcept
2485{
2486 Array4<T const> const& a = this->const_array(comp);
2487#ifdef AMREX_USE_GPU
2488 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
2489 ReduceOps<ReduceOpMin> reduce_op;
2490 ReduceData<T> reduce_data(reduce_op);
2491 using ReduceTuple = typename decltype(reduce_data)::Type;
2492 reduce_op.eval(subbox, reduce_data,
2493 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2494 {
2495 return { a(i,j,k) };
2496 });
2497 ReduceTuple hv = reduce_data.value(reduce_op);
2498 return amrex::get<0>(hv);
2499 } else
2500#endif
2501 {
2502 T r = std::numeric_limits<T>::max();
2503 amrex::LoopOnCpu(subbox, [=,&r] (int i, int j, int k) noexcept
2504 {
2505 r = amrex::min(r, a(i,j,k));
2506 });
2507 return r;
2508 }
2509}
2510
2511template <class T>
2512template <RunOn run_on>
2513T
2514BaseFab<T>::max (int comp) const noexcept
2515{
2516 return this->max<run_on>(this->domain,comp);
2517}
2518
2519template <class T>
2520template <RunOn run_on>
2521T
2522BaseFab<T>::max (const Box& subbox, int comp) const noexcept
2523{
2524 Array4<T const> const& a = this->const_array(comp);
2525#ifdef AMREX_USE_GPU
2526 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
2527 ReduceOps<ReduceOpMax> reduce_op;
2528 ReduceData<T> reduce_data(reduce_op);
2529 using ReduceTuple = typename decltype(reduce_data)::Type;
2530 reduce_op.eval(subbox, reduce_data,
2531 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2532 {
2533 return { a(i,j,k) };
2534 });
2535 ReduceTuple hv = reduce_data.value(reduce_op);
2536 return amrex::get<0>(hv);
2537 } else
2538#endif
2539 {
2540 T r = std::numeric_limits<T>::lowest();
2541 amrex::LoopOnCpu(subbox, [=,&r] (int i, int j, int k) noexcept
2542 {
2543 r = amrex::max(r, a(i,j,k));
2544 });
2545 return r;
2546 }
2547}
2548
2549template <class T>
2550template <RunOn run_on>
2551std::pair<T,T>
2552BaseFab<T>::minmax (int comp) const noexcept
2553{
2554 return this->minmax<run_on>(this->domain,comp);
2555}
2556
2557template <class T>
2558template <RunOn run_on>
2559std::pair<T,T>
2560BaseFab<T>::minmax (const Box& subbox, int comp) const noexcept
2561{
2562 Array4<T const> const& a = this->const_array(comp);
2563#ifdef AMREX_USE_GPU
2564 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
2566 ReduceData<T,T> reduce_data(reduce_op);
2567 using ReduceTuple = typename decltype(reduce_data)::Type;
2568 reduce_op.eval(subbox, reduce_data,
2569 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2570 {
2571 auto const x = a(i,j,k);
2572 return { x, x };
2573 });
2574 ReduceTuple hv = reduce_data.value(reduce_op);
2575 return std::make_pair(amrex::get<0>(hv), amrex::get<1>(hv));
2576 } else
2577#endif
2578 {
2579 T rmax = std::numeric_limits<T>::lowest();
2580 T rmin = std::numeric_limits<T>::max();
2581 amrex::LoopOnCpu(subbox, [=,&rmin,&rmax] (int i, int j, int k) noexcept
2582 {
2583 auto const x = a(i,j,k);
2584 rmin = amrex::min(rmin, x);
2585 rmax = amrex::max(rmax, x);
2586 });
2587 return std::make_pair(rmin,rmax);
2588 }
2589}
2590
2591template <class T>
2592template <RunOn run_on>
2593T
2594BaseFab<T>::maxabs (int comp) const noexcept
2595{
2596 return this->maxabs<run_on>(this->domain,comp);
2597}
2598
2599template <class T>
2600template <RunOn run_on>
2601T
2602BaseFab<T>::maxabs (const Box& subbox, int comp) const noexcept
2603{
2604 Array4<T const> const& a = this->const_array(comp);
2605#ifdef AMREX_USE_GPU
2606 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
2607 ReduceOps<ReduceOpMax> reduce_op;
2608 ReduceData<T> reduce_data(reduce_op);
2609 using ReduceTuple = typename decltype(reduce_data)::Type;
2610 reduce_op.eval(subbox, reduce_data,
2611 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2612 {
2613 return { std::abs(a(i,j,k)) };
2614 });
2615 ReduceTuple hv = reduce_data.value(reduce_op);
2616 return amrex::get<0>(hv);
2617 } else
2618#endif
2619 {
2620 T r = 0;
2621 amrex::LoopOnCpu(subbox, [=,&r] (int i, int j, int k) noexcept
2622 {
2623 r = amrex::max(r, std::abs(a(i,j,k)));
2624 });
2625 return r;
2626 }
2627}
2628
2629
2630template <class T>
2631template <RunOn run_on>
2632IntVect
2633BaseFab<T>::indexFromValue (Box const& subbox, int comp, T const& value) const noexcept
2634{
2635 Array4<T const> const& a = this->const_array(comp);
2636#ifdef AMREX_USE_GPU
2637 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
2638 Array<int,1+AMREX_SPACEDIM> ha{0,AMREX_D_DECL(std::numeric_limits<int>::lowest(),
2639 std::numeric_limits<int>::lowest(),
2640 std::numeric_limits<int>::lowest())};
2641 Gpu::DeviceVector<int> dv(1+AMREX_SPACEDIM);
2642 int* p = dv.data();
2643 Gpu::htod_memcpy_async(p, ha.data(), sizeof(int)*ha.size());
2644 amrex::ParallelFor(subbox, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
2645 {
2646 int* flag = p;
2647 if ((*flag == 0) && (a(i,j,k) == value)) {
2648 if (Gpu::Atomic::Exch(flag,1) == 0) {
2649 AMREX_D_TERM(p[1] = i;,
2650 p[2] = j;,
2651 p[3] = k;);
2652 }
2653 }
2654 });
2655 Gpu::dtoh_memcpy_async(ha.data(), p, sizeof(int)*ha.size());
2657 return IntVect(AMREX_D_DECL(ha[1],ha[2],ha[2]));
2658 } else
2659#endif
2660 {
2661 AMREX_LOOP_3D(subbox, i, j, k,
2662 {
2663 if (a(i,j,k) == value) { return IntVect(AMREX_D_DECL(i,j,k)); }
2664 });
2665 return IntVect::TheMinVector();
2666 }
2667}
2668
2669template <class T>
2670template <RunOn run_on>
2671IntVect
2672BaseFab<T>::minIndex (int comp) const noexcept
2673{
2674 return this->minIndex<run_on>(this->domain,comp);
2675}
2676
2677template <class T>
2678template <RunOn run_on>
2679IntVect
2680BaseFab<T>::minIndex (const Box& subbox, int comp) const noexcept
2681{
2682 T min_val = this->min<run_on>(subbox, comp);
2683 return this->indexFromValue<run_on>(subbox, comp, min_val);
2684}
2685
2686template <class T>
2687template <RunOn run_on>
2688void
2689BaseFab<T>::minIndex (const Box& subbox, Real& min_val, IntVect& min_idx, int comp) const noexcept
2690{
2691 min_val = this->min<run_on>(subbox, comp);
2692 min_idx = this->indexFromValue<run_on>(subbox, comp, min_val);
2693}
2694
2695template <class T>
2696template <RunOn run_on>
2697IntVect
2698BaseFab<T>::maxIndex (int comp) const noexcept
2699{
2700 return this->maxIndex<run_on>(this->domain,comp);
2701}
2702
2703template <class T>
2704template <RunOn run_on>
2705IntVect
2706BaseFab<T>::maxIndex (const Box& subbox, int comp) const noexcept
2707{
2708 T max_val = this->max<run_on>(subbox, comp);
2709 return this->indexFromValue<run_on>(subbox, comp, max_val);
2710}
2711
2712template <class T>
2713template <RunOn run_on>
2714void
2715BaseFab<T>::maxIndex (const Box& subbox, Real& max_val, IntVect& max_idx, int comp) const noexcept
2716{
2717 max_val = this->max<run_on>(subbox, comp);
2718 max_idx = this->indexFromValue<run_on>(subbox, comp, max_val);
2719}
2720
2721template <class T>
2722template <RunOn run_on>
2723int
2724BaseFab<T>::maskLT (BaseFab<int>& mask, T const& val, int comp) const noexcept
2725{
2726 mask.resize(this->domain,1);
2727 int cnt = 0;
2728 Array4<int> const& m = mask.array();
2729 Array4<T const> const& a = this->const_array(comp);
2730#ifdef AMREX_USE_GPU
2731 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
2732 ReduceOps<ReduceOpSum> reduce_op;
2733 ReduceData<int> reduce_data(reduce_op);
2734 using ReduceTuple = typename decltype(reduce_data)::Type;
2735 reduce_op.eval(this->domain, reduce_data,
2736 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2737 {
2738 int t;
2739 if (a(i,j,k) < val) {
2740 m(i,j,k) = 1;
2741 t = 1;
2742 } else {
2743 m(i,j,k) = 0;
2744 t = 0;
2745 }
2746 return {t};
2747 });
2748 ReduceTuple hv = reduce_data.value(reduce_op);
2749 cnt = amrex::get<0>(hv);
2750 } else
2751#endif
2752 {
2753 AMREX_LOOP_3D(this->domain, i, j, k,
2754 {
2755 if (a(i,j,k) < val) {
2756 m(i,j,k) = 1;
2757 ++cnt;
2758 } else {
2759 m(i,j,k) = 0;
2760 }
2761 });
2762 }
2763
2764 return cnt;
2765}
2766
2767template <class T>
2768template <RunOn run_on>
2769int
2770BaseFab<T>::maskLE (BaseFab<int>& mask, T const& val, int comp) const noexcept
2771{
2772 mask.resize(this->domain,1);
2773 int cnt = 0;
2774 Array4<int> const& m = mask.array();
2775 Array4<T const> const& a = this->const_array(comp);
2776#ifdef AMREX_USE_GPU
2777 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
2778 ReduceOps<ReduceOpSum> reduce_op;
2779 ReduceData<int> reduce_data(reduce_op);
2780 using ReduceTuple = typename decltype(reduce_data)::Type;
2781 reduce_op.eval(this->domain, reduce_data,
2782 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2783 {
2784 int t;
2785 if (a(i,j,k) <= val) {
2786 m(i,j,k) = 1;
2787 t = 1;
2788 } else {
2789 m(i,j,k) = 0;
2790 t = 0;
2791 }
2792 return {t};
2793 });
2794 ReduceTuple hv = reduce_data.value(reduce_op);
2795 cnt = amrex::get<0>(hv);
2796 } else
2797#endif
2798 {
2799 AMREX_LOOP_3D(this->domain, i, j, k,
2800 {
2801 if (a(i,j,k) <= val) {
2802 m(i,j,k) = 1;
2803 ++cnt;
2804 } else {
2805 m(i,j,k) = 0;
2806 }
2807 });
2808 }
2809
2810 return cnt;
2811}
2812
2813template <class T>
2814template <RunOn run_on>
2815int
2816BaseFab<T>::maskEQ (BaseFab<int>& mask, T const& val, int comp) const noexcept
2817{
2818 mask.resize(this->domain,1);
2819 int cnt = 0;
2820 Array4<int> const& m = mask.array();
2821 Array4<T const> const& a = this->const_array(comp);
2822#ifdef AMREX_USE_GPU
2823 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
2824 ReduceOps<ReduceOpSum> reduce_op;
2825 ReduceData<int> reduce_data(reduce_op);
2826 using ReduceTuple = typename decltype(reduce_data)::Type;
2827 reduce_op.eval(this->domain, reduce_data,
2828 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2829 {
2830 int t;
2831 if (a(i,j,k) == val) {
2832 m(i,j,k) = 1;
2833 t = 1;
2834 } else {
2835 m(i,j,k) = 0;
2836 t = 0;
2837 }
2838 return {t};
2839 });
2840 ReduceTuple hv = reduce_data.value(reduce_op);
2841 cnt = amrex::get<0>(hv);
2842 } else
2843#endif
2844 {
2845 AMREX_LOOP_3D(this->domain, i, j, k,
2846 {
2847 if (a(i,j,k) == val) {
2848 m(i,j,k) = 1;
2849 ++cnt;
2850 } else {
2851 m(i,j,k) = 0;
2852 }
2853 });
2854 }
2855
2856 return cnt;
2857}
2858
2859template <class T>
2860template <RunOn run_on>
2861int
2862BaseFab<T>::maskGT (BaseFab<int>& mask, T const& val, int comp) const noexcept
2863{
2864 mask.resize(this->domain,1);
2865 int cnt = 0;
2866 Array4<int> const& m = mask.array();
2867 Array4<T const> const& a = this->const_array(comp);
2868#ifdef AMREX_USE_GPU
2869 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
2870 ReduceOps<ReduceOpSum> reduce_op;
2871 ReduceData<int> reduce_data(reduce_op);
2872 using ReduceTuple = typename decltype(reduce_data)::Type;
2873 reduce_op.eval(this->domain, reduce_data,
2874 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2875 {
2876 int t;
2877 if (a(i,j,k) > val) {
2878 m(i,j,k) = 1;
2879 t = 1;
2880 } else {
2881 m(i,j,k) = 0;
2882 t = 0;
2883 }
2884 return {t};
2885 });
2886 ReduceTuple hv = reduce_data.value(reduce_op);
2887 cnt = amrex::get<0>(hv);
2888 } else
2889#endif
2890 {
2891 AMREX_LOOP_3D(this->domain, i, j, k,
2892 {
2893 if (a(i,j,k) > val) {
2894 m(i,j,k) = 1;
2895 ++cnt;
2896 } else {
2897 m(i,j,k) = 0;
2898 }
2899 });
2900 }
2901
2902 return cnt;
2903}
2904
2905template <class T>
2906template <RunOn run_on>
2907int
2908BaseFab<T>::maskGE (BaseFab<int>& mask, T const& val, int comp) const noexcept
2909{
2910 mask.resize(this->domain,1);
2911 int cnt = 0;
2912 Array4<int> const& m = mask.array();
2913 Array4<T const> const& a = this->const_array(comp);
2914#ifdef AMREX_USE_GPU
2915 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
2916 ReduceOps<ReduceOpSum> reduce_op;
2917 ReduceData<int> reduce_data(reduce_op);
2918 using ReduceTuple = typename decltype(reduce_data)::Type;
2919 reduce_op.eval(this->domain, reduce_data,
2920 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
2921 {
2922 int t;
2923 if (a(i,j,k) >= val) {
2924 m(i,j,k) = 1;
2925 t = 1;
2926 } else {
2927 m(i,j,k) = 0;
2928 t = 0;
2929 }
2930 return {t};
2931 });
2932 ReduceTuple hv = reduce_data.value(reduce_op);
2933 cnt = amrex::get<0>(hv);
2934 } else
2935#endif
2936 {
2937 AMREX_LOOP_3D(this->domain, i, j, k,
2938 {
2939 if (a(i,j,k) >= val) {
2940 m(i,j,k) = 1;
2941 ++cnt;
2942 } else {
2943 m(i,j,k) = 0;
2944 }
2945 });
2946 }
2947
2948 return cnt;
2949}
2950
2951template <class T>
2952template <RunOn run_on>
2955{
2956 Box ovlp(this->domain);
2957 ovlp &= x.domain;
2958 return ovlp.ok() ? this->atomicAdd<run_on>(x,ovlp,ovlp,0,0,this->nvar) : *this;
2959}
2960
2961template <class T>
2962template <RunOn run_on>
2964BaseFab<T>::saxpy (T a, const BaseFab<T>& x, const Box& srcbox, const Box& destbox,
2965 int srccomp, int destcomp, int numcomp) noexcept
2966{
2967 BL_ASSERT(srcbox.ok());
2968 BL_ASSERT(x.box().contains(srcbox));
2969 BL_ASSERT(destbox.ok());
2970 BL_ASSERT(box().contains(destbox));
2971 BL_ASSERT(destbox.sameSize(srcbox));
2972 BL_ASSERT( srccomp >= 0 && srccomp+numcomp <= x.nComp());
2973 BL_ASSERT(destcomp >= 0 && destcomp+numcomp <= nComp());
2974
2975 Array4<T> const& d = this->array();
2976 Array4<T const> const& s = x.const_array();
2977 const auto dlo = amrex::lbound(destbox);
2978 const auto slo = amrex::lbound(srcbox);
2979 const Dim3 offset{slo.x-dlo.x,slo.y-dlo.y,slo.z-dlo.z};
2980 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, destbox, numcomp, i, j, k, n,
2981 {
2982 d(i,j,k,n+destcomp) += a * s(i+offset.x,j+offset.y,k+offset.z,n+srccomp);
2983 });
2984
2985 return *this;
2986}
2987
2988template <class T>
2989template <RunOn run_on>
2991BaseFab<T>::saxpy (T a, const BaseFab<T>& x) noexcept
2992{
2993 Box ovlp(this->domain);
2994 ovlp &= x.domain;
2995 return ovlp.ok() ? saxpy<run_on>(a,x,ovlp,ovlp,0,0,this->nvar) : *this;
2996}
2997
2998template <class T>
2999template <RunOn run_on>
3002 const Box& srcbox, const Box& destbox,
3003 int srccomp, int destcomp, int numcomp) noexcept
3004{
3005 BL_ASSERT(srcbox.ok());
3006 BL_ASSERT(x.box().contains(srcbox));
3007 BL_ASSERT(destbox.ok());
3008 BL_ASSERT(box().contains(destbox));
3009 BL_ASSERT(destbox.sameSize(srcbox));
3010 BL_ASSERT( srccomp >= 0 && srccomp+numcomp <= x.nComp());
3011 BL_ASSERT(destcomp >= 0 && destcomp+numcomp <= nComp());
3012
3013 Array4<T> const& d = this->array();
3014 Array4<T const> const& s = x.const_array();
3015 const auto dlo = amrex::lbound(destbox);
3016 const auto slo = amrex::lbound(srcbox);
3017 const Dim3 offset{slo.x-dlo.x,slo.y-dlo.y,slo.z-dlo.z};
3018 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, destbox, numcomp, i, j, k, n,
3019 {
3020 d(i,j,k,n+destcomp) = s(i+offset.x,j+offset.y,k+offset.z,n+srccomp) + a*d(i,j,k,n+destcomp);
3021 });
3022
3023 return *this;
3024}
3025
3026template <class T>
3027template <RunOn run_on>
3029BaseFab<T>::addproduct (const Box& destbox, int destcomp, int numcomp,
3030 const BaseFab<T>& src1, int comp1,
3031 const BaseFab<T>& src2, int comp2) noexcept
3032{
3033 BL_ASSERT(destbox.ok());
3034 BL_ASSERT(box().contains(destbox));
3035 BL_ASSERT( comp1 >= 0 && comp1+numcomp <= src1.nComp());
3036 BL_ASSERT( comp2 >= 0 && comp2+numcomp <= src2.nComp());
3037 BL_ASSERT(destcomp >= 0 && destcomp+numcomp <= nComp());
3038
3039 Array4<T> const& d = this->array();
3040 Array4<T const> const& s1 = src1.const_array();
3041 Array4<T const> const& s2 = src2.const_array();
3042 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, destbox, numcomp, i, j, k, n,
3043 {
3044 d(i,j,k,n+destcomp) += s1(i,j,k,n+comp1) * s2(i,j,k,n+comp2);
3045 });
3046
3047 return *this;
3048}
3049
3050template <class T>
3051template <RunOn run_on>
3053BaseFab<T>::linComb (const BaseFab<T>& f1, const Box& b1, int comp1,
3054 const BaseFab<T>& f2, const Box& b2, int comp2,
3055 Real alpha, Real beta, const Box& b,
3056 int comp, int numcomp) noexcept
3057{
3058 BL_ASSERT(b1.ok());
3059 BL_ASSERT(f1.box().contains(b1));
3060 BL_ASSERT(b2.ok());
3061 BL_ASSERT(f2.box().contains(b2));
3062 BL_ASSERT(b.ok());
3063 BL_ASSERT(box().contains(b));
3064 BL_ASSERT(b.sameSize(b1));
3065 BL_ASSERT(b.sameSize(b2));
3066 BL_ASSERT(comp1 >= 0 && comp1+numcomp <= f1.nComp());
3067 BL_ASSERT(comp2 >= 0 && comp2+numcomp <= f2.nComp());
3068 BL_ASSERT(comp >= 0 && comp +numcomp <= nComp());
3069
3070 Array4<T> const& d = this->array();
3071 Array4<T const> const& s1 = f1.const_array();
3072 Array4<T const> const& s2 = f2.const_array();
3073 const auto dlo = amrex::lbound(b);
3074 const auto slo1 = amrex::lbound(b1);
3075 const auto slo2 = amrex::lbound(b2);
3076 const Dim3 off1{slo1.x-dlo.x,slo1.y-dlo.y,slo1.z-dlo.z};
3077 const Dim3 off2{slo2.x-dlo.x,slo2.y-dlo.y,slo2.z-dlo.z};
3078
3079 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, b, numcomp, i, j, k, n,
3080 {
3081 d(i,j,k,n+comp) = alpha*s1(i+off1.x,j+off1.y,k+off1.z,n+comp1)
3082 + beta*s2(i+off2.x,j+off2.y,k+off2.z,n+comp2);
3083 });
3084 return *this;
3085}
3086
3087template <class T>
3088template <RunOn run_on>
3089T
3090BaseFab<T>::dot (const Box& xbx, int xcomp,
3091 const BaseFab<T>& y, const Box& ybx, int ycomp,
3092 int numcomp) const noexcept
3093{
3094 BL_ASSERT(xbx.ok());
3095 BL_ASSERT(box().contains(xbx));
3096 BL_ASSERT(y.box().contains(ybx));
3097 BL_ASSERT(xbx.sameSize(ybx));
3098 BL_ASSERT(xcomp >= 0 && xcomp+numcomp <= nComp());
3099 BL_ASSERT(ycomp >= 0 && ycomp+numcomp <= y.nComp());
3100
3101 T r = 0;
3102
3103 const auto xlo = amrex::lbound(xbx);
3104 const auto ylo = amrex::lbound(ybx);
3105 const Dim3 offset{ylo.x-xlo.x,ylo.y-xlo.y,ylo.z-xlo.z};
3106 Array4<T const> const& xa = this->const_array();
3107 Array4<T const> const& ya = y.const_array();
3108
3109#ifdef AMREX_USE_GPU
3110 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
3111 ReduceOps<ReduceOpSum> reduce_op;
3112 ReduceData<T> reduce_data(reduce_op);
3113 using ReduceTuple = typename decltype(reduce_data)::Type;
3114 reduce_op.eval(xbx, reduce_data,
3115 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
3116 {
3117 T t = 0;
3118 for (int n = 0; n < numcomp; ++n) {
3119 t += xa(i,j,k,n+xcomp) * ya(i+offset.x,j+offset.y,k+offset.z,n+ycomp);
3120 }
3121 return {t};
3122 });
3123 ReduceTuple hv = reduce_data.value(reduce_op);
3124 r = amrex::get<0>(hv);
3125 } else
3126#endif
3127 {
3128 AMREX_LOOP_4D(xbx, numcomp, i, j, k, n,
3129 {
3130 r += xa(i,j,k,n+xcomp) * ya(i+offset.x,j+offset.y,k+offset.z,n+ycomp);
3131 });
3132 }
3133
3134 return r;
3135}
3136
3137template <class T>
3138template <RunOn run_on>
3139T
3140BaseFab<T>::dotmask (const BaseFab<int>& mask, const Box& xbx, int xcomp,
3141 const BaseFab<T>& y, const Box& ybx, int ycomp,
3142 int numcomp) const noexcept
3143{
3144 BL_ASSERT(xbx.ok());
3145 BL_ASSERT(box().contains(xbx));
3146 BL_ASSERT(y.box().contains(ybx));
3147 BL_ASSERT(xbx.sameSize(ybx));
3148 BL_ASSERT(xcomp >= 0 && xcomp+numcomp <= nComp());
3149 BL_ASSERT(ycomp >= 0 && ycomp+numcomp <= y.nComp());
3150
3151 T r = 0;
3152
3153 const auto xlo = amrex::lbound(xbx);
3154 const auto ylo = amrex::lbound(ybx);
3155 const Dim3 offset{ylo.x-xlo.x,ylo.y-xlo.y,ylo.z-xlo.z};
3156
3157 Array4<T const> const& xa = this->const_array();
3158 Array4<T const> const& ya = y.const_array();
3159 Array4<int const> const& ma = mask.const_array();
3160
3161#ifdef AMREX_USE_GPU
3162 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
3163 ReduceOps<ReduceOpSum> reduce_op;
3164 ReduceData<T> reduce_data(reduce_op);
3165 using ReduceTuple = typename decltype(reduce_data)::Type;
3166 reduce_op.eval(xbx, reduce_data,
3167 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
3168 {
3169 int m = static_cast<int>(static_cast<bool>(ma(i,j,k)));
3170 T t = 0;
3171 for (int n = 0; n < numcomp; ++n) {
3172 t += xa(i,j,k,n+xcomp) * ya(i+offset.x,j+offset.y,k+offset.z,n+ycomp) * m;
3173 }
3174 return {t};
3175 });
3176 ReduceTuple hv = reduce_data.value(reduce_op);
3177 r = amrex::get<0>(hv);
3178 } else
3179#endif
3180 {
3181 AMREX_LOOP_4D(xbx, numcomp, i, j, k, n,
3182 {
3183 int m = static_cast<int>(static_cast<bool>(ma(i,j,k)));
3184 r += xa(i,j,k,n+xcomp) * ya(i+offset.x,j+offset.y,k+offset.z,n+ycomp) * m;
3185 });
3186 }
3187
3188 return r;
3189}
3190
3191template <class T>
3192template <RunOn run_on>
3193T
3194BaseFab<T>::sum (int comp, int numcomp) const noexcept
3195{
3196 return this->sum<run_on>(this->domain, DestComp{comp}, NumComps{numcomp});
3197}
3198
3199template <class T>
3200template <RunOn run_on>
3201T
3202BaseFab<T>::sum (const Box& subbox, int comp, int numcomp) const noexcept
3203{
3204 return this->sum<run_on>(subbox, DestComp{comp}, NumComps{numcomp});
3205}
3206
3207template <class T>
3208template <RunOn run_on>
3210BaseFab<T>::negate (int comp, int numcomp) noexcept
3211{
3212 return this->negate<run_on>(this->domain, DestComp{comp}, NumComps{numcomp});
3213}
3214
3215template <class T>
3216template <RunOn run_on>
3218BaseFab<T>::negate (const Box& b, int comp, int numcomp) noexcept
3219{
3220 return this->negate<run_on>(b, DestComp{comp}, NumComps{numcomp});
3221}
3222
3223template <class T>
3224template <RunOn run_on>
3226BaseFab<T>::invert (T const& r, int comp, int numcomp) noexcept
3227{
3228 return this->invert<run_on>(r, this->domain, DestComp{comp}, NumComps{numcomp});
3229}
3230
3231template <class T>
3232template <RunOn run_on>
3234BaseFab<T>::invert (T const& r, const Box& b, int comp, int numcomp) noexcept
3235{
3236 return this->invert<run_on>(r, b, DestComp{comp}, NumComps{numcomp});
3237}
3238
3239template <class T>
3240template <RunOn run_on>
3242BaseFab<T>::plus (T const& r, int comp, int numcomp) noexcept
3243{
3244 return this->plus<run_on>(r, this->domain, DestComp{comp}, NumComps{numcomp});
3245}
3246
3247template <class T>
3248template <RunOn run_on>
3250BaseFab<T>::plus (T const& r, const Box& b, int comp, int numcomp) noexcept
3251{
3252 return this->plus<run_on>(r, b, DestComp{comp}, NumComps{numcomp});
3253}
3254
3255template <class T>
3256template <RunOn run_on>
3258BaseFab<T>::plus (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp) noexcept
3259{
3260 return this->plus<run_on>(src, this->domain, SrcComp{srccomp}, DestComp{destcomp}, NumComps{numcomp});
3261}
3262
3263template <class T>
3264template <RunOn run_on>
3266BaseFab<T>::atomicAdd (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp) noexcept
3267{
3268 Box ovlp(this->domain);
3269 ovlp &= src.domain;
3270 return ovlp.ok() ? this->atomicAdd<run_on>(src,ovlp,ovlp,srccomp,destcomp,numcomp) : *this;
3271}
3272
3273template <class T>
3274template <RunOn run_on>
3276BaseFab<T>::plus (const BaseFab<T>& src, const Box& subbox, int srccomp, int destcomp,
3277 int numcomp) noexcept
3278{
3279 return this->plus<run_on>(src, subbox, SrcComp{srccomp}, DestComp{destcomp}, NumComps{numcomp});
3280}
3281
3282template <class T>
3283template <RunOn run_on>
3285BaseFab<T>::atomicAdd (const BaseFab<T>& src, const Box& subbox, int srccomp, int destcomp,
3286 int numcomp) noexcept
3287{
3288 Box ovlp(this->domain);
3289 ovlp &= src.domain;
3290 ovlp &= subbox;
3291 return ovlp.ok() ? this->atomicAdd<run_on>(src,ovlp,ovlp,srccomp,destcomp,numcomp) : *this;
3292}
3293
3294template <class T>
3295template <RunOn run_on>
3297BaseFab<T>::plus (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
3298 int srccomp, int destcomp, int numcomp) noexcept
3299{
3300 BL_ASSERT(destbox.ok());
3301 BL_ASSERT(src.box().contains(srcbox));
3302 BL_ASSERT(box().contains(destbox));
3303 BL_ASSERT(destbox.sameSize(srcbox));
3304 BL_ASSERT(srccomp >= 0 && srccomp+numcomp <= src.nComp());
3305 BL_ASSERT(destcomp >= 0 && destcomp+numcomp <= nComp());
3306
3307 Array4<T> const& d = this->array();
3308 Array4<T const> const& s = src.const_array();
3309 const auto dlo = amrex::lbound(destbox);
3310 const auto slo = amrex::lbound(srcbox);
3311 const Dim3 offset{slo.x-dlo.x,slo.y-dlo.y,slo.z-dlo.z};
3312 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, destbox, numcomp, i, j, k, n,
3313 {
3314 d(i,j,k,n+destcomp) += s(i+offset.x,j+offset.y,k+offset.z,n+srccomp);
3315 });
3316
3317 return *this;
3318}
3319
3320template <class T>
3321template <RunOn run_on>
3323BaseFab<T>::atomicAdd (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
3324 int srccomp, int destcomp, int numcomp) noexcept
3325{
3326 BL_ASSERT(destbox.ok());
3327 BL_ASSERT(src.box().contains(srcbox));
3328 BL_ASSERT(box().contains(destbox));
3329 BL_ASSERT(destbox.sameSize(srcbox));
3330 BL_ASSERT(srccomp >= 0 && srccomp+numcomp <= src.nComp());
3331 BL_ASSERT(destcomp >= 0 && destcomp+numcomp <= nComp());
3332
3333 Array4<T> const& d = this->array();
3334 Array4<T const> const& s = src.const_array();
3335 const auto dlo = amrex::lbound(destbox);
3336 const auto slo = amrex::lbound(srcbox);
3337 const Dim3 offset{slo.x-dlo.x,slo.y-dlo.y,slo.z-dlo.z};
3338 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, destbox, numcomp, i, j, k, n,
3339 {
3340 T* p = d.ptr(i,j,k,n+destcomp);
3341 HostDevice::Atomic::Add(p, s(i+offset.x,j+offset.y,k+offset.z,n+srccomp));
3342 });
3343
3344 return *this;
3345}
3346
3347template <class T>
3348template <RunOn run_on>
3350BaseFab<T>::lockAdd (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
3351 int srccomp, int destcomp, int numcomp) noexcept
3352{
3353#if defined(AMREX_USE_OMP) && (AMREX_SPACEDIM > 1)
3354#if defined(AMREX_USE_GPU)
3355 if (run_on == RunOn::Host || Gpu::notInLaunchRegion()) {
3356#endif
3357 BL_ASSERT(destbox.ok());
3358 BL_ASSERT(src.box().contains(srcbox));
3359 BL_ASSERT(box().contains(destbox));
3360 BL_ASSERT(destbox.sameSize(srcbox));
3361 BL_ASSERT(srccomp >= 0 && srccomp+numcomp <= src.nComp());
3362 BL_ASSERT(destcomp >= 0 && destcomp+numcomp <= nComp());
3363
3364 Array4<T> const& d = this->array();
3365 Array4<T const> const& s = src.const_array();
3366 auto const& dlo = amrex::lbound(destbox);
3367 auto const& dhi = amrex::ubound(destbox);
3368 auto const& len = amrex::length(destbox);
3369 auto const& slo = amrex::lbound(srcbox);
3370 Dim3 const offset{slo.x-dlo.x, slo.y-dlo.y, slo.z-dlo.z};
3371
3372 int planedim;
3373 int nplanes;
3374 int plo;
3375 if (len.z == 1) {
3376 planedim = 1;
3377 nplanes = len.y;
3378 plo = dlo.y;
3379 } else {
3380 planedim = 2;
3381 nplanes = len.z;
3382 plo = dlo.z;
3383 }
3384
3385 auto* mask = (bool*) amrex_mempool_alloc(sizeof(bool)*nplanes);
3386 for (int ip = 0; ip < nplanes; ++ip) {
3387 mask[ip] = false;
3388 }
3389
3390 int mm = 0;
3391 int planes_left = nplanes;
3392 while (planes_left > 0) {
3393 AMREX_ASSERT(mm < nplanes);
3394 auto const m = mm + plo;
3395 auto* lock = OpenMP::get_lock(m);
3396 if (omp_test_lock(lock))
3397 {
3398 auto lo = dlo;
3399 auto hi = dhi;
3400 if (planedim == 1) {
3401 lo.y = m;
3402 hi.y = m;
3403 } else {
3404 lo.z = m;
3405 hi.z = m;
3406 }
3407
3408 for (int n = 0; n < numcomp; ++n) {
3409 for (int k = lo.z; k <= hi.z; ++k) {
3410 for (int j = lo.y; j <= hi.y; ++j) {
3411 auto * pdst = d.ptr(dlo.x,j ,k ,n+destcomp);
3412 auto const* psrc = s.ptr(slo.x,j+offset.y,k+offset.z,n+ srccomp);
3413#pragma omp simd
3414 for (int ii = 0; ii < len.x; ++ii) {
3415 pdst[ii] += psrc[ii];
3416 }
3417 }
3418 }
3419 }
3420
3421 mask[mm] = true;
3422 --planes_left;
3423 omp_unset_lock(lock);
3424 if (planes_left == 0) { break; }
3425 }
3426
3427 ++mm;
3428 for (int ip = 0; ip < nplanes; ++ip) {
3429 int new_mm = (mm+ip) % nplanes;
3430 if ( ! mask[new_mm] ) {
3431 mm = new_mm;
3432 break;
3433 }
3434 }
3435 }
3436
3438
3439 return *this;
3440
3441#if defined(AMREX_USE_GPU)
3442 } else {
3443 return this->template atomicAdd<run_on>(src, srcbox, destbox, srccomp, destcomp, numcomp);
3444 }
3445#endif
3446#else
3447 return this->template atomicAdd<run_on>(src, srcbox, destbox, srccomp, destcomp, numcomp);
3448#endif
3449}
3450
3451template <class T>
3452template <RunOn run_on>
3454BaseFab<T>::minus (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp) noexcept
3455{
3456 return this->minus<run_on>(src, this->domain, SrcComp{srccomp}, DestComp{destcomp}, NumComps{numcomp});
3457}
3458
3459template <class T>
3460template <RunOn run_on>
3462BaseFab<T>::minus (const BaseFab<T>& src, const Box& subbox, int srccomp, int destcomp, int numcomp) noexcept
3463{
3464 return this->minus<run_on>(src, subbox, SrcComp{srccomp}, DestComp{destcomp}, NumComps{numcomp});
3465}
3466
3467template <class T>
3468template <RunOn run_on>
3470BaseFab<T>::minus (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
3471 int srccomp, int destcomp, int numcomp) noexcept
3472{
3473 BL_ASSERT(destbox.ok());
3474 BL_ASSERT(src.box().contains(srcbox));
3475 BL_ASSERT(box().contains(destbox));
3476 BL_ASSERT(destbox.sameSize(srcbox));
3477 BL_ASSERT(srccomp >= 0 && srccomp+numcomp <= src.nComp());
3478 BL_ASSERT(destcomp >= 0 && destcomp+numcomp <= nComp());
3479
3480 Array4<T> const& d = this->array();
3481 Array4<T const> const& s = src.const_array();
3482 const auto dlo = amrex::lbound(destbox);
3483 const auto slo = amrex::lbound(srcbox);
3484 const Dim3 offset{slo.x-dlo.x,slo.y-dlo.y,slo.z-dlo.z};
3485 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, destbox, numcomp, i, j, k, n,
3486 {
3487 d(i,j,k,n+destcomp) -= s(i+offset.x,j+offset.y,k+offset.z,n+srccomp);
3488 });
3489
3490 return *this;
3491}
3492
3493template <class T>
3494template <RunOn run_on>
3496BaseFab<T>::mult (T const& r, int comp, int numcomp) noexcept
3497{
3498 return this->mult<run_on>(r, this->domain, DestComp{comp}, NumComps{numcomp});
3499}
3500
3501template <class T>
3502template <RunOn run_on>
3504BaseFab<T>::mult (T const& r, const Box& b, int comp, int numcomp) noexcept
3505{
3506 return this->mult<run_on>(r, b, DestComp{comp}, NumComps{numcomp});
3507}
3508
3509template <class T>
3510template <RunOn run_on>
3512BaseFab<T>::mult (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp) noexcept
3513{
3514 return this->mult<run_on>(src, this->domain, SrcComp{srccomp}, DestComp{destcomp}, NumComps{numcomp});
3515}
3516
3517template <class T>
3518template <RunOn run_on>
3520BaseFab<T>::mult (const BaseFab<T>& src, const Box& subbox, int srccomp, int destcomp, int numcomp) noexcept
3521{
3522 return this->mult<run_on>(src, subbox, SrcComp{srccomp}, DestComp{destcomp}, NumComps{numcomp});
3523}
3524
3525template <class T>
3526template <RunOn run_on>
3528BaseFab<T>::mult (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
3529 int srccomp, int destcomp, int numcomp) noexcept
3530{
3531 BL_ASSERT(destbox.ok());
3532 BL_ASSERT(src.box().contains(srcbox));
3533 BL_ASSERT(box().contains(destbox));
3534 BL_ASSERT(destbox.sameSize(srcbox));
3535 BL_ASSERT(srccomp >= 0 && srccomp+numcomp <= src.nComp());
3536 BL_ASSERT(destcomp >= 0 && destcomp+numcomp <= nComp());
3537
3538 Array4<T> const& d = this->array();
3539 Array4<T const> const& s = src.const_array();
3540 const auto dlo = amrex::lbound(destbox);
3541 const auto slo = amrex::lbound(srcbox);
3542 const Dim3 offset{slo.x-dlo.x,slo.y-dlo.y,slo.z-dlo.z};
3543 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, destbox, numcomp, i, j, k, n,
3544 {
3545 d(i,j,k,n+destcomp) *= s(i+offset.x,j+offset.y,k+offset.z,n+srccomp);
3546 });
3547
3548 return *this;
3549}
3550
3551template <class T>
3552template <RunOn run_on>
3554BaseFab<T>::divide (T const& r, int comp, int numcomp) noexcept
3555{
3556 return this->divide<run_on>(r, this->domain, DestComp{comp}, NumComps{numcomp});
3557}
3558
3559template <class T>
3560template <RunOn run_on>
3562BaseFab<T>::divide (T const& r, const Box& b, int comp, int numcomp) noexcept
3563{
3564 return this->divide<run_on>(r, b, DestComp{comp}, NumComps{numcomp});
3565}
3566
3567template <class T>
3568template <RunOn run_on>
3570BaseFab<T>::divide (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp) noexcept
3571{
3572 return this->divide<run_on>(src, this->domain, SrcComp{srccomp}, DestComp{destcomp}, NumComps{numcomp});
3573}
3574
3575template <class T>
3576template <RunOn run_on>
3578BaseFab<T>::divide (const BaseFab<T>& src, const Box& subbox, int srccomp, int destcomp, int numcomp) noexcept
3579{
3580 return this->divide<run_on>(src, subbox, SrcComp{srccomp}, DestComp{destcomp}, NumComps{numcomp});
3581}
3582
3583template <class T>
3584template <RunOn run_on>
3586BaseFab<T>::divide (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
3587 int srccomp, int destcomp, int numcomp) noexcept
3588{
3589 BL_ASSERT(destbox.ok());
3590 BL_ASSERT(src.box().contains(srcbox));
3591 BL_ASSERT(box().contains(destbox));
3592 BL_ASSERT(destbox.sameSize(srcbox));
3593 BL_ASSERT(srccomp >= 0 && srccomp+numcomp <= src.nComp());
3594 BL_ASSERT(destcomp >= 0 && destcomp+numcomp <= nComp());
3595
3596 Array4<T> const& d = this->array();
3597 Array4<T const> const& s = src.const_array();
3598 const auto dlo = amrex::lbound(destbox);
3599 const auto slo = amrex::lbound(srcbox);
3600 const Dim3 offset{slo.x-dlo.x,slo.y-dlo.y,slo.z-dlo.z};
3601 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, destbox, numcomp, i, j, k, n,
3602 {
3603 d(i,j,k,n+destcomp) /= s(i+offset.x,j+offset.y,k+offset.z,n+srccomp);
3604 });
3605
3606 return *this;
3607}
3608
3609template <class T>
3610template <RunOn run_on>
3613{
3614 Box ovlp(this->domain);
3615 ovlp &= src.domain;
3616 return ovlp.ok() ? this->protected_divide<run_on>(src,ovlp,ovlp,0,0,this->nvar) : *this;
3617}
3618
3619template <class T>
3620template <RunOn run_on>
3622BaseFab<T>::protected_divide (const BaseFab<T>& src, int srccomp, int destcomp, int numcomp) noexcept
3623{
3624 Box ovlp(this->domain);
3625 ovlp &= src.domain;
3626 return ovlp.ok() ? this->protected_divide<run_on>(src,ovlp,ovlp,srccomp,destcomp,numcomp) : *this;
3627}
3628
3629template <class T>
3630template <RunOn run_on>
3632BaseFab<T>::protected_divide (const BaseFab<T>& src, const Box& subbox, int srccomp, int destcomp,
3633 int numcomp) noexcept
3634{
3635 Box ovlp(this->domain);
3636 ovlp &= src.domain;
3637 ovlp &= subbox;
3638 return ovlp.ok() ? this->protected_divide<run_on>(src,ovlp,ovlp,srccomp,destcomp,numcomp) : *this;
3639}
3640
3641template <class T>
3642template <RunOn run_on>
3644BaseFab<T>::protected_divide (const BaseFab<T>& src, const Box& srcbox, const Box& destbox,
3645 int srccomp, int destcomp, int numcomp) noexcept
3646{
3647 BL_ASSERT(destbox.ok());
3648 BL_ASSERT(src.box().contains(srcbox));
3649 BL_ASSERT(box().contains(destbox));
3650 BL_ASSERT(destbox.sameSize(srcbox));
3651 BL_ASSERT(srccomp >= 0 && srccomp+numcomp <= src.nComp());
3652 BL_ASSERT(destcomp >= 0 && destcomp+numcomp <= nComp());
3653
3654 Array4<T> const& d = this->array();
3655 Array4<T const> const& s = src.const_array();
3656 const auto dlo = amrex::lbound(destbox);
3657 const auto slo = amrex::lbound(srcbox);
3658 const Dim3 offset{slo.x-dlo.x,slo.y-dlo.y,slo.z-dlo.z};
3659 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, destbox, numcomp, i, j, k, n,
3660 {
3661 if (s(i+offset.x,j+offset.y,k+offset.z,n+srccomp) != 0) {
3662 d(i,j,k,n+destcomp) /= s(i+offset.x,j+offset.y,k+offset.z,n+srccomp);
3663 }
3664 });
3665
3666 return *this;
3667}
3668
3679template <class T>
3680template <RunOn run_on>
3682BaseFab<T>::linInterp (const BaseFab<T>& f1, const Box& b1, int comp1,
3683 const BaseFab<T>& f2, const Box& b2, int comp2,
3684 Real t1, Real t2, Real t,
3685 const Box& b, int comp, int numcomp) noexcept
3686{
3687 if (amrex::almostEqual(t1,t2) || amrex::almostEqual(t1,t)) {
3688 return copy<run_on>(f1,b1,comp1,b,comp,numcomp);
3689 } else if (amrex::almostEqual(t2,t)) {
3690 return copy<run_on>(f2,b2,comp2,b,comp,numcomp);
3691 } else {
3692 Real alpha = (t2-t)/(t2-t1);
3693 Real beta = (t-t1)/(t2-t1);
3694 return linComb<run_on>(f1,b1,comp1,f2,b2,comp2,alpha,beta,b,comp,numcomp);
3695 }
3696}
3697
3698template <class T>
3699template <RunOn run_on>
3701BaseFab<T>::linInterp (const BaseFab<T>& f1, int comp1,
3702 const BaseFab<T>& f2, int comp2,
3703 Real t1, Real t2, Real t,
3704 const Box& b, int comp, int numcomp) noexcept
3705{
3706 if (amrex::almostEqual(t1,t2) || amrex::almostEqual(t1,t)) {
3707 return copy<run_on>(f1,b,comp1,b,comp,numcomp);
3708 } else if (amrex::almostEqual(t2,t)) {
3709 return copy<run_on>(f2,b,comp2,b,comp,numcomp);
3710 } else {
3711 Real alpha = (t2-t)/(t2-t1);
3712 Real beta = (t-t1)/(t2-t1);
3713 return linComb<run_on>(f1,b,comp1,f2,b,comp2,alpha,beta,b,comp,numcomp);
3714 }
3715}
3716
3717//
3718// New interfaces
3719//
3720
3721template <class T>
3722template <RunOn run_on>
3723void
3724BaseFab<T>::setVal (T const& val) noexcept
3725{
3726 this->setVal<run_on>(val, this->domain, DestComp{0}, NumComps{this->nvar});
3727}
3728
3729template <class T>
3730template <RunOn run_on>
3731void
3732BaseFab<T>::setVal (T const& x, Box const& bx, DestComp dcomp, NumComps ncomp) noexcept
3733{
3734 AMREX_ASSERT(dcomp.i >= 0 && dcomp.i + ncomp.n <= this->nvar);
3735 Array4<T> const& a = this->array();
3736 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG (run_on, bx, ncomp.n, i, j, k, n,
3737 {
3738 a(i,j,k,n+dcomp.i) = x;
3739 });
3740}
3741
3742template <class T>
3743template <RunOn run_on>
3744void
3745BaseFab<T>::setValIf (T const& val, const BaseFab<int>& mask) noexcept
3746{
3747 this->setValIf<run_on>(val, this->domain, mask, DestComp{0}, NumComps{this->nvar});
3748}
3749
3750template <class T>
3751template <RunOn run_on>
3752void
3753BaseFab<T>::setValIf (T const& val, Box const& bx, const BaseFab<int>& mask, DestComp dcomp, NumComps ncomp) noexcept
3754{
3755 AMREX_ASSERT(dcomp.i >= 0 && dcomp.i + ncomp.n <= this->nvar);
3756 Array4<T> const& a = this->array();
3757 Array4<int const> const& m = mask.const_array();
3758 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG (run_on, bx, ncomp.n, i, j, k, n,
3759 {
3760 if (m(i,j,k)) { a(i,j,k,n+dcomp.i) = val; }
3761 });
3762}
3763
3764template <class T>
3765template <RunOn run_on>
3766void
3767BaseFab<T>::setValIfNot (T const& val, const BaseFab<int>& mask) noexcept
3768{
3769 this->setValIfNot<run_on>(val, this->domain, mask, DestComp{0}, NumComps{this->nvar});
3770}
3771
3772template <class T>
3773template <RunOn run_on>
3774void
3775BaseFab<T>::setValIfNot (T const& val, Box const& bx, const BaseFab<int>& mask, DestComp dcomp, NumComps ncomp) noexcept
3776{
3777 AMREX_ASSERT(dcomp.i >= 0 && dcomp.i + ncomp.n <= this->nvar);
3778 Array4<T> const& a = this->array();
3779 Array4<int const> const& m = mask.const_array();
3780 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG (run_on, bx, ncomp.n, i, j, k, n,
3781 {
3782 if (!m(i,j,k)) { a(i,j,k,n+dcomp.i) = val; }
3783 });
3784}
3785
3786template <class T>
3787template <RunOn run_on>
3788void
3789BaseFab<T>::setComplement (T const& x, const Box& bx, DestComp dcomp, NumComps ncomp) noexcept
3790{
3791#ifdef AMREX_USE_GPU
3792 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
3793 Array4<T> const& a = this->array();
3794 amrex::ParallelFor(this->domain, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
3795 {
3796 if (! bx.contains(IntVect(AMREX_D_DECL(i,j,k)))) {
3797 for (int n = dcomp.i; n < ncomp.n+dcomp.i; ++n) {
3798 a(i,j,k,n) = x;
3799 }
3800 }
3801 });
3802 } else
3803#endif
3804 {
3805 const BoxList b_lst = amrex::boxDiff(this->domain,bx);
3806 for (auto const& b : b_lst) {
3807 this->setVal<RunOn::Host>(x, b, dcomp, ncomp);
3808 }
3809 }
3810}
3811
3812template <class T>
3813template <RunOn run_on>
3815BaseFab<T>::copy (const BaseFab<T>& src) noexcept
3816{
3817 this->copy<run_on>(src, this->domain, SrcComp{0}, DestComp{0}, NumComps{this->nvar});
3818 return *this;
3819}
3820
3821template <class T>
3822template <RunOn run_on>
3825 SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept
3826{
3827 AMREX_ASSERT(this->domain.sameType(src.domain));
3828 AMREX_ASSERT(scomp.i >= 0 && scomp.i+ncomp.n <= src.nvar);
3829 AMREX_ASSERT(dcomp.i >= 0 && dcomp.i+ncomp.n <= this->nvar);
3830
3831 bx &= src.domain;
3832
3833 Array4<T> const& d = this->array();
3834 Array4<T const> const& s = src.const_array();
3835 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, bx, ncomp.n, i, j, k, n,
3836 {
3837 d(i,j,k,n+dcomp.i) = s(i,j,k,n+scomp.i);
3838 });
3839
3840 return *this;
3841}
3842
3843template <class T>
3844template <RunOn run_on>
3846BaseFab<T>::plus (T const& val) noexcept
3847{
3848 return this->plus<run_on>(val, this->domain, DestComp{0}, NumComps{this->nvar});
3849}
3850
3851template <class T>
3852template <RunOn run_on>
3854BaseFab<T>::operator+= (T const& val) noexcept
3855{
3856 return this->plus<run_on>(val, this->domain, DestComp{0}, NumComps{this->nvar});
3857}
3858
3859template <class T>
3860template <RunOn run_on>
3862BaseFab<T>::plus (T const& val, Box const& bx, DestComp dcomp, NumComps ncomp) noexcept
3863{
3864 BL_ASSERT(dcomp.i >= 0 && dcomp.i + ncomp.n <= this->nvar);
3865
3866 Array4<T> const& a = this->array();
3867 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, bx, ncomp.n, i, j, k, n,
3868 {
3869 a(i,j,k,n+dcomp.i) += val;
3870 });
3871
3872 return *this;
3873}
3874
3875template <class T>
3876template <RunOn run_on>
3878BaseFab<T>::plus (const BaseFab<T>& src) noexcept
3879{
3880 return this->plus<run_on>(src, this->domain, SrcComp{0}, DestComp{0}, NumComps{this->nvar});
3881}
3882
3883template <class T>
3884template <RunOn run_on>
3887{
3888 return this->plus<run_on>(src, this->domain, SrcComp{0}, DestComp{0}, NumComps{this->nvar});
3889}
3890
3891template <class T>
3892template <RunOn run_on>
3895 SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept
3896{
3897 AMREX_ASSERT(this->domain.sameType(src.domain));
3898 AMREX_ASSERT(scomp.i >= 0 && scomp.i+ncomp.n <= src.nvar);
3899 AMREX_ASSERT(dcomp.i >= 0 && dcomp.i+ncomp.n <= this->nvar);
3900
3901 bx &= src.domain;
3902
3903 Array4<T> const& d = this->array();
3904 Array4<T const> const& s = src.const_array();
3905 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, bx, ncomp.n, i, j, k, n,
3906 {
3907 d(i,j,k,n+dcomp.i) += s(i,j,k,n+scomp.i);
3908 });
3909
3910 return *this;
3911}
3912
3913template <class T>
3914template <RunOn run_on>
3916BaseFab<T>::minus (T const& val) noexcept
3917{
3918 return this->minus<run_on>(val, this->domain, DestComp{0}, NumComps{this->nvar});
3919}
3920
3921template <class T>
3922template <RunOn run_on>
3924BaseFab<T>::operator-= (T const& val) noexcept
3925{
3926 return this->minus<run_on>(val, this->domain, DestComp{0}, NumComps{this->nvar});
3927}
3928
3929template <class T>
3930template <RunOn run_on>
3932BaseFab<T>::minus (T const& val, Box const& bx, DestComp dcomp, NumComps ncomp) noexcept
3933{
3934 BL_ASSERT(dcomp.i >= 0 && dcomp.i + ncomp.n <= this->nvar);
3935
3936 Array4<T> const& a = this->array();
3937 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, bx, ncomp.n, i, j, k, n,
3938 {
3939 a(i,j,k,n+dcomp.i) -= val;
3940 });
3941
3942 return *this;
3943}
3944
3945template <class T>
3946template <RunOn run_on>
3948BaseFab<T>::minus (const BaseFab<T>& src) noexcept
3949{
3950 return this->minus<run_on>(src, this->domain, SrcComp{0}, DestComp{0}, NumComps{this->nvar});
3951}
3952
3953template <class T>
3954template <RunOn run_on>
3957{
3958 return this->minus<run_on>(src, this->domain, SrcComp{0}, DestComp{0}, NumComps{this->nvar});
3959}
3960
3961template <class T>
3962template <RunOn run_on>
3965 SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept
3966{
3967 AMREX_ASSERT(this->domain.sameType(src.domain));
3968 AMREX_ASSERT(scomp.i >= 0 && scomp.i+ncomp.n <= src.nvar);
3969 AMREX_ASSERT(dcomp.i >= 0 && dcomp.i+ncomp.n <= this->nvar);
3970
3971 bx &= src.domain;
3972
3973 Array4<T> const& d = this->array();
3974 Array4<T const> const& s = src.const_array();
3975 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, bx, ncomp.n, i, j, k, n,
3976 {
3977 d(i,j,k,n+dcomp.i) -= s(i,j,k,n+scomp.i);
3978 });
3979
3980 return *this;
3981}
3982
3983template <class T>
3984template <RunOn run_on>
3986BaseFab<T>::mult (T const& val) noexcept
3987{
3988 return this->mult<run_on>(val, this->domain, DestComp{0}, NumComps{this->nvar});
3989}
3990
3991template <class T>
3992template <RunOn run_on>
3994BaseFab<T>::operator*= (T const& val) noexcept
3995{
3996 return this->mult<run_on>(val, this->domain, DestComp{0}, NumComps{this->nvar});
3997}
3998
3999template <class T>
4000template <RunOn run_on>
4002BaseFab<T>::mult (T const& val, Box const& bx, DestComp dcomp, NumComps ncomp) noexcept
4003{
4004 BL_ASSERT(dcomp.i >= 0 && dcomp.i + ncomp.n <= this->nvar);
4005
4006 Array4<T> const& a = this->array();
4007 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, bx, ncomp.n, i, j, k, n,
4008 {
4009 a(i,j,k,n+dcomp.i) *= val;
4010 });
4011
4012 return *this;
4013}
4014
4015template <class T>
4016template <RunOn run_on>
4018BaseFab<T>::mult (const BaseFab<T>& src) noexcept
4019{
4020 return this->mult<run_on>(src, this->domain, SrcComp{0}, DestComp{0}, NumComps{this->nvar});
4021}
4022
4023template <class T>
4024template <RunOn run_on>
4027{
4028 return this->mult<run_on>(src, this->domain, SrcComp{0}, DestComp{0}, NumComps{this->nvar});
4029}
4030
4031template <class T>
4032template <RunOn run_on>
4035 SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept
4036{
4037 AMREX_ASSERT(this->domain.sameType(src.domain));
4038 AMREX_ASSERT(scomp.i >= 0 && scomp.i+ncomp.n <= src.nvar);
4039 AMREX_ASSERT(dcomp.i >= 0 && dcomp.i+ncomp.n <= this->nvar);
4040
4041 bx &= src.domain;
4042
4043 Array4<T> const& d = this->array();
4044 Array4<T const> const& s = src.const_array();
4045 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, bx, ncomp.n, i, j, k, n,
4046 {
4047 d(i,j,k,n+dcomp.i) *= s(i,j,k,n+scomp.i);
4048 });
4049
4050 return *this;
4051}
4052
4053template <class T>
4054template <RunOn run_on>
4056BaseFab<T>::divide (T const& val) noexcept
4057{
4058 return this->divide<run_on>(val, this->domain, DestComp{0}, NumComps{this->nvar});
4059}
4060
4061template <class T>
4062template <RunOn run_on>
4064BaseFab<T>::operator/= (T const& val) noexcept
4065{
4066 return this->divide<run_on>(val, this->domain, DestComp{0}, NumComps{this->nvar});
4067}
4068
4069template <class T>
4070template <RunOn run_on>
4072BaseFab<T>::divide (T const& val, Box const& bx, DestComp dcomp, NumComps ncomp) noexcept
4073{
4074 BL_ASSERT(dcomp.i >= 0 && dcomp.i + ncomp.n <= this->nvar);
4075
4076 Array4<T> const& a = this->array();
4077 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, bx, ncomp.n, i, j, k, n,
4078 {
4079 a(i,j,k,n+dcomp.i) /= val;
4080 });
4081
4082 return *this;
4083}
4084
4085template <class T>
4086template <RunOn run_on>
4088BaseFab<T>::divide (const BaseFab<T>& src) noexcept
4089{
4090 return this->divide<run_on>(src, this->domain, SrcComp{0}, DestComp{0}, NumComps{this->nvar});
4091}
4092
4093template <class T>
4094template <RunOn run_on>
4097{
4098 return this->divide<run_on>(src, this->domain, SrcComp{0}, DestComp{0}, NumComps{this->nvar});
4099}
4100
4101template <class T>
4102template <RunOn run_on>
4105 SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept
4106{
4107 AMREX_ASSERT(this->domain.sameType(src.domain));
4108 AMREX_ASSERT(scomp.i >= 0 && scomp.i+ncomp.n <= src.nvar);
4109 AMREX_ASSERT(dcomp.i >= 0 && dcomp.i+ncomp.n <= this->nvar);
4110
4111 bx &= src.domain;
4112
4113 Array4<T> const& d = this->array();
4114 Array4<T const> const& s = src.const_array();
4115 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, bx, ncomp.n, i, j, k, n,
4116 {
4117 d(i,j,k,n+dcomp.i) /= s(i,j,k,n+scomp.i);
4118 });
4119
4120 return *this;
4121}
4122
4123template <class T>
4124template <RunOn run_on>
4127{
4128 return this->negate<run_on>(this->domain, DestComp{0}, NumComps{this->nvar});
4129}
4130
4131template <class T>
4132template <RunOn run_on>
4134BaseFab<T>::negate (const Box& bx, DestComp dcomp, NumComps ncomp) noexcept
4135{
4136 BL_ASSERT(dcomp.i >= 0 && dcomp.i + ncomp.n <= this->nvar);
4137
4138 Array4<T> const& a = this->array();
4139 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, bx, ncomp.n, i, j, k, n,
4140 {
4141 a(i,j,k,n+dcomp.i) = -a(i,j,k,n+dcomp.i);
4142 });
4143
4144 return *this;
4145}
4146
4147template <class T>
4148template <RunOn run_on>
4150BaseFab<T>::invert (T const& r) noexcept
4151{
4152 return this->invert<run_on>(r, this->domain, DestComp{0}, NumComps{this->nvar});
4153}
4154
4155template <class T>
4156template <RunOn run_on>
4158BaseFab<T>::invert (T const& r, const Box& bx, DestComp dcomp, NumComps ncomp) noexcept
4159{
4160 BL_ASSERT(dcomp.i >= 0 && dcomp.i + ncomp.n <= this->nvar);
4161
4162 Array4<T> const& a = this->array();
4163 AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(run_on, bx, ncomp.n, i, j, k, n,
4164 {
4165 a(i,j,k,n+dcomp.i) = r / a(i,j,k,n+dcomp.i);
4166 });
4167
4168 return *this;
4169}
4170
4171template <class T>
4172template <RunOn run_on>
4173T
4174BaseFab<T>::sum (const Box& bx, DestComp dcomp, NumComps ncomp) const noexcept
4175{
4176 AMREX_ASSERT(dcomp.i >= 0 && dcomp.i+ncomp.n <= this->nvar);
4177
4178 T r = 0;
4179 Array4<T const> const& a = this->const_array();
4180#ifdef AMREX_USE_GPU
4181 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
4182 ReduceOps<ReduceOpSum> reduce_op;
4183 ReduceData<T> reduce_data(reduce_op);
4184 using ReduceTuple = typename decltype(reduce_data)::Type;
4185 reduce_op.eval(bx, reduce_data,
4186 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
4187 {
4188 T t = 0;
4189 for (int n = 0; n < ncomp.n; ++n) {
4190 t += a(i,j,k,n+dcomp.i);
4191 }
4192 return { t };
4193 });
4194 ReduceTuple hv = reduce_data.value(reduce_op);
4195 r = amrex::get<0>(hv);
4196 } else
4197#endif
4198 {
4199 amrex::LoopOnCpu(bx, ncomp.n, [=,&r] (int i, int j, int k, int n) noexcept
4200 {
4201 r += a(i,j,k,n+dcomp.i);
4202 });
4203 }
4204
4205 return r;
4206}
4207
4208template <class T>
4209template <RunOn run_on>
4210T
4211BaseFab<T>::dot (const BaseFab<T>& src, const Box& bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) const noexcept
4212{
4213 AMREX_ASSERT(this->domain.sameType(src.domain));
4214 AMREX_ASSERT(scomp.i >= 0 && scomp.i+ncomp.n <= src.nvar);
4215 AMREX_ASSERT(dcomp.i >= 0 && dcomp.i+ncomp.n <= this->nvar);
4216
4217 T r = 0;
4218 Array4<T const> const& d = this->const_array();
4219 Array4<T const> const& s = src.const_array();
4220#ifdef AMREX_USE_GPU
4221 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
4222 ReduceOps<ReduceOpSum> reduce_op;
4223 ReduceData<T> reduce_data(reduce_op);
4224 using ReduceTuple = typename decltype(reduce_data)::Type;
4225 reduce_op.eval(bx, reduce_data,
4226 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
4227 {
4228 T t = 0;
4229 for (int n = 0; n < ncomp.n; ++n) {
4230 t += d(i,j,k,n+dcomp.i) * s(i,j,k,n+scomp.i);
4231 }
4232 return { t };
4233 });
4234 ReduceTuple hv = reduce_data.value(reduce_op);
4235 r = amrex::get<0>(hv);
4236 } else
4237#endif
4238 {
4239 amrex::LoopOnCpu(bx, ncomp.n, [=,&r] (int i, int j, int k, int n) noexcept
4240 {
4241 r += d(i,j,k,n+dcomp.i) * s(i,j,k,n+scomp.i);
4242 });
4243 }
4244
4245 return r;
4246}
4247
4248template <class T>
4249template <RunOn run_on>
4250T
4251BaseFab<T>::dot (const Box& bx, int destcomp, int numcomp) const noexcept
4252{
4253 return dot<run_on>(bx, DestComp{destcomp}, NumComps{numcomp});
4254}
4255
4256
4257template <class T>
4258template <RunOn run_on>
4259T
4260BaseFab<T>::dot (const Box& bx, DestComp dcomp, NumComps ncomp) const noexcept
4261{
4262 AMREX_ASSERT(dcomp.i >= 0 && dcomp.i+ncomp.n <= this->nvar);
4263
4264 T r = 0;
4265 Array4<T const> const& a = this->const_array();
4266#ifdef AMREX_USE_GPU
4267 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
4268 ReduceOps<ReduceOpSum> reduce_op;
4269 ReduceData<T> reduce_data(reduce_op);
4270 using ReduceTuple = typename decltype(reduce_data)::Type;
4271 reduce_op.eval(bx, reduce_data,
4272 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
4273 {
4274 T t = 0;
4275 for (int n = 0; n < ncomp.n; ++n) {
4276 t += a(i,j,k,n+dcomp.i)*a(i,j,k,n+dcomp.i);
4277 }
4278 return { t };
4279 });
4280 ReduceTuple hv = reduce_data.value(reduce_op);
4281 r = amrex::get<0>(hv);
4282 } else
4283#endif
4284 {
4285 amrex::LoopOnCpu(bx, ncomp.n, [=,&r] (int i, int j, int k, int n) noexcept
4286 {
4287 r += a(i,j,k,n+dcomp.i)*a(i,j,k,n+dcomp.i);
4288 });
4289 }
4290
4291 return r;
4292}
4293
4294template <class T>
4295template <RunOn run_on>
4296T
4297BaseFab<T>::dotmask (const BaseFab<T>& src, const Box& bx, const BaseFab<int>& mask,
4298 SrcComp scomp, DestComp dcomp, NumComps ncomp) const noexcept
4299{
4300 AMREX_ASSERT(this->domain.sameType(src.domain));
4301 AMREX_ASSERT(this->domain.sameType(mask.domain));
4302 AMREX_ASSERT(scomp.i >= 0 && scomp.i+ncomp.n <= src.nvar);
4303 AMREX_ASSERT(dcomp.i >= 0 && dcomp.i+ncomp.n <= this->nvar);
4304
4305 T r = 0;
4306 Array4<T const> const& d = this->const_array();
4307 Array4<T const> const& s = src.const_array();
4308 Array4<int const> const& m = mask.const_array();
4309#ifdef AMREX_USE_GPU
4310 if (run_on == RunOn::Device && Gpu::inLaunchRegion()) {
4311 ReduceOps<ReduceOpSum> reduce_op;
4312 ReduceData<T> reduce_data(reduce_op);
4313 using ReduceTuple = typename decltype(reduce_data)::Type;
4314 reduce_op.eval(bx, reduce_data,
4315 [=] AMREX_GPU_DEVICE (int i, int j, int k) -> ReduceTuple
4316 {
4317 T t = 0;
4318 T mi = static_cast<T>(static_cast<int>(static_cast<bool>(m(i,j,k))));
4319 for (int n = 0; n < ncomp.n; ++n) {
4320 t += d(i,j,k,n+dcomp.i)*s(i,j,k,n+scomp.i)*mi;
4321 }
4322 return { t };
4323 });
4324 ReduceTuple hv = reduce_data.value(reduce_op);
4325 r = amrex::get<0>(hv);
4326 } else
4327#endif
4328 {
4329 amrex::LoopOnCpu(bx, ncomp.n, [=,&r] (int i, int j, int k, int n) noexcept
4330 {
4331 int mi = static_cast<int>(static_cast<bool>(m(i,j,k)));
4332 r += d(i,j,k,n+dcomp.i)*s(i,j,k,n+scomp.i)*mi;
4333 });
4334 }
4335
4336 return r;
4337}
4338
4339}
4340
4341#endif /*BL_BASEFAB_H*/
#define BL_ASSERT(EX)
Definition AMReX_BLassert.H:39
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_CUDA_SAFE_CALL(call)
Definition AMReX_GpuError.H:73
#define AMREX_HOST_DEVICE_FOR_1D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:105
#define AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(where_to_run, box, nc, i, j, k, n, block)
Definition AMReX_GpuLaunch.nolint.H:73
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
int idir
Definition AMReX_HypreMLABecLap.cpp:1093
Array4< int const > offset
Definition AMReX_HypreMLABecLap.cpp:1089
Real * pdst
Definition AMReX_HypreMLABecLap.cpp:1090
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
void amrex_mempool_free(void *p)
Definition AMReX_MemPool.cpp:80
void * amrex_mempool_alloc(size_t nbytes)
Definition AMReX_MemPool.cpp:74
#define AMREX_D_TERM(a, b, c)
Definition AMReX_SPACE.H:129
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:104
void free(void *)
A virtual base class for objects that manage their own dynamic memory allocation.
Definition AMReX_Arena.H:100
A FortranArrayBox(FAB)-like object.
Definition AMReX_BaseFab.H:183
int maskGE(BaseFab< int > &mask, T const &val, int comp=0) const noexcept
Same as above except mark cells with value greater than or equal to val.
Definition AMReX_BaseFab.H:2908
BaseFab< T > & saxpy(T a, const BaseFab< T > &x, const Box &srcbox, const Box &destbox, int srccomp, int destcomp, int numcomp=1) noexcept
FAB SAXPY (y[i] <- y[i] + a * x[i]), in place.
Definition AMReX_BaseFab.H:2964
BaseFab< T > & copy(const BaseFab< T > &src, Box bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept
Do nothing if bx does not intersect with src fab.
Definition AMReX_BaseFab.H:3824
T sum(int comp, int numcomp=1) const noexcept
Returns sum of given component of FAB state vector.
Definition AMReX_BaseFab.H:3194
gpuStream_t alloc_stream
Definition AMReX_BaseFab.H:1656
Real norminfmask(const Box &subbox, const BaseFab< int > &mask, int scomp=0, int ncomp=1) const noexcept
Definition AMReX_BaseFab.H:2337
BaseFab< T > & divide(T const &val) noexcept
Scalar division on the whole domain and all components.
Definition AMReX_BaseFab.H:4056
BaseFab< T > & atomicAdd(const BaseFab< T > &src, int srccomp, int destcomp, int numcomp=1) noexcept
Atomically add src components (srccomp:srccomp+numcomp-1) to this FABs components (destcomp:destcomp+...
Definition AMReX_BaseFab.H:3266
std::pair< T, T > minmax(const Box &subbox, int comp=0) const noexcept
Definition AMReX_BaseFab.H:2560
const int * hiVect() const noexcept
Returns the upper corner of the domain.
Definition AMReX_BaseFab.H:326
BaseFab< T > & minus(const BaseFab< T > &src, Box bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept
Do nothing if bx does not intersect with src fab.
Definition AMReX_BaseFab.H:3964
BaseFab< T > & lockAdd(const BaseFab< T > &src, const Box &srcbox, const Box &destbox, int srccomp, int destcomp, int numcomp) noexcept
Atomically add srcbox region of src FAB to destbox region of this FAB. The srcbox and destbox must be...
Definition AMReX_BaseFab.H:3350
static void Initialize()
std::size_t copyToMem(const Box &srcbox, int srccomp, int numcomp, void *dst) const noexcept
Copy from the srcbox of this Fab to raw memory and return the number of bytes copied.
Definition AMReX_BaseFab.H:2218
std::size_t addFromMem(const Box &dstbox, int dstcomp, int numcomp, const void *src) noexcept
Add from raw memory to the dstbox of this Fab and return the number of bytes copied.
Definition AMReX_BaseFab.H:2273
BaseFab< T > & divide(const BaseFab< T > &src, int srccomp, int destcomp, int numcomp=1) noexcept
This FAB is numerator, src FAB is denominator divide src components (srccomp:srccomp+numcomp-1) into ...
Definition AMReX_BaseFab.H:3570
std::size_t nBytesOwned() const noexcept
Definition AMReX_BaseFab.H:268
BaseFab< T > & copy(const BaseFab< T > &src) noexcept
Definition AMReX_BaseFab.H:3815
BaseFab< T > & addproduct(const Box &destbox, int destcomp, int numcomp, const BaseFab< T > &src1, int comp1, const BaseFab< T > &src2, int comp2) noexcept
y[i] <- y[i] + x1[i] * x2[i])
Definition AMReX_BaseFab.H:3029
BaseFab< T > & minus(T const &val) noexcept
Scalar subtraction on the whole domain and all components.
Definition AMReX_BaseFab.H:3916
BaseFab< T > & copy(const BaseFab< T > &src, int srccomp, int destcomp, int numcomp=1) noexcept
As above, except the destination Box and the source Box are taken to be the entire domain of the dest...
Definition AMReX_BaseFab.H:1920
BaseFab< T > & negate(const Box &b, int comp=0, int numcomp=1) noexcept
Negate BaseFab, most general.
Definition AMReX_BaseFab.H:3218
int maskLT(BaseFab< int > &mask, T const &val, int comp=0) const noexcept
Compute mask array with value of 1 in cells where BaseFab has value less than val,...
Definition AMReX_BaseFab.H:2724
BaseFab< T > & plus(T const &val) noexcept
Scalar addition on the whole domain and all components.
Definition AMReX_BaseFab.H:3846
BaseFab< T > & plus(T const &r, int comp, int numcomp=1) noexcept
As above, except on entire domain.
Definition AMReX_BaseFab.H:3242
BaseFab< T > & mult(T const &val, Box const &bx, DestComp dcomp, NumComps ncomp) noexcept
Do nothing if bx is empty.
Definition AMReX_BaseFab.H:4002
BaseFab< T > & mult(const BaseFab< T > &src, Box bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept
Do nothing if bx does not intersect with src fab.
Definition AMReX_BaseFab.H:4034
std::size_t nBytes(const Box &bx, int ncomps) const noexcept
Returns bytes used in the Box for those components.
Definition AMReX_BaseFab.H:273
void setPtr(T *p, Long sz) noexcept
Definition AMReX_BaseFab.H:373
BaseFab< T > & linComb(const BaseFab< T > &f1, const Box &b1, int comp1, const BaseFab< T > &f2, const Box &b2, int comp2, Real alpha, Real beta, const Box &b, int comp, int numcomp=1) noexcept
Linear combination. Result is alpha*f1 + beta*f2. Data is taken from b1 region of f1,...
Definition AMReX_BaseFab.H:3053
void define()
Allocates memory for the BaseFab<T>.
Definition AMReX_BaseFab.H:1927
BaseFab< T > & operator*=(T const &val) noexcept
Definition AMReX_BaseFab.H:3994
void resize(const Box &b, int N=1, Arena *ar=nullptr)
This function resizes a BaseFab so it covers the Box b with N components.
Definition AMReX_BaseFab.H:2098
BaseFab< T > & divide(T const &r, const Box &b, int comp=0, int numcomp=1) noexcept
As above except specify sub-box.
Definition AMReX_BaseFab.H:3562
const IntVect & smallEnd() const noexcept
Returns the lower corner of the domain See class Box for analogue.
Definition AMReX_BaseFab.H:303
BaseFab< T > & mult(T const &r, int comp, int numcomp=1) noexcept
Scalar multiplication, except control which components are multiplied.
Definition AMReX_BaseFab.H:3496
BaseFab< T > & invert(T const &r, const Box &bx, DestComp dcomp, NumComps ncomp) noexcept
Definition AMReX_BaseFab.H:4158
BaseFab< T > & atomicAdd(const BaseFab< T > &x) noexcept
Atomic FAB addition (a[i] <- a[i] + b[i]).
Definition AMReX_BaseFab.H:2954
int maskEQ(BaseFab< int > &mask, T const &val, int comp=0) const noexcept
Same as above except mark cells with value equal to val.
Definition AMReX_BaseFab.H:2816
const int * loVect() const noexcept
Returns the lower corner of the domain.
Definition AMReX_BaseFab.H:316
bool contains(const BaseFab< T > &fab) const noexcept
Returns true if the domain of fab is totally contained within the domain of this BaseFab.
Definition AMReX_BaseFab.H:332
bool isAllocated() const noexcept
Returns true if the data for the FAB has been allocated.
Definition AMReX_BaseFab.H:433
std::unique_ptr< T, DataDeleter > release() noexcept
Release ownership of memory.
Definition AMReX_BaseFab.H:2200
void setVal(T const &x, Box const &bx, DestComp dcomp, NumComps ncomp) noexcept
Do nothing if bx is empty.
Definition AMReX_BaseFab.H:3732
BaseFab< T > & protected_divide(const BaseFab< T > &src, int srccomp, int destcomp, int numcomp=1) noexcept
Divide wherever "src" is "true" or "non-zero". This FAB is numerator, src FAB is denominator divide s...
Definition AMReX_BaseFab.H:3622
BaseFab< T > & operator-=(T const &val) noexcept
Definition AMReX_BaseFab.H:3924
const Box & box() const noexcept
Returns the domain (box) where the array is defined.
Definition AMReX_BaseFab.H:291
void setValIf(T const &val, Box const &bx, const BaseFab< int > &mask, DestComp dcomp, NumComps ncomp) noexcept
Do nothing if bx is empty.
Definition AMReX_BaseFab.H:3753
static void Finalize()
IntVect indexFromValue(const Box &subbox, int comp, T const &value) const noexcept
Definition AMReX_BaseFab.H:2633
BaseFab< T > & mult(const BaseFab< T > &src) noexcept
Definition AMReX_BaseFab.H:4018
bool shared_memory
Is the memory allocated in shared memory?
Definition AMReX_BaseFab.H:1654
BaseFab< T > & minus(const BaseFab< T > &src, const Box &srcbox, const Box &destbox, int srccomp, int destcomp, int numcomp=1) noexcept
Subtract srcbox region of src FAB from destbox region of this FAB. srcbox and destbox must be same si...
Definition AMReX_BaseFab.H:3470
void abs(const Box &subbox, int comp=0, int numcomp=1) noexcept
Calculate abs() on subbox for given component range.
Definition AMReX_BaseFab.H:2325
int maskLE(BaseFab< int > &mask, T const &val, int comp=0) const noexcept
Same as above except mark cells with value less than or equal to val.
Definition AMReX_BaseFab.H:2770
void setValIf(T const &val, const BaseFab< int > &mask) noexcept
Definition AMReX_BaseFab.H:3745
Real norm(const Box &subbox, int p, int scomp=0, int numcomp=1) const noexcept
Same as above except only on given subbox.
Definition AMReX_BaseFab.H:2389
BaseFab< T > & plus(const BaseFab< T > &src, Box bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept
Do nothing if bx does not intersect with src fab.
Definition AMReX_BaseFab.H:3894
void setValIfNot(T const &val, const BaseFab< int > &mask) noexcept
Definition AMReX_BaseFab.H:3767
BaseFab< T > & xpay(T a, const BaseFab< T > &x, const Box &srcbox, const Box &destbox, int srccomp, int destcomp, int numcomp=1) noexcept
FAB XPAY (y[i] <- x[i] + a * y[i])
Definition AMReX_BaseFab.H:3001
std::size_t nBytes() const noexcept
Returns how many bytes used.
Definition AMReX_BaseFab.H:266
std::size_t copyFromMem(const Box &dstbox, int dstcomp, int numcomp, const void *src) noexcept
Copy from raw memory to the dstbox of this Fab and return the number of bytes copied.
Definition AMReX_BaseFab.H:2245
BaseFab< T > & negate() noexcept
on the whole domain and all components
Definition AMReX_BaseFab.H:4126
BaseFab< T > & minus(const BaseFab< T > &src) noexcept
Definition AMReX_BaseFab.H:3948
AMREX_FORCE_INLINE Array4< T const > const_array(int start_comp, int num_comps) const noexcept
Definition AMReX_BaseFab.H:427
BaseFab< T > & linInterp(const BaseFab< T > &f1, int comp1, const BaseFab< T > &f2, int comp2, Real t1, Real t2, Real t, const Box &b, int comp, int numcomp=1) noexcept
Version of linInterp() in which b, b1, & b2 are the same.
Definition AMReX_BaseFab.H:3701
BaseFab< T > & copy(const BaseFab< T > &src, const Box &destbox) noexcept
As above, except that the destination Box is specified, but the source Box is taken to the equal to t...
Definition AMReX_BaseFab.H:1912
T maxabs(const Box &subbox, int comp=0) const noexcept
Definition AMReX_BaseFab.H:2602
T min(const Box &subbox, int comp=0) const noexcept
Definition AMReX_BaseFab.H:2484
AMREX_FORCE_INLINE Array4< T > array() noexcept
Definition AMReX_BaseFab.H:397
BaseFab< T > & minus(const BaseFab< T > &src, int srccomp, int destcomp, int numcomp=1) noexcept
Subtract src components (srccomp:srccomp+numcomp-1) to this FABs components (destcomp:destcomp+numcom...
Definition AMReX_BaseFab.H:3454
T dot(const BaseFab< T > &src, const Box &bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) const noexcept
Dot product of two Fabs.
Definition AMReX_BaseFab.H:4211
T value_type
Definition AMReX_BaseFab.H:188
void SetBoxType(const IndexType &typ) noexcept
Change the Box type without change the length.
Definition AMReX_BaseFab.H:1298
BaseFab< T > & mult(const BaseFab< T > &src, int srccomp, int destcomp, int numcomp=1) noexcept
Multiply src components (srccomp:srccomp+numcomp-1) with this FABs components (destcomp:destcomp+numc...
Definition AMReX_BaseFab.H:3512
BaseFab< T > & divide(const BaseFab< T > &src, const Box &subbox, int srccomp, int destcomp, int numcomp=1) noexcept
Same as above except division is restricted to intersection of subbox and src FAB....
Definition AMReX_BaseFab.H:3578
T sum(const Box &bx, DestComp dcomp, NumComps ncomp) const noexcept
Sum.
Definition AMReX_BaseFab.H:4174
T maxabs(int comp=0) const noexcept
Definition AMReX_BaseFab.H:2594
BaseFab< T > & mult(T const &r, const Box &b, int comp=0, int numcomp=1) noexcept
As above, except specify sub-box.
Definition AMReX_BaseFab.H:3504
BaseFab< T > & operator+=(T const &val) noexcept
Definition AMReX_BaseFab.H:3854
void setComplement(T const &x, Box const &bx, DestComp dcomp, NumComps ncomp) noexcept
setVal on the complement of bx in the fab's domain
Definition AMReX_BaseFab.H:3789
T dot(const Box &bx, DestComp dcomp, NumComps ncomp) const noexcept
Dot product.
Definition AMReX_BaseFab.H:4260
BaseFab< T > & mult(const BaseFab< T > &src, const Box &srcbox, const Box &destbox, int srccomp, int destcomp, int numcomp=1) noexcept
Multiply srcbox region of src FAB with destbox region of this FAB. The srcbox and destbox must be sam...
Definition AMReX_BaseFab.H:3528
BaseFab< T > & minus(T const &val, Box const &bx, DestComp dcomp, NumComps ncomp) noexcept
Do nothing if bx is empty.
Definition AMReX_BaseFab.H:3932
BaseFab< T > & divide(const BaseFab< T > &src, const Box &srcbox, const Box &destbox, int srccomp, int destcomp, int numcomp=1) noexcept
destbox region of this FAB is numerator. srcbox regions of src FAB is denominator....
Definition AMReX_BaseFab.H:3586
Long truesize
nvar*numpts that was allocated on heap.
Definition AMReX_BaseFab.H:1652
void setVal(T const &val) noexcept
Set value on the whole domain and all components.
Definition AMReX_BaseFab.H:3724
const int * nCompPtr() const noexcept
for calls to fortran.
Definition AMReX_BaseFab.H:280
T dotmask(const BaseFab< T > &src, const Box &bx, const BaseFab< int > &mask, SrcComp scomp, DestComp dcomp, NumComps ncomp) const noexcept
Dot product of two Fabs with mask.
Definition AMReX_BaseFab.H:4297
IntVect minIndex(const Box &subbox, int comp=0) const noexcept
Definition AMReX_BaseFab.H:2680
BaseFab< T > & saxpy(T a, const BaseFab< T > &x) noexcept
FAB SAXPY (y[i] <- y[i] + a * x[i]), in place. All components.
Definition AMReX_BaseFab.H:2991
Box domain
My index space.
Definition AMReX_BaseFab.H:1650
BaseFab< T > & plus(const BaseFab< T > &src, const Box &srcbox, const Box &destbox, int srccomp, int destcomp, int numcomp=1) noexcept
Add srcbox region of src FAB to destbox region of this FAB. The srcbox and destbox must be same size.
Definition AMReX_BaseFab.H:3297
bool contains(const Box &bx) const noexcept
Returns true if bx is totally contained within the domain of this BaseFab.
Definition AMReX_BaseFab.H:341
AMREX_FORCE_INLINE Array4< T > array(int start_comp, int num_comps) noexcept
Definition AMReX_BaseFab.H:409
T * dptr
The data pointer.
Definition AMReX_BaseFab.H:1649
BaseFab< T > & shift(const IntVect &v) noexcept
Perform shifts upon the domain of the BaseFab. They are completely analogous to the corresponding Box...
Definition AMReX_BaseFab.H:1811
T max(const Box &subbox, int comp=0) const noexcept
Definition AMReX_BaseFab.H:2522
BaseFab< T > & divide(T const &val, Box const &bx, DestComp dcomp, NumComps ncomp) noexcept
Do nothing if bx is empty.
Definition AMReX_BaseFab.H:4072
T max(int comp=0) const noexcept
Definition AMReX_BaseFab.H:2514
BaseFab< T > & copy(const BaseFab< T > &src, const Box &srcbox, int srccomp, const Box &destbox, int destcomp, int numcomp) noexcept
The copy functions copy the contents of one BaseFab into another. The destination BaseFab is always t...
Definition AMReX_BaseFab.H:1885
BaseFab< T > & mult(const BaseFab< T > &src, const Box &subbox, int srccomp, int destcomp, int numcomp=1) noexcept
Same as above except multiplication is restricted to intersection of subbox and src FAB....
Definition AMReX_BaseFab.H:3520
int nvar
Number components.
Definition AMReX_BaseFab.H:1651
BaseFab< T > & protected_divide(const BaseFab< T > &src, const Box &subbox, int srccomp, int destcomp, int numcomp=1) noexcept
Divide wherever "src" is "true" or "non-zero". Same as above except division is restricted to interse...
Definition AMReX_BaseFab.H:3632
AMREX_FORCE_INLINE Array4< T const > array(int start_comp) const noexcept
Definition AMReX_BaseFab.H:385
T dot(const Box &xbx, int xcomp, const BaseFab< T > &y, const Box &ybx, int ycomp, int numcomp=1) const noexcept
Dot product of x (i.e.,this) and y.
Definition AMReX_BaseFab.H:3090
BaseFab< T > & shiftHalf(const IntVect &v) noexcept
Perform shifts upon the domain of the BaseFab. They are completely analogous to the corresponding Box...
Definition AMReX_BaseFab.H:1827
BaseFab< T > & divide(T const &r, int comp, int numcomp=1) noexcept
As above except specify which components.
Definition AMReX_BaseFab.H:3554
Real norm(int p, int scomp=0, int numcomp=1) const noexcept
Compute the Lp-norm of this FAB using components (scomp : scomp+ncomp-1). p < 0 -> ERROR p = 0 -> inf...
Definition AMReX_BaseFab.H:2381
BaseFab< T > & atomicAdd(const BaseFab< T > &src, const Box &subbox, int srccomp, int destcomp, int numcomp=1) noexcept
Same as above except addition is restricted to intersection of subbox and src FAB....
Definition AMReX_BaseFab.H:3285
BaseFab< T > & minus(const BaseFab< T > &src, const Box &subbox, int srccomp, int destcomp, int numcomp=1) noexcept
Same as above except subtraction is restricted to intersection of subbox and src FAB....
Definition AMReX_BaseFab.H:3462
AMREX_FORCE_INLINE Array4< T const > array() const noexcept
Definition AMReX_BaseFab.H:379
BaseFab< T > & plus(const BaseFab< T > &src, const Box &subbox, int srccomp, int destcomp, int numcomp=1) noexcept
Same as above except addition is restricted to intersection of subbox and src FAB....
Definition AMReX_BaseFab.H:3276
BaseFab< T > & operator/=(T const &val) noexcept
Definition AMReX_BaseFab.H:4064
std::pair< T, T > minmax(int comp=0) const noexcept
Definition AMReX_BaseFab.H:2552
BaseFab< T > & negate(const Box &bx, DestComp dcomp, NumComps ncomp) noexcept
Definition AMReX_BaseFab.H:4134
void fill_snan() noexcept
Definition AMReX_BaseFab.H:1845
void setVal(T const &x, const Box &bx, int dcomp, int ncomp) noexcept
The setVal functions set sub-regions in the BaseFab to a constant value. This most general form speci...
Definition AMReX_BaseFab.H:1869
BaseFab< T > & protected_divide(const BaseFab< T > &src, const Box &srcbox, const Box &destbox, int srccomp, int destcomp, int numcomp=1) noexcept
Definition AMReX_BaseFab.H:3644
T dot(const Box &bx, int destcomp, int numcomp) const noexcept
Int wrapper for dot.
Definition AMReX_BaseFab.H:4251
Long size() const noexcept
Returns the total number of points of all components.
Definition AMReX_BaseFab.H:288
BaseFab< T > & plus(T const &r, const Box &b, int comp=0, int numcomp=1) noexcept
Scalar addition (a[i] <- a[i] + r), most general.
Definition AMReX_BaseFab.H:3250
AMREX_FORCE_INLINE Array4< T const > array(int start_comp, int num_comps) const noexcept
Definition AMReX_BaseFab.H:391
BaseFab< T > & operator=(const BaseFab< T > &rhs)=delete
void maxIndex(const Box &subbox, Real &max_value, IntVect &max_idx, int comp=0) const noexcept
Definition AMReX_BaseFab.H:2715
void getVal(T *data, const IntVect &pos, int N, int numcomp) const noexcept
This function puts numcomp component values, starting at component N, from position pos in the domain...
Definition AMReX_BaseFab.H:1785
const IntVect & bigEnd() const noexcept
Returns the upper corner of the domain. See class Box for analogue.
Definition AMReX_BaseFab.H:306
AMREX_FORCE_INLINE Array4< T const > const_array() const noexcept
Definition AMReX_BaseFab.H:415
Elixir elixir() noexcept
Definition AMReX_BaseFab.H:2140
Long numPts() const noexcept
Returns the number of points.
Definition AMReX_BaseFab.H:285
IntVect maxIndex(const Box &subbox, int comp=0) const noexcept
Definition AMReX_BaseFab.H:2706
const T * dataPtr(int n=0) const noexcept
Same as above except works on const FABs.
Definition AMReX_BaseFab.H:361
void setValIfNot(T const &val, Box const &bx, const BaseFab< int > &mask, DestComp dcomp, NumComps ncomp) noexcept
Do nothing if bx is empty.
Definition AMReX_BaseFab.H:3775
BaseFab< T > & mult(T const &val) noexcept
Scalar multiplication on the whole domain and all components.
Definition AMReX_BaseFab.H:3986
BaseFab< T > & divide(const BaseFab< T > &src, Box bx, SrcComp scomp, DestComp dcomp, NumComps ncomp) noexcept
Do nothing if bx does not intersect with src fab.
Definition AMReX_BaseFab.H:4104
void setValIfNot(T const &val, const Box &bx, const BaseFab< int > &mask, int nstart, int num) noexcept
Definition AMReX_BaseFab.H:1877
BaseFab< T > & shiftHalf(int dir, int n_cell) noexcept
Perform shifts upon the domain of the BaseFab. They are completely analogous to the corresponding Box...
Definition AMReX_BaseFab.H:1835
void setVal(T const &x, const Box &bx, int N=0) noexcept
Same as above, except the number of modified components is one. N is the component to be modified.
Definition AMReX_BaseFab.H:1853
void prefetchToDevice() const noexcept
Definition AMReX_BaseFab.H:1713
T * dataPtr(int n=0) noexcept
Returns a pointer to an object of type T that is the value of the Nth component associated with the c...
Definition AMReX_BaseFab.H:352
bool ptr_owner
Owner of T*?
Definition AMReX_BaseFab.H:1653
BaseFab< T > & negate(int comp, int numcomp=1) noexcept
As above, except on entire domain.
Definition AMReX_BaseFab.H:3210
virtual ~BaseFab() noexcept
The destructor deletes the array memory.
Definition AMReX_BaseFab.H:2045
void setVal(T const &x, int N) noexcept
Same as above, except the sub-box defaults to the entire domain.
Definition AMReX_BaseFab.H:1861
BaseFab< T > & shift(int idir, int n_cell) noexcept
Perform shifts upon the domain of the BaseFab. They are completely analogous to the corresponding Box...
Definition AMReX_BaseFab.H:1819
AMREX_FORCE_INLINE Array4< T const > const_array(int start_comp) const noexcept
Definition AMReX_BaseFab.H:421
IntVect length() const noexcept
Returns a pointer to an array of SPACEDIM integers giving the length of the domain in each direction.
Definition AMReX_BaseFab.H:297
BaseFab< T > & invert(T const &r, int comp, int numcomp=1) noexcept
As above except on entire domain.
Definition AMReX_BaseFab.H:3226
T & operator()(const IntVect &p, int N) noexcept
Returns a reference to the Nth component value defined at position p in the domain....
Definition AMReX_BaseFab.H:1738
IntVect maxIndex(int comp=0) const noexcept
Definition AMReX_BaseFab.H:2698
BaseFab< T > & protected_divide(const BaseFab< T > &src) noexcept
Divide wherever "src" is "true" or "non-zero".
Definition AMReX_BaseFab.H:3612
friend class BaseFab
Definition AMReX_BaseFab.H:186
BaseFab< T > & invert(T const &r, const Box &b, int comp=0, int numcomp=1) noexcept
Most general version, specify subbox and which components.
Definition AMReX_BaseFab.H:3234
AMREX_FORCE_INLINE Array4< T > array(int start_comp) noexcept
Definition AMReX_BaseFab.H:403
BaseFab< T > & invert(T const &r) noexcept
Fab <- Fab/r on the whole domain and all components.
Definition AMReX_BaseFab.H:4150
T sum(const Box &subbox, int comp, int numcomp=1) const noexcept
Compute sum of given component of FAB state vector in given subbox.
Definition AMReX_BaseFab.H:3202
int nComp() const noexcept
Returns the number of components.
Definition AMReX_BaseFab.H:277
int maskGT(BaseFab< int > &mask, T const &val, int comp=0) const noexcept
Same as above except mark cells with value greater than val.
Definition AMReX_BaseFab.H:2862
T dotmask(const BaseFab< int > &mask, const Box &xbx, int xcomp, const BaseFab< T > &y, const Box &ybx, int ycomp, int numcomp) const noexcept
Definition AMReX_BaseFab.H:3140
void clear() noexcept
The function returns the BaseFab to the invalid state. The memory is freed.
Definition AMReX_BaseFab.H:2161
BaseFab< T > & plus(const BaseFab< T > &src) noexcept
Definition AMReX_BaseFab.H:3878
void abs(int comp, int numcomp=1) noexcept
Same as above except only for components (comp: comp+numcomp-1)
Definition AMReX_BaseFab.H:2317
BaseFab() noexcept=default
Construct an empty BaseFab, which must be resized (see BaseFab::resize) before use.
BaseFab< T > & divide(const BaseFab< T > &src) noexcept
Definition AMReX_BaseFab.H:4088
void prefetchToHost() const noexcept
Definition AMReX_BaseFab.H:1688
T min(int comp=0) const noexcept
Definition AMReX_BaseFab.H:2476
void setComplement(T const &x, const Box &b, int ns, int num) noexcept
This function is analogous to the fourth form of setVal above, except that instead of setting values ...
Definition AMReX_BaseFab.H:2301
BaseFab< T > & linInterp(const BaseFab< T > &f1, const Box &b1, int comp1, const BaseFab< T > &f2, const Box &b2, int comp2, Real t1, Real t2, Real t, const Box &b, int comp, int numcomp=1) noexcept
Linear interpolation / extrapolation. Result is (t2-t)/(t2-t1)*f1 + (t-t1)/(t2-t1)*f2 Data is taken f...
Definition AMReX_BaseFab.H:3682
IntVect minIndex(int comp=0) const noexcept
Definition AMReX_BaseFab.H:2672
void minIndex(const Box &subbox, Real &min_val, IntVect &min_idx, int comp=0) const noexcept
Definition AMReX_BaseFab.H:2689
T * dataPtr(const IntVect &p, int n=0) noexcept
Definition AMReX_BaseFab.H:1663
BaseFab< T > & plus(const BaseFab< T > &src, int srccomp, int destcomp, int numcomp=1) noexcept
Add src components (srccomp:srccomp+numcomp-1) to this FABs components (destcomp:destcomp+numcomp-1) ...
Definition AMReX_BaseFab.H:3258
void abs() noexcept
Compute absolute value for all components of this FAB.
Definition AMReX_BaseFab.H:2309
void getVal(T *data, const IntVect &pos) const noexcept
Same as above, except that starts at component 0 and copies all comps.
Definition AMReX_BaseFab.H:1803
BaseFab< T > & atomicAdd(const BaseFab< T > &src, const Box &srcbox, const Box &destbox, int srccomp, int destcomp, int numcomp=1) noexcept
Atomically add srcbox region of src FAB to destbox region of this FAB. The srcbox and destbox must be...
Definition AMReX_BaseFab.H:3323
BaseFab< T > & plus(T const &val, Box const &bx, DestComp dcomp, NumComps ncomp) noexcept
Do nothing if bx is empty.
Definition AMReX_BaseFab.H:3862
A class for managing a List of Boxes that share a common IndexType. This class implements operations ...
Definition AMReX_BoxList.H:52
AMREX_GPU_HOST_DEVICE BoxND & setType(const IndexTypeND< dim > &t) noexcept
Set indexing type.
Definition AMReX_Box.H:492
AMREX_GPU_HOST_DEVICE const int * loVect() const &noexcept
Returns a constant pointer the array of low end coordinates. Useful for calls to FORTRAN.
Definition AMReX_Box.H:178
AMREX_GPU_HOST_DEVICE const int * hiVect() const &noexcept
Returns a constant pointer the array of high end coordinates. Useful for calls to FORTRAN.
Definition AMReX_Box.H:183
AMREX_GPU_HOST_DEVICE IntVectND< dim > length() const noexcept
Return the length of the BoxND.
Definition AMReX_Box.H:146
AMREX_GPU_HOST_DEVICE const IntVectND< dim > & smallEnd() const &noexcept
Get the smallend of the BoxND.
Definition AMReX_Box.H:105
AMREX_GPU_HOST_DEVICE bool ok() const noexcept
Checks if it is a proper BoxND (including a valid type).
Definition AMReX_Box.H:200
AMREX_GPU_HOST_DEVICE bool sameSize(const BoxND &b) const noexcept
Returns true is Boxes same size, ie translates of each other,. It is an error if they have different ...
Definition AMReX_Box.H:279
AMREX_GPU_HOST_DEVICE Long numPts() const noexcept
Returns the number of points contained in the BoxND.
Definition AMReX_Box.H:346
AMREX_GPU_HOST_DEVICE bool contains(const IntVectND< dim > &p) const noexcept
Returns true if argument is contained within BoxND.
Definition AMReX_Box.H:204
AMREX_GPU_HOST_DEVICE const IntVectND< dim > & bigEnd() const &noexcept
Get the bigend.
Definition AMReX_Box.H:116
Definition AMReX_Tuple.H:93
static gpuStream_t setStream(gpuStream_t s) noexcept
Definition AMReX_GpuDevice.cpp:620
static gpuStream_t gpuStream() noexcept
Definition AMReX_GpuDevice.H:60
static int deviceId() noexcept
Definition AMReX_GpuDevice.cpp:573
static int devicePropMajor() noexcept
Definition AMReX_GpuDevice.H:142
Definition AMReX_GpuElixir.H:13
AMREX_GPU_HOST_DEVICE static AMREX_FORCE_INLINE constexpr IntVectND< dim > TheMinVector() noexcept
Definition AMReX_IntVect.H:720
Definition AMReX_PODVector.H:262
T * data() noexcept
Definition AMReX_PODVector.H:609
Definition AMReX_Reduce.H:249
Type value()
Definition AMReX_Reduce.H:281
Definition AMReX_Reduce.H:364
std::enable_if_t< IsFabArray< MF >::value > eval(MF const &mf, IntVect const &nghost, D &reduce_data, F &&f)
Definition AMReX_Reduce.H:441
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T Exch(T *address, T val) noexcept
Definition AMReX_GpuAtomic.H:485
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:237
void dtoh_memcpy_async(void *p_h, const void *p_d, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:265
bool inLaunchRegion() noexcept
Definition AMReX_GpuControl.H:86
bool notInLaunchRegion() noexcept
Definition AMReX_GpuControl.H:87
void htod_memcpy_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:251
gpuStream_t gpuStream() noexcept
Definition AMReX_GpuDevice.H:218
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void Add(T *const sum, T const value) noexcept
Definition AMReX_GpuAtomic.H:619
Definition AMReX_Amr.cpp:49
std::atomic< Long > atomic_total_bytes_allocated_in_fabs_hwm
Definition AMReX_BaseFab.cpp:14
MakeType
Definition AMReX_MakeType.H:7
@ make_deep_copy
Definition AMReX_MakeType.H:7
@ make_alias
Definition AMReX_MakeType.H:7
int nComp(FabArrayBase const &fa)
Long private_total_cells_allocated_in_fabs_hwm
high-water-mark over a given interval
Definition AMReX_BaseFab.cpp:20
AMREX_ATTRIBUTE_FLATTEN_FOR void LoopOnCpu(Dim3 lo, Dim3 hi, F const &f) noexcept
Definition AMReX_Loop.H:355
std::enable_if_t< std::is_integral_v< T > > ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:191
RunOn
Definition AMReX_GpuControl.H:69
std::enable_if_t< std::is_arithmetic_v< T > > placementNew(T *const, Long)
Definition AMReX_BaseFab.H:94
cudaStream_t gpuStream_t
Definition AMReX_GpuControl.H:77
Long private_total_cells_allocated_in_fabs
total cells at any given time
Definition AMReX_BaseFab.cpp:19
bool InitSNaN() noexcept
Definition AMReX.cpp:168
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr const T & min(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:21
Long TotalBytesAllocatedInFabs() noexcept
Definition AMReX_BaseFab.cpp:64
Long private_total_bytes_allocated_in_fabs_hwm
high-water-mark over a given interval
Definition AMReX_BaseFab.cpp:18
void BaseFab_Initialize()
Definition AMReX_BaseFab.cpp:28
void BaseFab_Finalize()
Definition AMReX_BaseFab.cpp:57
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 end(BoxND< dim > const &box) noexcept
Definition AMReX_Box.H:1890
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 ubound(Array4< T > const &a) noexcept
Definition AMReX_Array4.H:315
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 lbound(Array4< T > const &a) noexcept
Definition AMReX_Array4.H:308
void ResetTotalBytesAllocatedInFabsHWM() noexcept
Definition AMReX_BaseFab.cpp:132
BoxList boxDiff(const Box &b1in, const Box &b2)
Returns BoxList defining the compliment of b2 in b1in.
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Array4< T > makeArray4(T *p, Box const &bx, int ncomp) noexcept
Definition AMReX_BaseFab.H:87
IntVectND< AMREX_SPACEDIM > IntVect
Definition AMReX_BaseFwd.H:30
Long TotalBytesAllocatedInFabsHWM() noexcept
Definition AMReX_BaseFab.cpp:81
std::atomic< Long > atomic_total_bytes_allocated_in_fabs
Definition AMReX_BaseFab.cpp:13
Long TotalCellsAllocatedInFabsHWM() noexcept
Definition AMReX_BaseFab.cpp:115
Long TotalCellsAllocatedInFabs() noexcept
Definition AMReX_BaseFab.cpp:98
void Error(const std::string &msg)
Print out message to cerr and exit via amrex::Abort().
Definition AMReX.cpp:219
std::atomic< Long > atomic_total_cells_allocated_in_fabs
Definition AMReX_BaseFab.cpp:15
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 length(Array4< T > const &a) noexcept
Definition AMReX_Array4.H:322
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 begin(BoxND< dim > const &box) noexcept
Definition AMReX_Box.H:1881
std::enable_if_t< std::is_trivially_destructible_v< T > > placementDelete(T *const, Long)
Definition AMReX_BaseFab.H:119
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::enable_if_t< std::is_floating_point_v< T >, bool > almostEqual(T x, T y, int ulp=2)
Definition AMReX_Algorithm.H:93
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr const T & max(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:35
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:225
Long private_total_bytes_allocated_in_fabs
total bytes at any given time
Definition AMReX_BaseFab.cpp:17
std::atomic< Long > atomic_total_cells_allocated_in_fabs_hwm
Definition AMReX_BaseFab.cpp:16
void update_fab_stats(Long n, Long s, size_t szt) noexcept
Definition AMReX_BaseFab.cpp:144
std::array< T, N > Array
Definition AMReX_Array.H:24
Definition AMReX_Array4.H:61
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::size_t size() const noexcept
Definition AMReX_Array4.H:243
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T * ptr(int i, int j, int k) const noexcept
Definition AMReX_Array4.H:149
Definition AMReX_DataAllocator.H:9
void * alloc(std::size_t sz) const noexcept
Definition AMReX_DataAllocator.H:16
Arena * arena() const noexcept
Definition AMReX_DataAllocator.H:24
Definition AMReX_DataAllocator.H:29
Definition AMReX_BaseFab.H:72
int i
Definition AMReX_BaseFab.H:75
AMREX_GPU_HOST_DEVICE DestComp(int ai) noexcept
Definition AMReX_BaseFab.H:74
Definition AMReX_Dim3.H:12
int x
Definition AMReX_Dim3.H:12
Definition AMReX_BaseFab.H:78
int n
Definition AMReX_BaseFab.H:81
AMREX_GPU_HOST_DEVICE NumComps(int an) noexcept
Definition AMReX_BaseFab.H:80
Definition AMReX_BaseFab.H:66
AMREX_GPU_HOST_DEVICE SrcComp(int ai) noexcept
Definition AMReX_BaseFab.H:68
int i
Definition AMReX_BaseFab.H:69