alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
ViewAccessOps.hpp
Go to the documentation of this file.
1/* Copyright 2026 Andrea Bocci, Bernhard Manfred Gruber, Jan Stephan, Simone Balducci
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
7#include "alpaka/acc/Tag.hpp"
11
12#include <cstdint>
13#include <span>
14#include <sstream>
15#include <stdexcept>
16#include <type_traits>
17#include <utility>
18
19namespace alpaka
20{
21 class DevCpu;
22} // namespace alpaka
23
24namespace alpaka::concepts
25{
26 template<typename TView>
27 concept View = requires {
28 typename Idx<TView>;
29 typename Dim<TView>;
30 {
31 getPtrNative(std::declval<TView>())
32 };
33 {
34 getPitchesInBytes(std::declval<TView>())
35 };
36 {
37 getExtents(std::declval<TView>())
38 };
39 };
40} // namespace alpaka::concepts
41
42namespace alpaka::internal
43{
44
45 template<concepts::View TView>
47 {
48 private:
49 using value_type = Elem<TView>;
50 using pointer = value_type*;
51 using const_pointer = value_type const*;
52 using reference = value_type&;
53 using const_reference = value_type const&;
54 using Idx = alpaka::Idx<TView>;
55 using Dim = alpaka::Dim<TView>;
56
57 public:
58 [[nodiscard]] ALPAKA_FN_HOST auto data() -> pointer
59 {
60 return getPtrNative(*static_cast<TView*>(this));
61 }
62
63 [[nodiscard]] ALPAKA_FN_HOST auto data() const -> const_pointer
64 {
65 return getPtrNative(*static_cast<TView const*>(this));
66 }
67
68 ALPAKA_FN_HOST auto begin() -> pointer requires(Dim::value == 1)
69 {
70 return data();
71 }
72
73 ALPAKA_FN_HOST auto begin() const -> const_pointer requires(Dim::value == 1)
74 {
75 return data();
76 }
77
78 ALPAKA_FN_HOST auto cbegin() const -> const_pointer requires(Dim::value == 1)
79 {
80 return data();
81 }
82
83 ALPAKA_FN_HOST auto end() -> pointer requires(Dim::value == 1)
84 {
85 return data() + getExtents(*static_cast<TView*>(this))[0];
86 }
87
88 ALPAKA_FN_HOST auto end() const -> const_pointer requires(Dim::value == 1)
89 {
90 return data() + getExtents(*static_cast<TView const*>(this))[0];
91 }
92
93 ALPAKA_FN_HOST auto cend() const -> const_pointer requires(Dim::value == 1)
94 {
95 return data() + getExtents(*static_cast<TView const*>(this))[0];
96 }
97
98 ALPAKA_FN_HOST auto rank() const -> Idx
99 {
100 return Dim::value;
101 }
102
103 ALPAKA_FN_HOST auto size() const -> Idx requires(Dim::value == 1)
104 {
105 return getExtents(*static_cast<TView const*>(this))[0];
106 }
107
108 ALPAKA_FN_HOST auto size() const -> Idx requires(Dim::value > 1)
109 {
110 return getExtents(*static_cast<TView const*>(this)).prod();
111 }
112
113 ALPAKA_FN_HOST auto extent(Idx dim) const -> Idx
114 {
115 return getExtents(*static_cast<TView const*>(this))[dim];
116 }
117
118 ALPAKA_FN_HOST auto extents() const -> Vec<Dim, Idx>;
119
120#if ALPAKA_COMP_CLANG
121# pragma clang diagnostic push
122# if __has_warning("-Wunsafe-buffer-usage-in-container")
123# pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"
124# endif
125#endif
126 ALPAKA_FN_HOST operator std::span<value_type const>() const requires(Dim::value == 1)
127 {
128 return std::span<value_type const>{begin(), end()};
129 }
130
131 ALPAKA_FN_HOST operator std::span<value_type>() requires(Dim::value == 1)
132 {
133 return std::span<value_type>{begin(), end()};
134 }
135#if ALPAKA_COMP_CLANG
136# pragma clang diagnostic pop
137#endif
138 };
139
140 template<concepts::View TView>
142
143 template<concepts::View TView>
145 {
146 private:
147 using value_type = Elem<TView>;
148 using pointer = value_type*;
149 using const_pointer = value_type const*;
150 using reference = value_type&;
151 using const_reference = value_type const&;
152 using Idx = alpaka::Idx<TView>;
153 using Dim = alpaka::Dim<TView>;
154
155 public:
156 ALPAKA_FN_HOST auto operator*() -> reference
157 {
158 static_assert(Dim::value == 0, "operator* is only valid for Buffers and Views of dimension 0");
159 return *(this->data());
160 }
161
162 ALPAKA_FN_HOST auto operator*() const -> const_reference
163 {
164 static_assert(Dim::value == 0, "operator* is only valid for Buffers and Views of dimension 0");
165 return *(this->data());
166 }
167
168 ALPAKA_FN_HOST auto operator->() -> pointer
169 {
170 static_assert(Dim::value == 0, "operator-> is only valid for Buffers and Views of dimension 0");
171 return this->data();
172 }
173
174 ALPAKA_FN_HOST auto operator->() const -> const_pointer
175 {
176 static_assert(Dim::value == 0, "operator-> is only valid for Buffers and Views of dimension 0");
177 return this->data();
178 }
179
180 ALPAKA_FN_HOST auto operator[](Idx i) -> reference
181 {
182 static_assert(Dim::value == 1, "operator[i] is only valid for Buffers and Views of dimension 1");
183 return this->data()[i];
184 }
185
186 ALPAKA_FN_HOST auto operator[](Idx i) const -> const_reference
187 {
188 static_assert(Dim::value == 1, "operator[i] is only valid for Buffers and Views of dimension 1");
189 return this->data()[i];
190 }
191
192 private:
193 template<typename TIdx>
194 [[nodiscard]] ALPAKA_FN_HOST auto ptr_at([[maybe_unused]] Vec<Dim, TIdx> index) const -> const_pointer
195 {
196 static_assert(
197 std::is_convertible_v<TIdx, Idx>,
198 "the index type must be convertible to the index of the Buffer or View");
199
200 auto ptr = reinterpret_cast<std::uintptr_t>(this->data());
201 if constexpr(Dim::value > 0)
202 {
203 ptr += static_cast<std::uintptr_t>(
204 (getPitchesInBytes(*static_cast<TView const*>(this)) * castVec<Idx>(index)).sum());
205 }
206 return reinterpret_cast<const_pointer>(ptr);
207 }
208
209 public:
210 template<typename TIdx>
211 ALPAKA_FN_HOST auto operator[](Vec<Dim, TIdx> index) -> reference
212 {
213 return *const_cast<pointer>(ptr_at(index));
214 }
215
216 template<typename TIdx>
217 ALPAKA_FN_HOST auto operator[](Vec<Dim, TIdx> index) const -> const_reference
218 {
219 return *ptr_at(index);
220 }
221
222 template<typename TIdx>
223 ALPAKA_FN_HOST auto at(Vec<Dim, TIdx> index) -> reference
224 {
225 auto extent = getExtents(*static_cast<TView*>(this));
226 if(!(index < extent).all())
227 {
228 std::stringstream msg;
229 msg << "index " << index << " is outside of the Buffer or View extent " << extent;
230 throw std::out_of_range(msg.str());
231 }
232 return *const_cast<pointer>(ptr_at(index));
233 }
234
235 template<typename TIdx>
236 [[nodiscard]] ALPAKA_FN_HOST auto at(Vec<Dim, TIdx> index) const -> const_reference
237 {
238 auto extent = getExtents(*static_cast<TView const*>(this));
239 if(!(index < extent).all())
240 {
241 std::stringstream msg;
242 msg << "index " << index << " is outside of the Buffer or View extent " << extent;
243 throw std::out_of_range(msg.str());
244 }
245 return *ptr_at(index);
246 }
247 };
248
249 template<typename TDev>
251 {
252 template<concepts::View TView>
254 };
255
256 template<>
258 {
259 template<concepts::View TView>
261 };
262
263#ifdef ALPAKA_ACC_SYCL_ENABLED
264 template<>
265 struct ViewAccessor<alpaka::DevGenericSycl<alpaka::TagCpuSycl>>
266 {
267 template<concepts::View TView>
269 };
270#endif
271
272 template<typename TDev, concepts::View TView>
273 using ViewAccessorType = typename ViewAccessor<TDev>::template AccessorType<TView>;
274
275} // namespace alpaka::internal
The CPU device handle.
Definition DevCpu.hpp:56
A n-dimensional vector.
Definition Vec.hpp:38
#define ALPAKA_FN_HOST
Definition Common.hpp:43
typename ViewAccessor< TDev >::template AccessorType< TView > ViewAccessorType
The alpaka accelerator library.
std::remove_volatile_t< typename trait::ElemType< TView >::type > Elem
The element type trait alias template to remove the ::type.
Definition Traits.hpp:21
ALPAKA_FN_HOST auto getPitchesInBytes(TView const &view) -> Vec< Dim< TView >, Idx< TView > >
Definition Traits.hpp:237
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC constexpr auto castVec(TVec const &vec)
Definition Traits.hpp:82
typename trait::IdxType< T >::type Idx
Definition Traits.hpp:29
ALPAKA_FN_HOST auto getPtrNative(TView const &view) -> Elem< TView > const *
Gets the native pointer of the memory view.
Definition Traits.hpp:177
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto getExtents(T const &object) -> Vec< Dim< T >, Idx< T > >
Definition Traits.hpp:59
typename trait::DimType< T >::type Dim
The dimension type trait alias template to remove the ::type.
Definition Traits.hpp:19
ALPAKA_FN_HOST auto size() const -> Idx requires(Dim::value==1)
ALPAKA_FN_HOST auto data() const -> const_pointer
ALPAKA_FN_HOST auto cbegin() const -> const_pointer requires(Dim::value==1)
ALPAKA_FN_HOST auto size() const -> Idx requires(Dim::value > 1)
ALPAKA_FN_HOST auto extent(Idx dim) const -> Idx
ALPAKA_FN_HOST auto cend() const -> const_pointer requires(Dim::value==1)
ALPAKA_FN_HOST auto end() -> pointer requires(Dim::value==1)
ALPAKA_FN_HOST auto rank() const -> Idx
ALPAKA_FN_HOST auto extents() const -> Vec< Dim, Idx >
ALPAKA_FN_HOST auto end() const -> const_pointer requires(Dim::value==1)
ALPAKA_FN_HOST auto begin() const -> const_pointer requires(Dim::value==1)
ALPAKA_FN_HOST auto data() -> pointer
ALPAKA_FN_HOST auto begin() -> pointer requires(Dim::value==1)
ALPAKA_FN_HOST auto at(Vec< Dim, TIdx > index) const -> const_reference
ALPAKA_FN_HOST auto operator[](Vec< Dim, TIdx > index) -> reference
ALPAKA_FN_HOST auto at(Vec< Dim, TIdx > index) -> reference
ALPAKA_FN_HOST auto operator[](Idx i) -> reference
ALPAKA_FN_HOST auto operator*() const -> const_reference
ALPAKA_FN_HOST auto operator*() -> reference
ALPAKA_FN_HOST auto operator->() const -> const_pointer
ALPAKA_FN_HOST auto operator[](Vec< Dim, TIdx > index) const -> const_reference
ALPAKA_FN_HOST auto operator[](Idx i) const -> const_reference
ALPAKA_FN_HOST auto operator->() -> pointer
DeviceViewAccessor< TView > AccessorType