RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
Layout.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_LAYOUT_HPP
21 #define RAJA_LAYOUT_HPP
22 
23 #include "RAJA/config.hpp"
24 
25 #include <cassert>
26 #include <iostream>
27 #include <limits>
28 
30 
31 #include "RAJA/internal/foldl.hpp"
32 
33 #include "RAJA/util/Operators.hpp"
35 
36 namespace RAJA
37 {
38 
39 namespace detail
40 {
41 
42 
43 template<typename Range,
44  typename IdxLin = Index_type,
45  ptrdiff_t StrideOneDim = -1>
47 
52 template<size_t j, size_t n_dims, typename IdxLin = Index_type>
54 {
55  RAJA_INLINE RAJA_HOST_DEVICE constexpr IdxLin operator()(
56  IdxLin cur_stride,
57  IdxLin const (&sizes)[n_dims]) const
58  {
60  cur_stride * (sizes[j] ? sizes[j] : 1), sizes);
61  }
62 };
63 
64 template<size_t n_dims, typename IdxLin>
65 struct stride_calculator<n_dims, n_dims, IdxLin>
66 {
67  RAJA_INLINE RAJA_HOST_DEVICE constexpr IdxLin operator()(
68  IdxLin cur_stride,
69  IdxLin const (&)[n_dims]) const
70  {
71  return cur_stride;
72  }
73 };
74 
75 template<camp::idx_t... RangeInts, typename IdxLin, ptrdiff_t StrideOneDim>
76 struct LayoutBase_impl<camp::idx_seq<RangeInts...>, IdxLin, StrideOneDim>
77 {
78 public:
79  using IndexLinear = IdxLin;
80  using IndexRange = camp::make_idx_seq_t<sizeof...(RangeInts)>;
81 
82  static inline constexpr size_t n_dims = sizeof...(RangeInts);
83  static inline constexpr IdxLin limit = RAJA::operators::limits<IdxLin>::max();
84  static inline constexpr ptrdiff_t stride_one_dim = StrideOneDim;
85 
86  IdxLin sizes[n_dims] = {0};
87  IdxLin strides[n_dims] = {0};
88  IdxLin inv_strides[n_dims] = {0};
89  IdxLin inv_mods[n_dims] = {0};
90 
91 
95  RAJA_INLINE constexpr LayoutBase_impl() = default;
96  RAJA_INLINE constexpr LayoutBase_impl(LayoutBase_impl const&) = default;
97  RAJA_INLINE constexpr LayoutBase_impl(LayoutBase_impl&&) = default;
98  RAJA_INLINE constexpr LayoutBase_impl& operator=(LayoutBase_impl const&) =
99  default;
100  RAJA_INLINE constexpr LayoutBase_impl& operator=(LayoutBase_impl&&) = default;
101 
105  template<typename... Types>
106  RAJA_INLINE RAJA_HOST_DEVICE constexpr LayoutBase_impl(Types... ns)
107  : sizes {static_cast<IdxLin>(stripIndexType(ns))...},
108  strides {(detail::stride_calculator<RangeInts + 1, n_dims, IdxLin> {}(
109  sizes[RangeInts] ? IdxLin(1) : IdxLin(0),
110  sizes))...},
111  inv_strides {(strides[RangeInts] ? strides[RangeInts] : IdxLin(1))...},
112  inv_mods {(sizes[RangeInts] ? sizes[RangeInts] : IdxLin(1))...}
113  {
114  static_assert(n_dims == sizeof...(Types),
115  "number of dimensions must match");
116  }
117 
121  template<typename CIdxLin, ptrdiff_t CStrideOneDim>
122  RAJA_INLINE RAJA_HOST_DEVICE constexpr LayoutBase_impl(
123  const LayoutBase_impl<camp::idx_seq<RangeInts...>,
124  CIdxLin,
125  CStrideOneDim>& rhs)
126  : sizes {static_cast<IdxLin>(rhs.sizes[RangeInts])...},
127  strides {static_cast<IdxLin>(rhs.strides[RangeInts])...},
128  inv_strides {static_cast<IdxLin>(rhs.inv_strides[RangeInts])...},
129  inv_mods {static_cast<IdxLin>(rhs.inv_mods[RangeInts])...}
130  {}
131 
135  template<typename... Types>
136  RAJA_INLINE constexpr LayoutBase_impl(
137  const std::array<IdxLin, n_dims>& sizes_in,
138  const std::array<IdxLin, n_dims>& strides_in)
139  : sizes {sizes_in[RangeInts]...},
140  strides {strides_in[RangeInts]...},
141  inv_strides {(strides[RangeInts] ? strides[RangeInts] : IdxLin(1))...},
142  inv_mods {(sizes[RangeInts] ? sizes[RangeInts] : IdxLin(1))...}
143  {}
144 
148  template<camp::idx_t N, typename Idx>
149  RAJA_INLINE RAJA_HOST_DEVICE void BoundsCheckError(Idx idx) const
150  {
151  printf("Error at index %d, value %ld is not within bounds [0, %ld] \n",
152  static_cast<int>(N), static_cast<long int>(idx),
153  static_cast<long int>(sizes[N] - 1));
154  RAJA_ABORT_OR_THROW("Out of bounds error \n");
155  }
156 
157  template<camp::idx_t N>
158  RAJA_INLINE RAJA_HOST_DEVICE void BoundsCheck() const
159  {}
160 
161  template<camp::idx_t N, typename Idx, typename... Indices>
162  RAJA_INLINE RAJA_HOST_DEVICE void BoundsCheck(Idx idx,
163  Indices... indices) const
164  {
165  if (sizes[N] > 0 && !(0 <= idx && idx < static_cast<Idx>(sizes[N])))
166  {
167  BoundsCheckError<N>(idx);
168  }
169  RAJA_UNUSED_VAR(idx);
170  BoundsCheck<N + 1>(indices...);
171  }
172 
181  template<typename... Indices>
182  RAJA_INLINE RAJA_HOST_DEVICE RAJA_BOUNDS_CHECK_constexpr IdxLin
183  operator()(Indices... indices) const
184  {
185 #if defined(RAJA_BOUNDS_CHECK_INTERNAL)
186  BoundsCheck<0>(indices...);
187 #endif
188  // dot product of strides and indices
189  return sum<IdxLin>((RangeInts == stride_one_dim
190  ? // Is this dimension stride-one?
191  indices
192  : // it's stride one, so dont bother with multiply
193  strides[RangeInts] * indices // it's not stride one
194  )...);
195  }
196 
207  template<typename... Indices>
208  RAJA_INLINE RAJA_HOST_DEVICE void toIndices(IdxLin linear_index,
209  Indices&&... indices) const
210  {
211 #if defined(RAJA_BOUNDS_CHECK_INTERNAL)
212  IdxLin totSize = size_noproj();
213  if (totSize > 0 && (linear_index < 0 || linear_index >= totSize))
214  {
215  printf("Error! Linear index %ld is not within bounds [0, %ld]. \n",
216  static_cast<long int>(linear_index),
217  static_cast<long int>(totSize - 1));
218  RAJA_ABORT_OR_THROW("Out of bounds error \n");
219  }
220 #endif
221 
222  camp::sink((indices = (camp::decay<Indices>)((linear_index /
223  inv_strides[RangeInts]) %
224  inv_mods[RangeInts]))...);
225  }
226 
233  RAJA_INLINE RAJA_HOST_DEVICE constexpr IdxLin size() const
234  {
235  // Multiply together all of the sizes,
236  // replacing 1 for any zero-sized dimensions
237  return foldl(
239  (sizes[RangeInts] == IdxLin(0) ? IdxLin(1) : sizes[RangeInts])...);
240  }
241 
248  RAJA_INLINE RAJA_HOST_DEVICE constexpr IdxLin size_noproj() const
249  {
250  // Multiply together all of the sizes
251  return foldl(RAJA::operators::multiplies<IdxLin>(), sizes[RangeInts]...);
252  }
253 
254  template<camp::idx_t DIM>
255  RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexLinear get_dim_stride() const
256  {
257  return strides[DIM];
258  }
259 
260  template<camp::idx_t DIM>
261  RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexLinear get_dim_size() const
262  {
263  return sizes[DIM];
264  }
265 
266  template<camp::idx_t DIM>
267  RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexLinear get_dim_begin() const
268  {
269  return 0;
270  }
271 };
272 
273 } // namespace detail
274 
324 template<size_t n_dims, typename IdxLin = Index_type, ptrdiff_t StrideOne = -1>
325 using Layout =
327 
328 template<typename IdxLin, typename DimTuple, ptrdiff_t StrideOne = -1>
329 struct TypedLayout;
330 
331 template<typename IdxLin, typename... DimTypes, ptrdiff_t StrideOne>
332 struct TypedLayout<IdxLin, camp::tuple<DimTypes...>, StrideOne>
333  : public Layout<sizeof...(DimTypes), strip_index_type_t<IdxLin>, StrideOne>
334 {
335 
337  using Self = TypedLayout<IdxLin, camp::tuple<DimTypes...>, StrideOne>;
338  using Base = Layout<sizeof...(DimTypes), StrippedIdxLin, StrideOne>;
339  using DimArr = std::array<StrippedIdxLin, sizeof...(DimTypes)>;
340 
341  // Pull in base constructors
342  using Base::Base;
343 
351  RAJA_INLINE RAJA_HOST_DEVICE constexpr IdxLin operator()(
352  DimTypes... indices) const
353  {
354  return IdxLin(Base::operator()(stripIndexType(indices)...));
355  }
356 
367  RAJA_INLINE RAJA_HOST_DEVICE void toIndices(IdxLin linear_index,
368  DimTypes&... indices) const
369  {
370  toIndicesHelper(camp::make_idx_seq_t<sizeof...(DimTypes)> {},
371  std::forward<IdxLin>(linear_index),
372  std::forward<DimTypes&>(indices)...);
373  }
374 
375 private:
383  template<typename... Indices, camp::idx_t... RangeInts>
384  RAJA_INLINE RAJA_HOST_DEVICE void toIndicesHelper(camp::idx_seq<RangeInts...>,
385  IdxLin linear_index,
386  Indices&... indices) const
387  {
388  StrippedIdxLin locals[sizeof...(DimTypes)];
389  Base::toIndices(stripIndexType(linear_index), locals[RangeInts]...);
390  camp::sink(
391  (indices = Indices {static_cast<Indices>(locals[RangeInts])})...);
392  }
393 };
394 
399 template<ptrdiff_t s1_dim, size_t n_dims, typename IdxLin>
400 RAJA_INLINE RAJA_HOST_DEVICE constexpr Layout<n_dims, IdxLin, s1_dim>
402 {
404 }
405 
410 template<ptrdiff_t s1_dim, typename IdxLin, typename IdxTuple>
411 RAJA_INLINE RAJA_HOST_DEVICE constexpr TypedLayout<IdxLin, IdxTuple, s1_dim>
413 {
414  // strip l to it's base-class type
415  using Base = typename TypedLayout<IdxLin, IdxTuple>::Base;
416  Base const& b = (Base const&)l;
417 
418  // Use non-typed layout to initialize new typed layout
420 }
421 
422 
423 } // namespace RAJA
424 
425 #endif
RAJA header file for strongly-typed integer class.
Header file for RAJA operator definitions.
RAJA header file defining permutations.
Header file with support for pre-C++14 compilers.
RAJA_HOST_DEVICE RAJA_INLINE void RAJA_UNUSED_VAR(T &&...) noexcept
Definition: macros.hpp:120
RAJA_HOST_DEVICE void RAJA_ABORT_OR_THROW(const char *str)
Definition: macros.hpp:143
#define RAJA_HOST_DEVICE
Definition: macros.hpp:65
Definition: AlignedRangeIndexSetBuilders.cpp:35
std::ptrdiff_t Index_type
Definition: types.hpp:226
RAJA_HOST_DEVICE constexpr RAJA_INLINE auto foldl(Op &&RAJA_UNUSED_ARG(operation), Arg1 &&arg) -> typename detail::foldl_impl< Op, Arg1 >::Ret
Definition: foldl.hpp:104
typename internal::StripIndexTypeT< FROM >::type strip_index_type_t
Strips a strongly typed index to its underlying type In the case of a non-strongly typed index,...
Definition: IndexValue.hpp:364
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
RAJA_INLINE constexpr RAJA_HOST_DEVICE Layout< n_dims, IdxLin, s1_dim > make_stride_one(Layout< n_dims, IdxLin > const &l)
Definition: Layout.hpp:401
RAJA_HOST_DEVICE constexpr RAJA_INLINE Result max(Args... args)
Definition: foldl.hpp:155
strip_index_type_t< IdxLin > StrippedIdxLin
Definition: Layout.hpp:336
RAJA_INLINE constexpr RAJA_HOST_DEVICE IdxLin operator()(DimTypes... indices) const
Definition: Layout.hpp:351
RAJA_INLINE RAJA_HOST_DEVICE void toIndices(IdxLin linear_index, DimTypes &... indices) const
Definition: Layout.hpp:367
std::array< StrippedIdxLin, sizeof...(DimTypes)> DimArr
Definition: Layout.hpp:339
Definition: Layout.hpp:329
constexpr RAJA_INLINE LayoutBase_impl(const std::array< IdxLin, n_dims > &sizes_in, const std::array< IdxLin, n_dims > &strides_in)
Definition: Layout.hpp:136
RAJA_INLINE constexpr RAJA_HOST_DEVICE IndexLinear get_dim_stride() const
Definition: Layout.hpp:255
RAJA_INLINE constexpr RAJA_HOST_DEVICE LayoutBase_impl(const LayoutBase_impl< camp::idx_seq< RangeInts... >, CIdxLin, CStrideOneDim > &rhs)
Definition: Layout.hpp:122
constexpr RAJA_INLINE LayoutBase_impl & operator=(LayoutBase_impl const &)=default
RAJA_INLINE RAJA_HOST_DEVICE void BoundsCheck() const
Definition: Layout.hpp:158
RAJA_INLINE constexpr RAJA_HOST_DEVICE IndexLinear get_dim_size() const
Definition: Layout.hpp:261
RAJA_INLINE constexpr RAJA_HOST_DEVICE IndexLinear get_dim_begin() const
Definition: Layout.hpp:267
RAJA_INLINE RAJA_HOST_DEVICE void BoundsCheckError(Idx idx) const
Definition: Layout.hpp:149
camp::make_idx_seq_t< sizeof...(RangeInts)> IndexRange
Definition: Layout.hpp:80
constexpr RAJA_INLINE LayoutBase_impl(LayoutBase_impl const &)=default
constexpr RAJA_INLINE LayoutBase_impl & operator=(LayoutBase_impl &&)=default
RAJA_INLINE constexpr RAJA_HOST_DEVICE LayoutBase_impl(Types... ns)
Definition: Layout.hpp:106
RAJA_INLINE constexpr RAJA_HOST_DEVICE IdxLin size_noproj() const
Definition: Layout.hpp:248
RAJA_INLINE constexpr RAJA_HOST_DEVICE IdxLin size() const
Definition: Layout.hpp:233
RAJA_INLINE RAJA_HOST_DEVICE RAJA_BOUNDS_CHECK_constexpr IdxLin operator()(Indices... indices) const
Definition: Layout.hpp:183
RAJA_INLINE RAJA_HOST_DEVICE void toIndices(IdxLin linear_index, Indices &&... indices) const
Definition: Layout.hpp:208
RAJA_INLINE RAJA_HOST_DEVICE void BoundsCheck(Idx idx, Indices... indices) const
Definition: Layout.hpp:162
Definition: Layout.hpp:46
RAJA_INLINE constexpr RAJA_HOST_DEVICE IdxLin operator()(IdxLin cur_stride, IdxLin const (&)[n_dims]) const
Definition: Layout.hpp:67
Definition: Layout.hpp:54
RAJA_INLINE constexpr RAJA_HOST_DEVICE IdxLin operator()(IdxLin cur_stride, IdxLin const (&sizes)[n_dims]) const
Definition: Layout.hpp:55
Definition: Operators.hpp:400