RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
View.hpp
Go to the documentation of this file.
1 
11 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
12 // Copyright (c) Lawrence Livermore National Security, LLC and other
13 // RAJA Project Developers. See top-level LICENSE and COPYRIGHT
14 // files for dates and other details. No copyright assignment is required
15 // to contribute to RAJA.
16 //
17 // SPDX-License-Identifier: (BSD-3-Clause)
18 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
19 
20 #ifndef RAJA_VIEW_HPP
21 #define RAJA_VIEW_HPP
22 
23 #include <array>
24 #include <type_traits>
25 
26 #include "RAJA/config.hpp"
27 #include "RAJA/pattern/atomic.hpp"
29 #include "RAJA/util/Layout.hpp"
32 
33 namespace RAJA
34 {
35 
36 // Helpers to convert
37 // layouts -> OffsetLayouts
38 // Typedlayouts -> TypedOffsetLayouts
39 template<typename layout>
40 struct add_offset
41 {
43 };
44 
45 template<typename IdxLin, typename... DimTypes>
46 struct add_offset<RAJA::TypedLayout<IdxLin, camp::tuple<DimTypes...>>>
47 {
48  using type = RAJA::TypedOffsetLayout<IdxLin, camp::tuple<DimTypes...>>;
49 };
50 
51 template<typename ValueType,
52  typename LayoutType,
53  typename PointerType = ValueType*>
55 
56 
57 template<typename ValueType, typename LayoutType, typename... IndexTypes>
58 using TypedView = internal::
59  TypedViewBase<ValueType, ValueType*, LayoutType, camp::list<IndexTypes...>>;
60 
61 template<typename IndexType, typename ValueType>
63 make_view(ValueType* ptr)
64 {
66 }
67 
68 template<size_t n_dims,
69  typename IndexType,
70  typename ValueType,
71  typename... IndexTypes>
72 RAJA_HOST_DEVICE RAJA_INLINE constexpr View<
73  ValueType,
74  IndexLayout<n_dims, IndexType, IndexTypes...>>
75 make_index_view(ValueType* ptr,
77 {
78  return View<ValueType, IndexLayout<n_dims, IndexType, IndexTypes...>>(
79  ptr, index_layout);
80 }
81 
82 // select certain indices from a tuple, given a curated index sequence
83 // returns linear index of layout(ar...)
84 template<typename Lay, typename Tup, camp::idx_t... Idxs>
85 RAJA_HOST_DEVICE RAJA_INLINE constexpr auto selecttuple(Lay lyout,
86  Tup&& tup,
87  camp::idx_seq<Idxs...>)
88  -> decltype(lyout(camp::get<Idxs>(std::forward<Tup>(tup))...))
89 {
90  return lyout(camp::get<Idxs>(std::forward<Tup>(tup))...);
91 }
92 
93 // sequence combiner
94 template<typename Seq1, typename Seq2>
95 struct cat_seq;
96 
97 template<camp::idx_t... Idxs1, camp::idx_t... Idxs2>
98 struct cat_seq<camp::idx_seq<Idxs1...>, camp::idx_seq<Idxs2...>>
99 {
100  using type = camp::idx_seq<Idxs1..., Idxs2...>;
101 };
102 
103 template<typename Seq1, typename Seq2>
105 
106 // sequence offsetter
107 template<camp::idx_t Offset, typename Seq>
108 struct offset_seq;
109 
110 template<camp::idx_t Offset, camp::idx_t... Idxs>
111 struct offset_seq<Offset, camp::idx_seq<Idxs...>>
112 {
113  using type = camp::idx_seq<(Idxs + Offset)...>;
114 };
115 
116 template<camp::idx_t Offset, typename Seq>
118 
119 // remove the Nth index in a parameter pack
120 // returns linear index of layout(ar...)
121 template<typename Lay, RAJA::Index_type Nth = 0, typename Tup>
122 RAJA_HOST_DEVICE RAJA_INLINE constexpr auto removenth(Lay lyout, Tup&& tup)
123  -> decltype(selecttuple<Lay>(
124  lyout,
125  std::forward<Tup>(tup),
126  cat_seq_t<
127  camp::make_idx_seq_t<Nth>, // sequence up to Nth
128  offset_seq_t<Nth + 1, // after Nth
129  camp::make_idx_seq_t<camp::tuple_size<Tup>::value -
130  Nth - 1>> // sequence after Nth
131  > {}))
132 {
133  return selecttuple<Lay>(
134  lyout, std::forward<Tup>(tup),
135  cat_seq_t<camp::make_idx_seq_t<Nth>, // sequence up to Nth
136  offset_seq_t<Nth + 1, // after Nth
137  camp::make_idx_seq_t<camp::tuple_size<Tup>::value -
138  Nth - 1>> // sequence after
139  // Nth
140  > {});
141 }
142 
143 // P2Pidx represents the array-of-pointers index. This allows the position of
144 // the index into the array-of-pointers to be moved around in the MultiView
145 // operator(); see the operator overload. Default of 0 means that the p2p index
146 // is in the 0th position.
147 template<
148  typename ValueType,
149  typename LayoutType,
150  RAJA::Index_type P2Pidx = 0,
151  typename PointerType = ValueType**,
152  typename NonConstPointerType = camp::type::ptr::add< // adds *
153  camp::type::ptr::add<camp::type::cv::rem< // removes cv
154  camp::type::ptr::rem<camp::type::ptr::rem<PointerType> // removes
155  // *
156  >>>>>
157 struct MultiView
158 {
159  using value_type = ValueType;
160  using pointer_type = PointerType;
161  using layout_type = LayoutType;
162  using nc_value_type = camp::decay<value_type>;
163  using nc_pointer_type = NonConstPointerType;
164  using NonConstView =
166 
169 
170  MultiView() = default;
171 
172  template<typename... Args>
173  RAJA_HOST_DEVICE RAJA_INLINE constexpr MultiView(pointer_type data_ptr,
174  Args... dim_sizes)
175  : layout(dim_sizes...),
176  data(nc_pointer_type(data_ptr))
177  {}
178 
179  RAJA_HOST_DEVICE RAJA_INLINE constexpr MultiView(pointer_type data_ptr,
180  layout_type const& ly)
181  : layout(ly),
182  data(nc_pointer_type(data_ptr))
183  {}
184 
185  // TODO: Should be able to construct a const MultiView from non-const array of
186  // arrays. For now, this becomes an ambiguous call to constructor error.
187  // template<typename... Args,
188  // bool IsConstValue = std::is_const<value_type>::value>
189  // RAJA_HOST_DEVICE RAJA_INLINE constexpr MultiView(
190  // std::enable_if_t<IsConstValue, NonConstPointerType> data_ptr,
191  // Args... dim_sizes)
192  // : layout(dim_sizes...),
193  // data(nc_pointer_type(data_ptr))
194  //{}
195  // template<bool IsConstValue = std::is_const<value_type>::value>
196  // RAJA_HOST_DEVICE RAJA_INLINE constexpr MultiView(
197  // std::enable_if_t<IsConstValue, NonConstPointerType> data_ptr,
198  // layout_type const& ly)
199  // : layout(ly),
200  // data(nc_pointer_type(data_ptr))
201  //{}
202 
203  RAJA_INLINE constexpr MultiView(MultiView const&) = default;
204  RAJA_INLINE constexpr MultiView(MultiView&&) = default;
205  RAJA_INLINE constexpr MultiView& operator=(MultiView const&) = default;
206  RAJA_INLINE constexpr MultiView& operator=(MultiView&&) = default;
207 
208  template<bool IsConstView = std::is_const<value_type>::value>
209  RAJA_HOST_DEVICE RAJA_INLINE constexpr MultiView(
210  std::enable_if_t<IsConstView, NonConstView> const& rhs)
211  : layout(rhs.layout),
213  {}
214 
215  RAJA_HOST_DEVICE RAJA_INLINE constexpr void set_layout(layout_type const& ly)
216  {
217  layout = ly;
218  }
219 
220  template<bool IsConstValue = std::is_const<value_type>::value>
221  RAJA_HOST_DEVICE RAJA_INLINE constexpr void set_data(
222  std::enable_if_t<IsConstValue, NonConstPointerType> data_ptr)
223  {
225  data_ptr); // This data_ptr should already be non-const.
226  }
227 
228  RAJA_HOST_DEVICE RAJA_INLINE constexpr void set_data(pointer_type data_ptr)
229  {
230  data = nc_pointer_type(data_ptr);
231  }
232 
233  RAJA_HOST_DEVICE RAJA_INLINE constexpr layout_type const& get_layout() const
234  {
235  return layout;
236  }
237 
238  RAJA_HOST_DEVICE RAJA_INLINE constexpr pointer_type get_data() const
239  {
240  return pointer_type(data);
241  }
242 
243  // why doesn't this return a shifted copy instead of shifting this view?
244  template<size_t n_dims = layout_type::n_dims, typename IdxLin = Index_type>
245  RAJA_HOST_DEVICE RAJA_INLINE constexpr RAJA::
246  MultiView<ValueType, typename add_offset<layout_type>::type, P2Pidx>
247  shift(const std::array<IdxLin, n_dims>& shift)
248  {
249  static_assert(n_dims == layout_type::n_dims,
250  "Dimension mismatch in MultiView shift");
251 
252  typename add_offset<layout_type>::type shift_layout(layout);
253  shift_layout.shift(shift);
254 
256  P2Pidx>(pointer_type(data), shift_layout);
257  }
258 
259  // Moving the position of the index into the array-of-pointers
260  // is set by P2Pidx, which is defaulted to 0.
261  // making this specifically typed would require unpacking the layout,
262  // this is easier to maintain
263  template<typename... Args>
264  RAJA_HOST_DEVICE RAJA_INLINE value_type& operator()(Args... ar) const
265  {
266  auto pidx =
267  stripIndexType(camp::get<P2Pidx>(camp::forward_as_tuple(ar...)));
268 
269  if (pidx < 0)
270  {
272  "Negative index while accessing array of pointers.\n");
273  }
274  auto idx = stripIndexType(
275  removenth<LayoutType, P2Pidx>(layout, camp::forward_as_tuple(ar...)));
276  return pointer_type(data)[pidx][idx];
277  }
278 };
279 
280 template<typename ViewType, typename AtomicPolicy = RAJA::auto_atomic>
282 {
283  using base_type = ViewType;
284  using pointer_type = typename base_type::pointer_type;
285  using value_type = typename base_type::value_type;
287 
289 
290  RAJA_HOST_DEVICE RAJA_INLINE constexpr explicit AtomicViewWrapper(
291  ViewType view)
292  : base_(view)
293  {}
294 
295  RAJA_HOST_DEVICE RAJA_INLINE constexpr void set_data(pointer_type data_ptr)
296  {
297  base_.set_data(data_ptr);
298  }
299 
300  template<typename... ARGS>
301  RAJA_HOST_DEVICE RAJA_INLINE atomic_type operator()(ARGS&&... args) const
302  {
303  return atomic_type(&base_.operator()(std::forward<ARGS>(args)...));
304  }
305 };
306 
307 /*
308  * Specialized AtomicViewWrapper for seq_atomic that acts as pass-thru
309  * for performance
310  */
311 template<typename ViewType>
313 {
314  using base_type = ViewType;
315  using pointer_type = typename base_type::pointer_type;
316  using value_type = typename base_type::value_type;
318 
320 
321  RAJA_HOST_DEVICE RAJA_INLINE constexpr explicit AtomicViewWrapper(
322  ViewType const& view)
323  : base_ {view}
324  {}
325 
326  RAJA_HOST_DEVICE RAJA_INLINE constexpr void set_data(pointer_type data_ptr)
327  {
328  base_.set_data(data_ptr);
329  }
330 
331  template<typename... ARGS>
332  RAJA_HOST_DEVICE RAJA_INLINE value_type& operator()(ARGS&&... args) const
333  {
334  return base_.operator()(std::forward<ARGS>(args)...);
335  }
336 };
337 
338 template<typename AtomicPolicy, typename ViewType>
339 RAJA_HOST_DEVICE RAJA_INLINE constexpr AtomicViewWrapper<ViewType, AtomicPolicy>
340 make_atomic_view(ViewType const& view)
341 {
342 
344 }
345 
347 {};
348 
350 {};
351 
352 namespace detail
353 {
354 
355 template<typename meta_layout>
357 
358 template<typename T>
359 RAJA_HOST_DEVICE RAJA_INLINE constexpr auto get_last_index(T last)
360 {
361  return last;
362 }
363 
364 template<typename T0, typename T1, typename... Args>
365 RAJA_HOST_DEVICE RAJA_INLINE constexpr auto get_last_index(T0,
366  T1 t1,
367  Args... args)
368 {
369  return get_last_index(t1, args...);
370 }
371 
372 template<std::size_t... stride_order_idx>
373 struct PermutedViewHelper<std::index_sequence<stride_order_idx...>>
374 {
375  template<typename IndexType, typename T, typename... Extents>
376  static RAJA_HOST_DEVICE RAJA_INLINE constexpr auto get(T* ptr,
377  Extents&&... extents)
378  {
379  constexpr int N = sizeof...(Extents);
380 
381  auto custom_layout = RAJA::make_permuted_layout(
382  std::array<RAJA::idx_t, N> {std::forward<Extents>(extents)...},
383  std::array<RAJA::idx_t, N> {stride_order_idx...});
384 
385  constexpr auto unit_stride = detail::get_last_index(stride_order_idx...);
387 
388  return view_t(ptr, custom_layout);
389  }
390 };
391 
392 template<>
394 {
395  template<typename IndexType, typename T, typename... Extents>
396  static RAJA_HOST_DEVICE RAJA_INLINE constexpr auto get(T* ptr,
397  Extents&&... extents)
398  {
399  constexpr int N = sizeof...(Extents);
400  using view_t = RAJA::View<T, RAJA::Layout<N, IndexType, N - 1>>;
401 
402  return view_t(ptr, std::forward<Extents>(extents)...);
403  }
404 };
405 
406 template<std::size_t... idx>
407 RAJA_HOST_DEVICE RAJA_INLINE constexpr auto make_reverse_array(
408  std::index_sequence<idx...>)
409 {
410  return std::array<RAJA::idx_t, sizeof...(idx)> {sizeof...(idx) - 1U - idx...};
411 }
412 
413 template<>
415 {
416  template<typename IndexType, typename T, typename... Extents>
417  static RAJA_HOST_DEVICE RAJA_INLINE constexpr auto get(T* ptr,
418  Extents&&... extents)
419  {
420  constexpr int N = sizeof...(Extents);
421 
422  auto reverse_layout = RAJA::make_permuted_layout(
423  std::array<RAJA::idx_t, N> {std::forward<Extents>(extents)...},
424  make_reverse_array(std::make_index_sequence<N> {}));
426 
427  return view_t(ptr, reverse_layout);
428  }
429 };
430 
431 } // namespace detail
432 
433 template<typename meta_layout,
434  typename IndexType = RAJA::Index_type,
435  typename T,
436  typename... Extents>
437 RAJA_HOST_DEVICE RAJA_INLINE constexpr auto make_permuted_view(
438  T* ptr,
439  Extents&&... extents)
440 {
442  ptr, std::forward<Extents>(extents)...);
443 }
444 
445 } // namespace RAJA
446 
447 #endif
RAJA header file defining the IndexLayout class and IndexList classes.
RAJA header file defining Layout, a N-dimensional index calculator.
RAJA header file defining Layout, a N-dimensional index calculator with offset indices.
RAJA header file defining a multi-dimensional view class.
Atomic wrapper object.
Definition: atomic.hpp:302
Definition: TypedViewBase.hpp:725
Definition: TypedViewBase.hpp:569
RAJA_HOST_DEVICE void RAJA_ABORT_OR_THROW(const char *str)
Definition: macros.hpp:143
#define RAJA_HOST_DEVICE
Definition: macros.hpp:65
RAJA_HOST_DEVICE constexpr RAJA_INLINE auto get_last_index(T last)
Definition: View.hpp:359
Args args
Definition: WorkRunner.hpp:212
RAJA_HOST_DEVICE constexpr RAJA_INLINE auto make_reverse_array(std::index_sequence< idx... >)
Definition: View.hpp:407
Definition: AlignedRangeIndexSetBuilders.cpp:35
RAJA_HOST_DEVICE constexpr RAJA_INLINE auto make_permuted_view(T *ptr, Extents &&... extents)
Definition: View.hpp:437
RAJA_HOST_DEVICE constexpr RAJA_INLINE View< ValueType, Layout< 1, IndexType, 0 > > make_view(ValueType *ptr)
Definition: View.hpp:63
std::ptrdiff_t Index_type
Definition: types.hpp:226
typename cat_seq< Seq1, Seq2 >::type cat_seq_t
Definition: View.hpp:104
internal::ViewBase< ValueType, PointerType, LayoutType > View
Definition: View.hpp:54
RAJA_HOST_DEVICE constexpr RAJA_INLINE View< ValueType, IndexLayout< n_dims, IndexType, IndexTypes... > > make_index_view(ValueType *ptr, IndexLayout< n_dims, IndexType, IndexTypes... > index_layout)
Definition: View.hpp:75
RAJA_HOST_DEVICE constexpr RAJA_INLINE auto selecttuple(Lay lyout, Tup &&tup, camp::idx_seq< Idxs... >) -> decltype(lyout(camp::get< Idxs >(std::forward< Tup >(tup))...))
Definition: View.hpp:85
RAJA_HOST_DEVICE constexpr RAJA_INLINE auto removenth(Lay lyout, Tup &&tup) -> decltype(selecttuple< Lay >(lyout, std::forward< Tup >(tup), cat_seq_t< camp::make_idx_seq_t< Nth >, offset_seq_t< Nth+1, camp::make_idx_seq_t< camp::tuple_size< Tup >::value - Nth - 1 >> > {}))
Definition: View.hpp:122
constexpr RAJA_HOST_DEVICE RAJA_INLINE std::enable_if< std::is_base_of< IndexValueBase, FROM >::value, typename FROM::value_type >::type stripIndexType(FROM const val)
Function that strips the strongly typed Index<> and returns its underlying value_type value.
Definition: IndexValue.hpp:323
typename offset_seq< Offset, Seq >::type offset_seq_t
Definition: View.hpp:117
RAJA_HOST_DEVICE constexpr RAJA_INLINE AtomicViewWrapper< ViewType, AtomicPolicy > make_atomic_view(ViewType const &view)
Definition: View.hpp:340
constexpr RAJA_INLINE RAJA_HOST_DEVICE auto make_permuted_layout(std::array< IdxLin, Rank > sizes, std::array< camp::idx_t, Rank > permutation) -> Layout< Rank, IdxLin >
Creates a permuted Layout object.
Definition: PermutedLayout.hpp:66
Definition: ListSegment.hpp:416
RAJA header file defining atomic operations.
RAJA_HOST_DEVICE constexpr RAJA_INLINE void set_data(pointer_type data_ptr)
Definition: View.hpp:326
typename base_type::value_type value_type
Definition: View.hpp:316
RAJA_HOST_DEVICE RAJA_INLINE value_type & operator()(ARGS &&... args) const
Definition: View.hpp:332
RAJA_HOST_DEVICE constexpr RAJA_INLINE AtomicViewWrapper(ViewType const &view)
Definition: View.hpp:321
typename base_type::pointer_type pointer_type
Definition: View.hpp:315
Definition: View.hpp:282
RAJA::AtomicRef< value_type, AtomicPolicy > atomic_type
Definition: View.hpp:286
base_type base_
Definition: View.hpp:288
typename base_type::value_type value_type
Definition: View.hpp:285
RAJA_HOST_DEVICE RAJA_INLINE atomic_type operator()(ARGS &&... args) const
Definition: View.hpp:301
RAJA_HOST_DEVICE constexpr RAJA_INLINE void set_data(pointer_type data_ptr)
Definition: View.hpp:295
typename base_type::pointer_type pointer_type
Definition: View.hpp:284
ViewType base_type
Definition: View.hpp:283
RAJA_HOST_DEVICE constexpr RAJA_INLINE AtomicViewWrapper(ViewType view)
Definition: View.hpp:290
Definition: IndexLayout.hpp:163
Definition: View.hpp:158
RAJA_HOST_DEVICE constexpr RAJA_INLINE void set_data(pointer_type data_ptr)
Definition: View.hpp:228
RAJA_HOST_DEVICE constexpr RAJA_INLINE void set_layout(layout_type const &ly)
Definition: View.hpp:215
RAJA_HOST_DEVICE RAJA_INLINE value_type & operator()(Args... ar) const
Definition: View.hpp:264
LayoutType layout_type
Definition: View.hpp:161
RAJA_HOST_DEVICE constexpr RAJA_INLINE RAJA::MultiView< ValueType, typename add_offset< layout_type >::type, P2Pidx > shift(const std::array< IdxLin, n_dims > &shift)
Definition: View.hpp:247
PointerType pointer_type
Definition: View.hpp:160
RAJA_HOST_DEVICE constexpr RAJA_INLINE void set_data(std::enable_if_t< IsConstValue, NonConstPointerType > data_ptr)
Definition: View.hpp:221
MultiView()=default
nc_pointer_type data
Definition: View.hpp:168
layout_type layout
Definition: View.hpp:167
RAJA_HOST_DEVICE constexpr RAJA_INLINE layout_type const & get_layout() const
Definition: View.hpp:233
constexpr RAJA_INLINE MultiView(MultiView &&)=default
RAJA_HOST_DEVICE constexpr RAJA_INLINE MultiView(std::enable_if_t< IsConstView, NonConstView > const &rhs)
Definition: View.hpp:209
constexpr RAJA_INLINE MultiView(MultiView const &)=default
constexpr RAJA_INLINE MultiView & operator=(MultiView &&)=default
RAJA_HOST_DEVICE constexpr RAJA_INLINE MultiView(pointer_type data_ptr, layout_type const &ly)
Definition: View.hpp:179
RAJA_HOST_DEVICE constexpr RAJA_INLINE MultiView(pointer_type data_ptr, Args... dim_sizes)
Definition: View.hpp:173
NonConstPointerType nc_pointer_type
Definition: View.hpp:163
camp::decay< value_type > nc_value_type
Definition: View.hpp:162
ValueType value_type
Definition: View.hpp:159
constexpr RAJA_INLINE MultiView & operator=(MultiView const &)=default
RAJA_HOST_DEVICE constexpr RAJA_INLINE pointer_type get_data() const
Definition: View.hpp:238
Definition: OffsetLayout.hpp:172
Definition: Layout.hpp:329
Definition: OffsetLayout.hpp:188
Definition: View.hpp:41
camp::idx_seq< Idxs1..., Idxs2... > type
Definition: View.hpp:100
Definition: View.hpp:95
Definition: Layout.hpp:46
static RAJA_HOST_DEVICE constexpr RAJA_INLINE auto get(T *ptr, Extents &&... extents)
Definition: View.hpp:417
static RAJA_HOST_DEVICE constexpr RAJA_INLINE auto get(T *ptr, Extents &&... extents)
Definition: View.hpp:396
static RAJA_HOST_DEVICE constexpr RAJA_INLINE auto get(T *ptr, Extents &&... extents)
Definition: View.hpp:376
Definition: View.hpp:356
Definition: View.hpp:347
Definition: View.hpp:350
camp::idx_seq<(Idxs+Offset)... > type
Definition: View.hpp:113
Definition: View.hpp:108
Definition: policy.hpp:127