alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
View.hpp
Go to the documentation of this file.
1/* Copyright 2024 Bernhard Manfred Gruber, René Widera
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
11#include "alpaka/mem/MdSpan.hpp"
14#include "alpaka/mem/trait.hpp"
16
17#include <cstdint>
18#include <functional>
19
20namespace alpaka
21{
22 /** @brief Non owning view to data
23 *
24 * This view is only holding a pointer to real data, copying the view is cheap.
25 * Const-ness of the view instance is propagated to the data region.
26 *
27 * This satisfies the alpaka::concepts::IView concept and, therefore, also the alpaka::concepts::IMdSpan concept.
28 */
29 template<
30 alpaka::concepts::Api T_Api,
31 typename T_Type,
32 alpaka::concepts::Vector T_Extents,
33 alpaka::concepts::Alignment T_MemAlignment = Alignment<>>
34 struct View;
35
36 template<typename T_ValueType, concepts::Alignment T_MemAlignment = Alignment<>>
37 inline constexpr auto makeView(
38 auto&& anyWithApi,
39 T_ValueType* pointer,
40 concepts::Vector auto const& extents,
41 T_MemAlignment const memAlignment = T_MemAlignment{})
42 {
44 return View{getApi(ALPAKA_FORWARD(anyWithApi)), pointer, extents, pitchMd, memAlignment};
45 }
46
47 template<typename T_ValueType, concepts::Alignment T_MemAlignment = Alignment<>>
48 inline constexpr auto makeView(
49 auto&& anyWithApi,
50 T_ValueType* pointer,
51 concepts::Vector auto const& extents,
52 concepts::Vector auto const& pitches,
53 T_MemAlignment const memAlignment = T_MemAlignment{})
54 {
55 static_assert(std::is_same_v<ALPAKA_TYPEOF(extents), ALPAKA_TYPEOF(pitches)>);
56 return View{getApi(ALPAKA_FORWARD(anyWithApi)), pointer, extents, pitches, memAlignment};
57 }
58
59 inline constexpr auto makeView(auto&& any)
60 {
61 return View{
62 internal::getApi(ALPAKA_FORWARD(any)),
67 }
68
69 template<
71 typename T_Type,
73 alpaka::concepts::Alignment T_MemAlignment>
74 struct View : MdSpan<T_Type, typename T_Extents::UniVec, typename T_Extents::UniVec, T_MemAlignment>
75 {
76 private:
78
79 public:
80 /** Creates a view
81 *
82 * @param data handle to the physical data
83 * @param extents n-dimensional extents in elements of the view. Must satisfy `n <= number_of_elements` in the
84 * data handle.
85 */
86 template<
88 alpaka::concepts::Vector T_UserExtents,
89 alpaka::concepts::Vector T_UserPitches>
90 constexpr View(
91 T_Any const& any,
92 T_Type* data,
93 T_UserExtents const& extents,
94 T_UserPitches const& pitches,
95 T_MemAlignment const memAlignment = T_MemAlignment{})
96 : BaseMdSpan{
97 data,
98 typename T_UserExtents::UniVec{extents},
99 typename T_UserPitches::UniVec{pitches},
100 memAlignment}
101 {
102 alpaka::unused(any);
103 static_assert(
105 "extent type and pitch type must be lossless convertible");
106 }
107
108 template<typename T_Type_Other>
109 requires alpaka::internal::concepts::InnerTypeAllowedCast<T_Type, T_Type_Other>
111 : BaseMdSpan{static_cast<BaseMdSpan>(other)}
112 {
113 }
114
115 constexpr View(View const&) = default;
116
117 template<typename T_Type_Other>
118 requires alpaka::internal::concepts::InnerTypeAllowedCast<T_Type, T_Type_Other>
120 : BaseMdSpan{std::move(static_cast<BaseMdSpan>(other))}
121 {
122 }
123
124 constexpr View(View&&) = default;
125
126 /** Assignment operator keeping const-ness
127 *
128 * @attention the assign operator is not removing inner const-ness because the type signature is not changed.
129 */
130 constexpr View& operator=(View const&) = default;
131
132 constexpr View& operator=(View&&) = default;
133
134 static consteval T_Api getApi()
135 {
136 return T_Api{};
137 }
138
140 {
142 }
143
145 {
146 return BaseMdSpan{*this};
147 }
148
149 /** create a read only view */
150 constexpr auto getConstView() const
151 {
152 using ConstValueType = std::add_const_t<typename BaseMdSpan::value_type>;
154 T_Api{},
155 static_cast<ConstValueType*>(this->data()),
156 this->getExtents(),
157 this->getPitches(),
158 T_MemAlignment{}};
159 }
160
161 /** @brief Creates a sub view to a part of the memory.
162 *
163 * The sub view has the same dimension as the original.
164 *
165 * @param extents Number of elements for each dimension. Each number must be less than or equal to
166 * the number of elements in the original dimension.
167 * @return View which is pointing only to a part of the original view.
168 *
169 * @{
170 */
171 constexpr auto getSubView(alpaka::concepts::VectorOrScalar auto const& extents) const
172 {
173 static_assert(alpaka::trait::getDim_v<ALPAKA_TYPEOF(extents)> == T_Extents::dim());
174 Vec extentMd = extents;
175 assert((extentMd <= this->getExtents()).reduce(std::logical_and{}));
176 return makeView(T_Api{}, this->data(), extentMd, this->getPitches(), T_MemAlignment{});
177 }
178
179 constexpr auto getSubView(alpaka::concepts::VectorOrScalar auto const& extents)
180 {
181 static_assert(alpaka::trait::getDim_v<ALPAKA_TYPEOF(extents)> == T_Extents::dim());
182 Vec extentMd = extents;
183 assert((extentMd <= this->getExtents()).reduce(std::logical_and{}));
184 return makeView(T_Api{}, this->data(), extentMd, this->getPitches(), T_MemAlignment{});
185 }
186
187 /** @} */
188
189 /** @brief Creates a sub view to a part of the memory.
190 *
191 * The sub view has the same dimension as the original. The offset defines the first coordinate of
192 * each dimension. The `offset + extents - 1` defines the last element for each dimension in the
193 * original view. Offset plus extents should not exceed the extents of the original view.
194 *
195 * @param offset offset in elements to the original view
196 * @param extents number of elements for each dimension
197 * @return View which is pointing only to a part of the original view with a shifted origin pointer.
198 * The alignment of the sub view is reduced to the element alignment.
199 *
200 * @{
201 */
202 constexpr auto getSubView(
203 alpaka::concepts::VectorOrScalar auto const& offset,
204 alpaka::concepts::VectorOrScalar auto const& extents) const
205 {
206 static_assert(alpaka::trait::getDim_v<ALPAKA_TYPEOF(extents)> == T_Extents::dim());
207 static_assert(alpaka::trait::getDim_v<ALPAKA_TYPEOF(offset)> == T_Extents::dim());
208
209 Vec offsetMd = offset;
210 Vec extentMd = extents;
211 assert((offsetMd + extentMd <= this->getExtents()).reduce(std::logical_and{}));
212 auto shiftedPtr = &(*this)[offsetMd];
213 return makeView(T_Api{}, shiftedPtr, extentMd, this->getPitches(), Alignment<>{});
214 }
215
216 constexpr auto getSubView(
217 alpaka::concepts::VectorOrScalar auto const& offset,
218 alpaka::concepts::VectorOrScalar auto const& extents)
219 {
220 static_assert(alpaka::trait::getDim_v<ALPAKA_TYPEOF(extents)> == T_Extents::dim());
221 static_assert(alpaka::trait::getDim_v<ALPAKA_TYPEOF(offset)> == T_Extents::dim());
222
223 Vec offsetMd = offset;
224 Vec extentMd = extents;
225 assert((offsetMd + extentMd <= this->getExtents()).reduce(std::logical_and{}));
226 auto shiftedPtr = &(*this)[offsetMd];
227 return makeView(T_Api{}, shiftedPtr, extentMd, this->getPitches(), Alignment<>{});
228 }
229
230 /** @} */
231
232 template<alpaka::concepts::Vector LowHaloVecType, alpaka::concepts::Vector UpHaloVecType>
233 constexpr auto getSubView(
234 alpaka::BoundaryDirection<View::dim(), LowHaloVecType, UpHaloVecType> boundaryDir) const
235 {
236 constexpr uint32_t dim = View::dim();
237 auto offset = alpaka::Vec<uint32_t, dim>{};
238 auto extents = alpaka::Vec<uint32_t, dim>{};
239
240 for(uint32_t i = 0; i < dim; ++i)
241 {
242 switch(boundaryDir.data[i])
243 {
245 offset[i] = 0;
246 extents[i] = boundaryDir.lowerHaloSize[i];
247 break;
249 offset[i] = this->getExtents()[i] - boundaryDir.upperHaloSize[i];
250 extents[i] = boundaryDir.upperHaloSize[i];
251 break;
253 offset[i] = boundaryDir.lowerHaloSize[i];
254 extents[i] = this->getExtents()[i] - boundaryDir.lowerHaloSize[i] - boundaryDir.upperHaloSize[i];
255 break;
256 default:
257 throw std::invalid_argument("invalid direction");
258 }
259 }
260 return getSubView(offset, extents);
261 }
262 };
263
264 template<typename T_Api, typename T_Type, concepts::Vector T_Extents, concepts::Alignment T_MemAlignment>
265 std::ostream& operator<<(std::ostream& s, View<T_Api, T_Type, T_Extents, T_MemAlignment> const& view)
266 {
267 return s << "View{ dim=" << ALPAKA_TYPEOF(view)::dim() << ", api= " << onHost::getName(T_Api{})
268 << ", extents=" << view.getExtents().toString() << ", pitches=" << view.getPitches().toString()
269 << " , alignment=" << T_MemAlignment::template get<T_Type>() << " }";
270 }
271
272 template<
274 typename T_Type,
275 alpaka::concepts::Vector T_UserExtents,
276 alpaka::concepts::Vector T_UserPitches,
277 alpaka::concepts::Alignment T_MemAlignment>
279 T_Any const&,
280 T_Type*,
281 T_UserExtents const&,
282 T_UserPitches const&,
283 T_MemAlignment const memAlignment)
284 -> View<ALPAKA_TYPEOF(getApi(std::declval<T_Any>())), T_Type, typename T_UserPitches::UniVec, T_MemAlignment>;
285
286 template<
288 typename T_Type,
289 alpaka::concepts::Vector T_UserExtents,
290 alpaka::concepts::Vector T_UserPitches>
291 ALPAKA_FN_HOST_ACC View(T_Any, T_Type*, T_UserExtents const&, T_UserPitches const&)
292 -> View<ALPAKA_TYPEOF(getApi(std::declval<T_Any>())), T_Type, typename T_UserPitches::UniVec, Alignment<>>;
293} // namespace alpaka
294
295namespace alpaka::internal
296{
297 // externally define the API trait to support constexpr evaluation
298 template<
300 typename T_Type,
301 alpaka::concepts::Vector T_Extents,
302 alpaka::concepts::Alignment T_MemAlignment>
303 struct GetApi::Op<alpaka::View<T_Api, T_Type, T_Extents, T_MemAlignment>>
304 {
305 inline constexpr auto operator()(auto&& view) const
306 {
307 alpaka::unused(view);
308 return T_Api{};
309 }
310 };
311
312 template<
313 alpaka::concepts::Api T_Api,
314 typename T_Type,
315 alpaka::concepts::Vector T_Extents,
316 alpaka::concepts::Alignment T_MemAlignment>
317 struct CopyConstructableDataSource<View<T_Api, T_Type, T_Extents, T_MemAlignment>> : std::true_type
318 {
319 using InnerMutable = View<T_Api, std::remove_const_t<T_Type>, T_Extents, T_MemAlignment>;
320 using InnerConst = View<T_Api, std::add_const_t<T_Type>, T_Extents, T_MemAlignment>;
321 };
322} // namespace alpaka::internal
#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
#define ALPAKA_FORWARD(instance)
Perfectly forward an instance as argument.
Definition common.hpp:148
Concept to check for an alignment object.
Definition Alignment.hpp:89
Concept to check for APIs.
Definition api.hpp:42
Concept to check if the given type implements the getApi(T x) function returning an alpaka::concepts:...
Definition interface.hpp:64
Interface concept for objects describing multidimensional memory access.
Definition IMdSpan.hpp:91
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
decltype(auto) data(auto &&any)
pointer to data of an object
decltype(auto) getExtents(auto &&any)
Object extents.
Definition interface.hpp:25
std::convertible_to< std::string > auto getName(auto &&any)
Runtime name for a given object.
decltype(auto) getPitches(auto &&any)
Object pitches.
Definition interface.hpp:55
constexpr uint32_t getDim_v
Definition trait.hpp:41
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.
ALPAKA_FN_HOST_ACC View(T_Any const &, T_Type *, T_UserExtents const &, T_UserPitches const &, T_MemAlignment const memAlignment) -> View< ALPAKA_TYPEOF(getApi(std::declval< T_Any >())), T_Type, typename T_UserPitches::UniVec, T_MemAlignment >
constexpr auto getAlignment(auto &&any)
Get the value type alignment of an object.
constexpr bool isLosslesslyConvertible_v
Definition trait.hpp:122
constexpr decltype(auto) getApi(auto &&any)
Get the API an object depends on.
Definition interface.hpp:42
constexpr auto makeView(auto &&anyWithApi, T_ValueType *pointer, concepts::Vector auto const &extents, T_MemAlignment const memAlignment=T_MemAlignment{})
Definition View.hpp:37
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
An n-dimensional boundary direction.
Non owning view to data.
Definition View.hpp:75
constexpr View & operator=(View const &)=default
Assignment operator keeping const-ness.
constexpr auto getSubView(alpaka::BoundaryDirection< View::dim(), LowHaloVecType, UpHaloVecType > boundaryDir) const
Definition View.hpp:233
constexpr auto getSubView(alpaka::concepts::VectorOrScalar auto const &extents)
Creates a sub view to a part of the memory.
Definition View.hpp:179
static consteval T_Api getApi()
Definition View.hpp:134
constexpr alpaka::concepts::IMdSpan auto getMdSpan() const
Definition View.hpp:139
constexpr auto getSubView(alpaka::concepts::VectorOrScalar auto const &offset, alpaka::concepts::VectorOrScalar auto const &extents)
Creates a sub view to a part of the memory.
Definition View.hpp:216
constexpr View(View< T_Api, T_Type_Other, T_Extents, T_MemAlignment > const &other)
Definition View.hpp:110
constexpr View & operator=(View &&)=default
constexpr auto getSubView(alpaka::concepts::VectorOrScalar auto const &offset, alpaka::concepts::VectorOrScalar auto const &extents) const
Creates a sub view to a part of the memory.
Definition View.hpp:202
constexpr auto getConstView() const
create a read only view
Definition View.hpp:150
constexpr alpaka::concepts::IMdSpan auto getMdSpan()
Definition View.hpp:144
constexpr View(T_Any const &any, T_Type *data, T_UserExtents const &extents, T_UserPitches const &pitches, T_MemAlignment const memAlignment=T_MemAlignment{})
Creates a view.
Definition View.hpp:90
constexpr auto getSubView(alpaka::concepts::VectorOrScalar auto const &extents) const
Creates a sub view to a part of the memory.
Definition View.hpp:171
constexpr View(View< T_Api, T_Type_Other, T_Extents, T_MemAlignment > &&other)
Definition View.hpp:119
constexpr View(View &&)=default
constexpr View(View const &)=default