Hipace
GPUUtil.H
Go to the documentation of this file.
1 /* Copyright 2022
2  *
3  * This file is part of HiPACE++.
4  *
5  * Authors: AlexanderSinn
6  * License: BSD-3-Clause-LBNL
7  */
8 #ifndef HIPACE_GPUUTIL_H_
9 #define HIPACE_GPUUTIL_H_
10 
11 #include <AMReX_Array4.H>
12 #include <AMReX_MFIter.H>
13 
14 template<class T>
15 struct Array2 {
17  amrex::Long jstride = 0;
18  amrex::Long start = 0;
19 
20 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
21  amrex::Dim3 begin{1,1,1};
22  amrex::Dim3 end{0,0,0}; // end is hi + 1
23  int ncomp=0;
24 #endif
25 
26  Array2 (const amrex::Array4<T>& rhs) noexcept
27  : p(rhs.p),
28  jstride(rhs.jstride),
29  start(-rhs.begin.x - rhs.begin.y * rhs.jstride)
30 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
31  ,begin(rhs.begin),
32  end(rhs.end),
33  ncomp(rhs.ncomp)
34 #endif
35  {
36  // slice is only one cell thick if allocated
37  AMREX_ALWAYS_ASSERT(!rhs.p || rhs.begin.z + 1 == rhs.end.z);
38  }
39 
41  T& operator() (int i, int j) const noexcept {
42 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
43  index_assert(i,j,begin.z,0);
44 #endif
45  return p[i + j*jstride + start];
46  }
47 
49  T* ptr (int i, int j) const noexcept {
50 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
51  index_assert(i,j,begin.z,0);
52 #endif
53  return p + (i + j*jstride + start);
54  }
55 
56 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
58  void index_assert (int i, int j, int k, int n) const
59  {
60  if (i<begin.x || i>=end.x || j<begin.y || j>=end.y || k<begin.z || k>=end.z
61  || n < 0 || n >= ncomp) {
62 #if AMREX_DEVICE_COMPILE
63  AMREX_DEVICE_PRINTF(" (%d,%d,%d,%d) is out of bound (%d:%d,%d:%d,%d:%d,0:%d)\n",
64  i, j, k, n, begin.x, end.x-1, begin.y, end.y-1,
65  begin.z, end.z-1, ncomp-1);
66  amrex::Abort();
67 #else
68  std::stringstream ss;
69  ss << " (" << i << "," << j << "," << k << "," << n
70  << ") is out of bound ("
71  << begin.x << ":" << end.x-1 << ","
72  << begin.y << ":" << end.y-1 << ","
73  << begin.z << ":" << end.z-1 << ","
74  << "0:" << ncomp-1 << ")";
75  amrex::Abort(ss.str());
76 #endif
77  }
78  }
79 #endif
80 };
81 
82 template<class T> inline
84  return Array2<T>{in};
85 }
86 
87 template<class T> inline
89  return Array2<T>{in};
90 }
91 
92 template<class T> inline
93 T to_array2 (T&& in) {
94  return in;
95 }
96 
97 template<class T>
98 struct Array3 {
100  amrex::Long jstride = 0;
101  amrex::Long nstride = 0;
102  amrex::Long start = 0;
103 
104 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
105  amrex::Dim3 begin{1,1,1};
106  amrex::Dim3 end{0,0,0}; // end is hi + 1
107  int ncomp=0;
108 #endif
109 
110  Array3 (const amrex::Array4<T>& rhs) noexcept
111  : p(rhs.p),
112  jstride(rhs.jstride),
113  nstride(rhs.nstride),
114  start(-rhs.begin.x - rhs.begin.y * rhs.jstride)
115 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
116  ,begin(rhs.begin),
117  end(rhs.end),
118  ncomp(rhs.ncomp)
119 #endif
120  {
121  // slice is only one cell thick if allocated
122  AMREX_ALWAYS_ASSERT(!rhs.p || rhs.begin.z + 1 == rhs.end.z);
123  }
124 
126  T& operator() (int i, int j, int n) const noexcept {
127 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
128  index_assert(i,j,begin.z,n);
129 #endif
130  return p[(start + i + j*jstride) + n*nstride];
131  }
132 
134  T* ptr (int i, int j, int n) const noexcept {
135 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
136  index_assert(i,j,begin.z,n);
137 #endif
138  return p + ((start + i + j*jstride) + n*nstride);
139  }
140 
141 
142 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
143  AMREX_GPU_HOST_DEVICE inline
144  void index_assert (int i, int j, int k, int n) const
145  {
146  if (i<begin.x || i>=end.x || j<begin.y || j>=end.y || k<begin.z || k>=end.z
147  || n < 0 || n >= ncomp) {
148 #if AMREX_DEVICE_COMPILE
149  AMREX_DEVICE_PRINTF(" (%d,%d,%d,%d) is out of bound (%d:%d,%d:%d,%d:%d,0:%d)\n",
150  i, j, k, n, begin.x, end.x-1, begin.y, end.y-1,
151  begin.z, end.z-1, ncomp-1);
152  amrex::Abort();
153 #else
154  std::stringstream ss;
155  ss << " (" << i << "," << j << "," << k << "," << n
156  << ") is out of bound ("
157  << begin.x << ":" << end.x-1 << ","
158  << begin.y << ":" << end.y-1 << ","
159  << begin.z << ":" << end.z-1 << ","
160  << "0:" << ncomp-1 << ")";
161  amrex::Abort(ss.str());
162 #endif
163  }
164  }
165 #endif
166 };
167 
168 template<class T> inline
170  return Array3<T>{in};
171 }
172 
173 template<class T> inline
175  return Array3<T>{in};
176 }
177 
178 template<class T> inline
179 T to_array3 (T&& in) {
180  return in;
181 }
182 
183 inline amrex::MFItInfo DfltMfi; // Default MFIter
184 inline amrex::MFItInfo DfltMfiTlng; // Default MFIter with Tiling
185 
187 amrex::Real abssq(amrex::Real r, amrex::Real i)
188 {
189  return r*r + i*i;
190 }
191 
193 void AtomicAdd(amrex::Real* ptr, amrex::Real val, [[maybe_unused]] bool do_omp_atomic=true) {
194 #ifdef AMREX_USE_GPU
195  amrex::Gpu::Atomic::Add(ptr, val);
196 #elif defined(AMREX_USE_OMP)
197  if (do_omp_atomic) {
198 #pragma omp atomic
199  *ptr += val;
200  } else {
201  *ptr += val;
202  }
203 #else
204  *ptr += val;
205 #endif
206 }
207 
208 #endif
#define AMREX_ALWAYS_ASSERT(EX)
#define AMREX_FORCE_INLINE
#define AMREX_RESTRICT
#define AMREX_DEVICE_PRINTF(...)
#define AMREX_GPU_HOST_DEVICE
Array3< T > to_array3(amrex::Array4< T > &&in)
Definition: GPUUtil.H:169
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real abssq(amrex::Real r, amrex::Real i)
Definition: GPUUtil.H:187
Array2< T > to_array2(amrex::Array4< T > &&in)
Definition: GPUUtil.H:83
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void AtomicAdd(amrex::Real *ptr, amrex::Real val, [[maybe_unused]] bool do_omp_atomic=true)
Definition: GPUUtil.H:193
amrex::MFItInfo DfltMfi
Definition: GPUUtil.H:183
amrex::MFItInfo DfltMfiTlng
Definition: GPUUtil.H:184
int i
Definition: MakeOpenBoundary.py:152
j
Definition: MakeOpenBoundary.py:128
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T Add(T *sum, T value) noexcept
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 end(Box const &box) noexcept
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 begin(Box const &box) noexcept
void Abort(const std::string &msg)
Definition: GPUUtil.H:15
T *AMREX_RESTRICT p
Definition: GPUUtil.H:16
amrex::Long start
Definition: GPUUtil.H:18
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & operator()(int i, int j) const noexcept
Definition: GPUUtil.H:41
amrex::Long jstride
Definition: GPUUtil.H:17
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T * ptr(int i, int j) const noexcept
Definition: GPUUtil.H:49
Array2(const amrex::Array4< T > &rhs) noexcept
Definition: GPUUtil.H:26
Definition: GPUUtil.H:98
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & operator()(int i, int j, int n) const noexcept
Definition: GPUUtil.H:126
T *AMREX_RESTRICT p
Definition: GPUUtil.H:99
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T * ptr(int i, int j, int n) const noexcept
Definition: GPUUtil.H:134
amrex::Long jstride
Definition: GPUUtil.H:100
amrex::Long start
Definition: GPUUtil.H:102
amrex::Long nstride
Definition: GPUUtil.H:101
Array3(const amrex::Array4< T > &rhs) noexcept
Definition: GPUUtil.H:110