alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
MdSpan.hpp
Go to the documentation of this file.
1/* Copyright 2025 René Widera, Simeon Ehrig
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
7#include "alpaka/Vec.hpp"
14#include "alpaka/mem/trait.hpp"
16#include "alpaka/trait.hpp"
17#include "concepts/IndexVec.hpp"
18
19#include <type_traits>
20
21namespace alpaka
22{
23 /** Lightweight view to data in an n-dimensional array.
24 *
25 * Const-ness of the MdSpan instance is propagated to the data region.
26 * A constant MdSpan can be used to access non-const data.
27 *
28 * @tparam T_Type if the type is const the data is only readable
29 */
30 template<
31 typename T_Type,
32 concepts::Vector T_Extents,
33 concepts::Vector T_Pitches,
34 concepts::Alignment T_MemAlignment = Alignment<>>
35 struct MdSpan;
36
37 template<concepts::Alignment T_MemAlignment = Alignment<>>
38 inline constexpr auto makeMdSpan(
39 auto* pointer,
40 concepts::Vector auto const& extents,
41 concepts::Vector auto const& pitchBytes,
42 T_MemAlignment const memAlignment = T_MemAlignment{})
43 {
44 return MdSpan{pointer, extents, pitchBytes, memAlignment};
45 }
46
47 template<typename T_ValueType, concepts::Alignment T_MemAlignment = Alignment<>>
48 inline constexpr auto makeMdSpan(
49 T_ValueType* pointer,
50 concepts::Vector auto const& extents,
51 T_MemAlignment const memAlignment = T_MemAlignment{})
52 {
54 return MdSpan{pointer, extents, pitchMd, memAlignment};
55 }
56
57 inline constexpr auto makeMdSpan(auto&& any)
58 {
60 }
61
62 template<
63 typename T_Type,
64 concepts::Vector T_Extents,
65 concepts::Vector T_Pitches,
66 concepts::Alignment T_MemAlignment>
67 struct MdSpan
68 {
69 using value_type = T_Type;
71 using const_reference = std::add_const_t<value_type>&;
73 using const_pointer = std::add_const_t<value_type>*;
74 using index_type = typename T_Pitches::type;
75
76 using ConstThis = MdSpan<std::add_const_t<value_type>, T_Extents, T_Pitches, T_MemAlignment>;
77
78 static_assert(std::is_convertible_v<index_type, typename T_Extents::type>);
79 static_assert(T_Extents::dim() == T_Pitches::dim());
80
81 static consteval uint32_t dim()
82 {
83 return T_Extents::dim();
84 }
85
86 /** return value the origin pointer is pointing to
87 *
88 * @return value at the current location
89 */
90 constexpr const_reference operator*() const
91 {
92 return *this->m_ptr;
93 }
94
95 constexpr reference operator*()
96 {
97 return *this->m_ptr;
98 }
99
100 /** get origin pointer
101 *
102 * If the pointer is const and therefore read only depends on T_Type and not the const-ness of MdSPan.
103 */
104 constexpr const_pointer data() const
105 {
106 return this->m_ptr;
107 }
108
109 constexpr pointer data()
110 {
111 return this->m_ptr;
112 }
113
114 constexpr auto begin() const
115 {
116 return MdForwardIter{this->getConstMdSpan()};
117 }
118
119 constexpr auto begin()
120 {
121 return MdForwardIter{*this};
122 }
123
124 constexpr auto end() const
125 {
126 return MdForwardIterEnd{this->getConstMdSpan()};
127 }
128
129 constexpr auto end()
130 {
131 return MdForwardIterEnd{*this};
132 }
133
134 constexpr auto cbegin() const
135 {
136 return MdForwardIter{this->getConstMdSpan()};
137 }
138
139 constexpr auto cend() const
140 {
141 return MdForwardIterEnd{this->getConstMdSpan()};
142 }
143
144 /*Object must init by copy a valid instance*/
145 constexpr MdSpan() = default;
146
147 /** Constructor
148 *
149 * @param pointer pointer to the memory
150 * @param extents number of elements
151 * @param pitchBytes pitch in bytes per dimension
152 * @param memAlignmentInByte alignment in bytes (zero will set alignment to element alignment)
153 */
154 constexpr MdSpan(
155 T_Type* pointer,
156 T_Extents extents,
157 T_Pitches const& pitchBytes,
158 [[maybe_unused]] T_MemAlignment const& memAlignmentInByte = T_MemAlignment{})
159 : m_ptr(pointer)
160 , m_extent(extents)
161 , m_pitch(pitchBytes)
162 {
163 }
164
165 template<typename T_Type_Other>
166 requires internal::concepts::InnerTypeAllowedCast<T_Type, T_Type_Other>
168 : m_ptr(other.data())
169 , m_extent(other.getExtents())
170 , m_pitch(other.getPitches())
171 {
172 }
173
174 template<typename T_Type_Other>
175 requires alpaka::internal::concepts::InnerTypeAllowedCast<T_Type, T_Type_Other>
177 : m_ptr(std::move(other.data()))
178 , m_extent(std::move(other.getExtents()))
179 , m_pitch(std::move(other.getPitches()))
180 {
181 }
182
183 constexpr MdSpan(MdSpan const&) = default;
184 constexpr MdSpan(MdSpan&&) = default;
185
186 /** Assignment operator keeping const-ness
187 *
188 * @attention the assign operator is not removing inner const-ness because the type signature is not changed.
189 */
190 constexpr MdSpan& operator=(MdSpan const&) = default;
191
192 constexpr MdSpan& operator=(MdSpan&&) = default;
193
194 static constexpr auto getAlignment()
195 {
196 return T_MemAlignment{};
197 }
198
199 /** get value at the given index
200 *
201 * @param idx n-dimensional offset, relative to the origin pointer
202 * @return reference to the value
203 */
205 // cannot use dim() or alpaka::trait::GetDim_v<T_Extents> because they cause a segmentation fault in nvcc
207 {
208 return *ptr(idx);
209 }
210
212 // cannot use dim() or alpaka::trait::GetDim_v<T_Extents> because they cause a segmentation fault in nvcc
214 {
215 return *ptr(idx);
216 }
217
218 constexpr const_reference operator[](std::integral auto const& idx) const requires(dim() == 1u)
219 {
220 return *ptr(Vec{idx});
221 }
222
223 constexpr reference operator[](std::integral auto const& idx) requires(dim() == 1u)
224 {
225 return *ptr(Vec{idx});
226 }
227
228 constexpr auto getExtents() const
229 {
230 return m_extent;
231 }
232
233 constexpr T_Pitches getPitches() const
234 {
235 return m_pitch.getPitches();
236 }
237
238 constexpr auto getConstMdSpan() const
239 {
240 using ConstValueType = std::add_const_t<value_type>;
241 return makeMdSpan(
242 static_cast<ConstValueType*>(m_ptr),
243 this->getExtents(),
244 this->getPitches(),
245 T_MemAlignment{});
246 }
247
248 /** True if MdSpan is pointing to valid memory.
249 *
250 * @details
251 * An MdSpan remains valid even after being moved. The reason for this is that the MdSpan is simply copied.
252 * This is more efficient than a real move (e.g., setting the data pointer to nullptr). Implementing a real
253 * move is also not possible because MdSpan must be trivially copyable, which requires a default move
254 * constructor.
255 */
256 [[nodiscard]] constexpr explicit operator bool() const noexcept
257 {
258 return true;
259 }
260
261 protected:
262 /** get the pointer of the value relative to the origin pointer m_ptr
263 *
264 * @param idx n-dimensional offset
265 * @return pointer to value
266 */
267 constexpr auto ptr(concepts::Vector auto const& idx) const requires(dim() >= 2u)
268 {
269 /** offset in bytes
270 *
271 * We calculate the complete offset in bytes even if it would be possible to change the x-dimension
272 * with the native value_types pointer, this is reducing the register footprint.
273 */
274 index_type offset = sizeof(value_type) * idx.back();
275 for(uint32_t d = 0u; d < dim() - 1u; ++d)
276 {
277 offset += m_pitch[d] * idx[d];
278 }
279 using CharPtrType = std::conditional_t<std::is_const_v<value_type>, char const*, char*>;
280 using ResultPtrType = std::conditional_t<std::is_const_v<value_type>, const_pointer, pointer>;
281 return reinterpret_cast<ResultPtrType>(reinterpret_cast<CharPtrType>(this->m_ptr) + offset);
282 }
283
284 constexpr const_pointer ptr(concepts::Vector auto const& idx) const requires(dim() == 1u)
285 {
286 return this->m_ptr + idx.x();
287 }
288
289 constexpr pointer ptr(concepts::Vector auto const& idx) requires(dim() == 1u)
290 {
291 return this->m_ptr + idx.x();
292 }
293
294 private:
295 pointer m_ptr;
296 T_Extents m_extent;
298 };
299
300 template<
301 typename T_Type,
302 concepts::Vector T_Extents,
303 concepts::Vector T_Pitches,
304 concepts::Alignment T_MemAlignment>
305 std::ostream& operator<<(std::ostream& s, MdSpan<T_Type, T_Extents, T_Pitches, T_MemAlignment> const& mdSpan)
306 {
307 return s << "MdSpan{ dim=" << ALPAKA_TYPEOF(mdSpan)::dim() << ", extents=" << mdSpan.getExtents().toString()
308 << ", pitches=" << mdSpan.getPitches().toString()
309 << " , alignment=" << T_MemAlignment::template get<T_Type>() << " }";
310 }
311
312 template<
313 typename T_Type,
314 alpaka::concepts::Vector T_Extents,
315 alpaka::concepts::Vector T_Pitches,
316 alpaka::concepts::Alignment T_MemAlignment>
317 struct internal::CopyConstructableDataSource<MdSpan<T_Type, T_Extents, T_Pitches, T_MemAlignment>> : std::true_type
318 {
319 using InnerMutable = MdSpan<std::remove_const_t<T_Type>, T_Extents, T_Pitches, T_MemAlignment>;
320 using InnerConst = MdSpan<std::add_const_t<T_Type>, T_Extents, T_Pitches, T_MemAlignment>;
321 };
322} // namespace alpaka
special implementation to define the end
#define ALPAKA_TYPEOF(...)
Get the type of instance.
Definition common.hpp:154
Concept to check for an alignment object.
Definition Alignment.hpp:89
Check whether the specified type is a multidimensional index.
Definition IndexVec.hpp:22
Concept to check if a type is a vector.
Definition Vec.hpp:54
decltype(auto) data(auto &&any)
pointer to data of an object
decltype(auto) getExtents(auto &&any)
Object extents.
Definition interface.hpp:25
decltype(auto) getPitches(auto &&any)
Object pitches.
Definition interface.hpp:55
main alpaka namespace.
Definition alpaka.hpp:76
std::ostream & operator<<(std::ostream &os, concepts::BoundaryDirection auto const &bd)
constexpr auto calculatePitchesFromExtents(T_Vec const &extent)
Calculate the pitches purely from the extents.
constexpr auto getAlignment(auto &&any)
Get the value type alignment of an object.
constexpr auto makeMdSpan(auto *pointer, concepts::Vector auto const &extents, concepts::Vector auto const &pitchBytes, T_MemAlignment const memAlignment=T_MemAlignment{})
Definition MdSpan.hpp:38
constexpr decltype(auto) get(concepts::SpecializationOf< Dict > auto &t) noexcept
Definition Dict.hpp:156
STL namespace.
Strongly typed and constexpr representation of a byte-alignment of memory.
Definition Alignment.hpp:26
Lightweight view to data in an n-dimensional array.
Definition MdSpan.hpp:68
constexpr auto ptr(concepts::Vector auto const &idx) const
get the pointer of the value relative to the origin pointer m_ptr
Definition MdSpan.hpp:267
constexpr MdSpan(T_Type *pointer, T_Extents extents, T_Pitches const &pitchBytes, T_MemAlignment const &memAlignmentInByte=T_MemAlignment{})
Constructor.
Definition MdSpan.hpp:154
std::add_const_t< value_type > & const_reference
Definition MdSpan.hpp:71
constexpr auto end() const
Definition MdSpan.hpp:124
constexpr reference operator*()
Definition MdSpan.hpp:95
constexpr auto cbegin() const
Definition MdSpan.hpp:134
constexpr auto cend() const
Definition MdSpan.hpp:139
constexpr reference operator[](concepts::IndexVec< index_type, alpaka::trait::GetDim< T_Extents >::value > auto const &idx)
Definition MdSpan.hpp:211
constexpr const_reference operator[](concepts::IndexVec< index_type, alpaka::trait::GetDim< T_Extents >::value > auto const &idx) const
get value at the given index
Definition MdSpan.hpp:204
constexpr MdSpan(MdSpan< T_Type_Other, T_Extents, T_Pitches, T_MemAlignment > const &other)
Definition MdSpan.hpp:167
value_type * pointer
Definition MdSpan.hpp:72
constexpr const_pointer ptr(concepts::Vector auto const &idx) const
Definition MdSpan.hpp:284
value_type & reference
Definition MdSpan.hpp:70
constexpr MdSpan()=default
constexpr pointer ptr(concepts::Vector auto const &idx)
Definition MdSpan.hpp:289
typename T_Pitches::type index_type
Definition MdSpan.hpp:74
T_Type value_type
Definition MdSpan.hpp:69
constexpr auto begin() const
Definition MdSpan.hpp:114
constexpr MdSpan(MdSpan< T_Type_Other, T_Extents, T_Pitches, T_MemAlignment > &&other)
Definition MdSpan.hpp:176
constexpr MdSpan(MdSpan &&)=default
constexpr MdSpan(MdSpan const &)=default
static consteval uint32_t dim()
Definition MdSpan.hpp:81
constexpr auto getConstMdSpan() const
Definition MdSpan.hpp:238
constexpr const_pointer data() const
get origin pointer
Definition MdSpan.hpp:104
constexpr auto end()
Definition MdSpan.hpp:129
constexpr MdSpan & operator=(MdSpan const &)=default
Assignment operator keeping const-ness.
constexpr const_reference operator*() const
return value the origin pointer is pointing to
Definition MdSpan.hpp:90
constexpr pointer data()
Definition MdSpan.hpp:109
std::add_const_t< value_type > * const_pointer
Definition MdSpan.hpp:73
constexpr const_reference operator[](std::integral auto const &idx) const
Definition MdSpan.hpp:218
constexpr auto begin()
Definition MdSpan.hpp:119
static constexpr auto getAlignment()
Definition MdSpan.hpp:194
MdSpan< std::add_const_t< value_type >, T_Extents, T_Pitches, T_MemAlignment > ConstThis
Definition MdSpan.hpp:76
constexpr reference operator[](std::integral auto const &idx)
Definition MdSpan.hpp:223
constexpr MdSpan & operator=(MdSpan &&)=default
static constexpr uint32_t value
Definition trait.hpp:31