Block-Structured AMR Software Framework
AMReX_TableData.H
Go to the documentation of this file.
1 #ifndef AMREX_TABLE_DATA_H_
2 #define AMREX_TABLE_DATA_H_
3 #include <AMReX_Config.H>
4 
5 #include <AMReX.H>
6 #include <AMReX_Array.H>
7 #include <AMReX_DataAllocator.H>
8 #include <AMReX_GpuDevice.H>
9 #include <AMReX_GpuPrint.H>
10 
11 #include <cstring>
12 #include <iostream>
13 #include <sstream>
14 #include <type_traits>
15 
16 namespace amrex {
17 
18 template <typename T>
19 struct Table1D
20 {
21  T* AMREX_RESTRICT p = nullptr;
22  int begin = 1;
23  int end = 0;
24 
25  constexpr Table1D () noexcept = default;
26 
27  template <class U=T, std::enable_if_t<std::is_const_v<U>,int> = 0>
29  constexpr Table1D (Table1D<std::remove_const_t<T>> const& rhs) noexcept
30  : p(rhs.p),
31  begin(rhs.begin),
32  end(rhs.end)
33  {}
34 
36  constexpr Table1D (T* a_p, int a_begin, int a_end) noexcept
37  : p(a_p),
38  begin(a_begin),
39  end(a_end)
40  {}
41 
43  explicit operator bool () const noexcept { return p != nullptr; }
44 
45  template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
47  U& operator() (int i) const noexcept {
48 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
49  index_assert(i);
50 #endif
51  return p[i-begin];
52  }
53 
54 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
56  void index_assert (int i) const
57  {
58  if (i < begin || i >= end) {
60  AMREX_DEVICE_PRINTF(" (%d) is out of bound (%d:%d)\n",
61  i, begin, end-1);
62  amrex::Abort();
63  ))
65  std::stringstream ss;
66  ss << " (" << i << ") is out of bound ("
67  << begin << ":" << end-1 << ")";
68  amrex::Abort(ss.str());
69  ))
70  }
71  }
72 #endif
73 };
74 
75 template <typename T, Order ORDER = Order::F>
76 struct Table2D
77 {
78  T* AMREX_RESTRICT p = nullptr;
79  Long stride1 = 0;
82 
83  constexpr Table2D () noexcept = default;
84 
85  template <class U=T, std::enable_if_t<std::is_const_v<U>,int> = 0>
87  constexpr Table2D (Table2D<std::remove_const_t<T>, ORDER> const& rhs) noexcept
88  : p(rhs.p),
89  stride1(rhs.stride1),
90  begin(rhs.begin),
91  end(rhs.end)
92  {}
93 
95  constexpr Table2D (T* a_p,
96  GpuArray<int,2> const& a_begin,
97  GpuArray<int,2> const& a_end) noexcept
98  : p(a_p),
99  stride1(len0(a_begin,a_end)),
100  begin(a_begin),
101  end(a_end)
102  {}
103 
105  explicit operator bool () const noexcept { return p != nullptr; }
106 
107  template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
109  U& operator() (int i, int j) const noexcept {
110 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
111  index_assert(i,j);
112 #endif
113  if constexpr (ORDER == Order::F) {
114  return p[(i-begin[0])+(j-begin[1])*stride1];
115  } else {
116  return p[(i-begin[0])*stride1+(j-begin[1])];
117  }
118  }
119 
120 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
121  AMREX_GPU_HOST_DEVICE inline
122  void index_assert (int i, int j) const
123  {
124  if (i < begin[0] || i >= end[0] ||
125  j < begin[1] || j >= end[1]) {
127  AMREX_DEVICE_PRINTF(" (%d,%d) is out of bound (%d:%d,%d:%d)\n",
128  i, j, begin[0], end[0]-1, begin[1], end[1]-1);
129  amrex::Abort();
130  ))
132  std::stringstream ss;
133  ss << " (" << i << "," << j << ") is out of bound ("
134  << begin[0] << ":" << end[0]-1
135  << "," << begin[1] << ":" << end[1]-1 << ")";
136  amrex::Abort(ss.str());
137  ))
138  }
139  }
140 #endif
141 
142 private:
143 
144  static constexpr int len0 (GpuArray<int,2> const& a_begin,
145  GpuArray<int,2> const& a_end) noexcept
146  {
147  if constexpr (ORDER == Order::F) {
148  return a_end[0] - a_begin[0];
149  } else {
150  return a_end[1] - a_begin[1];
151  }
152  }
153 };
154 
155 template <typename T, Order ORDER = Order::F>
156 struct Table3D
157 {
158  T* AMREX_RESTRICT p = nullptr;
159  Long stride1 = 0;
160  Long stride2 = 0;
163 
164  constexpr Table3D () noexcept = default;
165 
166  template <class U=T, std::enable_if_t<std::is_const_v<U>,int> = 0>
168  constexpr Table3D (Table3D<std::remove_const_t<T>,ORDER> const& rhs) noexcept
169  : p(rhs.p),
170  stride1(rhs.stride1),
171  stride2(rhs.stride2),
172  begin(rhs.begin),
173  end(rhs.end)
174  {}
175 
177  constexpr Table3D (T* a_p,
178  GpuArray<int,3> const& a_begin,
179  GpuArray<int,3> const& a_end) noexcept
180  : p(a_p),
181  stride1( len0(a_begin,a_end)),
182  stride2(stride1*len1(a_begin,a_end)),
183  begin(a_begin),
184  end(a_end)
185  {}
186 
188  explicit operator bool () const noexcept { return p != nullptr; }
189 
190  template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
192  U& operator() (int i, int j, int k) const noexcept {
193 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
194  index_assert(i,j,k);
195 #endif
196  if constexpr (ORDER == Order::F) {
197  return p[(i-begin[0])+(j-begin[1])*stride1+(k-begin[2])*stride2];
198  } else {
199  return p[(i-begin[0])*stride2+(j-begin[1])*stride1+(k-begin[2])];
200  }
201  }
202 
203 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
204  AMREX_GPU_HOST_DEVICE inline
205  void index_assert (int i, int j, int k) const
206  {
207  if (i < begin[0] || i >= end[0] ||
208  j < begin[1] || j >= end[1] ||
209  k < begin[2] || k >= end[2]) {
211  AMREX_DEVICE_PRINTF(" (%d,%d,%d) is out of bound (%d:%d,%d:%d,%d:%d)\n",
212  i, j, k, begin[0], end[0]-1, begin[1], end[1]-1,
213  begin[2], end[2]-1);
214  amrex::Abort();
215  ))
217  std::stringstream ss;
218  ss << " (" << i << "," << j << "," << k << ") is out of bound ("
219  << begin[0] << ":" << end[0]-1
220  << "," << begin[1] << ":" << end[1]-1
221  << "," << begin[2] << ":" << end[2]-1 << ")";
222  amrex::Abort(ss.str());
223  ))
224  }
225  }
226 #endif
227 
228 private:
229 
230  static constexpr int len0 (GpuArray<int,3> const& a_begin,
231  GpuArray<int,3> const& a_end) noexcept
232  {
233  if constexpr (ORDER == Order::F) {
234  return a_end[0] - a_begin[0];
235  } else {
236  return a_end[2] - a_begin[2];
237  }
238  }
239 
240  static constexpr int len1 (GpuArray<int,3> const& a_begin,
241  GpuArray<int,3> const& a_end) noexcept
242  {
243  return a_end[1] - a_begin[1];
244  }
245 };
246 
247 template <typename T, Order ORDER = Order::F>
248 struct Table4D
249 {
250  T* AMREX_RESTRICT p = nullptr;
251  Long stride1 = 0;
252  Long stride2 = 0;
253  Long stride3 = 0;
254  GpuArray<int,4> begin{{1,1,1,1}};
255  GpuArray<int,4> end{{0,0,0,0}};
256 
257  constexpr Table4D () noexcept = default;
258 
259  template <class U=T, std::enable_if_t<std::is_const_v<U>,int> = 0>
261  constexpr Table4D (Table4D<std::remove_const_t<T>,ORDER> const& rhs) noexcept
262  : p(rhs.p),
263  stride1(rhs.stride1),
264  stride2(rhs.stride2),
265  stride3(rhs.stride3),
266  begin(rhs.begin),
267  end(rhs.end)
268  {}
269 
271  constexpr Table4D (T* a_p,
272  GpuArray<int,4> const& a_begin,
273  GpuArray<int,4> const& a_end) noexcept
274  : p(a_p),
275  stride1( len0(a_begin,a_end)),
276  stride2(stride1*len1(a_begin,a_end)),
277  stride3(stride2*len2(a_begin,a_end)),
278  begin(a_begin),
279  end(a_end)
280  {}
281 
283  explicit operator bool () const noexcept { return p != nullptr; }
284 
285  template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
287  U& operator() (int i, int j, int k, int n) const noexcept {
288 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
289  index_assert(i,j,k,n);
290 #endif
291  if constexpr (ORDER == Order::F) {
292  return p[(i-begin[0])+(j-begin[1])*stride1+(k-begin[2])*stride2+(n-begin[3])*stride3];
293  } else {
294  return p[(i-begin[0])*stride3+(j-begin[1])*stride2+(k-begin[2])*stride1+(n-begin[3])];
295  }
296  }
297 
298 #if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
299  AMREX_GPU_HOST_DEVICE inline
300  void index_assert (int i, int j, int k, int n) const
301  {
302  if (i < begin[0] || i >= end[0] ||
303  j < begin[1] || j >= end[1] ||
304  k < begin[2] || k >= end[2] ||
305  n < begin[3] || n >= end[3]) {
307  AMREX_DEVICE_PRINTF(" (%d,%d,%d,%d) is out of bound (%d:%d,%d:%d,%d:%d,%d:%d)\n",
308  i, j, k, n, begin[0], end[0]-1, begin[1], end[1]-1,
309  begin[2], end[2]-1, begin[3], end[3]-1);
310  amrex::Abort();
311  ))
313  std::stringstream ss;
314  ss << " (" << i << "," << j << "," << k << "," << n << ") is out of bound ("
315  << begin[0] << ":" << end[0]-1
316  << "," << begin[1] << ":" << end[1]-1
317  << "," << begin[2] << ":" << end[2]-1
318  << "," << begin[3] << ":" << end[3]-1 << ")";
319  amrex::Abort(ss.str());
320  ))
321  }
322  }
323 #endif
324 
325 private:
326 
327  static constexpr int len0 (GpuArray<int,4> const& a_begin,
328  GpuArray<int,4> const& a_end) noexcept
329  {
330  if constexpr (ORDER == Order::F) {
331  return a_end[0] - a_begin[0];
332  } else {
333  return a_end[3] - a_begin[3];
334  }
335  }
336 
337  static constexpr int len1 (GpuArray<int,4> const& a_begin,
338  GpuArray<int,4> const& a_end) noexcept
339  {
340  if constexpr (ORDER == Order::F) {
341  return a_end[1] - a_begin[1];
342  } else {
343  return a_end[2] - a_begin[2];
344  }
345  }
346 
347  static constexpr int len2 (GpuArray<int,4> const& a_begin,
348  GpuArray<int,4> const& a_end) noexcept
349  {
350  if constexpr (ORDER == Order::F) {
351  return a_end[2] - a_begin[2];
352  } else {
353  return a_end[1] - a_begin[1];
354  }
355  }
356 };
357 
396 template <typename T, int N, Order ORDER = Order::F>
398  : public DataAllocator
399 {
400 public:
401 
402  template <class U, int M, Order O> friend class TableData;
403  using value_type = T;
404  using table_type = std::conditional_t<N==1, Table1D<T>,
405  std::conditional_t<N==2, Table2D<T, ORDER>,
406  std::conditional_t<N==3, Table3D<T, ORDER>,
407  Table4D<T, ORDER> > > >;
408  using const_table_type = std::conditional_t<N==1, Table1D<T const>,
409  std::conditional_t<N==2, Table2D<T const, ORDER>,
410  std::conditional_t<N==3, Table3D<T const, ORDER>,
412 
413  TableData () noexcept = default;
414 
415  explicit TableData (Arena* ar) noexcept;
416 
417  TableData (Array<int,N> const& lo, Array<int,N> const& hi, Arena* ar = nullptr);
418 
419  TableData (TableData<T,N,ORDER> const&) = delete;
420  TableData<T,N,ORDER>& operator= (TableData<T,N,ORDER> const&) = delete;
421 
422  TableData (TableData<T,N,ORDER>&& rhs) noexcept;
423  TableData<T,N,ORDER>& operator= (TableData<T,N,ORDER> && rhs) noexcept;
424 
425  ~TableData () noexcept;
426 
427  [[nodiscard]] constexpr int dim () const noexcept { return N; }
428 
429  void resize (Array<int,N> const& lo, Array<int,N> const& hi, Arena* ar = nullptr);
430 
431  [[nodiscard]] Long size () const noexcept;
432 
433  Array<int,N> const& lo () const noexcept { return m_lo; }
434 
435  Array<int,N> const& hi () const noexcept { return m_hi; }
436 
437  void clear () noexcept;
438 
439  void copy (TableData<T,N,ORDER> const& rhs) noexcept;
440 
441  table_type table () noexcept;
442  const_table_type table () const noexcept;
443  const_table_type const_table () const noexcept;
444 
445 private:
446 
447  void define ();
448 
449  T* m_dptr = nullptr;
450  Array<int,N> m_lo;
451  Array<int,N> m_hi;
452  Long m_truesize = 0L;
453  bool m_ptr_owner = false;
454 };
455 
456 template <typename T, int N, Order ORDER>
457 TableData<T,N,ORDER>::TableData (Array<int,N> const& lo, Array<int,N> const& hi, Arena* ar)
458  : DataAllocator{ar}, m_lo(lo), m_hi(hi)
459 {
460  define();
461 }
462 
463 
464 template <typename T, int N, Order ORDER>
466  : DataAllocator{rhs.arena()},
467  m_dptr(rhs.m_dptr),
468  m_lo(rhs.m_lo),
469  m_hi(rhs.m_hi),
470  m_truesize(rhs.m_truesize),
471  m_ptr_owner(rhs.m_ptr_owner)
472 {
473  rhs.m_dptr = nullptr;
474  rhs.m_ptr_owner = false;
475 }
476 
477 template <typename T, int N, Order ORDER>
478 TableData<T,N,ORDER>&
480 {
481  if (this != &rhs) {
482  clear();
483  m_arena = rhs.m_arena;
484  m_dptr = rhs.m_dptr;
485  m_lo = rhs.m_lo;
486  m_hi = rhs.m_hi;
487  m_truesize = rhs.m_truesize;
488  m_ptr_owner = rhs.m_ptr_owner;
489  rhs.m_dptr = nullptr;
490  rhs.m_ptr_owner = false;
491  }
492  return *this;
493 }
494 
495 template <typename T, int N, Order ORDER>
497 {
498  static_assert(std::is_trivially_copyable<T>() &&
499  std::is_trivially_destructible<T>(),
500  "TableData<T,N,ORDER>: T must be trivially copyable and trivially destructible");
501  static_assert(N>=1 && N <=4, "TableData<T,N,ORDER>: N must be in the range of [1,4]");
502  clear();
503 }
504 
505 template <typename T, int N, Order ORDER>
506 void
508 {
509  m_lo = lo;
510  m_hi = hi;
511 
512  if (ar == nullptr) {
513  ar = m_arena;
514  }
515 
516  if (arena() != DataAllocator(ar).arena()) {
517  clear();
518  m_arena = ar;
519  define();
520  } else if (m_dptr == nullptr || !m_ptr_owner) {
521  m_dptr = nullptr;
522  define();
523  } else if (size() > m_truesize) {
524  clear();
525  define();
526  }
527 }
528 
529 template <typename T, int N, Order ORDER>
530 Long
531 TableData<T,N,ORDER>::size () const noexcept
532 {
533  Long r = 1;
534  for (int i = 0; i < N; ++i) {
535  r *= m_hi[i] - m_lo[i] + 1;
536  }
537  return r;
538 }
539 
540 template <typename T, int N, Order ORDER>
541 void
543 {
544  if (m_dptr) {
545  if (m_ptr_owner) {
546  this->free(m_dptr);
547  }
548  m_dptr = nullptr;
549  m_truesize = 0;
550  }
551 }
552 
553 template <typename T, int N, Order ORDER>
554 void
556 {
557  m_truesize = size();
558  AMREX_ASSERT(m_truesize >= 0);
559  if (m_truesize == 0) {
560  return;
561  } else {
562  m_ptr_owner = true;
563  m_dptr = static_cast<T*>(this->alloc(m_truesize*sizeof(T)));
564  }
565 }
566 
567 namespace detail {
568  template <typename T, Order>
569  Table1D<T> make_table (T* p, Array<int,1> const& lo, Array<int,1> const& hi) {
570  return Table1D<T>(p, lo[0], hi[0]+1);
571  }
572  template <typename T, Order ORDER>
574  return Table2D<T,ORDER>(p, {lo[0],lo[1]}, {hi[0]+1,hi[1]+1});
575  }
576  template <typename T, Order ORDER>
577  Table3D<T> make_table (T* p, Array<int,3> const& lo, Array<int,3> const& hi) {
578  return Table3D<T,ORDER>(p, {lo[0],lo[1],lo[2]}, {hi[0]+1,hi[1]+1,hi[2]+1});
579  }
580  template <typename T, Order ORDER>
581  Table4D<T> make_table (T* p, Array<int,4> const& lo, Array<int,4> const& hi) {
582  return Table4D<T,ORDER>(p, {lo[0],lo[1],lo[2],lo[3]}, {hi[0]+1,hi[1]+1,hi[2]+1,hi[3]+1});
583  }
584 }
585 
586 template <typename T, int N, Order ORDER>
589 {
590  return detail::make_table<T,ORDER>(m_dptr, m_lo, m_hi);
591 }
592 
593 template <typename T, int N, Order ORDER>
596 {
597  return detail::make_table<T const, ORDER>(m_dptr, m_lo, m_hi);
598 }
599 
600 template <typename T, int N, Order ORDER>
603 {
604  return detail::make_table<T const, ORDER>(m_dptr, m_lo, m_hi);
605 }
606 
607 template <typename T, int N, Order ORDER>
608 void
610 {
611  std::size_t count = sizeof(T)*size();
612 #ifdef AMREX_USE_GPU
613  bool this_on_device = arena()->isManaged() || arena()->isDevice();
614  bool rhs_on_device = rhs.arena()->isManaged() || rhs.arena()->isDevice();
615  if (this_on_device && rhs_on_device) {
616  Gpu::dtod_memcpy_async(m_dptr, rhs.m_dptr, count);
617  } else if (this_on_device && !rhs_on_device) {
618  Gpu::htod_memcpy_async(m_dptr, rhs.m_dptr, count);
619  } else if (!this_on_device && rhs_on_device) {
620  Gpu::dtoh_memcpy_async(m_dptr, rhs.m_dptr, count);
621  } else
622 #endif
623  {
624  std::memcpy(m_dptr, rhs.m_dptr, count);
625  }
626 }
627 
628 }
629 
630 #endif
#define AMREX_ASSERT(EX)
Definition: AMReX_BLassert.H:38
#define AMREX_FORCE_INLINE
Definition: AMReX_Extension.H:119
#define AMREX_RESTRICT
Definition: AMReX_Extension.H:37
#define AMREX_DEVICE_PRINTF(...)
Definition: AMReX_GpuPrint.H:21
#define AMREX_IF_ON_DEVICE(CODE)
Definition: AMReX_GpuQualifiers.H:56
#define AMREX_IF_ON_HOST(CODE)
Definition: AMReX_GpuQualifiers.H:58
#define AMREX_GPU_HOST_DEVICE
Definition: AMReX_GpuQualifiers.H:20
void free(void *)
A virtual base class for objects that manage their own dynamic memory allocation.
Definition: AMReX_Arena.H:100
Multi-dimensional array class.
Definition: AMReX_TableData.H:399
std::conditional_t< N==1, Table1D< T >, std::conditional_t< N==2, Table2D< T, ORDER >, std::conditional_t< N==3, Table3D< T, ORDER >, Table4D< T, ORDER > > > > table_type
Definition: AMReX_TableData.H:407
TableData() noexcept=default
const_table_type const_table() const noexcept
Definition: AMReX_TableData.H:602
void resize(Array< int, N > const &lo, Array< int, N > const &hi, Arena *ar=nullptr)
Definition: AMReX_TableData.H:507
friend class TableData
Definition: AMReX_TableData.H:402
void copy(TableData< T, N, ORDER > const &rhs) noexcept
Definition: AMReX_TableData.H:609
std::conditional_t< N==1, Table1D< T const >, std::conditional_t< N==2, Table2D< T const, ORDER >, std::conditional_t< N==3, Table3D< T const, ORDER >, Table4D< T const, ORDER > > > > const_table_type
Definition: AMReX_TableData.H:411
Long size() const noexcept
Definition: AMReX_TableData.H:531
void define()
Definition: AMReX_TableData.H:555
TableData< T, N, ORDER > & operator=(TableData< T, N, ORDER > const &)=delete
T value_type
Definition: AMReX_TableData.H:403
Array< int, N > const & hi() const noexcept
Definition: AMReX_TableData.H:435
~TableData() noexcept
Definition: AMReX_TableData.H:496
void clear() noexcept
Definition: AMReX_TableData.H:542
table_type table() noexcept
Definition: AMReX_TableData.H:588
AMREX_GPU_HOST_DEVICE Long size(T const &b) noexcept
integer version
Definition: AMReX_GpuRange.H:26
void dtod_memcpy_async(void *p_d_dst, const void *p_d_src, const std::size_t sz) noexcept
Definition: AMReX_GpuDevice.H:279
void copy(HostToDevice, InIter begin, InIter end, OutIter result) noexcept
A host-to-device copy routine. Note this is just a wrapper around memcpy, so it assumes contiguous st...
Definition: AMReX_GpuContainers.H:121
void dtoh_memcpy_async(void *p_h, const void *p_d, const std::size_t sz) noexcept
Definition: AMReX_GpuDevice.H:265
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void * memcpy(void *dest, const void *src, std::size_t count)
Definition: AMReX_GpuUtility.H:214
void htod_memcpy_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition: AMReX_GpuDevice.H:251
Table4D< T > make_table(T *p, Array< int, 4 > const &lo, Array< int, 4 > const &hi)
Definition: AMReX_TableData.H:581
Definition: AMReX_Amr.cpp:49
Order
Definition: AMReX_SmallMatrix.H:19
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition: AMReX.cpp:225
std::array< T, N > Array
Definition: AMReX_Array.H:24
Definition: AMReX_FabArrayCommI.H:896
Definition: AMReX_DataAllocator.H:9
Arena * arena() const noexcept
Definition: AMReX_DataAllocator.H:24
Definition: AMReX_TableData.H:20
int begin
Definition: AMReX_TableData.H:22
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE U & operator()(int i) const noexcept
Definition: AMReX_TableData.H:47
int end
Definition: AMReX_TableData.H:23
constexpr AMREX_GPU_HOST_DEVICE Table1D(T *a_p, int a_begin, int a_end) noexcept
Definition: AMReX_TableData.H:36
constexpr Table1D() noexcept=default
T *AMREX_RESTRICT p
Definition: AMReX_TableData.H:21
Definition: AMReX_TableData.H:77
constexpr AMREX_GPU_HOST_DEVICE Table2D(T *a_p, GpuArray< int, 2 > const &a_begin, GpuArray< int, 2 > const &a_end) noexcept
Definition: AMReX_TableData.H:95
static constexpr int len0(GpuArray< int, 2 > const &a_begin, GpuArray< int, 2 > const &a_end) noexcept
Definition: AMReX_TableData.H:144
constexpr Table2D() noexcept=default
Definition: AMReX_TableData.H:157
static constexpr int len1(GpuArray< int, 3 > const &a_begin, GpuArray< int, 3 > const &a_end) noexcept
Definition: AMReX_TableData.H:240
constexpr Table3D() noexcept=default
static constexpr int len0(GpuArray< int, 3 > const &a_begin, GpuArray< int, 3 > const &a_end) noexcept
Definition: AMReX_TableData.H:230
constexpr AMREX_GPU_HOST_DEVICE Table3D(T *a_p, GpuArray< int, 3 > const &a_begin, GpuArray< int, 3 > const &a_end) noexcept
Definition: AMReX_TableData.H:177
Definition: AMReX_TableData.H:249
static constexpr int len1(GpuArray< int, 4 > const &a_begin, GpuArray< int, 4 > const &a_end) noexcept
Definition: AMReX_TableData.H:337
constexpr Table4D() noexcept=default
static constexpr int len2(GpuArray< int, 4 > const &a_begin, GpuArray< int, 4 > const &a_end) noexcept
Definition: AMReX_TableData.H:347
static constexpr int len0(GpuArray< int, 4 > const &a_begin, GpuArray< int, 4 > const &a_end) noexcept
Definition: AMReX_TableData.H:327
constexpr AMREX_GPU_HOST_DEVICE Table4D(T *a_p, GpuArray< int, 4 > const &a_begin, GpuArray< int, 4 > const &a_end) noexcept
Definition: AMReX_TableData.H:271