YAKL
YAKL_CSArray.h
Go to the documentation of this file.
1 
2 #pragma once
3 // Included by YAKL_Array.h
4 
6 namespace yakl {
7 
8  // This is a low-overhead class to represent a multi-dimensional C-style array with compile-time
9  // known bounds placed on the stack of whatever context it is declared just like "int var[20];"
10  // except with multiple dimensions, index checking, and printing
11 
29  template <class T, int rank, unsigned D0, unsigned D1=1, unsigned D2=1, unsigned D3=1>
30  class CSArray {
31  protected:
33  static unsigned constexpr OFF0 = D3*D2*D1;
35  static unsigned constexpr OFF1 = D3*D2;
37  static unsigned constexpr OFF2 = D3;
39  static unsigned constexpr OFF3 = 1;
41  T mutable myData[D0*D1*D2*D3];
42 
43  public :
44 
46  typedef typename std::remove_cv<T>::type type;
48  typedef T value_type;
50  typedef typename std::add_const<type>::type const_value_type;
52  typedef typename std::remove_const<type>::type non_const_value_type;
53 
55  YAKL_INLINE CSArray(T init_fill) { for (int i=0; i < size(); i++) { myData[i] = init_fill; } }
56  CSArray() = default;
57  ~CSArray() = default;
58 
62  YAKL_INLINE T &operator()(uint const i0) const {
63  static_assert(rank==1,"ERROR: Improper number of dimensions specified in operator()");
64  #ifdef YAKL_DEBUG
65  if constexpr (rank >= 1) { if (i0>D0-1) { YAKL_EXECUTE_ON_HOST_ONLY( printf("CSArray i0 out of bounds (i0: %d; lb0: %d; ub0: %d)\n",i0,0,D0-1); ) } }
66  if constexpr (rank >= 1) { if (i0>D0-1) { yakl_throw("ERROR: CSArray index out of bounds"); } }
67  #endif
68  return myData[i0];
69  }
73  YAKL_INLINE T &operator()(uint const i0, uint const i1) const {
74  static_assert(rank==2,"ERROR: Improper number of dimensions specified in operator()");
75  #ifdef YAKL_DEBUG
76  if constexpr (rank >= 1) { if (i0>D0-1) { YAKL_EXECUTE_ON_HOST_ONLY( printf("CSArray i0 out of bounds (i0: %d; lb0: %d; ub0: %d)\n",i0,0,D0-1); ) } }
77  if constexpr (rank >= 2) { if (i1>D1-1) { YAKL_EXECUTE_ON_HOST_ONLY( printf("CSArray i1 out of bounds (i1: %d; lb1: %d; ub1: %d)\n",i1,0,D1-1); ) } }
78  if constexpr (rank >= 1) { if (i0>D0-1) { yakl_throw("ERROR: CSArray index out of bounds"); } }
79  if constexpr (rank >= 2) { if (i1>D1-1) { yakl_throw("ERROR: CSArray index out of bounds"); } }
80  #endif
81  return myData[i0*OFF0 + i1];
82  }
86  YAKL_INLINE T &operator()(uint const i0, uint const i1, uint const i2) const {
87  static_assert(rank==3,"ERROR: Improper number of dimensions specified in operator()");
88  #ifdef YAKL_DEBUG
89  if constexpr (rank >= 1) { if (i0>D0-1) { YAKL_EXECUTE_ON_HOST_ONLY( printf("CSArray i0 out of bounds (i0: %d; lb0: %d; ub0: %d)\n",i0,0,D0-1); ) } }
90  if constexpr (rank >= 2) { if (i1>D1-1) { YAKL_EXECUTE_ON_HOST_ONLY( printf("CSArray i1 out of bounds (i1: %d; lb1: %d; ub1: %d)\n",i1,0,D1-1); ) } }
91  if constexpr (rank >= 3) { if (i2>D2-1) { YAKL_EXECUTE_ON_HOST_ONLY( printf("CSArray i2 out of bounds (i2: %d; lb2: %d; ub2: %d)\n",i2,0,D2-1); ) } }
92  if constexpr (rank >= 1) { if (i0>D0-1) { yakl_throw("ERROR: CSArray index out of bounds"); } }
93  if constexpr (rank >= 2) { if (i1>D1-1) { yakl_throw("ERROR: CSArray index out of bounds"); } }
94  if constexpr (rank >= 3) { if (i2>D2-1) { yakl_throw("ERROR: CSArray index out of bounds"); } }
95  #endif
96  return myData[i0*OFF0 + i1*OFF1 + i2];
97  }
101  YAKL_INLINE T &operator()(uint const i0, uint const i1, uint const i2, uint const i3) const {
102  static_assert(rank==4,"ERROR: Improper number of dimensions specified in operator()");
103  #ifdef YAKL_DEBUG
104  if constexpr (rank >= 1) { if (i0>D0-1) { YAKL_EXECUTE_ON_HOST_ONLY( printf("CSArray i0 out of bounds (i0: %d; lb0: %d; ub0: %d)\n",i0,0,D0-1); ) } }
105  if constexpr (rank >= 2) { if (i1>D1-1) { YAKL_EXECUTE_ON_HOST_ONLY( printf("CSArray i1 out of bounds (i1: %d; lb1: %d; ub1: %d)\n",i1,0,D1-1); ) } }
106  if constexpr (rank >= 3) { if (i2>D2-1) { YAKL_EXECUTE_ON_HOST_ONLY( printf("CSArray i2 out of bounds (i2: %d; lb2: %d; ub2: %d)\n",i2,0,D2-1); ) } }
107  if constexpr (rank >= 4) { if (i3>D3-1) { YAKL_EXECUTE_ON_HOST_ONLY( printf("CSArray i3 out of bounds (i3: %d; lb3: %d; ub3: %d)\n",i3,0,D3-1); ) } }
108  if constexpr (rank >= 1) { if (i0>D0-1) { yakl_throw("ERROR: CSArray index out of bounds"); } }
109  if constexpr (rank >= 2) { if (i1>D1-1) { yakl_throw("ERROR: CSArray index out of bounds"); } }
110  if constexpr (rank >= 3) { if (i2>D2-1) { yakl_throw("ERROR: CSArray index out of bounds"); } }
111  if constexpr (rank >= 4) { if (i3>D3-1) { yakl_throw("ERROR: CSArray index out of bounds"); } }
112  #endif
113  return myData[i0*OFF0 + i1*OFF1 + i2*OFF2 + i3];
114  }
115 
116 
118  template <class TLOC , typename std::enable_if<std::is_arithmetic<TLOC>::value,int>::type = 0 >
119  YAKL_INLINE void operator= (TLOC val) { for (int i=0 ; i < totElems() ; i++) { myData[i] = val; } }
120 
121 
123  YAKL_INLINE T *data () const { return myData; }
125  YAKL_INLINE T *get_data() const { return myData; }
127  YAKL_INLINE T *begin() const { return myData; }
129  YAKL_INLINE T *end() const { return begin() + size(); }
131  static unsigned constexpr totElems () { return D3*D2*D1*D0; }
133  static unsigned constexpr get_totElems () { return D3*D2*D1*D0; }
135  static unsigned constexpr size () { return D3*D2*D1*D0; }
137  static unsigned constexpr get_elem_count() { return D3*D2*D1*D0; }
139  static unsigned constexpr get_rank () { return rank; }
141  static bool constexpr span_is_contiguous() { return true; }
143  static bool constexpr initialized() { return true; }
144 
145 
147  inline friend std::ostream &operator<<(std::ostream& os, CSArray<T,rank,D0,D1,D2,D3> const &v) {
148  for (uint i=0; i<totElems(); i++) { os << std::setw(12) << v.myData[i] << "\n"; }
149  os << "\n";
150  return os;
151  }
152 
153 
159  if constexpr (rank >= 1) ret(0) = D0;
160  if constexpr (rank >= 2) ret(1) = D1;
161  if constexpr (rank >= 3) ret(2) = D2;
162  if constexpr (rank >= 4) ret(3) = D3;
163  return ret;
164  }
170  if constexpr (rank >= 1) ret(0) = 0;
171  if constexpr (rank >= 2) ret(1) = 0;
172  if constexpr (rank >= 3) ret(2) = 0;
173  if constexpr (rank >= 4) ret(3) = 0;
174  return ret;
175  }
181  if constexpr (rank >= 1) ret(0) = D0-1;
182  if constexpr (rank >= 2) ret(1) = D1-1;
183  if constexpr (rank >= 3) ret(2) = D2-1;
184  if constexpr (rank >= 4) ret(3) = D3-1;
185  return ret;
186  }
187 
188  };
189 
190 
191 
193  template <class T, int rank, unsigned D0, unsigned D1=1, unsigned D2=1, unsigned D3=1>
195 
196 }
198 
199 
yakl::CSArray::operator<<
friend std::ostream & operator<<(std::ostream &os, CSArray< T, rank, D0, D1, D2, D3 > const &v)
Print out the contents of this array. This should be called only from the host.
Definition: YAKL_CSArray.h:147
yakl::CSArray::non_const_value_type
std::remove_const< type >::type non_const_value_type
This is the type T with const removed from it (if the original type has volatile, then so will this t...
Definition: YAKL_CSArray.h:52
yakl::CSArray::size
static constexpr unsigned size()
Get the total number of array elements.
Definition: YAKL_CSArray.h:135
yakl::CSArray::end
YAKL_INLINE T * end() const
Returns pointer to end of the data.
Definition: YAKL_CSArray.h:129
yakl::uint
unsigned int uint
Definition: YAKL.h:32
yakl::CSArray::CSArray
CSArray()=default
__YAKL_NAMESPACE_WRAPPER_END__
#define __YAKL_NAMESPACE_WRAPPER_END__
Definition: YAKL.h:20
yakl::CSArray::~CSArray
~CSArray()=default
__YAKL_NAMESPACE_WRAPPER_BEGIN__
#define __YAKL_NAMESPACE_WRAPPER_BEGIN__
Definition: YAKL.h:19
yakl::CSArray::span_is_contiguous
static constexpr bool span_is_contiguous()
Always true. All YAKL arrays are contiguous with no padding.
Definition: YAKL_CSArray.h:141
YAKL_INLINE
#define YAKL_INLINE
Used to decorate functions called from kernels (parallel_for and parallel_outer) or from CPU function...
Definition: YAKL_defines.h:140
yakl::CSArray::value_type
T value_type
This is the type T exactly as it was defined upon array object creation.
Definition: YAKL_CSArray.h:48
yakl::CSArray::get_rank
static constexpr unsigned get_rank()
Get the number of dimensions.
Definition: YAKL_CSArray.h:139
yakl::CSArray::operator()
YAKL_INLINE T & operator()(uint const i0, uint const i1, uint const i2, uint const i3) const
Returns a reference to the indexed element (4-D).
Definition: YAKL_CSArray.h:101
YAKL_EXECUTE_ON_HOST_ONLY
#define YAKL_EXECUTE_ON_HOST_ONLY(...)
[NOT COMMONLY USED] Macro function used to determine if the current code is compiling for the host.
Definition: YAKL_defines.h:153
yakl::yakl_throw
YAKL_INLINE void yakl_throw(const char *msg)
Throw an error message. Works from the host or device.
Definition: YAKL_error.h:17
yakl::CSArray::operator()
YAKL_INLINE T & operator()(uint const i0) const
Returns a reference to the indexed element (1-D).
Definition: YAKL_CSArray.h:62
yakl::CSArray::type
std::remove_cv< T >::type type
This is the type T without const and volatile modifiers.
Definition: YAKL_CSArray.h:46
yakl::CSArray
C-style array on the stack similar in nature to, e.g., float arr[ny][nx];
Definition: YAKL_CSArray.h:30
yakl::CSArray::get_totElems
static constexpr unsigned get_totElems()
Get the total number of array elements.
Definition: YAKL_CSArray.h:133
yakl::CSArray::const_value_type
std::add_const< type >::type const_value_type
This is the type T with const added to it (if the original type has volatile, then so will this type)...
Definition: YAKL_CSArray.h:50
yakl::CSArray::get_lbounds
YAKL_INLINE CSArray< uint, 1, rank > get_lbounds() const
Returns the lower bound of each dimension of this array as a yakl::SArray object.
Definition: YAKL_CSArray.h:168
yakl::CSArray::CSArray
YAKL_INLINE CSArray(T init_fill)
No constructor arguments allowed.
Definition: YAKL_CSArray.h:55
yakl::CSArray::get_elem_count
static constexpr unsigned get_elem_count()
Get the total number of array elements.
Definition: YAKL_CSArray.h:137
yakl
yakl::CSArray::get_dimensions
YAKL_INLINE CSArray< uint, 1, rank > get_dimensions() const
Returns the dimensions of this array as a yakl::SArray object.
Definition: YAKL_CSArray.h:157
yakl::CSArray::totElems
static constexpr unsigned totElems()
Get the total number of array elements.
Definition: YAKL_CSArray.h:131
yakl::CSArray::begin
YAKL_INLINE T * begin() const
Returns pointer to beginning of the data.
Definition: YAKL_CSArray.h:127
yakl::CSArray::get_ubounds
YAKL_INLINE CSArray< uint, 1, rank > get_ubounds() const
Returns the upper bound of each dimension of this array as a yakl::SArray object.
Definition: YAKL_CSArray.h:179
yakl::CSArray::get_data
YAKL_INLINE T * get_data() const
Get the underlying raw data pointer.
Definition: YAKL_CSArray.h:125
yakl::CSArray::operator()
YAKL_INLINE T & operator()(uint const i0, uint const i1, uint const i2) const
Returns a reference to the indexed element (3-D).
Definition: YAKL_CSArray.h:86
yakl::CSArray::operator=
YAKL_INLINE void operator=(TLOC val)
Assign a single arithmetic value to the entire array.
Definition: YAKL_CSArray.h:119
yakl::CSArray::operator()
YAKL_INLINE T & operator()(uint const i0, uint const i1) const
Returns a reference to the indexed element (2-D).
Definition: YAKL_CSArray.h:73
yakl::CSArray::data
YAKL_INLINE T * data() const
Get the underlying raw data pointer.
Definition: YAKL_CSArray.h:123
yakl::CSArray::initialized
static constexpr bool initialized()
Always true. yakl::SArray objects are by default always initialized / allocated.
Definition: YAKL_CSArray.h:143