Kokkos Core Kernels Package  Version of the Day
Kokkos_Array.hpp
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 3.0
6 // Copyright (2020) National Technology & Engineering
7 // Solutions of Sandia, LLC (NTESS).
8 //
9 // Under the terms of Contract DE-NA0003525 with NTESS,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
40 //
41 // ************************************************************************
42 //@HEADER
43 */
44 
45 #ifndef KOKKOS_ARRAY_HPP
46 #define KOKKOS_ARRAY_HPP
47 
48 #include <Kokkos_Macros.hpp>
49 #include <impl/Kokkos_Error.hpp>
50 
51 #include <type_traits>
52 #include <algorithm>
53 #include <limits>
54 #include <cstddef>
55 #include <string>
56 
57 namespace Kokkos {
58 
59 #ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
60 namespace Impl {
61 template <typename Integral, bool Signed = std::is_signed<Integral>::value>
62 struct ArrayBoundsCheck;
63 
64 template <typename Integral>
65 struct ArrayBoundsCheck<Integral, true> {
66  KOKKOS_INLINE_FUNCTION
67  ArrayBoundsCheck(Integral i, size_t N) {
68  if (i < 0) {
69 #ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
70  std::string s = "Kokkos::Array: index ";
71  s += std::to_string(i);
72  s += " < 0";
73  Kokkos::Impl::throw_runtime_exception(s);
74 #else
75  Kokkos::abort("Kokkos::Array: negative index in device code");
76 #endif
77  }
78  ArrayBoundsCheck<Integral, false>(i, N);
79  }
80 };
81 
82 template <typename Integral>
83 struct ArrayBoundsCheck<Integral, false> {
84  KOKKOS_INLINE_FUNCTION
85  ArrayBoundsCheck(Integral i, size_t N) {
86  if (size_t(i) >= N) {
87 #ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
88  std::string s = "Kokkos::Array: index ";
89  s += std::to_string(i);
90  s += " >= ";
91  s += std::to_string(N);
92  Kokkos::Impl::throw_runtime_exception(s);
93 #else
94  Kokkos::abort("Kokkos::Array: index >= size");
95 #endif
96  }
97  }
98 };
99 } // end namespace Impl
100 
101 #define KOKKOS_ARRAY_BOUNDS_CHECK(i, N) \
102  Kokkos::Impl::ArrayBoundsCheck<decltype(i)>(i, N)
103 
104 #else // !defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
105 
106 #define KOKKOS_ARRAY_BOUNDS_CHECK(i, N) (void)0
107 
108 #endif // !defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
109 
113 template <class T = void, size_t N = KOKKOS_INVALID_INDEX, class Proxy = void>
114 struct Array {
115  public:
122  T m_internal_implementation_private_member_data[N];
123 
124  public:
125  using reference = T&;
126  using const_reference = typename std::add_const<T>::type&;
127  using size_type = size_t;
128  using difference_type = ptrdiff_t;
129  using value_type = T;
130  using pointer = T*;
131  using const_pointer = typename std::add_const<T>::type*;
132 
133  KOKKOS_INLINE_FUNCTION static constexpr size_type size() { return N; }
134  KOKKOS_INLINE_FUNCTION static constexpr bool empty() { return false; }
135  KOKKOS_INLINE_FUNCTION constexpr size_type max_size() const { return N; }
136 
137  template <typename iType>
138  KOKKOS_INLINE_FUNCTION reference operator[](const iType& i) {
139  static_assert(
140  (std::is_integral<iType>::value || std::is_enum<iType>::value),
141  "Must be integral argument");
142  KOKKOS_ARRAY_BOUNDS_CHECK(i, N);
143  return m_internal_implementation_private_member_data[i];
144  }
145 
146  template <typename iType>
147  KOKKOS_INLINE_FUNCTION const_reference operator[](const iType& i) const {
148  static_assert(
149  (std::is_integral<iType>::value || std::is_enum<iType>::value),
150  "Must be integral argument");
151  KOKKOS_ARRAY_BOUNDS_CHECK(i, N);
152  return m_internal_implementation_private_member_data[i];
153  }
154 
155  KOKKOS_INLINE_FUNCTION pointer data() {
156  return &m_internal_implementation_private_member_data[0];
157  }
158  KOKKOS_INLINE_FUNCTION const_pointer data() const {
159  return &m_internal_implementation_private_member_data[0];
160  }
161 };
162 
163 template <class T, class Proxy>
164 struct Array<T, 0, Proxy> {
165  public:
166  using reference = T&;
167  using const_reference = typename std::add_const<T>::type&;
168  using size_type = size_t;
169  using difference_type = ptrdiff_t;
170  using value_type = T;
171  using pointer = T*;
172  using const_pointer = typename std::add_const<T>::type*;
173 
174  KOKKOS_INLINE_FUNCTION static constexpr size_type size() { return 0; }
175  KOKKOS_INLINE_FUNCTION static constexpr bool empty() { return true; }
176  KOKKOS_INLINE_FUNCTION constexpr size_type max_size() const { return 0; }
177 
178  template <typename iType>
179  KOKKOS_INLINE_FUNCTION reference operator[](const iType&) {
180  static_assert(
181  (std::is_integral<iType>::value || std::is_enum<iType>::value),
182  "Must be integer argument");
183  Kokkos::abort("Unreachable code");
184  return *reinterpret_cast<pointer>(-1);
185  }
186 
187  template <typename iType>
188  KOKKOS_INLINE_FUNCTION const_reference operator[](const iType&) const {
189  static_assert(
190  (std::is_integral<iType>::value || std::is_enum<iType>::value),
191  "Must be integer argument");
192  Kokkos::abort("Unreachable code");
193  return *reinterpret_cast<const_pointer>(-1);
194  }
195 
196  KOKKOS_INLINE_FUNCTION pointer data() { return pointer(0); }
197  KOKKOS_INLINE_FUNCTION const_pointer data() const { return const_pointer(0); }
198 
199  KOKKOS_DEFAULTED_FUNCTION ~Array() = default;
200  KOKKOS_DEFAULTED_FUNCTION Array() = default;
201  KOKKOS_DEFAULTED_FUNCTION Array(const Array&) = default;
202  KOKKOS_DEFAULTED_FUNCTION Array& operator=(const Array&) = default;
203 
204  // Some supported compilers are not sufficiently C++11 compliant
205  // for default move constructor and move assignment operator.
206  // Array( Array && ) = default ;
207  // Array & operator = ( Array && ) = default ;
208 };
209 
210 template <>
211 struct Array<void, KOKKOS_INVALID_INDEX, void> {
212  struct contiguous {};
213  struct strided {};
214 };
215 
216 template <class T>
217 struct Array<T, KOKKOS_INVALID_INDEX, Array<>::contiguous> {
218  private:
219  T* m_elem;
220  size_t m_size;
221 
222  public:
223  using reference = T&;
224  using const_reference = typename std::add_const<T>::type&;
225  using size_type = size_t;
226  using difference_type = ptrdiff_t;
227  using value_type = T;
228  using pointer = T*;
229  using const_pointer = typename std::add_const<T>::type*;
230 
231  KOKKOS_INLINE_FUNCTION constexpr size_type size() const { return m_size; }
232  KOKKOS_INLINE_FUNCTION constexpr bool empty() const { return 0 != m_size; }
233  KOKKOS_INLINE_FUNCTION constexpr size_type max_size() const { return m_size; }
234 
235  template <typename iType>
236  KOKKOS_INLINE_FUNCTION reference operator[](const iType& i) {
237  static_assert(
238  (std::is_integral<iType>::value || std::is_enum<iType>::value),
239  "Must be integral argument");
240  KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
241  return m_elem[i];
242  }
243 
244  template <typename iType>
245  KOKKOS_INLINE_FUNCTION const_reference operator[](const iType& i) const {
246  static_assert(
247  (std::is_integral<iType>::value || std::is_enum<iType>::value),
248  "Must be integral argument");
249  KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
250  return m_elem[i];
251  }
252 
253  KOKKOS_INLINE_FUNCTION pointer data() { return m_elem; }
254  KOKKOS_INLINE_FUNCTION const_pointer data() const { return m_elem; }
255 
256  KOKKOS_DEFAULTED_FUNCTION ~Array() = default;
257  KOKKOS_INLINE_FUNCTION_DELETED Array() = delete;
258  KOKKOS_INLINE_FUNCTION_DELETED Array(const Array& rhs) = delete;
259 
260  // Some supported compilers are not sufficiently C++11 compliant
261  // for default move constructor and move assignment operator.
262  // Array( Array && rhs ) = default ;
263  // Array & operator = ( Array && rhs ) = delete ;
264 
265  KOKKOS_INLINE_FUNCTION
266  Array& operator=(const Array& rhs) {
267  const size_t n = std::min(m_size, rhs.size());
268  for (size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
269  return *this;
270  }
271 
272  template <size_t N, class P>
273  KOKKOS_INLINE_FUNCTION Array& operator=(const Array<T, N, P>& rhs) {
274  const size_t n = std::min(m_size, rhs.size());
275  for (size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
276  return *this;
277  }
278 
279  KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
280  size_type = 0)
281  : m_elem(arg_ptr), m_size(arg_size) {}
282 };
283 
284 template <class T>
285 struct Array<T, KOKKOS_INVALID_INDEX, Array<>::strided> {
286  private:
287  T* m_elem;
288  size_t m_size;
289  size_t m_stride;
290 
291  public:
292  using reference = T&;
293  using const_reference = typename std::add_const<T>::type&;
294  using size_type = size_t;
295  using difference_type = ptrdiff_t;
296  using value_type = T;
297  using pointer = T*;
298  using const_pointer = typename std::add_const<T>::type*;
299 
300  KOKKOS_INLINE_FUNCTION constexpr size_type size() const { return m_size; }
301  KOKKOS_INLINE_FUNCTION constexpr bool empty() const { return 0 != m_size; }
302  KOKKOS_INLINE_FUNCTION constexpr size_type max_size() const { return m_size; }
303 
304  template <typename iType>
305  KOKKOS_INLINE_FUNCTION reference operator[](const iType& i) {
306  static_assert(
307  (std::is_integral<iType>::value || std::is_enum<iType>::value),
308  "Must be integral argument");
309  KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
310  return m_elem[i * m_stride];
311  }
312 
313  template <typename iType>
314  KOKKOS_INLINE_FUNCTION const_reference operator[](const iType& i) const {
315  static_assert(
316  (std::is_integral<iType>::value || std::is_enum<iType>::value),
317  "Must be integral argument");
318  KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
319  return m_elem[i * m_stride];
320  }
321 
322  KOKKOS_INLINE_FUNCTION pointer data() { return m_elem; }
323  KOKKOS_INLINE_FUNCTION const_pointer data() const { return m_elem; }
324 
325  KOKKOS_DEFAULTED_FUNCTION ~Array() = default;
326  KOKKOS_INLINE_FUNCTION_DELETED Array() = delete;
327  KOKKOS_INLINE_FUNCTION_DELETED Array(const Array&) = delete;
328 
329  // Some supported compilers are not sufficiently C++11 compliant
330  // for default move constructor and move assignment operator.
331  // Array( Array && rhs ) = default ;
332  // Array & operator = ( Array && rhs ) = delete ;
333 
334  KOKKOS_INLINE_FUNCTION
335  Array& operator=(const Array& rhs) {
336  const size_t n = std::min(m_size, rhs.size());
337  for (size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
338  return *this;
339  }
340 
341  template <size_t N, class P>
342  KOKKOS_INLINE_FUNCTION Array& operator=(const Array<T, N, P>& rhs) {
343  const size_t n = std::min(m_size, rhs.size());
344  for (size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
345  return *this;
346  }
347 
348  KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
349  size_type arg_stride)
350  : m_elem(arg_ptr), m_size(arg_size), m_stride(arg_stride) {}
351 };
352 
353 } // namespace Kokkos
354 
355 #endif /* #ifndef KOKKOS_ARRAY_HPP */
Derived from the C++17 &#39;std::array&#39;. Dropping the iterator interface.
Definition: dummy.cpp:3