26 #ifndef SCHNEK_GRID_GRIDSTORAGE_KOKKOSSTORAGE_HPP_ 27 #define SCHNEK_GRID_GRIDSTORAGE_KOKKOSSTORAGE_HPP_ 29 #include "../../config.hpp" 31 #ifdef SCHNEK_HAVE_KOKKOS 33 #include "../../macros.hpp" 34 #include "../array.hpp" 35 #include "../range.hpp" 41 #include <Kokkos_Core.hpp> 46 template<
typename T,
size_t rank>
47 struct KokkosViewType {
48 typedef typename KokkosViewType<T, rank-1>::type* type;
52 struct KokkosViewType<T, 1> {
67 class ...ViewProperties
69 class KokkosGridStorage
73 typedef Array<int, rank> IndexType;
76 typedef Range<int, rank> RangeType;
78 typedef std::function<void(const RangeType&)> UpdaterType;
79 typedef std::map<void *, UpdaterType> UpdaterMapType;
87 Kokkos::View<typename internal::KokkosViewType<T, rank>::type, ViewProperties...> view;
90 std::shared_ptr<UpdaterMapType> updaters;
98 KokkosGridStorage(
const KokkosGridStorage &);
106 KokkosGridStorage(
const IndexType &lo,
const IndexType &hi);
113 KokkosGridStorage(
const RangeType &range);
116 ~KokkosGridStorage();
124 SCHNEK_INLINE
const T&
get(
const IndexType &index)
const;
132 SCHNEK_INLINE T&
get(
const IndexType &index);
135 SCHNEK_INLINE
const IndexType &getLo()
const {
return this->range.getLo(); }
138 SCHNEK_INLINE
const IndexType &getHi()
const {
return this->range.getHi(); }
141 SCHNEK_INLINE
const RangeType &getRange()
const {
return this->range; }
144 SCHNEK_INLINE
const IndexType &getDims()
const {
return this->dims; }
147 SCHNEK_INLINE
int getLo(
int k)
const {
return this->range.getLo(k); }
150 SCHNEK_INLINE
int getHi(
int k)
const {
return this->range.getHi(k); }
153 SCHNEK_INLINE
int getDims(
int k)
const {
return this->dims[k]; }
156 SCHNEK_INLINE
int getSize()
const {
return this->size; }
162 void resize(
const IndexType &low,
const IndexType &high);
167 SCHNEK_INLINE ptrdiff_t stride(
size_t dim)
const;
170 template<std::size_t... I>
171 auto createKokkosViewImpl(
const IndexType& a, std::index_sequence<I...>)
173 Kokkos::View<typename internal::KokkosViewType<T, rank>::type, ViewProperties...> view(
"schnek", a[I]...);
177 auto createKokkosView(
const IndexType& dims)
179 return createKokkosViewImpl(dims, std::make_index_sequence<rank>{});
182 template<std::size_t... I>
183 SCHNEK_INLINE T& getFromViewImpl(
const IndexType& pos, std::index_sequence<I...>)
185 return view(pos[I]...);
188 template<std::size_t... I>
189 SCHNEK_INLINE
const T& getFromViewImpl(
const IndexType& pos, std::index_sequence<I...>)
const 191 return view(pos[I]...);
194 SCHNEK_INLINE T& getFromView(
const IndexType& pos)
196 return getFromViewImpl(pos, std::make_index_sequence<rank>{});
199 SCHNEK_INLINE
const T& getFromView(
const IndexType& pos)
const 201 return getFromViewImpl(pos, std::make_index_sequence<rank>{});
204 void update(
const RangeType& range) {
205 for (
auto& updater: *updaters) {
206 updater.second(range);
210 void updateSizeInfo(
const RangeType &range) {
212 for (
size_t i = 0; i < rank; ++i)
214 dims[i] = range.getHi(i) - range.getLo(i) + 1;
219 template<
typename T,
size_t rank>
220 using KokkosDefaultGridStorage = KokkosGridStorage<T, rank>;
226 template <
typename T,
size_t rank,
class ...ViewProperties>
227 KokkosGridStorage<T, rank, ViewProperties...>::KokkosGridStorage()
228 : range{IndexType{0}, IndexType{0}},
230 updaters{
new UpdaterMapType}
232 (*updaters)[
this] = [
this](
const RangeType& range) { this->updateSizeInfo(range); };
235 template <
typename T,
size_t rank,
class ...ViewProperties>
236 KokkosGridStorage<T, rank, ViewProperties...>::KokkosGridStorage(
const KokkosGridStorage &other)
237 : range{other.range},
238 dims{other.dims}, view{other.view},
239 updaters{other.updaters}
241 (*updaters)[
this] = [
this](
const RangeType& range) { this->updateSizeInfo(range); };
244 template <
typename T,
size_t rank,
class ...ViewProperties>
245 KokkosGridStorage<T, rank, ViewProperties...>::KokkosGridStorage(
const IndexType &lo,
const IndexType &hi)
247 updaters{
new UpdaterMapType}
250 view = createKokkosView(dims);
251 (*updaters)[
this] = [
this](
const RangeType& range) { this->updateSizeInfo(range); };
254 template <
typename T,
size_t rank,
class ...ViewProperties>
255 KokkosGridStorage<T, rank, ViewProperties...>::KokkosGridStorage(
const RangeType &range)
257 updaters{
new UpdaterMapType}
259 dims = range.getHi() - range.getLo() + 1;
260 view = createKokkosView(dims);
261 (*updaters)[
this] = [
this](
const RangeType& range) { this->updateSizeInfo(range); };
264 template <
typename T,
size_t rank,
class ...ViewProperties>
265 KokkosGridStorage<T, rank, ViewProperties...>::~KokkosGridStorage()
267 updaters->erase(
this);
270 template <
typename T,
size_t rank,
class ...ViewProperties>
271 SCHNEK_INLINE
const T &KokkosGridStorage<T, rank, ViewProperties...>::get(
const IndexType &index)
const 274 for (
size_t i=0; i<rank; ++i)
276 pos[i] = index[i] - range.getLo(i);
278 return getFromView(pos);
281 template <
typename T,
size_t rank,
class ...ViewProperties>
282 SCHNEK_INLINE T &KokkosGridStorage<T, rank, ViewProperties...>::get(
const IndexType &index)
285 for (
size_t i=0; i<rank; ++i)
287 pos[i] = index[i] - range.getLo(i);
289 return getFromView(pos);
292 template <
typename T,
size_t rank,
class ...ViewProperties>
293 void KokkosGridStorage<T, rank, ViewProperties...>::resize(
const IndexType &lo,
const IndexType &hi)
295 IndexType dims = hi - lo + 1;
296 this->view = createKokkosView(dims);
297 update(RangeType{lo, hi});
300 template <
typename T,
size_t rank,
class ...ViewProperties>
301 SCHNEK_INLINE ptrdiff_t KokkosGridStorage<T, rank, ViewProperties...>::stride(
size_t dim)
const 303 return this->view.stride(dim);
309 #endif // SCHNEK_HAVE_KOKKOS 311 #endif // SCHNEK_GRID_GRIDSTORAGE_KOKKOSSTORAGE_HPP_