https://mooseframework.inl.gov
KokkosJaggedArray.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 #include "KokkosArray.h"
13 
14 namespace Moose::Kokkos
15 {
16 
21 template <unsigned int inner>
23 {
27  unsigned int dim[inner] = {0};
31  unsigned int stride[inner + 1] = {0};
32 
33 #ifdef MOOSE_KOKKOS_SCOPE
34 
39  KOKKOS_FUNCTION unsigned int operator[](unsigned int i) const { return dim[i]; }
40 #endif
41 };
42 
43 #ifdef MOOSE_KOKKOS_SCOPE
44 
51 template <typename T, unsigned int inner, LayoutType layout>
53 {
54 public:
61  : _data(data), _dim(dim)
62  {
63  }
64 
69  KOKKOS_FUNCTION unsigned int size() const { return _dim.stride[inner]; }
75  KOKKOS_FUNCTION unsigned int n(unsigned int dim) const { return _dim[dim]; }
80  KOKKOS_FUNCTION T & operator[](unsigned int i) const
81  {
82  KOKKOS_ASSERT(i < _dim.stride[inner]);
83 
84  return _data[i];
85  }
90  template <typename... indices>
91  KOKKOS_FUNCTION T & operator()(indices... i) const;
92 
93 protected:
97  T * _data;
102 };
103 
104 template <typename T, unsigned int inner, LayoutType layout>
105 template <typename... indices>
106 KOKKOS_FUNCTION T &
108 {
109  static_assert((std::is_convertible<indices, unsigned int>::value && ...),
110  "All arguments must be convertible to unsigned int");
111  static_assert(sizeof...(i) == inner, "Number of arguments should match array dimension");
112 
113 #ifndef NDEBUG
114  {
115  unsigned int idx[inner] = {static_cast<unsigned int>(i)...};
116 
117  for (unsigned int d = 0; d < sizeof...(i); ++d)
118  KOKKOS_ASSERT(idx[d] < _dim[d]);
119  }
120 #endif
121 
122  unsigned int idx = 0;
123  unsigned int d = 0;
124 
125  if constexpr (layout == LayoutType::LEFT)
126  (((idx +=
127  (d == 0 ? static_cast<unsigned int>(i) : static_cast<unsigned int>(i) * _dim.stride[d])),
128  ++d),
129  ...);
130  else
131  (((idx += (d == inner - 1 ? static_cast<unsigned int>(i)
132  : static_cast<unsigned int>(i) * _dim.stride[d])),
133  ++d),
134  ...);
135 
136  return _data[idx];
137 }
138 #endif
139 
159 template <typename T,
160  unsigned int inner,
161  unsigned int outer,
162  typename index_type = MOOSE_KOKKOS_INDEX_TYPE,
163  LayoutType layout = LayoutType::LEFT>
165 {
166 public:
170  JaggedArray() = default;
171 
172 #ifdef MOOSE_KOKKOS_SCOPE
173 
176  template <typename... size_type>
177  JaggedArray(size_type... n)
178  {
179  create(n...);
180  }
181 
186  void create(const std::vector<index_type> & n);
191  template <typename... size_type>
192  void create(size_type... n);
198  void reserve(const std::array<uint64_t, outer> & index,
199  const std::array<uint64_t, inner> & dimension);
203  void finalize();
208  {
209  mooseAssert(_finalized, "KokkosJaggedArray not finalized.");
210 
211  _data.copyToDevice();
212  }
216  void copyToHost()
217  {
218  mooseAssert(_finalized, "KokkosJaggedArray not finalized.");
219 
220  _data.copyToHost();
221  }
226  {
227  mooseAssert(_finalized, "KokkosJaggedArray not finalized.");
228 
229  _dims.moveToDevice();
231  _data.moveToDevice();
232  }
236  void moveToHost()
237  {
238  mooseAssert(_finalized, "KokkosJaggedArray not finalized.");
239 
240  _dims.moveToHost();
242  _data.moveToHost();
243  }
248  auto & array() { return _data; }
249 
254  KOKKOS_FUNCTION bool isFinalized() const { return _finalized; }
259  KOKKOS_FUNCTION bool isHostAlloc() const { return _data.isHostAlloc(); }
264  KOKKOS_FUNCTION bool isDeviceAlloc() const { return _data.isDeviceAlloc(); }
269  KOKKOS_FUNCTION index_type size() const { return _data.size(); }
274  KOKKOS_FUNCTION index_type n() const { return _offsets.size(); }
280  KOKKOS_FUNCTION index_type n(unsigned int dim) const { return _offsets.n(dim); }
286  KOKKOS_FUNCTION auto operator[](index_type i) const;
292  template <typename... indices>
293  KOKKOS_FUNCTION auto operator()(indices... i) const;
294 #endif
295 
296 protected:
312  bool _finalized = false;
313 };
314 
315 #ifdef MOOSE_KOKKOS_SCOPE
316 template <typename T,
317  unsigned int inner,
318  unsigned int outer,
319  typename index_type,
320  LayoutType layout>
321 void
323 {
324  _data.destroy();
325  _offsets.create(n);
326  _dims.create(n);
327 
328  _finalized = false;
329 }
330 
331 template <typename T,
332  unsigned int inner,
333  unsigned int outer,
334  typename index_type,
335  LayoutType layout>
336 template <typename... size_type>
337 void
339 {
340  _data.destroy();
341  _offsets.create(n...);
342  _dims.create(n...);
343 
344  _finalized = false;
345 }
346 
347 template <typename T,
348  unsigned int inner,
349  unsigned int outer,
350  typename index_type,
351  LayoutType layout>
352 void
354  const std::array<uint64_t, outer> & index, const std::array<uint64_t, inner> & dimension)
355 {
356  mooseAssert(!_finalized, "KokkosJaggedArray already finalized.");
357 
358  index_type idx = 0;
359  index_type stride = 1;
360 
361  for (unsigned int o = 0; o < outer; ++o)
362  {
363  idx += index[o] * stride;
364  stride *= _offsets.n(o);
365  }
366 
367  for (unsigned int i = 0; i < inner; ++i)
368  _dims[idx].dim[i] = dimension[i];
369 
370  stride = 1;
371 
372  if constexpr (layout == LayoutType::LEFT)
373  for (unsigned int i = 0; i < inner; ++i)
374  {
375  _dims[idx].stride[i] = stride;
376  stride *= dimension[i];
377  }
378  else
379  for (int i = inner - 1; i >= 0; --i)
380  {
381  _dims[idx].stride[i] = stride;
382  stride *= dimension[i];
383  }
384 
385  _dims[idx].stride[inner] = stride;
386 }
387 
388 template <typename T,
389  unsigned int inner,
390  unsigned int outer,
391  typename index_type,
392  LayoutType layout>
393 void
395 {
396  mooseAssert(!_finalized, "KokkosJaggedArray already finalized.");
397 
398  index_type stride = 1;
399 
400  for (index_type o = 0; o < _offsets.size(); ++o)
401  {
402  stride = 1;
403 
404  for (unsigned int i = 0; i < inner; ++i)
405  stride *= _dims[o][i];
406 
407  _offsets[o] = stride;
408  }
409 
410  std::exclusive_scan(_offsets.begin(), _offsets.end(), _offsets.begin(), 0);
411 
412  _dims.copyToDevice();
413  _offsets.copyToDevice();
414 
415  // Pad an extra element at the end to avoid accessing the bound in the following operators when
416  // the last inner array has zero size
417  _data.create(_offsets.last() + stride + 1);
418 
419  _finalized = true;
420 }
421 
422 template <typename T,
423  unsigned int inner,
424  unsigned int outer,
425  typename index_type,
426  LayoutType layout>
427 KOKKOS_FUNCTION auto
429 {
430  auto data = &_data[_offsets[i]];
431  const auto & dim = _dims[i];
432 
434 }
435 
436 template <typename T,
437  unsigned int inner,
438  unsigned int outer,
439  typename index_type,
440  LayoutType layout>
441 template <typename... indices>
442 KOKKOS_FUNCTION auto
444 {
445  auto data = &_data[_offsets(i...)];
446  const auto & dim = _dims(i...);
447 
449 }
450 #endif
451 
452 } // namespace Moose::Kokkos
JaggedArray()=default
Default constructor.
void moveToHost()
Copy data from device to host and deallocate device.
The Kokkos array class.
Definition: KokkosArray.h:64
KOKKOS_FUNCTION index_type n(unsigned int dim) const
Get the size of a dimension.
Definition: KokkosArray.h:211
bool _finalized
Whether the array was finalized.
void moveToHost(bool should_free_device=true)
Copy data from device to host and deallocate device.
Definition: KokkosArray.h:1014
KOKKOS_FUNCTION index_type n() const
Get the total outer array size.
JaggedArrayInnerDim< inner > _dim
Inner array dimension information.
LayoutType
The enumerator that dictates the memory layout.
Definition: KokkosArray.h:51
Array1D< T, index_type > _data
Sequential data array.
Array< JaggedArrayInnerDim< inner >, outer, index_type > _dims
Dimension information of each inner array.
void moveToDevice(bool should_free_host=true)
Copy data from host to device and deallocate host.
Definition: KokkosArray.h:997
KOKKOS_FUNCTION bool isDeviceAlloc() const
Get whether the array was allocated on device.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition: Moose.h:163
void moveToDevice()
Copy data from host to device and deallocate host.
void copyToHost()
Copy data from device to host.
Array< index_type, outer, index_type > _offsets
Starting offset of each inner array into the sequential data array.
KOKKOS_FUNCTION index_type size() const
Get the total data array size.
KOKKOS_FUNCTION unsigned int size() const
Get the total inner array size.
A simple object holding the dimension information of an inner array.
JaggedArray(size_type... n)
Constructor.
KOKKOS_FUNCTION bool isFinalized() const
Get whether the array is finalized.
unsigned int dim[inner]
Size of each dimension.
KOKKOS_FUNCTION index_type size() const
Get the total array size.
Definition: KokkosArray.h:205
KOKKOS_FUNCTION auto operator[](index_type i) const
Get an inner array.
KOKKOS_FUNCTION T & operator()(indices... i) const
Get an array entry.
void create(const std::vector< index_type > &n)
Allocate outer array.
The inner array wrapper class.
auto & array()
Get the underlying data array.
T * _data
Pointer to the inner array data.
unsigned int stride[inner+1]
Stride of each dimension.
KOKKOS_FUNCTION unsigned int n(unsigned int dim) const
Get the size of a dimension of the inner array.
void reserve(const std::array< uint64_t, outer > &index, const std::array< uint64_t, inner > &dimension)
Reserve inner array for an outer array entry.
KOKKOS_FUNCTION auto operator()(indices... i) const
Get an inner array.
KOKKOS_FUNCTION index_type n(unsigned int dim) const
Get the size of a dimension of the outer array.
KOKKOS_FUNCTION unsigned int operator[](unsigned int i) const
Get the size of a dimension.
KOKKOS_FUNCTION bool isHostAlloc() const
Get whether the array was allocated on host.
The Kokkos jagged array class.
KOKKOS_FUNCTION JaggedArrayInnerData(T *data, JaggedArrayInnerDim< inner > dim)
Constructor.
void copyToDevice()
Copy data from host to device.
KOKKOS_FUNCTION T & operator[](unsigned int i) const
Get an array entry.
void finalize()
Setup array structure.
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)