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
15 {
16 namespace Kokkos
17 {
18 
23 template <unsigned int inner>
25 {
29  dof_id_type dim[inner] = {0};
33  dof_id_type stride[inner] = {0};
34 
35 #ifdef MOOSE_KOKKOS_SCOPE
36 
41  KOKKOS_FUNCTION dof_id_type operator[](unsigned int i) const { return dim[i]; }
42 #endif
43 };
44 
45 #ifdef MOOSE_KOKKOS_SCOPE
46 
52 template <typename T, unsigned int inner>
54 {
55 public:
62  : _data(data), _dim(dim)
63  {
64  }
65 
70  KOKKOS_FUNCTION dof_id_type size() const { return _dim.stride[inner - 1]; }
76  KOKKOS_FUNCTION dof_id_type n(unsigned int dim) const { return _dim[dim]; }
81  KOKKOS_FUNCTION T & operator[](dof_id_type i) const
82  {
83  KOKKOS_ASSERT(i < _dim.stride[inner - 1]);
84 
85  return _data[i];
86  }
87 
88 protected:
92  T * _data;
97 };
98 
99 #define usingKokkosJaggedArrayInnerDataBaseMembers(T, inner) \
100 private: \
101  using JaggedArrayInnerDataBase<T, inner>::_data; \
102  using JaggedArrayInnerDataBase<T, inner>::_dim
103 
107 template <typename T, unsigned int inner>
110 
111 template <typename T>
113 {
114  usingKokkosJaggedArrayInnerDataBaseMembers(T, 1);
115 
116 public:
123  : JaggedArrayInnerDataBase<T, 1>(data, dim)
124  {
125  }
126 
131  KOKKOS_FUNCTION T & operator()(dof_id_type i0) const
132  {
133  KOKKOS_ASSERT(i0 < _dim[0]);
134 
135  return _data[i0];
136  }
137 };
138 
139 template <typename T>
141 {
142  usingKokkosJaggedArrayInnerDataBaseMembers(T, 2);
143 
144 public:
151  : JaggedArrayInnerDataBase<T, 2>(data, dim)
152  {
153  }
154 
160  KOKKOS_FUNCTION T & operator()(dof_id_type i0, dof_id_type i1) const
161  {
162  KOKKOS_ASSERT(i0 < _dim[0]);
163  KOKKOS_ASSERT(i1 < _dim[1]);
164 
165  return _data[i0 + _dim.stride[0] * i1];
166  }
167 };
168 
169 template <typename T>
171 {
172  usingKokkosJaggedArrayInnerDataBaseMembers(T, 3);
173 
174 public:
181  : JaggedArrayInnerDataBase<T, 3>(data, dim)
182  {
183  }
184 
191  KOKKOS_FUNCTION T & operator()(dof_id_type i0, dof_id_type i1, dof_id_type i2) const
192  {
193  KOKKOS_ASSERT(i0 < _dim[0]);
194  KOKKOS_ASSERT(i1 < _dim[1]);
195  KOKKOS_ASSERT(i2 < _dim[2]);
196 
197  return _data[i0 + _dim.stride[0] * i1 + _dim.stride[1] * i2];
198  }
199 };
201 #endif
202 
220 template <typename T, unsigned int inner, unsigned int outer>
222 {
223 #ifdef MOOSE_KOKKOS_SCOPE
224 public:
229  void create(const std::vector<dof_id_type> & n);
235  void reserve(const std::array<dof_id_type, outer> & index,
236  const std::array<dof_id_type, inner> & dimension);
240  void finalize();
245  {
246  mooseAssert(_finalized, "KokkosJaggedArray not finalized.");
247 
248  _data.copyToDevice();
249  }
253  void copyToHost()
254  {
255  mooseAssert(_finalized, "KokkosJaggedArray not finalized.");
256 
257  _data.copyToHost();
258  }
263  auto & array() { return _data; }
264 
269  KOKKOS_FUNCTION bool isFinalized() const { return _finalized; }
274  KOKKOS_FUNCTION dof_id_type size() const { return _data.size(); }
279  KOKKOS_FUNCTION dof_id_type n() const { return _offsets.size(); }
285  KOKKOS_FUNCTION dof_id_type n(unsigned int dim) const { return _offsets.n(dim); }
291  KOKKOS_FUNCTION auto operator[](dof_id_type i) const
292  {
293  auto data = &_data[_offsets[i]];
294  const auto & dim = _dims[i];
295 
296  return JaggedArrayInnerData<T, inner>(data, dim);
297  }
298 #endif
299 
300 protected:
317 };
318 
319 #define usingKokkosJaggedArrayBaseMembers(T, inner, outer) \
320 private: \
321  using JaggedArrayBase<T, inner, outer>::_data; \
322  using JaggedArrayBase<T, inner, outer>::_dims; \
323  using JaggedArrayBase<T, inner, outer>::_offsets
324 
325 #ifdef MOOSE_KOKKOS_SCOPE
326 template <typename T, unsigned int inner, unsigned int outer>
327 void
328 JaggedArrayBase<T, inner, outer>::create(const std::vector<dof_id_type> & n)
329 {
330  _data.destroy();
331  _offsets.create(n);
332  _dims.create(n);
333 
334  _finalized = false;
335 }
336 
337 template <typename T, unsigned int inner, unsigned int outer>
338 void
339 JaggedArrayBase<T, inner, outer>::reserve(const std::array<dof_id_type, outer> & index,
340  const std::array<dof_id_type, inner> & dimension)
341 {
342  mooseAssert(!_finalized, "KokkosJaggedArray already finalized.");
343 
344  dof_id_type idx = 0;
345  dof_id_type stride = 1;
346 
347  for (unsigned int o = 0; o < outer; ++o)
348  {
349  idx += index[o] * stride;
350  stride *= _offsets.n(o);
351  }
352 
353  stride = 1;
354 
355  for (unsigned int i = 0; i < inner; ++i)
356  {
357  stride *= dimension[i];
358 
359  _dims[idx].dim[i] = dimension[i];
360  _dims[idx].stride[i] = stride;
361  }
362 }
363 
364 template <typename T, unsigned int inner, unsigned int outer>
365 void
367 {
368  mooseAssert(!_finalized, "KokkosJaggedArray already finalized.");
369 
370  dof_id_type stride = 1;
371 
372  for (dof_id_type o = 0; o < _offsets.size(); ++o)
373  {
374  stride = 1;
375 
376  for (unsigned int i = 0; i < inner; ++i)
377  stride *= _dims[o][i];
378 
379  _offsets[o] = stride;
380  }
381 
382  std::exclusive_scan(_offsets.begin(), _offsets.end(), _offsets.begin(), 0);
383 
384  _dims.copyToDevice();
385  _offsets.copyToDevice();
386  _data.create(_offsets.last() + stride);
387 
388  _finalized = true;
389 }
390 #endif
391 
395 template <typename T, unsigned int inner, unsigned int outer>
398 
399 template <typename T, unsigned int inner>
400 class JaggedArray<T, inner, 1> : public JaggedArrayBase<T, inner, 1>
401 {
402  usingKokkosJaggedArrayBaseMembers(T, inner, 1);
403 
404 public:
408  JaggedArray() = default;
409 
410 #ifdef MOOSE_KOKKOS_SCOPE
411 
416  JaggedArray(dof_id_type n0) { create(n0); }
422 
428  KOKKOS_FUNCTION auto operator()(dof_id_type i0) const
429  {
430  auto data = &_data[_offsets(i0)];
431  const auto & dim = _dims(i0);
432 
433  return JaggedArrayInnerData<T, inner>(data, dim);
434  }
435 #endif
436 };
437 
438 template <typename T, unsigned int inner>
439 class JaggedArray<T, inner, 2> : public JaggedArrayBase<T, inner, 2>
440 {
441  usingKokkosJaggedArrayBaseMembers(T, inner, 2);
442 
443 public:
447  JaggedArray() = default;
448 
449 #ifdef MOOSE_KOKKOS_SCOPE
450 
456  JaggedArray(dof_id_type n0, dof_id_type n1) { create(n0, n1); }
463 
470  KOKKOS_FUNCTION auto operator()(dof_id_type i0, dof_id_type i1) const
471  {
472  auto data = &_data[_offsets(i0, i1)];
473  const auto & dim = _dims(i0, i1);
474 
475  return JaggedArrayInnerData<T, inner>(data, dim);
476  }
477 #endif
478 };
479 
480 template <typename T, unsigned int inner>
481 class JaggedArray<T, inner, 3> : public JaggedArrayBase<T, inner, 3>
482 {
483  usingKokkosJaggedArrayBaseMembers(T, inner, 3);
484 
485 public:
489  JaggedArray() = default;
490 
491 #ifdef MOOSE_KOKKOS_SCOPE
492 
499  JaggedArray(dof_id_type n0, dof_id_type n1, dof_id_type n2) { create(n0, n1, n2); }
507  {
509  }
510 
518  KOKKOS_FUNCTION auto operator()(dof_id_type i0, dof_id_type i1, dof_id_type i2) const
519  {
520  auto data = &_data[_offsets(i0, i1, i2)];
521  const auto & dim = _dims(i0, i1, i2);
522 
523  return JaggedArrayInnerData<T, inner>(data, dim);
524  }
525 #endif
526 };
528 
529 } // namespace Kokkos
530 } // namespace Moose
JaggedArray(dof_id_type n0, dof_id_type n1, dof_id_type n2)
Constructor Allocate outer array with given dimensions.
void create(const std::vector< dof_id_type > &n)
Allocate outer array.
The base class for Kokkos jagged arrays.
KOKKOS_FUNCTION dof_id_type size() const
Get the total data array size.
void finalize()
Setup array structure.
JaggedArrayInnerDim< inner > _dim
Inner array dimension information.
KOKKOS_FUNCTION JaggedArrayInnerData(T *data, JaggedArrayInnerDim< 2 > dim)
Constructor.
void create(dof_id_type n0, dof_id_type n1, dof_id_type n2)
Allocate outer array with given dimensions.
void copyToDevice()
Copy data from host to device.
KOKKOS_FUNCTION dof_id_type operator[](unsigned int i) const
Get the size of a dimension.
JaggedArray(dof_id_type n0)
Constructor Allocate outer array with given dimensions.
dof_id_type stride[inner]
Stride of each dimension.
Array< JaggedArrayInnerDim< inner >, outer > _dims
Dimension information of each inner array.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition: Moose.h:162
Array< T > _data
Sequential data array.
auto & array()
Get the underlying data array.
void create(dof_id_type n0)
Allocate outer array with given dimensions.
bool _finalized
Whether the array was finalized.
KOKKOS_FUNCTION T & operator[](dof_id_type i) const
Get an array entry.
KOKKOS_FUNCTION auto operator()(dof_id_type i0, dof_id_type i1, dof_id_type i2) const
Get an inner array.
KOKKOS_FUNCTION dof_id_type n() const
Get the total outer array size.
A simple object holding the dimension information of an inner array.
KOKKOS_FUNCTION T & operator()(dof_id_type i0, dof_id_type i1, dof_id_type i2) const
Get an array entry.
void reserve(const std::array< dof_id_type, outer > &index, const std::array< dof_id_type, inner > &dimension)
Reserve inner array for an outer array entry.
KOKKOS_FUNCTION T & operator()(dof_id_type i0, dof_id_type i1) const
Get an array entry.
KOKKOS_FUNCTION dof_id_type n(unsigned int dim) const
Get the size of a dimension of the outer array.
void copyToHost()
Copy data from device to host.
KOKKOS_FUNCTION auto operator()(dof_id_type i0, dof_id_type i1) const
Get an inner array.
KOKKOS_FUNCTION auto operator()(dof_id_type i0) const
Get an inner array.
KOKKOS_FUNCTION JaggedArrayInnerData(T *data, JaggedArrayInnerDim< 3 > dim)
Constructor.
The specialization of the inner array wrapper class for each dimension.
KOKKOS_FUNCTION dof_id_type n(unsigned int dim) const
Get the size of a dimension of the inner array.
T * _data
Pointer to the inner array data.
KOKKOS_FUNCTION bool isFinalized() const
Get whether the array is finalized.
Array< dof_id_type, outer > _offsets
Starting offset of each inner array into the sequential data array.
KOKKOS_FUNCTION T & operator()(dof_id_type i0) const
Get an array entry.
KOKKOS_FUNCTION dof_id_type size() const
Get the total inner array size.
KOKKOS_FUNCTION auto operator[](dof_id_type i) const
Get an inner array.
void create(dof_id_type n0, dof_id_type n1)
Allocate outer array with given dimensions.
JaggedArray(dof_id_type n0, dof_id_type n1)
Constructor Allocate outer array with given dimensions.
The specialization of the Kokkos jagged array class for each dimension.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
dof_id_type dim[inner]
Size of each dimension.
KOKKOS_FUNCTION JaggedArrayInnerDataBase(T *data, JaggedArrayInnerDim< inner > dim)
Constructor.
KOKKOS_FUNCTION JaggedArrayInnerData(T *data, JaggedArrayInnerDim< 1 > dim)
Constructor.
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)
uint8_t dof_id_type
The base class of the inner array wrapper.