alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
interface.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
8#include "alpaka/concepts.hpp"
11#include "alpaka/tag.hpp"
12#include "alpaka/trait.hpp"
13
14/** Functionality which is usable on the host CPU controller thread. */
15namespace alpaka::onHost
16{
17 /** @{
18 * @name Query extents
19 */
20 /** Object extents
21 *
22 * @param any can be a std::vector, std::array, ...
23 * @return the extents of the object
24 */
25 inline decltype(auto) getExtents(auto&& any)
26 {
28 }
29
30 /** Handle extents
31 *
32 * @param handle can be a view, a data
33 * @return the extents of the object
34 */
35 inline decltype(auto) getExtents(alpaka::concepts::HasGet auto&& handle)
36 {
37 return internal::getExtents(*handle.get());
38 }
39
40 /** @} */
41
42 /** @{
43 * @name Query multi-dimensional pitches
44 */
45 /** Object pitches
46 *
47 * @param any can be a std::vector, std::array, ...
48 * @return Multidimensional value with number of bytes to jump to the next value within the corresponding
49 * dimension.
50 * The inner-most dimension (x) is sizeof(value_type), the next dimension (y) is the byte-stride of a
51 * full row including padding, and so on for higher dimensions.
52 * Given an ND index, the element-wise product with the pitches summed (dot product) yields the byte
53 * offset from the start of the buffer to that data element.
54 */
55 inline decltype(auto) getPitches(auto&& any)
56 {
58 }
59
60 /** Handle pitches
61 *
62 * @param handle can be a view, a data
63 * @return Multidimensional value with number of bytes to jump to the next value within the corresponding
64 * dimension.
65 * The inner-most dimension (x) is sizeof(value_type), the next dimension (y) is the byte-stride of a
66 * full row including padding, and so on for higher dimensions.
67 * Given an ND index, the element-wise product with the pitches summed (dot product) yields the byte
68 * offset from the start of the buffer to that data element.
69 */
70 inline decltype(auto) getPitches(alpaka::concepts::HasGet auto&& handle)
71 {
72 return internal::getPitches(*handle.get());
73 }
74
75 /** @} */
76
77 /** @{
78 * @name Query the name
79 */
80
81 /** Compile-time available name for a given object.
82 *
83 * @param any object whose name shall be queried
84 * @return a `std::string`-compatible value holding the static name
85 */
86 inline std::convertible_to<std::string> auto getStaticName(auto const& any)
87 {
89 }
90
91 /** Compile-time available name of an handle
92 *
93 * @param handle object whose name shall be queried
94 * @return a `std::string`-compatible value holding the static name
95 */
96 inline std::convertible_to<std::string> auto getStaticName(concepts::StaticNameHandle auto const& handle)
97 {
98 return alpaka::internal::GetStaticName::Op<std::decay_t<decltype(*handle.get())>>{}(*handle.get());
99 }
100
101 /** Runtime name for a given object.
102 *
103 * @param any object whose name shall be queried
104 * @return a `std::string`-compatible value holding the name
105 */
106 inline std::convertible_to<std::string> auto getName(auto&& any)
107 {
109 }
110
111 /** Runtime name for a given handle.
112 *
113 * @param handle object whose name shall be queried
114 * @return a `std::string`-compatible value holding the name
115 */
116 inline std::convertible_to<std::string> auto getName(concepts::NameHandle auto const& handle)
117 {
118 return alpaka::internal::GetName::Op<std::decay_t<decltype(*handle.get())>>{}(*handle.get());
119 }
120
121 /** @} */
122
123 /** Get the native handle of an handle.
124 *
125 * The native handle can be passed to the underlying backend API
126 * (e.g. CUDA, HIP, OpenMP) for low-level operations.
127 *
128 * @param handle object exposing a native handle
129 * @return the native handle returned by the backend-specific implementation
130 */
131 inline auto getNativeHandle(auto const& handle)
132 {
133 return internal::getNativeHandle(*handle.get());
134 }
135
136 /** wait for all work to be finished
137 *
138 * Waits until all work submitted to any before this call has finished
139 *
140 * @param handle queue/device/event
141 */
142 inline void wait(alpaka::concepts::HasGet auto& handle)
143 {
144 return internal::wait(*handle.get());
145 }
146
147 /** @{
148 * @name Query raw pointer
149 */
150 /** pointer to data of an object
151 *
152 * For multi-dimensional data the data is not required to be continuous.
153 *
154 * @param any object providing data access (e.g. std::vector)
155 * @return raw pointer to the underlying data (equivalent to `std::data`)
156 */
157 inline decltype(auto) data(auto&& any)
158 {
160 }
161
162 /** pointer to data of an handle
163 *
164 * For multi-dimensional data the data is not required to be continuous.
165 *
166 * @param handle handle providing data access (e.g. view)
167 * @return raw pointer to the underlying data
168 */
169 inline decltype(auto) data(alpaka::concepts::HasGet auto&& handle)
170 {
171 return internal::Data::data(*handle.get());
172 }
173
174 /** @} */
175
176 /** @{
177 * @name Host allocations
178 */
179 /** Allocate host memory for a given element type and extents.
180 *
181 * The allocation is performed on the host controller device
182 * (`api::host` ans `deviceKind::cpu`).
183 * The returned view owns the allocated memory.
184 *
185 * @tparam T_ValueType type of the data elements
186 * @param extents number of elements per dimension (vector or scalar)
187 * @return a view owning the newly allocated memory
188 */
189 template<typename T_ValueType>
190 inline auto allocHost(alpaka::concepts::VectorOrScalar auto const& extents)
191 {
192 auto device = makeHostDevice<T_ValueType>();
193 Vec const extentsVec = extents;
194 return internal::Alloc::Op<T_ValueType, std::decay_t<decltype(*device.get())>, ALPAKA_TYPEOF(extentsVec)>{}(
195 *device.get(),
196 extentsVec);
197 }
198
199 /** Allocate host memory with the same value type and extents as an existing view.
200 *
201 * The content of the source view is **not** copied. The function deduces the
202 * element type and extents from `view` and creates a new shared buffer on the
203 * host controller device.
204 *
205 * @param view a view (e.g. `std::vector`, `std::array`, or any compatible type)
206 * @return a view owning the newly allocated memory
207 */
208 inline auto allocHostLike(auto const& view)
209 {
212 }
213
214 /** @} */
215
216 /** @{
217 * @name Device selection utilities
218 */
219 /** Resolve the list of executors supported for a device specification.
220 *
221 * This helper is used internally to build backend dictionaries.
222 *
223 * @param deviceSpec device specification to be used
224 * @param listOfExecutors tuple of executor types to be filtered
225 * @return a tuple containing the supported executor types
226 *
227 * @{
228 */
229 constexpr auto getExecutorsList(auto const deviceSpec, auto const listOfExecutors)
230 requires(ALPAKA_TYPEOF(deviceSpec)::isValid())
231 {
232 using DevSelectorType = decltype(makeDeviceSelector(deviceSpec));
233 using DeviceType = decltype(std::declval<DevSelectorType>().makeDevice(0));
234 using ExecutorListType = decltype(supportedExecutors(std::declval<DeviceType>(), listOfExecutors));
235 return ExecutorListType{};
236 }
237
238 constexpr auto getExecutorsList(auto const deviceSpec, auto const listOfExecutors)
239 {
240 alpaka::unused(deviceSpec, listOfExecutors);
241 return std::tuple<>{};
242 }
243
244 /**@} */
245
246 /** Create a tuple of device specifications for a single API.
247 *
248 * Each device specifications combines the supplied API with one of the supported
249 * device types for that API.
250 *
251 * @param api a single alpaka API (e.g. `api::cuda`, `api::hip`)
252 * @return a tuple containing all device specifications for the given API
253 */
254 constexpr auto getDeviceSpecsFor(auto const api)
255 {
256 return std::apply(
257 [api](auto... devType) constexpr { return std::make_tuple(DeviceSpec{api, devType}...); },
259 }
260
261 /** Create a flattened tuple of device specification objects for a list of APIs.
262 *
263 * @param apiList a `std::tuple` containing the APIs
264 * @return a tuple containing all device specifications for the given API
265 */
266 template<alpaka::concepts::Api... T_Apis>
267 constexpr auto getDeviceSpecsFor(std::tuple<T_Apis...> const apiList)
268 {
269 return std::apply([](auto... api) constexpr { return std::tuple_cat(getDeviceSpecsFor(api)...); }, apiList);
270 }
271
272 /** Build a tuple of backends for a single device specification.
273 *
274 * A backend is the combination of a device specification and an executor.
275 * Query its executor via `alpaka::getExecutor(backend)` and recover its device
276 * specification via `alpaka::onHost::DeviceSpec{backend}`.
277 *
278 * @param deviceSpec the device specification to associate with the executors
279 * @param listOfExecutors tuple of executor types
280 * @return a tuple of backend objects, one per executor
281 */
282 constexpr auto createBackendsFor(auto const deviceSpec, auto const listOfExecutors)
283 {
284 return std::apply(
285 [deviceSpec](auto... executor) constexpr
286 {
287 return std::make_tuple(
288 Dict{
289 DictEntry{object::api, getApi(deviceSpec)},
291 DictEntry{object::exec, executor}}...);
292 },
293 listOfExecutors);
294 }
295
296 /** Create the complete backend list for all device specifications and executors.
297 *
298 * @param devSpecList tuple of device specifications
299 * @param listOfExecutors tuple of executor types
300 * @return a tuple of backend objects, for all executors
301 */
302 constexpr auto createBackendList(auto const devSpecList, auto const listOfExecutors)
303 {
304 return std::apply(
305 [listOfExecutors](auto... devSpec) constexpr
306 { return std::tuple_cat(createBackendsFor(devSpec, getExecutorsList(devSpec, listOfExecutors))...); },
307 devSpecList);
308 }
309
310 /** Generate the full set of backend dictionaries for a set of APIs.
311 *
312 * The result contains a backend entry for each combination of supported device
313 * specification for the APIs and executors.
314 *
315 * @param usedApis tuple of alpaka APIs to consider
316 * @param listOfExecutors tuple of executor types
317 * @return a tuple of backend dictionaries covering all APIs and executors
318 */
319 template<alpaka::concepts::Api... T_Apis>
320 consteval auto allBackends(std::tuple<T_Apis...> const& usedApis, auto const listOfExecutors)
321 {
322 return std::apply(
323 [listOfExecutors](auto... api) constexpr
324 { return std::tuple_cat(createBackendList(getDeviceSpecsFor(api), listOfExecutors)...); },
325 usedApis);
326 }
327
328 /** Generate the full set of backend dictionaries for a set of device kinds.
329 *
330 * The result contains a backend entry for each combination of supported device
331 * specification and executors.
332 *
333 * @param usedDeviceSpecs tuple of alpaka device kinds
334 * @param listOfExecutors tuple of executor types
335 * @return a tuple of backend dictionaries covering all device kinds and executors
336 */
337 template<alpaka::concepts::DeviceSpec... T_DevicesSpecs>
338 consteval auto allBackends(std::tuple<T_DevicesSpecs...> const& usedDeviceSpecs, auto const& listOfExecutors)
339 {
340 return std::tuple_cat(createBackendList(usedDeviceSpecs, listOfExecutors));
341 }
342} // namespace alpaka::onHost
#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 APIs.
Definition api.hpp:42
Concept to check that a device specification with an API and device kind can be extracted.
Definition concepts.hpp:58
Concept to check if the given type has a get() function.
Definition concepts.hpp:26
Concept to check if a type is a vector or scalar variable.
Definition Vec.hpp:65
constexpr DeviceKind deviceKind
Definition tag.hpp:30
constexpr Api api
Definition tag.hpp:24
void wait(auto &&any)
auto getNativeHandle(auto &&any)
Definition interface.hpp:95
auto getExtents(auto &&any)
auto getPitches(auto &&any)
Functionality which is usable on the host CPU controller thread.
Definition api.hpp:40
auto allocHostLike(auto const &view)
Allocate host memory with the same value type and extents as an existing view.
auto getNativeHandle(auto const &handle)
Get the native handle of an handle.
constexpr auto supportedDevices(auto const api)
Definition trait.hpp:174
constexpr auto createBackendsFor(auto const deviceSpec, auto const listOfExecutors)
Build a tuple of backends for a single device specification.
constexpr auto createBackendList(auto const devSpecList, auto const listOfExecutors)
Create the complete backend list for all device specifications and executors.
decltype(auto) data(auto &&any)
pointer to data of an object
consteval auto allBackends(std::tuple< T_Apis... > const &usedApis, auto const listOfExecutors)
Generate the full set of backend dictionaries for a set of APIs.
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.
constexpr auto getDeviceSpecsFor(auto const api)
Create a tuple of device specifications for a single API.
constexpr auto getExecutorsList(auto const deviceSpec, auto const listOfExecutors)
Resolve the list of executors supported for a device specification.
void wait(alpaka::concepts::HasGet auto &handle)
wait for all work to be finished
std::convertible_to< std::string > auto getStaticName(auto const &any)
Compile-time available name for a given object.
Definition interface.hpp:86
auto makeDeviceSelector(T_DeviceSpec deviceSpec)
create an object to get access to devices
auto allocHost(alpaka::concepts::VectorOrScalar auto const &extents)
Allocate host memory for a given element type and extents.
auto alloc(concepts::Device auto const &device, alpaka::concepts::VectorOrScalar auto const &extents)
Allocate memory on the given device.
Definition Device.hpp:180
constexpr auto supportedExecutors(internal::concepts::DeviceHandle auto deviceHandle, auto const listOfExecutors)
Definition trait.hpp:155
decltype(auto) getPitches(auto &&any)
Object pitches.
Definition interface.hpp:55
typename GetValueType< T >::type GetValueType_t
Definition trait.hpp:65
constexpr decltype(auto) getDeviceKind(auto &&any)
Get the device type of an object.
Definition interface.hpp:78
constexpr decltype(auto) getApi(auto &&any)
Get the API an object depends on.
Definition interface.hpp:42
Concept for a combination of an API and device kind.
auto get() const
Definition Device.hpp:47
static decltype(auto) data(auto &&any)