alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
IdxRange.hpp
Go to the documentation of this file.
1/* Copyright 2024 René Widera
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
7#include "alpaka/Vec.hpp"
8#include "alpaka/core/PP.hpp"
12
13#include <cstdint>
14
15namespace alpaka
16{
17
18 template<
20 concepts::Vector T_Begin = typename T_End::UniVec,
21 concepts::Vector T_Stride = typename T_End::UniVec>
22 struct IdxRange
23 {
24 using IdxType = typename T_End::type;
25 using IdxVecType = typename T_End::UniVec;
26
27 constexpr IdxRange(T_Begin const& begin, T_End const& end, T_Stride const& stride)
28 : m_begin{begin}
29 , m_end{end}
30 , m_stride{stride}
31 {
32 }
33
34 constexpr IdxRange(T_Begin const& begin, T_End const& end)
35 : m_begin{begin}
36 , m_end{end}
37 , m_stride{T_End::fill(1u)}
38 {
39 }
40
41 constexpr IdxRange(T_End const& extent) : m_begin{T_End::fill(0u)}, m_end{extent}, m_stride{T_End::fill(1u)}
42 {
43 }
44
45 static consteval uint32_t dim()
46 {
47 return IdxVecType::dim();
48 }
49
50 template<concepts::TypeOrVector<typename T_End::type> T_OpType>
51 ALPAKA_FN_HOST_ACC constexpr auto operator%(T_OpType const& rhs) const
52 {
53 return IdxRange<T_End, T_Begin, ALPAKA_TYPEOF(m_stride * rhs)>{m_begin, m_end, m_stride * rhs};
54 }
55
56 template<concepts::TypeOrVector<typename T_End::type> T_OpType>
57 ALPAKA_FN_HOST_ACC constexpr auto operator>>(T_OpType const& rhs) const
58 {
60 m_begin + rhs,
61 m_end + rhs,
62 m_stride};
63 }
64
65 template<concepts::TypeOrVector<typename T_End::type> T_OpType>
66 ALPAKA_FN_HOST_ACC constexpr auto operator<<(T_OpType const& rhs) const
67 {
68 return IdxRange<ALPAKA_TYPEOF(m_end - rhs), ALPAKA_TYPEOF(m_begin - rhs), T_Stride>{
69 m_begin - rhs,
70 m_end - rhs,
71 m_stride};
72 }
73
74 constexpr auto distance() const
75 {
76 return m_end - m_begin;
77 }
78
79 /** Begin iterator to iterate all positions in the range. It first iterates the fastest index (the one on the
80 * far right -> x-dimension) and then moves sequentially to the slowest index (the one on the far left) until
81 * it reaches the end.
82 *
83 * If you want to iterate the index in parallel with many threads, use the function
84 * alpaka::onAcc::makeIdxMap().
85 *
86 * @return Begin iterator
87 */
88 [[nodiscard]] constexpr auto begin() const
89 {
91 *this,
92 alpaka::ThreadSpace{T_End::fill(0), T_End::fill(1)},
95 .begin();
96 }
97
98 [[nodiscard]] constexpr auto end() const
99 {
101 *this,
102 alpaka::ThreadSpace{T_End::fill(0), T_End::fill(1)},
105 .end();
106 }
107
108 std::string toString(std::string const separator = ",", std::string const enclosings = "{}") const
109 {
110 std::string locale_enclosing_begin;
111 std::string locale_enclosing_end;
112 size_t enclosing_dim = enclosings.size();
113
114 if(enclosing_dim > 0)
115 {
116 /* % avoid out of memory access */
117 locale_enclosing_begin = enclosings[0 % enclosing_dim];
118 locale_enclosing_end = enclosings[1 % enclosing_dim];
119 }
120
121 std::stringstream stream;
122 stream << locale_enclosing_begin;
123 stream << m_begin << separator << m_end << separator << m_stride;
124 stream << locale_enclosing_end;
125 return stream.str();
126 }
127
128 T_Begin m_begin;
129 T_End m_end;
130 T_Stride m_stride;
131
132 using type = typename T_Begin::type;
133 };
134
135 template<uint32_t T_dim, alpaka::concepts::Vector T_LowHaloVec, alpaka::concepts::Vector T_UpHaloVec>
136 constexpr auto makeDirectionSubRange(
137 auto const range,
139 {
140 auto m_begin = Vec<uint32_t, T_dim>::fill(0u);
141 auto m_end = Vec<uint32_t, T_dim>::fill(0u);
142 for(uint32_t i = 0; i < T_dim; ++i)
143 {
144 switch(boundaryDir.data[i])
145 {
147 m_begin[i] = range.m_begin[i];
148 m_end[i] = range.m_begin[i] + boundaryDir.lowerHaloSize[i];
149 break;
151 m_begin[i] = range.m_end[i] - boundaryDir.upperHaloSize[i];
152 m_end[i] = range.m_end[i];
153 break;
155 m_begin[i] = range.m_begin[i] + boundaryDir.lowerHaloSize[i];
156 m_end[i] = range.m_end[i] - boundaryDir.upperHaloSize[i];
157 break;
159 [[fallthrough]];
160 default:
161 ALPAKA_ASSERT_ACC(false);
162 }
163 }
164 return IdxRange{m_begin, m_end, range.m_stride};
165 }
166
167 namespace internal
168 {
169 template<
170 typename T_To,
174 struct PCast::Op<T_To, IdxRange<T_End, T_Begin, T_Stride>>
175 {
176 constexpr auto operator()(auto&& input) const
177 requires std::convertible_to<typename T_End::type, T_To> && (!std::same_as<T_To, typename T_End::type>)
178 {
179 return IdxRange{pCast<T_To>(input.m_begin), pCast<T_To>(input.m_end), pCast<T_To>(input.m_stride)};
180 }
181
182 constexpr decltype(auto) operator()(auto&& input) const requires std::same_as<T_To, typename T_End::type>
183 {
184 return std::forward<decltype(input)>(input);
185 }
186 };
187
188 } // namespace internal
189
190 template<concepts::VectorOrScalar T_Extents>
192
193 template<concepts::VectorOrScalar T_Begin, concepts::VectorOrScalar T_End>
194 ALPAKA_FN_HOST_ACC IdxRange(T_Begin const&, T_End const&) -> IdxRange<
198
199 template<concepts::VectorOrScalar T_Begin, concepts::VectorOrScalar T_End, concepts::VectorOrScalar T_Stride>
200 ALPAKA_FN_HOST_ACC IdxRange(T_Begin const&, T_End const&, T_Stride const&) -> IdxRange<
204
205 namespace trait
206 {
207 template<typename T>
208 struct IsIndexRange : std::false_type
209 {
210 };
211
212 template<concepts::SpecializationOf<IdxRange> T>
213 struct IsIndexRange<T> : std::true_type
214 {
215 };
216
217 template<typename T>
218 struct IsLazyIndexRange : std::false_type
219 {
220 };
221
222 } // namespace trait
223
224 template<typename T>
226
227 template<typename T>
229
230 namespace concepts
231 {
232 /** Concept to check if a type is an index range
233 *
234 * @tparam T Type to check
235 * @tparam T_ValueType enforce a value type of the index range, if not provided the type is not checked
236 * @tparam T_dim enforce a dimensionality of the index range, if not provided the value is not checked
237 */
238 template<typename T, typename T_ValueType = alpaka::NotRequired, uint32_t T_dim = alpaka::notRequiredDim>
239 concept IdxRange
241 && (std::same_as<T_ValueType, typename T::IdxType> || std::same_as<T_ValueType, alpaka::NotRequired>)
242 && ((T_dim == alpaka::notRequiredDim) || (T::dim() == T_dim));
243
244 /** Concept to check if a type is a lazy-evaluated index range
245 *
246 * @attention the value type and dimension can not be evaluated for lazy index ranges.
247 *
248 * @tparam T Type to check
249 */
250 template<typename T>
252
253 template<typename T>
255
256 } // namespace concepts
257} // namespace alpaka
#define ALPAKA_ASSERT_ACC(...)
ALPAKA_ASSERT_ACC is an assert-like macro.
Definition Assert.hpp:53
ALPAKA_FN_ACC const_iterator_end end() const
ALPAKA_FN_ACC const_iterator begin() const
#define ALPAKA_FN_HOST_ACC
All functions that can be used on an accelerator have to be attributed with ALPAKA_FN_ACC or ALPAKA_F...
Definition common.hpp:32
#define ALPAKA_TYPEOF(...)
Get the type of instance.
Definition common.hpp:154
Concept to check if a type is an index range.
Definition IdxRange.hpp:240
Concept to check if a type is a lazy-evaluated index range.
Definition IdxRange.hpp:251
Concept to check if a type is a vector or scalar variable.
Definition Vec.hpp:65
Concept to check if a type is a vector.
Definition Vec.hpp:54
constexpr auto contiguous
Definition layout.hpp:23
typename GetVec< T >::type getVec_t
Definition Vec.hpp:948
main alpaka namespace.
Definition alpaka.hpp:76
constexpr uint32_t notRequiredDim
Definition trait.hpp:23
constexpr auto makeDirectionSubRange(auto const range, alpaka::BoundaryDirection< T_dim, T_LowHaloVec, T_UpHaloVec > const &boundaryDir)
Definition IdxRange.hpp:136
constexpr bool isLazyIndexRange_v
Definition IdxRange.hpp:228
constexpr bool isIndexRange_v
Definition IdxRange.hpp:225
ALPAKA_FN_HOST_ACC IdxRange(T_Extents const &) -> IdxRange< typename trait::getVec_t< T_Extents >::UniVec >
consteval auto iotaCVec()
Create and return a CVector of the given length with values 1, 2, ...
Definition CVec.hpp:135
constexpr decltype(auto) pCast(auto &&input)
Performs a static_cast on the storage type of combined data type.
Definition cast.hpp:48
An n-dimensional boundary direction.
constexpr auto begin() const
Begin iterator to iterate all positions in the range.
Definition IdxRange.hpp:88
constexpr IdxRange(T_Begin const &begin, T_End const &end, T_Stride const &stride)
Definition IdxRange.hpp:27
ALPAKA_FN_HOST_ACC constexpr auto operator<<(T_OpType const &rhs) const
Definition IdxRange.hpp:66
ALPAKA_FN_HOST_ACC constexpr auto operator%(T_OpType const &rhs) const
Definition IdxRange.hpp:51
typename T_End::UniVec IdxVecType
Definition IdxRange.hpp:25
T_Stride m_stride
Definition IdxRange.hpp:130
constexpr IdxRange(T_End const &extent)
Definition IdxRange.hpp:41
typename T_Begin::type type
Definition IdxRange.hpp:132
typename T_End::type IdxType
Definition IdxRange.hpp:24
std::string toString(std::string const separator=",", std::string const enclosings="{}") const
Definition IdxRange.hpp:108
constexpr auto end() const
Definition IdxRange.hpp:98
constexpr auto distance() const
Definition IdxRange.hpp:74
ALPAKA_FN_HOST_ACC constexpr auto operator>>(T_OpType const &rhs) const
Definition IdxRange.hpp:57
constexpr IdxRange(T_Begin const &begin, T_End const &end)
Definition IdxRange.hpp:34
static consteval uint32_t dim()
Definition IdxRange.hpp:45
static constexpr auto fill()
Definition Vec.hpp:285