45 #ifndef KOKKOS_ARRAY_HPP
46 #define KOKKOS_ARRAY_HPP
48 #include <Kokkos_Macros.hpp>
49 #include <impl/Kokkos_Error.hpp>
51 #include <type_traits>
59 #ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
61 template <typename Integral, bool Signed = std::is_signed<Integral>::value>
62 struct ArrayBoundsCheck;
64 template <
typename Integral>
65 struct ArrayBoundsCheck<Integral, true> {
66 KOKKOS_INLINE_FUNCTION
67 ArrayBoundsCheck(Integral i,
size_t N) {
69 #ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
70 std::string s =
"Kokkos::Array: index ";
71 s += std::to_string(i);
73 Kokkos::Impl::throw_runtime_exception(s);
75 Kokkos::abort(
"Kokkos::Array: negative index in device code");
78 ArrayBoundsCheck<Integral, false>(i, N);
82 template <
typename Integral>
83 struct ArrayBoundsCheck<Integral, false> {
84 KOKKOS_INLINE_FUNCTION
85 ArrayBoundsCheck(Integral i,
size_t N) {
87 #ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
88 std::string s =
"Kokkos::Array: index ";
89 s += std::to_string(i);
91 s += std::to_string(N);
92 Kokkos::Impl::throw_runtime_exception(s);
94 Kokkos::abort(
"Kokkos::Array: index >= size");
101 #define KOKKOS_ARRAY_BOUNDS_CHECK(i, N) \
102 Kokkos::Impl::ArrayBoundsCheck<decltype(i)>(i, N)
104 #else // !defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
106 #define KOKKOS_ARRAY_BOUNDS_CHECK(i, N) (void)0
108 #endif // !defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
113 template <
class T =
void,
size_t N = KOKKOS_INVALID_INDEX,
class Proxy =
void>
122 T m_internal_implementation_private_member_data[N];
125 typedef T& reference;
126 typedef typename std::add_const<T>::type& const_reference;
127 typedef size_t size_type;
128 typedef ptrdiff_t difference_type;
129 typedef T value_type;
131 typedef typename std::add_const<T>::type* const_pointer;
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; }
137 template <
typename iType>
138 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
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];
146 template <
typename iType>
147 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
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];
155 KOKKOS_INLINE_FUNCTION pointer data() {
156 return &m_internal_implementation_private_member_data[0];
158 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
159 return &m_internal_implementation_private_member_data[0];
162 #ifdef KOKKOS_IMPL_HIP_CLANG_WORKAROUND
164 KOKKOS_DEFAULTED_FUNCTION ~
Array() =
default;
165 KOKKOS_DEFAULTED_FUNCTION
Array() =
default;
166 KOKKOS_DEFAULTED_FUNCTION
Array(
const Array&) =
default;
167 KOKKOS_DEFAULTED_FUNCTION
Array& operator=(
const Array&) =
default;
171 KOKKOS_DEFAULTED_FUNCTION
Array(
Array&&) =
default;
172 KOKKOS_DEFAULTED_FUNCTION
Array& operator=(
Array&&) =
default;
174 KOKKOS_INLINE_FUNCTION
175 Array(
const std::initializer_list<T>& vals) {
176 for (
size_t i = 0; i < N; i++) {
177 m_internal_implementation_private_member_data[i] = vals.begin()[i];
183 template <
class T,
class Proxy>
184 struct Array<T, 0, Proxy> {
186 typedef T& reference;
187 typedef typename std::add_const<T>::type& const_reference;
188 typedef size_t size_type;
189 typedef ptrdiff_t difference_type;
190 typedef T value_type;
192 typedef typename std::add_const<T>::type* const_pointer;
194 KOKKOS_INLINE_FUNCTION
static constexpr size_type size() {
return 0; }
195 KOKKOS_INLINE_FUNCTION
static constexpr
bool empty() {
return true; }
196 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return 0; }
198 template <
typename iType>
199 KOKKOS_INLINE_FUNCTION reference operator[](
const iType&) {
201 (std::is_integral<iType>::value || std::is_enum<iType>::value),
202 "Must be integer argument");
203 Kokkos::abort(
"Unreachable code");
204 return *
reinterpret_cast<pointer
>(-1);
207 template <
typename iType>
208 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType&)
const {
210 (std::is_integral<iType>::value || std::is_enum<iType>::value),
211 "Must be integer argument");
212 Kokkos::abort(
"Unreachable code");
213 return *
reinterpret_cast<const_pointer
>(-1);
216 KOKKOS_INLINE_FUNCTION pointer data() {
return pointer(0); }
217 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return const_pointer(0); }
219 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
220 KOKKOS_DEFAULTED_FUNCTION Array() =
default;
221 KOKKOS_DEFAULTED_FUNCTION Array(
const Array&) =
default;
222 KOKKOS_DEFAULTED_FUNCTION Array& operator=(
const Array&) =
default;
231 struct Array<void, KOKKOS_INVALID_INDEX, void> {
232 struct contiguous {};
237 struct Array<T, KOKKOS_INVALID_INDEX, Array<>::contiguous> {
243 typedef T& reference;
244 typedef typename std::add_const<T>::type& const_reference;
245 typedef size_t size_type;
246 typedef ptrdiff_t difference_type;
247 typedef T value_type;
249 typedef typename std::add_const<T>::type* const_pointer;
251 KOKKOS_INLINE_FUNCTION constexpr size_type size()
const {
return m_size; }
252 KOKKOS_INLINE_FUNCTION constexpr
bool empty()
const {
return 0 != m_size; }
253 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return m_size; }
255 template <
typename iType>
256 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
258 (std::is_integral<iType>::value || std::is_enum<iType>::value),
259 "Must be integral argument");
260 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
264 template <
typename iType>
265 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
267 (std::is_integral<iType>::value || std::is_enum<iType>::value),
268 "Must be integral argument");
269 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
273 KOKKOS_INLINE_FUNCTION pointer data() {
return m_elem; }
274 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return m_elem; }
276 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
277 KOKKOS_INLINE_FUNCTION_DELETED Array() =
delete;
278 KOKKOS_INLINE_FUNCTION_DELETED Array(
const Array& rhs) =
delete;
285 KOKKOS_INLINE_FUNCTION
286 Array& operator=(
const Array& rhs) {
287 const size_t n = std::min(m_size, rhs.size());
288 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
292 template <
size_t N,
class P>
293 KOKKOS_INLINE_FUNCTION Array& operator=(
const Array<T, N, P>& rhs) {
294 const size_t n = std::min(m_size, rhs.size());
295 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
299 KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
301 : m_elem(arg_ptr), m_size(arg_size) {}
305 struct Array<T, KOKKOS_INVALID_INDEX, Array<>::strided> {
312 typedef T& reference;
313 typedef typename std::add_const<T>::type& const_reference;
314 typedef size_t size_type;
315 typedef ptrdiff_t difference_type;
316 typedef T value_type;
318 typedef typename std::add_const<T>::type* const_pointer;
320 KOKKOS_INLINE_FUNCTION constexpr size_type size()
const {
return m_size; }
321 KOKKOS_INLINE_FUNCTION constexpr
bool empty()
const {
return 0 != m_size; }
322 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return m_size; }
324 template <
typename iType>
325 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
327 (std::is_integral<iType>::value || std::is_enum<iType>::value),
328 "Must be integral argument");
329 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
330 return m_elem[i * m_stride];
333 template <
typename iType>
334 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
336 (std::is_integral<iType>::value || std::is_enum<iType>::value),
337 "Must be integral argument");
338 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
339 return m_elem[i * m_stride];
342 KOKKOS_INLINE_FUNCTION pointer data() {
return m_elem; }
343 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return m_elem; }
345 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
346 KOKKOS_INLINE_FUNCTION_DELETED Array() =
delete;
347 KOKKOS_INLINE_FUNCTION_DELETED Array(
const Array&) =
delete;
354 KOKKOS_INLINE_FUNCTION
355 Array& operator=(
const Array& rhs) {
356 const size_t n = std::min(m_size, rhs.size());
357 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
361 template <
size_t N,
class P>
362 KOKKOS_INLINE_FUNCTION Array& operator=(
const Array<T, N, P>& rhs) {
363 const size_t n = std::min(m_size, rhs.size());
364 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
368 KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
369 size_type arg_stride)
370 : m_elem(arg_ptr), m_size(arg_size), m_stride(arg_stride) {}
Derived from the C++17 'std::array'. Dropping the iterator interface.