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