RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
OffsetLayout.hpp
Go to the documentation of this file.
1 
12 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
13 // Copyright (c) Lawrence Livermore National Security, LLC and other
14 // RAJA Project Developers. See top-level LICENSE and COPYRIGHT
15 // files for dates and other details. No copyright assignment is required
16 // to contribute to RAJA.
17 //
18 // SPDX-License-Identifier: (BSD-3-Clause)
19 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
20 
21 #ifndef RAJA_OFFSETLAYOUT_HPP
22 #define RAJA_OFFSETLAYOUT_HPP
23 
24 #include "RAJA/config.hpp"
25 
26 #include <array>
27 #include <limits>
28 
29 #include "camp/camp.hpp"
30 
32 
35 
36 namespace RAJA
37 {
38 
39 namespace internal
40 {
41 
42 template<typename Range, typename IdxLin>
44 
45 template<camp::idx_t... RangeInts, typename IdxLin>
46 struct OffsetLayout_impl<camp::idx_seq<RangeInts...>, IdxLin>
47 {
48  using Self = OffsetLayout_impl<camp::idx_seq<RangeInts...>, IdxLin>;
49  using IndexRange = camp::idx_seq<RangeInts...>;
50  using IndexLinear = IdxLin;
53 
54  static inline constexpr camp::idx_t stride_one_dim = Base::stride_one_dim;
55 
56  static inline constexpr size_t n_dims = sizeof...(RangeInts);
57  IdxLin offsets[n_dims] = {0}; // If not specified set to zero
58 
59  constexpr RAJA_INLINE RAJA_HOST_DEVICE
60  OffsetLayout_impl(std::array<IdxLin, sizeof...(RangeInts)> begin,
61  std::array<IdxLin, sizeof...(RangeInts)> end)
62  : base_ {(end[RangeInts] - begin[RangeInts])...},
63  offsets {begin[RangeInts]...}
64  {}
65 
66  constexpr RAJA_INLINE RAJA_HOST_DEVICE OffsetLayout_impl(Self const& c)
67  : base_(c.base_),
68  offsets {c.offsets[RangeInts]...}
69  {}
70 
71  constexpr RAJA_INLINE RAJA_HOST_DEVICE void shift(
72  std::array<IdxLin, sizeof...(RangeInts)> shift)
73  {
74  for (size_t i = 0; i < n_dims; ++i)
75  offsets[i] += shift[i];
76  }
77 
78  template<camp::idx_t N, typename Idx>
79  RAJA_INLINE RAJA_HOST_DEVICE void BoundsCheckError(Idx idx) const
80  {
81  printf("Error at index %d, value %ld is not within bounds [%ld, %ld] \n",
82  static_cast<int>(N), static_cast<long int>(idx),
83  static_cast<long int>(offsets[N]),
84  static_cast<long int>(offsets[N] + base_.sizes[N] - 1));
85  RAJA_ABORT_OR_THROW("Out of bounds error \n");
86  }
87 
88  template<camp::idx_t N>
89  RAJA_INLINE RAJA_HOST_DEVICE void BoundsCheck() const
90  {}
91 
92  template<camp::idx_t N, typename Idx, typename... Indices>
93  RAJA_INLINE RAJA_HOST_DEVICE void BoundsCheck(Idx idx,
94  Indices... indices) const
95  {
96  if (!(offsets[N] <= idx && idx < offsets[N] + base_.sizes[N]))
97  {
98  BoundsCheckError<N>(idx);
99  }
100  RAJA_UNUSED_VAR(idx);
101  BoundsCheck<N + 1>(indices...);
102  }
103 
104  template<typename... Indices>
105  RAJA_INLINE RAJA_HOST_DEVICE RAJA_BOUNDS_CHECK_constexpr IdxLin
106  operator()(Indices... indices) const
107  {
108 #if defined(RAJA_BOUNDS_CHECK_INTERNAL)
109  BoundsCheck<0>(indices...);
110 #endif
111  return base_((indices - offsets[RangeInts])...);
112  }
113 
114  template<typename... Indices>
115  RAJA_INLINE RAJA_HOST_DEVICE void toIndices(IdxLin linear_index,
116  Indices&&... indices) const
117  {
118  base_.toIndices(linear_index, std::forward<Indices>(indices)...);
119  camp::sink((indices = (offsets[RangeInts] + indices))...);
120  }
121 
122  static constexpr RAJA_INLINE RAJA_HOST_DEVICE
125  const std::array<IdxLin, sizeof...(RangeInts)>& offsets_in,
126  const Layout<sizeof...(RangeInts), IdxLin>& rhs)
127  {
128  OffsetLayout_impl ret {rhs};
129  camp::sink((ret.offsets[RangeInts] = offsets_in[RangeInts])...);
130  return ret;
131  }
132 
133  constexpr RAJA_INLINE RAJA_HOST_DEVICE
134  OffsetLayout_impl(const Layout<sizeof...(RangeInts), IdxLin>& rhs)
135  : base_ {rhs}
136  {}
137 
138  RAJA_INLINE RAJA_HOST_DEVICE constexpr IdxLin size() const
139  {
140  return base_.size();
141  }
142 
143  RAJA_INLINE RAJA_HOST_DEVICE constexpr IdxLin size_noproj() const
144  {
145  return base_.size_noproj();
146  }
147 
148  template<camp::idx_t DIM>
149  RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexLinear get_dim_stride() const
150  {
151  return base_.get_dim_stride();
152  }
153 
154  template<camp::idx_t DIM>
155  RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexLinear get_dim_size() const
156  {
157  return base_.get_dim_size();
158  }
159 
160  template<camp::idx_t DIM>
161  RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexLinear get_dim_begin() const
162  {
163  return offsets[DIM];
164  }
165 };
166 
167 } // namespace internal
168 
169 template<size_t n_dims = 1, typename IdxLin = Index_type>
171  : public internal::OffsetLayout_impl<camp::make_idx_seq_t<n_dims>, IdxLin>
172 {
173  using Base =
175 
177  IdxLin>::OffsetLayout_impl;
178 
179  constexpr RAJA_INLINE RAJA_HOST_DEVICE OffsetLayout(
180  const internal::OffsetLayout_impl<camp::make_idx_seq_t<n_dims>, IdxLin>&
181  rhs)
182  : Base {rhs}
183  {}
184 };
185 
186 // TypedOffsetLayout
187 template<typename IdxLin, typename DimTuple>
189 
190 template<typename IdxLin, typename... DimTypes>
191 struct TypedOffsetLayout<IdxLin, camp::tuple<DimTypes...>>
192  : public OffsetLayout<sizeof...(DimTypes), strip_index_type_t<IdxLin>>
193 {
195  using Self = TypedOffsetLayout<IdxLin, camp::tuple<DimTypes...>>;
196  using Base = OffsetLayout<sizeof...(DimTypes), StrippedIdxLin>;
197  using DimArr = std::array<StrippedIdxLin, sizeof...(DimTypes)>;
198  using DimTuple = camp::tuple<DimTypes...>;
199  using IndexLinear = IdxLin;
200 
201  // Pull in base coonstructors
202 #if 0
203  // This breaks with nvcc11
204  using Base::Base;
205 #else
206  using OffsetLayout<sizeof...(DimTypes), StrippedIdxLin>::OffsetLayout;
207 #endif
208 
209  RAJA_INLINE RAJA_HOST_DEVICE RAJA_BOUNDS_CHECK_constexpr IdxLin
210  operator()(DimTypes... indices) const
211  {
212  return IdxLin(Base::operator()(stripIndexType(indices)...));
213  }
214 
215  RAJA_INLINE RAJA_HOST_DEVICE void toIndices(IdxLin linear_index,
216  DimTypes&... indices) const
217  {
218  toIndicesHelper(camp::make_idx_seq_t<sizeof...(DimTypes)> {},
219  std::forward<IdxLin>(linear_index),
220  std::forward<DimTypes&>(indices)...);
221  }
222 
223 private:
224  template<typename... Indices, camp::idx_t... RangeInts>
225  RAJA_INLINE RAJA_HOST_DEVICE void toIndicesHelper(camp::idx_seq<RangeInts...>,
226  IdxLin linear_index,
227  Indices&... indices) const
228  {
229  StrippedIdxLin locals[sizeof...(DimTypes)];
230  Base::toIndices(stripIndexType(linear_index), locals[RangeInts]...);
231  camp::sink(
232  (indices = Indices {static_cast<Indices>(locals[RangeInts])})...);
233  }
234 };
235 
236 template<size_t n_dims, typename IdxLin = Index_type>
237 RAJA_INLINE RAJA_HOST_DEVICE constexpr auto make_offset_layout(
238  const std::array<IdxLin, n_dims>& begin,
239  const std::array<IdxLin, n_dims>& end) -> OffsetLayout<n_dims, IdxLin>
240 {
241  return OffsetLayout<n_dims, IdxLin> {begin, end};
242 }
243 
244 template<size_t Rank, typename IdxLin = Index_type>
246  const std::array<IdxLin, Rank>& begin,
247  const std::array<IdxLin, Rank>& end,
248  const std::array<IdxLin, Rank>& permutation)
249  -> decltype(make_offset_layout<Rank, IdxLin>(begin, end))
250 {
251  std::array<IdxLin, Rank> sizes;
252  for (size_t i = 0; i < Rank; ++i)
253  {
254  sizes[i] = end[i] - begin[i];
255  }
257  from_layout_and_offsets(begin, make_permuted_layout(sizes, permutation));
258 }
259 
260 } // namespace RAJA
261 
262 #endif
RAJA header file for strongly-typed integer class.
RAJA header file defining permutations.
RAJA header file defining Layout, a N-dimensional index calculator with permuted stride orderings.
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
RAJA_INLINE constexpr RAJA_HOST_DEVICE auto make_permuted_offset_layout(const std::array< IdxLin, Rank > &begin, const std::array< IdxLin, Rank > &end, const std::array< IdxLin, Rank > &permutation) -> decltype(make_offset_layout< Rank, IdxLin >(begin, end))
Definition: OffsetLayout.hpp:245
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
RAJA_INLINE constexpr RAJA_HOST_DEVICE auto make_offset_layout(const std::array< IdxLin, n_dims > &begin, const std::array< IdxLin, n_dims > &end) -> OffsetLayout< n_dims, IdxLin >
Definition: OffsetLayout.hpp:237
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
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: OffsetLayout.hpp:172
constexpr RAJA_INLINE RAJA_HOST_DEVICE OffsetLayout(const internal::OffsetLayout_impl< camp::make_idx_seq_t< n_dims >, IdxLin > &rhs)
Definition: OffsetLayout.hpp:179
std::array< StrippedIdxLin, sizeof...(DimTypes)> DimArr
Definition: OffsetLayout.hpp:197
RAJA_INLINE RAJA_HOST_DEVICE RAJA_BOUNDS_CHECK_constexpr IdxLin operator()(DimTypes... indices) const
Definition: OffsetLayout.hpp:210
RAJA_INLINE RAJA_HOST_DEVICE void toIndices(IdxLin linear_index, DimTypes &... indices) const
Definition: OffsetLayout.hpp:215
camp::tuple< DimTypes... > DimTuple
Definition: OffsetLayout.hpp:198
IdxLin IndexLinear
Definition: OffsetLayout.hpp:199
strip_index_type_t< IdxLin > StrippedIdxLin
Definition: OffsetLayout.hpp:194
Definition: OffsetLayout.hpp:188
constexpr RAJA_INLINE RAJA_HOST_DEVICE void shift(std::array< IdxLin, sizeof...(RangeInts)> shift)
Definition: OffsetLayout.hpp:71
RAJA_INLINE RAJA_HOST_DEVICE void BoundsCheck(Idx idx, Indices... indices) const
Definition: OffsetLayout.hpp:93
RAJA_INLINE constexpr RAJA_HOST_DEVICE IdxLin size() const
Definition: OffsetLayout.hpp:138
constexpr RAJA_INLINE RAJA_HOST_DEVICE OffsetLayout_impl(const Layout< sizeof...(RangeInts), IdxLin > &rhs)
Definition: OffsetLayout.hpp:134
RAJA_INLINE constexpr RAJA_HOST_DEVICE IdxLin size_noproj() const
Definition: OffsetLayout.hpp:143
RAJA_INLINE RAJA_HOST_DEVICE void BoundsCheck() const
Definition: OffsetLayout.hpp:89
RAJA_INLINE RAJA_HOST_DEVICE RAJA_BOUNDS_CHECK_constexpr IdxLin operator()(Indices... indices) const
Definition: OffsetLayout.hpp:106
constexpr RAJA_INLINE RAJA_HOST_DEVICE OffsetLayout_impl(Self const &c)
Definition: OffsetLayout.hpp:66
RAJA_INLINE constexpr RAJA_HOST_DEVICE IndexLinear get_dim_size() const
Definition: OffsetLayout.hpp:155
static constexpr RAJA_INLINE RAJA_HOST_DEVICE OffsetLayout_impl< IndexRange, IdxLin > from_layout_and_offsets(const std::array< IdxLin, sizeof...(RangeInts)> &offsets_in, const Layout< sizeof...(RangeInts), IdxLin > &rhs)
Definition: OffsetLayout.hpp:124
constexpr RAJA_INLINE RAJA_HOST_DEVICE OffsetLayout_impl(std::array< IdxLin, sizeof...(RangeInts)> begin, std::array< IdxLin, sizeof...(RangeInts)> end)
Definition: OffsetLayout.hpp:60
RAJA_INLINE constexpr RAJA_HOST_DEVICE IndexLinear get_dim_begin() const
Definition: OffsetLayout.hpp:161
RAJA_INLINE RAJA_HOST_DEVICE void toIndices(IdxLin linear_index, Indices &&... indices) const
Definition: OffsetLayout.hpp:115
RAJA_INLINE constexpr RAJA_HOST_DEVICE IndexLinear get_dim_stride() const
Definition: OffsetLayout.hpp:149
camp::idx_seq< RangeInts... > IndexRange
Definition: OffsetLayout.hpp:49
RAJA_INLINE RAJA_HOST_DEVICE void BoundsCheckError(Idx idx) const
Definition: OffsetLayout.hpp:79
Definition: OffsetLayout.hpp:43