Kokkos Core Kernels Package Version of the Day
Loading...
Searching...
No Matches
Kokkos_Array.hpp
1//@HEADER
2// ************************************************************************
3//
4// Kokkos v. 4.0
5// Copyright (2022) National Technology & Engineering
6// Solutions of Sandia, LLC (NTESS).
7//
8// Under the terms of Contract DE-NA0003525 with NTESS,
9// the U.S. Government retains certain rights in this software.
10//
11// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12// See https://kokkos.org/LICENSE for license information.
13// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14//
15//@HEADER
16
17#ifndef KOKKOS_ARRAY_HPP
18#define KOKKOS_ARRAY_HPP
19#ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
20#define KOKKOS_IMPL_PUBLIC_INCLUDE
21#define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY
22#endif
23
24#include <Kokkos_Macros.hpp>
25#include <Kokkos_Swap.hpp>
26#include <impl/Kokkos_Error.hpp>
27#include <impl/Kokkos_StringManipulation.hpp>
28
29#include <type_traits>
30#include <algorithm>
31#include <utility>
32#include <cstddef>
33
34namespace Kokkos {
35
36#ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
37namespace Impl {
38template <typename Integral, bool Signed = std::is_signed_v<Integral>>
39struct ArrayBoundsCheck;
40
41template <typename Integral>
42struct ArrayBoundsCheck<Integral, true> {
43 KOKKOS_INLINE_FUNCTION
44 constexpr ArrayBoundsCheck(Integral i, size_t N) {
45 if (i < 0) {
46 char err[128] = "Kokkos::Array: index ";
47 to_chars_i(err + strlen(err), err + 128, i);
48 strcat(err, " < 0");
49 Kokkos::abort(err);
50 }
51 ArrayBoundsCheck<Integral, false>(i, N);
52 }
53};
54
55template <typename Integral>
56struct ArrayBoundsCheck<Integral, false> {
57 KOKKOS_INLINE_FUNCTION
58 constexpr ArrayBoundsCheck(Integral i, size_t N) {
59 if (size_t(i) >= N) {
60 char err[128] = "Kokkos::Array: index ";
61 to_chars_i(err + strlen(err), err + 128, i);
62 strcat(err, " >= ");
63 to_chars_i(err + strlen(err), err + 128, N);
64 Kokkos::abort(err);
65 }
66 }
67};
68} // end namespace Impl
69
70#define KOKKOS_ARRAY_BOUNDS_CHECK(i, N) \
71 Kokkos::Impl::ArrayBoundsCheck<decltype(i)>(i, N)
72
73#else // !defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
74
75#define KOKKOS_ARRAY_BOUNDS_CHECK(i, N) (void)0
76
77#endif // !defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
78
82#ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
83template <class T = void, size_t N = KOKKOS_INVALID_INDEX, class Proxy = void>
84#else
85template <class T, size_t N>
86#endif
87struct Array {
88 public:
95 T m_internal_implementation_private_member_data[N];
96
97 public:
98 using reference = T&;
99 using const_reference = std::add_const_t<T>&;
100 using size_type = size_t;
102 using value_type = T;
103 using pointer = T*;
104 using const_pointer = std::add_const_t<T>*;
105
106 KOKKOS_INLINE_FUNCTION static constexpr size_type size() { return N; }
107 KOKKOS_INLINE_FUNCTION static constexpr bool empty() { return false; }
108 KOKKOS_INLINE_FUNCTION constexpr size_type max_size() const { return N; }
109
110 template <typename iType>
111 KOKKOS_INLINE_FUNCTION constexpr reference operator[](const iType& i) {
112 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
113 "Must be integral argument");
114 KOKKOS_ARRAY_BOUNDS_CHECK(i, N);
115 return m_internal_implementation_private_member_data[i];
116 }
117
118 template <typename iType>
119 KOKKOS_INLINE_FUNCTION constexpr const_reference operator[](
120 const iType& i) const {
121 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
122 "Must be integral argument");
123 KOKKOS_ARRAY_BOUNDS_CHECK(i, N);
124 return m_internal_implementation_private_member_data[i];
125 }
126
127 KOKKOS_INLINE_FUNCTION constexpr pointer data() {
128 return &m_internal_implementation_private_member_data[0];
129 }
130 KOKKOS_INLINE_FUNCTION constexpr const_pointer data() const {
131 return &m_internal_implementation_private_member_data[0];
132 }
133
134 friend KOKKOS_FUNCTION constexpr bool operator==(Array const& lhs,
135 Array const& rhs) noexcept {
136 for (size_t i = 0; i != N; ++i)
137 if (lhs[i] != rhs[i]) return false;
138 return true;
139 }
140
141 friend KOKKOS_FUNCTION constexpr bool operator!=(Array const& lhs,
142 Array const& rhs) noexcept {
143 return !(lhs == rhs);
144 }
145
146 private:
147 template <class U = T>
148 friend KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<
149 Impl::is_swappable<U>::value>
150 kokkos_swap(Array<T, N>& a,
151 Array<T, N>& b) noexcept(Impl::is_nothrow_swappable_v<U>) {
152 for (std::size_t i = 0; i < N; ++i) {
153 kokkos_swap(a[i], b[i]);
154 }
155 }
156};
157
158#ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
159template <class T, class Proxy>
160struct Array<T, 0, Proxy> {
161#else
162template <class T>
163struct Array<T, 0> {
164#endif
165 public:
166 using reference = T&;
167 using const_reference = std::add_const_t<T>&;
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 = std::add_const_t<T>*;
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((std::is_integral_v<iType> || std::is_enum_v<iType>),
181 "Must be integer argument");
182 Kokkos::abort("Unreachable code");
183 return *reinterpret_cast<pointer>(-1);
184 }
185
186 template <typename iType>
187 KOKKOS_INLINE_FUNCTION const_reference operator[](const iType&) const {
188 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
189 "Must be integer argument");
190 Kokkos::abort("Unreachable code");
191 return *reinterpret_cast<const_pointer>(-1);
192 }
193
194 KOKKOS_INLINE_FUNCTION constexpr pointer data() { return nullptr; }
195 KOKKOS_INLINE_FUNCTION constexpr const_pointer data() const {
196 return nullptr;
197 }
198
199 friend KOKKOS_FUNCTION constexpr bool operator==(Array const&,
200 Array const&) noexcept {
201 return true;
202 }
203 friend KOKKOS_FUNCTION constexpr bool operator!=(Array const&,
204 Array const&) noexcept {
205 return false;
206 }
207
208 private:
209 friend KOKKOS_INLINE_FUNCTION constexpr void kokkos_swap(
210 Array<T, 0>&, Array<T, 0>&) noexcept {}
211};
212
213#ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
214namespace Impl {
215struct KokkosArrayContiguous {};
216struct KokkosArrayStrided {};
217} // namespace Impl
218
219template <>
220struct KOKKOS_DEPRECATED Array<void, KOKKOS_INVALID_INDEX, void> {
221 using contiguous = Impl::KokkosArrayContiguous;
222 using strided = Impl::KokkosArrayStrided;
223};
224
225template <class T>
226struct KOKKOS_DEPRECATED
227 Array<T, KOKKOS_INVALID_INDEX, Impl::KokkosArrayContiguous> {
228 private:
229 T* m_elem;
230 size_t m_size;
231
232 public:
233 using reference = T&;
234 using const_reference = std::add_const_t<T>&;
235 using size_type = size_t;
236 using difference_type = ptrdiff_t;
237 using value_type = T;
238 using pointer = T*;
239 using const_pointer = std::add_const_t<T>*;
240
241 KOKKOS_INLINE_FUNCTION constexpr size_type size() const { return m_size; }
242 KOKKOS_INLINE_FUNCTION constexpr bool empty() const { return 0 == m_size; }
243 KOKKOS_INLINE_FUNCTION constexpr size_type max_size() const { return m_size; }
244
245 template <typename iType>
246 KOKKOS_INLINE_FUNCTION reference operator[](const iType& i) {
247 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
248 "Must be integral argument");
249 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
250 return m_elem[i];
251 }
252
253 template <typename iType>
254 KOKKOS_INLINE_FUNCTION const_reference operator[](const iType& i) const {
255 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
256 "Must be integral argument");
257 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
258 return m_elem[i];
259 }
260
261 KOKKOS_INLINE_FUNCTION pointer data() { return m_elem; }
262 KOKKOS_INLINE_FUNCTION const_pointer data() const { return m_elem; }
263
264 KOKKOS_DEFAULTED_FUNCTION ~Array() = default;
265 KOKKOS_INLINE_FUNCTION_DELETED Array() = delete;
266 KOKKOS_INLINE_FUNCTION_DELETED Array(const Array& rhs) = delete;
267
268 // Some supported compilers are not sufficiently C++11 compliant
269 // for default move constructor and move assignment operator.
270 // Array( Array && rhs ) = default ;
271 // Array & operator = ( Array && rhs ) = delete ;
272
273 KOKKOS_INLINE_FUNCTION
274 Array& operator=(const Array& rhs) {
275 if (&rhs == this) return *this;
276 const size_t n = size() < rhs.size() ? size() : rhs.size();
277 for (size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
278 return *this;
279 }
280
281 template <size_t N, class P>
282 KOKKOS_INLINE_FUNCTION Array& operator=(const Array<T, N, P>& rhs) {
283 const size_t n = size() < rhs.size() ? size() : rhs.size();
284 for (size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
285 return *this;
286 }
287
288 KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
289 size_type = 0)
290 : m_elem(arg_ptr), m_size(arg_size) {}
291};
292
293template <class T>
294struct KOKKOS_DEPRECATED
295 Array<T, KOKKOS_INVALID_INDEX, Impl::KokkosArrayStrided> {
296 private:
297 T* m_elem;
298 size_t m_size;
299 size_t m_stride;
300
301 public:
302 using reference = T&;
303 using const_reference = std::add_const_t<T>&;
304 using size_type = size_t;
305 using difference_type = ptrdiff_t;
306 using value_type = T;
307 using pointer = T*;
308 using const_pointer = std::add_const_t<T>*;
309
310 KOKKOS_INLINE_FUNCTION constexpr size_type size() const { return m_size; }
311 KOKKOS_INLINE_FUNCTION constexpr bool empty() const { return 0 == m_size; }
312 KOKKOS_INLINE_FUNCTION constexpr size_type max_size() const { return m_size; }
313
314 template <typename iType>
315 KOKKOS_INLINE_FUNCTION reference operator[](const iType& i) {
316 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
317 "Must be integral argument");
318 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
319 return m_elem[i * m_stride];
320 }
321
322 template <typename iType>
323 KOKKOS_INLINE_FUNCTION const_reference operator[](const iType& i) const {
324 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
325 "Must be integral argument");
326 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
327 return m_elem[i * m_stride];
328 }
329
330 KOKKOS_INLINE_FUNCTION pointer data() { return m_elem; }
331 KOKKOS_INLINE_FUNCTION const_pointer data() const { return m_elem; }
332
333 KOKKOS_DEFAULTED_FUNCTION ~Array() = default;
334 KOKKOS_INLINE_FUNCTION_DELETED Array() = delete;
335 KOKKOS_INLINE_FUNCTION_DELETED Array(const Array&) = delete;
336
337 // Some supported compilers are not sufficiently C++11 compliant
338 // for default move constructor and move assignment operator.
339 // Array( Array && rhs ) = default ;
340 // Array & operator = ( Array && rhs ) = delete ;
341
342 KOKKOS_INLINE_FUNCTION
343 Array& operator=(const Array& rhs) {
344 if (&rhs == this) return *this;
345 const size_t n = size() < rhs.size() ? size() : rhs.size();
346 for (size_t i = 0; i < n; ++i) m_elem[i * m_stride] = rhs[i];
347 return *this;
348 }
349
350 template <size_t N, class P>
351 KOKKOS_INLINE_FUNCTION Array& operator=(const Array<T, N, P>& rhs) {
352 const size_t n = size() < rhs.size() ? size() : rhs.size();
353 for (size_t i = 0; i < n; ++i) m_elem[i * m_stride] = rhs[i];
354 return *this;
355 }
356
357 KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
358 size_type arg_stride)
359 : m_elem(arg_ptr), m_size(arg_size), m_stride(arg_stride) {}
360};
361#endif
362
363template <typename T, typename... Us>
364Array(T, Us...) -> Array<T, 1 + sizeof...(Us)>;
365
366namespace Impl {
367
368template <typename T, size_t N, size_t... I>
369KOKKOS_FUNCTION constexpr Array<std::remove_cv_t<T>, N> to_array_impl(
370 T (&a)[N], std::index_sequence<I...>) {
371 return {{a[I]...}};
372}
373
374template <typename T, size_t N, size_t... I>
375KOKKOS_FUNCTION constexpr Array<std::remove_cv_t<T>, N> to_array_impl(
376 T (&&a)[N], std::index_sequence<I...>) {
377 return {{std::move(a[I])...}};
378}
379
380} // namespace Impl
381
382template <typename T, size_t N>
383KOKKOS_FUNCTION constexpr auto to_array(T (&a)[N]) {
384 return Impl::to_array_impl(a, std::make_index_sequence<N>{});
385}
386
387template <typename T, size_t N>
388KOKKOS_FUNCTION constexpr auto to_array(T (&&a)[N]) {
389 return Impl::to_array_impl(std::move(a), std::make_index_sequence<N>{});
390}
391
392} // namespace Kokkos
393
394//<editor-fold desc="Support for structured binding">
395template <class T, std::size_t N>
396struct std::tuple_size<Kokkos::Array<T, N>>
397 : std::integral_constant<std::size_t, N> {};
398
399template <std::size_t I, class T, std::size_t N>
400struct std::tuple_element<I, Kokkos::Array<T, N>> {
401 static_assert(I < N);
402 using type = T;
403};
404
405namespace Kokkos {
406
407template <std::size_t I, class T, std::size_t N>
408KOKKOS_FUNCTION constexpr T& get(Array<T, N>& a) noexcept {
409 static_assert(I < N);
410 return a[I];
411}
412
413template <std::size_t I, class T, std::size_t N>
414KOKKOS_FUNCTION constexpr T const& get(Array<T, N> const& a) noexcept {
415 static_assert(I < N);
416 return a[I];
417}
418
419template <std::size_t I, class T, std::size_t N>
420KOKKOS_FUNCTION constexpr T&& get(Array<T, N>&& a) noexcept {
421 static_assert(I < N);
422 return std::move(a[I]);
423}
424
425template <std::size_t I, class T, std::size_t N>
426KOKKOS_FUNCTION constexpr T const&& get(Array<T, N> const&& a) noexcept {
427 static_assert(I < N);
428 return std::move(a[I]);
429}
430
431} // namespace Kokkos
432//</editor-fold>
433
434//<editor-fold desc="Support for range-based for loop">
435namespace Kokkos {
436
437template <class T, std::size_t N>
438KOKKOS_FUNCTION constexpr T const* begin(Array<T, N> const& a) noexcept {
439 return a.data();
440}
441
442template <class T, std::size_t N>
443KOKKOS_FUNCTION constexpr T* begin(Array<T, N>& a) noexcept {
444 return a.data();
445}
446
447template <class T, std::size_t N>
448KOKKOS_FUNCTION constexpr T const* end(Array<T, N> const& a) noexcept {
449 return a.data() + a.size();
450}
451
452template <class T, std::size_t N>
453KOKKOS_FUNCTION constexpr T* end(Array<T, N>& a) noexcept {
454 return a.data() + a.size();
455}
456
457} // namespace Kokkos
458//</editor-fold>
459
460#ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY
461#undef KOKKOS_IMPL_PUBLIC_INCLUDE
462#undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY
463#endif
464#endif /* #ifndef KOKKOS_ARRAY_HPP */
A thread safe view to a bitset.
KOKKOS_FORCEINLINE_FUNCTION unsigned size() const
Derived from the C++17 'std::array'. Dropping the iterator interface.