alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
Traits.hpp
Go to the documentation of this file.
1/* Copyright 2026 Axel Hübl, Benjamin Worpitz, Matthias Werner, Andrea Bocci, Jan Stephan, Bernhard Manfred Gruber,
2 * Aurora Perego, Simone Balducci
3 * SPDX-License-Identifier: MPL-2.0
4 */
5
6#pragma once
7
10#include "alpaka/dev/Traits.hpp"
11#include "alpaka/dim/Traits.hpp"
14#include "alpaka/meta/Fold.hpp"
18#include "alpaka/vec/Traits.hpp"
19#include "alpaka/vec/Vec.hpp"
20
21#include <array>
22#include <cassert>
23#include <cstddef>
24#include <iosfwd>
25#include <type_traits>
26#include <vector>
27
28#ifdef ALPAKA_USE_MDSPAN
29# ifdef ALPAKA_HAS_STD_MDSPAN
30// mdspan from the standard library
31# include <mdspan>
32# include <version>
33
34namespace alpaka::experimental
35{
36 // Import C++23 mdspan into alpaka::experimental namespace.
37 // See https://wg21.link/P0009R18 .
38 using ::std::default_accessor;
39 using ::std::dextents;
40 using ::std::extents;
41 using ::std::layout_left;
42 using ::std::layout_right;
43 using ::std::layout_stride;
44 using ::std::mdspan;
45# ifdef __cpp_lib_submdspan
46 // Import C++26 submdspan into alpaka::experimental namespace.
47 // See https://wg21.link/P2630R4 .
48 using ::std::full_extent;
49 using ::std::submdspan;
50# endif
51} // namespace alpaka::experimental
52
53# else
54
55# ifdef ALPAKA_ACC_SYCL_ENABLED
56// do not expose the macro definition of printf
57# pragma push_macro("printf")
58# ifdef printf
59# undef printf
60# endif
61# endif // ALPAKA_ACC_SYCL_ENABLED
62
63# if defined(ALPAKA_ACC_SYCL_ENABLED) && (defined(ALPAKA_SYCL_ONEAPI_FPGA) || defined(ALPAKA_SYCL_TARGET_FPGA))
64// the fpga compiler does not handle well the [[no_unique_address]] attribute, resulting in:
65// GEP has !intel-tbaa annotation but its "shape" is unexpected!
66// /opt/intel/oneapi/compiler/2025.0/bin/compiler/llvm-link: error: linked module is broken!
67// icpx: error: sycl-link command failed with exit code 1 (use -v to see invocation)
68# include <experimental/__p0009_bits/config.hpp>
69# undef MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS
70# undef MDSPAN_IMPL_NO_UNIQUE_ADDRESS
71# define MDSPAN_IMPL_NO_UNIQUE_ADDRESS
72# endif
73
74// mdspan from the Kokkos reference implementation
75# define MDSPAN_IMPL_STANDARD_NAMESPACE alpaka::experimental
76# include <experimental/mdspan>
77
78# ifdef ALPAKA_ACC_SYCL_ENABLED
79// restore the macro definition of printf
80# pragma pop_macro("printf")
81# endif // ALPAKA_ACC_SYCL_ENABLED
82# endif
83#endif
84
85namespace alpaka
86{
87 namespace detail
88 {
89 //! Calculate the pitches purely from the extents.
90 template<typename TElem, typename TDim, typename TIdx>
92 {
93 Vec<TDim, TIdx> pitchBytes{};
94 constexpr auto dim = TIdx{TDim::value};
95 if constexpr(dim > 0)
96 pitchBytes.back() = static_cast<TIdx>(sizeof(TElem));
97 if constexpr(dim > 1)
98 for(TIdx i = TDim::value - 1; i > 0; i--)
99 pitchBytes[i - 1] = extent[i] * pitchBytes[i];
100#if ALPAKA_COMP_CLANG >= ALPAKA_VERSION_NUMBER(21, 0, 0)
101# pragma clang diagnostic push
102# pragma clang diagnostic ignored "-Wnrvo"
103#endif
104 return pitchBytes;
105#if ALPAKA_COMP_CLANG >= ALPAKA_VERSION_NUMBER(21, 0, 0)
106# pragma clang diagnostic pop
107#endif
108 }
109
110 //! Calculate the pitches from the extents and the one-dimensional pitch.
111 template<typename TElem, typename TDim, typename TIdx>
113 Vec<TDim, TIdx> const& extent,
114 std::size_t pitch)
115 {
116 Vec<TDim, TIdx> pitchBytes{};
117 constexpr auto dim = TIdx{TDim::value};
118 if constexpr(dim > 0)
119 pitchBytes.back() = static_cast<TIdx>(sizeof(TElem));
120 if constexpr(dim > 1)
121 {
122 if(pitch == 0)
123 pitchBytes[TDim::value - 2] = extent.back() * pitchBytes.back();
124 else
125 pitchBytes[TDim::value - 2] = static_cast<TIdx>(
126 (static_cast<std::size_t>(extent.back() * pitchBytes.back()) + pitch - 1) / pitch * pitch);
127 }
128 if constexpr(dim > 2)
129 for(TIdx i = TDim::value - 2; i > 0; i--)
130 pitchBytes[i - 1] = extent[i] * pitchBytes[i];
131#if ALPAKA_COMP_CLANG >= ALPAKA_VERSION_NUMBER(21, 0, 0)
132# pragma clang diagnostic push
133# pragma clang diagnostic ignored "-Wnrvo"
134#endif
135 return pitchBytes;
136#if ALPAKA_COMP_CLANG >= ALPAKA_VERSION_NUMBER(21, 0, 0)
137# pragma clang diagnostic pop
138#endif
139 }
140
141 } // namespace detail
142
143 //! The view traits.
144 namespace trait
145 {
146 //! The native pointer get trait.
147 template<typename TView, typename TSfinae = void>
149
150 //! The pointer on device get trait.
151 template<typename TView, typename TDev, typename TSfinae = void>
152 struct GetPtrDev;
153
154 //! The pitch in bytes.
155 //! This is the distance in bytes in the linear memory between two consecutive elements in the next higher
156 //! dimension (TIdx-1).
157 //!
158 //! The default implementation uses the extent to calculate the pitch.
159 template<typename TIdx, typename TView, typename TSfinae = void>
160 struct [[deprecated("Use GetPitchesInBytes instead")]] GetPitchBytes
161 {
163
164 ALPAKA_FN_HOST static auto getPitchBytes(TView const& view) -> ViewIdx
165 {
166 return getPitchBytesDefault(view);
167 }
168
169 private:
170 static auto getPitchBytesDefault(TView const& view) -> ViewIdx
171 {
172 constexpr auto idx = TIdx::value;
173 constexpr auto viewDim = Dim<TView>::value;
174 if constexpr(idx < viewDim - 1)
175 {
176#if ALPAKA_COMP_CLANG || ALPAKA_COMP_GNUC
177# pragma GCC diagnostic push
178# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
179#endif
180 return getExtents(view)[idx] * GetPitchBytes<DimInt<idx + 1>, TView>::getPitchBytes(view);
181#if ALPAKA_COMP_CLANG || ALPAKA_COMP_GNUC
182# pragma GCC diagnostic pop
183#endif
184 }
185 else if constexpr(idx == viewDim - 1)
186 return getExtents(view)[viewDim - 1] * static_cast<ViewIdx>(sizeof(Elem<TView>));
187 else
188 return static_cast<ViewIdx>(sizeof(Elem<TView>));
190 }
191 };
192
193 //! Customization point for \ref getPitchesInBytes.
194 //! The default implementation uses the extent to calculate the pitches.
195 template<typename TView, typename TSfinae = void>
197 {
198 ALPAKA_FN_HOST_ACC constexpr auto operator()(TView const& view) const
199 {
200 return alpaka::detail::calculatePitchesFromExtents<Elem<TView>>(getExtents(view));
201 }
202 };
203
204 //! The memory set task trait.
205 //!
206 //! Fills the view with data.
207 template<typename TDim, typename TDev, typename TSfinae = void>
209
210 template<typename TDim, typename TDev, typename TSfinae = void>
212
213 //! The memory copy task trait.
214 //!
215 //! Copies memory from one view into another view possibly on a different device.
216 template<typename TDim, typename TDevDst, typename TDevSrc, typename TSfinae = void>
218
219 //! The device memory view creation trait.
220 template<typename TDev, typename TSfinae = void>
222
223 //! The sub view creation trait.
224 template<typename TDev, typename TSfinae = void>
225 struct CreateSubView;
226 } // namespace trait
227
228 //! Gets the native pointer of the memory view.
229 //!
230 //! \param view The memory view.
231 //! \return The native pointer.
232 template<typename TView>
233 ALPAKA_FN_HOST auto getPtrNative(TView const& view) -> Elem<TView> const*
234 {
236 }
237
238 //! Gets the native pointer of the memory view.
239 //!
240 //! \param view The memory view.
241 //! \return The native pointer.
242 template<typename TView>
244 {
246 }
247
248 //! Gets the pointer to the view on the given device.
249 //!
250 //! \param view The memory view.
251 //! \param dev The device.
252 //! \return The pointer on the device.
253 template<typename TView, typename TDev>
254 ALPAKA_FN_HOST auto getPtrDev(TView const& view, TDev const& dev) -> Elem<TView> const*
255 {
257 }
258
259 //! Gets the pointer to the view on the given device.
260 //!
261 //! \param view The memory view.
262 //! \param dev The device.
263 //! \return The pointer on the device.
264 template<typename TView, typename TDev>
265 ALPAKA_FN_HOST auto getPtrDev(TView& view, TDev const& dev) -> Elem<TView>*
266 {
268 }
269
270 //! \return The pitch in bytes. This is the distance in bytes between two consecutive elements in the given
271 //! dimension.
272 template<std::size_t Tidx, typename TView>
273 [[deprecated("Use getPitchesInBytes instead")]] ALPAKA_FN_HOST auto getPitchBytes(TView const& view) -> Idx<TView>
274 {
275#if ALPAKA_COMP_CLANG || ALPAKA_COMP_GNUC
276# pragma GCC diagnostic push
277# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
278#endif
280#if ALPAKA_COMP_CLANG || ALPAKA_COMP_GNUC
281# pragma GCC diagnostic pop
282#endif
283 }
284
285 //! \return The pitches in bytes as an alpaka::Vec. This is the distance in bytes between two consecutive elements
286 //! in the given dimension.
287 //! E.g. for a 3D view without padding, the 0-dim pitch is the distance in bytes to jump from one element to the
288 //! next within the same row, the 1-dim pitch (aka. the row pitch) is the distance in bytes to jump from one
289 //! element to the neighboring element on the next row. The 2-dim pitch (aka. the slice pitch) is the distance in
290 //! bytes to jump from one element to the neighboring element on the next slice.
291 //! E.g. a 3D view of floats without padding and the extents {42, 10, 2}, would have a pitch vector of {80, 8, 4}.
292 template<typename TView>
294 {
295 return trait::GetPitchesInBytes<TView>{}(view);
296 }
297
298 //! Create a memory set task.
299 //!
300 //! \param view The memory view to fill.
301 //! \param byte Value to set for each element of the specified view.
302 //! \param extent The extent of the view to fill.
303 template<typename TExtent, typename TViewFwd>
304 ALPAKA_FN_HOST auto createTaskMemset(TViewFwd&& view, std::uint8_t const& byte, TExtent const& extent)
305 {
306 using TView = std::remove_reference_t<TViewFwd>;
307 static_assert(!std::is_const_v<TView>, "The view must not be const!");
308 static_assert(
310 "The view and the extent are required to have the same dimensionality!");
311
312 assert((extent <= getExtents(view)).all() && "The memset extent must not be larger than the view's extent!");
313
315 std::forward<TViewFwd>(view),
316 byte,
317 extent);
318 }
319
320 template<typename TExtent, typename TViewFwd, typename TValue>
321 ALPAKA_FN_HOST auto createTaskFill(TViewFwd&& view, TValue const& value, TExtent const& extent)
322 {
323 using TView = std::remove_reference_t<TViewFwd>;
324 static_assert(!std::is_const_v<TView>, "The view must not be const!");
325 static_assert(
327 "The view and the extent are required to have the same dimensionality!");
328
329 assert((extent <= getExtents(view)).all() && "The fill extent must not be larger than the view's extent!");
330
332 std::forward<TViewFwd>(view),
333 value,
334 extent);
335 }
336
337 //! Sets the bytes of the memory of view, described by extent, to the given value.
338 //!
339 //! \param queue The queue to enqueue the view fill task into.
340 //! \param[in,out] view The memory view to fill. May be a temporary object.
341 //! \param byte Value to set for each element of the specified view.
342 //! \param extent The extent of the view to fill.
343 template<typename TExtent, typename TViewFwd, typename TQueue>
344 ALPAKA_FN_HOST auto memset(TQueue& queue, TViewFwd&& view, std::uint8_t const& byte, TExtent const& extent) -> void
345 {
346 enqueue(queue, createTaskMemset(std::forward<TViewFwd>(view), byte, extent));
347 }
348
349 //! Sets each byte of the memory of the entire view to the given value.
350 //!
351 //! \param queue The queue to enqueue the view fill task into.
352 //! \param[in,out] view The memory view to fill. May be a temporary object.
353 //! \param byte Value to set for each element of the specified view.
354 template<typename TViewFwd, typename TQueue>
355 ALPAKA_FN_HOST auto memset(TQueue& queue, TViewFwd&& view, std::uint8_t const& byte) -> void
356 {
357 enqueue(queue, createTaskMemset(std::forward<TViewFwd>(view), byte, getExtents(view)));
358 }
359
360 template<typename TViewFwd, typename TValue, typename TQueue>
361 ALPAKA_FN_HOST auto fill(TQueue& queue, TViewFwd&& view, TValue const& value) -> void
362 {
363 enqueue(queue, createTaskFill(std::forward<TViewFwd>(view), value, getExtents(view)));
364 }
365
366 template<typename TExtent, typename TViewFwd, typename TValue, typename TQueue>
367 ALPAKA_FN_HOST auto fill(TQueue& queue, TViewFwd&& view, TValue const& value, TExtent const& extent) -> void
368 {
369 enqueue(queue, createTaskFill(std::forward<TViewFwd>(view), value, extent));
370 }
371
372 //! Creates a memory copy task.
373 //!
374 //! \param viewDst The destination memory view.
375 //! \param viewSrc The source memory view.
376 //! \param extent The extent of the view to copy.
377 template<typename TExtent, typename TViewSrc, typename TViewDstFwd>
378 ALPAKA_FN_HOST auto createTaskMemcpy(TViewDstFwd&& viewDst, TViewSrc const& viewSrc, TExtent const& extent)
379 {
380 using TViewDst = std::remove_reference_t<TViewDstFwd>;
381 using SrcElem = Elem<TViewSrc>;
382 using DstElem = Elem<TViewDst>;
383
384 static_assert(!std::is_const_v<TViewDst>, "The destination view must not be const!");
385 static_assert(!std::is_const_v<DstElem>, "The destination view's element type must not be const!");
386 static_assert(
388 "The source and the destination view must have the same dimensionality!");
389 static_assert(
391 "The destination view and the extent must have the same dimensionality!");
392 static_assert(
393 std::is_same_v<DstElem, std::remove_const_t<SrcElem>>,
394 "The source and destination view must have the same element type!");
395
396 assert(
397 (extent <= getExtents(viewSrc)).all()
398 && "The memcpy extent must not be larger than the source view's extent!");
399 assert(
400 (extent <= getExtents(viewDst)).all()
401 && "The memcpy extent must not be larger than the destination view's extent!");
402
404 std::forward<TViewDstFwd>(viewDst),
405 viewSrc,
406 extent);
407 }
408
409 //! Copies memory from a part of viewSrc to viewDst, described by extent. Possibly copies between different memory
410 //! spaces.
411 //!
412 //! \param queue The queue to enqueue the view copy task into.
413 //! \param[in,out] viewDst The destination memory view. May be a temporary object.
414 //! \param viewSrc The source memory view. May be a temporary object.
415 //! \param extent The extent of the view to copy.
416 template<typename TExtent, typename TViewSrc, typename TViewDstFwd, typename TQueue>
417 ALPAKA_FN_HOST auto memcpy(TQueue& queue, TViewDstFwd&& viewDst, TViewSrc const& viewSrc, TExtent const& extent)
418 -> void
419 {
420 enqueue(queue, createTaskMemcpy(std::forward<TViewDstFwd>(viewDst), viewSrc, extent));
421 }
422
423 //! Copies the entire memory of viewSrc to viewDst. Possibly copies between different memory
424 //! spaces.
425 //!
426 //! \param queue The queue to enqueue the view copy task into.
427 //! \param[in,out] viewDst The destination memory view. May be a temporary object.
428 //! \param viewSrc The source memory view. May be a temporary object.
429 template<typename TViewSrc, typename TViewDstFwd, typename TQueue>
430 ALPAKA_FN_HOST auto memcpy(TQueue& queue, TViewDstFwd&& viewDst, TViewSrc const& viewSrc) -> void
431 {
432 enqueue(queue, createTaskMemcpy(std::forward<TViewDstFwd>(viewDst), viewSrc, getExtents(viewSrc)));
433 }
434
435 namespace concepts
436 {
437 template<typename T>
438 concept DeviceProvider = alpaka::isDevice<T> || alpaka::isQueue<T>;
439 } // namespace concepts
440
441 namespace detail
442 {
443 template<typename TDim, typename TView>
444 struct Print
445 {
447 TView const& view,
448 Elem<TView> const* const ptr,
449 Vec<Dim<TView>, Idx<TView>> const& extent,
450 std::ostream& os,
451 std::string const& elementSeparator,
452 std::string const& rowSeparator,
453 std::string const& rowPrefix,
454 std::string const& rowSuffix) -> void
455 {
456 os << rowPrefix;
457
458 auto const pitch = getPitchesInBytes(view)[TDim::value + 1];
459 auto const lastIdx(extent[TDim::value] - 1u);
460 for(auto i(decltype(lastIdx)(0)); i <= lastIdx; ++i)
461 {
463 view,
464 reinterpret_cast<Elem<TView> const*>(reinterpret_cast<std::uint8_t const*>(ptr) + i * pitch),
465 extent,
466 os,
467 elementSeparator,
468 rowSeparator,
469 rowPrefix,
470 rowSuffix);
471
472 // While we are not at the end of a row, add the row separator.
473 if(i != lastIdx)
474 {
475 os << rowSeparator;
476 }
477 }
478
479 os << rowSuffix;
480 }
481 };
482
483 template<typename TView>
484 struct Print<DimInt<Dim<TView>::value - 1u>, TView>
485 {
487 TView const& /* view */,
488 Elem<TView> const* const ptr,
489 Vec<Dim<TView>, Idx<TView>> const& extent,
490 std::ostream& os,
491 std::string const& elementSeparator,
492 std::string const& /* rowSeparator */,
493 std::string const& rowPrefix,
494 std::string const& rowSuffix) -> void
495 {
496 os << rowPrefix;
497
498 auto const lastIdx(extent[Dim<TView>::value - 1u] - 1u);
499 for(auto i(decltype(lastIdx)(0)); i <= lastIdx; ++i)
500 {
501 // Add the current element.
502 os << *(ptr + i);
503
504 // While we are not at the end of a line, add the element separator.
505 if(i != lastIdx)
506 {
507 os << elementSeparator;
508 }
509 }
510
511 os << rowSuffix;
512 }
513 };
514
515 template<typename TDeviceProvider>
516 auto getDeviceFromProvider(TDeviceProvider const& provider)
517 {
518 if constexpr(alpaka::isDevice<TDeviceProvider>)
519 {
520 return provider;
521 }
522 else
523 {
524 return alpaka::getDev(provider);
525 }
526 }
527
528 } // namespace detail
529
530 //! Prints the content of the view to the given queue.
531 // \TODO: Add precision flag.
532 // \TODO: Add column alignment flag.
533 template<typename TView>
535 TView const& view,
536 std::ostream& os,
537 std::string const& elementSeparator = ", ",
538 std::string const& rowSeparator = "\n",
539 std::string const& rowPrefix = "[",
540 std::string const& rowSuffix = "]") -> void
541 {
543 view,
544 getPtrNative(view),
545 getExtents(view),
546 os,
547 elementSeparator,
548 rowSeparator,
549 rowPrefix,
550 rowSuffix);
551 }
552
553 //! \return The pitch vector.
554 template<typename TView>
555 [[deprecated("Use getPitchesInBytes instead")]] auto getPitchBytesVec(TView const& view)
557 {
558 return getPitchesInBytes(view);
559 }
560
561 //! \return The pitch but only the last N elements.
562 template<typename TDim, typename TView>
563 ALPAKA_FN_HOST auto getPitchBytesVecEnd(TView const& view = TView()) -> Vec<TDim, Idx<TView>>
564 {
565 return subVecEnd<TDim>(getPitchesInBytes(view));
566 }
567
568 //! Creates a view to a device pointer
569 //!
570 //! \param dev Object from which the device can be obtained.
571 //! \param pMem Pointer to memory. The pointer must be accessible from the given device.
572 //! \param extent Number of elements represented by the pMem.
573 //! Using a multi dimensional extent will result in a multi dimension view to the memory represented
574 //! by pMem.
575 //! \return A view to device memory.
576 template<concepts::DeviceProvider TDev, typename TElem, typename TExtent>
577 auto createView(TDev const& dev, TElem* pMem, TExtent const& extent)
578 {
581 auto const extentVec = Vec<Dim, Idx>(extent);
582 auto device = detail::getDeviceFromProvider(dev);
583 return trait::CreateViewPlainPtr<decltype(device)>::createViewPlainPtr(
584 device,
585 pMem,
586 extentVec,
587 detail::calculatePitchesFromExtents<TElem>(extentVec));
588 }
589
590 //! Creates a view to a device pointer
591 //!
592 //! \param dev Object from which the device can be obtained.
593 //! \param pMem Pointer to memory. The pointer must be accessible from the given device.
594 //! \param extent Number of elements represented by the pMem.
595 //! Using a multi dimensional extent will result in a multi dimension view to the memory represented
596 //! by pMem.
597 //! \param pitch Pitch in bytes for each dimension. Dimensionality must be equal to extent.
598 //! \return A view to device memory.
599 template<concepts::DeviceProvider TDev, typename TElem, typename TExtent, typename TPitch>
600 auto createView(TDev const& dev, TElem* pMem, TExtent const& extent, TPitch pitch)
601 {
602 auto device = detail::getDeviceFromProvider(dev);
603 return trait::CreateViewPlainPtr<decltype(device)>::createViewPlainPtr(device, pMem, extent, pitch);
604 }
605
606 //! Creates a view to a contiguous container of device-accessible memory.
607 //!
608 //! \param dev Object from which the device can be obtained.
609 //! \param con Contiguous container. The container must provide a `data()` method. The data held by the container
610 //! must be accessible from the given device. The `GetExtent` trait must be defined for the container.
611 //! \return A view to device memory.
612 template<concepts::DeviceProvider TDev, typename TContainer>
613 auto createView(TDev const& dev, TContainer& con)
614 {
615 auto const device = detail::getDeviceFromProvider(dev);
616 return createView(device, std::data(con), getExtents(con));
617 }
618
619 //! Creates a view to a contiguous container of device-accessible memory.
620 //!
621 //! \param dev Object from which the device can be obtained.
622 //! \param con Contiguous container. The container must provide a `data()` method. The data held by the container
623 //! must be accessible from the given device. The `GetExtent` trait must be defined for the container.
624 //! \param extent Number of elements held by the container. Using a multi-dimensional extent will result in a
625 //! multi-dimensional view to the memory represented by the container.
626 //! \return A view to device memory.
627 template<concepts::DeviceProvider TDev, typename TContainer, typename TExtent>
628 auto createView(TDev const& dev, TContainer& con, TExtent const& extent)
629 {
630 auto const device = detail::getDeviceFromProvider(dev);
631 return createView(device, std::data(con), extent);
632 }
633
634 //! Creates a sub view to an existing view.
635 //!
636 //! \param view The view this view is a sub-view of.
637 //! \param extent Number of elements the resulting view holds.
638 //! \param offset Number of elements skipped in view for the new origin of the resulting view.
639 //! \return A sub view to a existing view.
640 template<typename TView, typename TExtent, typename TOffsets>
641 auto createSubView(TView& view, TExtent const& extent, TOffsets const& offset = TExtent())
642 {
644 }
645
646#ifdef ALPAKA_USE_MDSPAN
647 namespace experimental
648 {
649 namespace traits
650 {
651 namespace detail
652 {
653 template<typename ElementType>
654 struct ByteIndexedAccessor
655 {
656 using offset_policy = ByteIndexedAccessor;
657 using element_type = ElementType;
658 using reference = ElementType&;
659
660 using data_handle_type
661 = std::conditional_t<std::is_const_v<ElementType>, std::byte const*, std::byte*>;
662
663 constexpr ByteIndexedAccessor() noexcept = default;
664
665 ALPAKA_FN_HOST_ACC constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept
666 {
667 return p + i;
668 }
669
670 ALPAKA_FN_HOST_ACC constexpr reference access(data_handle_type p, size_t i) const noexcept
671 {
672 assert(i % alignof(ElementType) == 0);
673 return *reinterpret_cast<ElementType*>(__builtin_assume_aligned(p + i, alignof(ElementType)));
674 }
675 };
676
677 template<typename TView, std::size_t... Is>
678 ALPAKA_FN_HOST auto makeExtents(TView const& view, std::index_sequence<Is...>)
679 {
680 auto const ex = getExtents(view);
681 return dextents<Idx<TView>, Dim<TView>::value>{ex[Is]...};
682 }
683 } // namespace detail
684
685 //! Customization point for getting an mdspan from a view.
686 template<typename TView, typename TSfinae = void>
687 struct GetMdSpan
688 {
689 ALPAKA_FN_HOST static auto getMdSpan(TView& view)
690 {
691 constexpr auto dim = Dim<TView>::value;
692 using Element = Elem<TView>;
693 auto extents = detail::makeExtents(view, std::make_index_sequence<dim>{});
694 auto* ptr = reinterpret_cast<std::byte*>(getPtrNative(view));
695 auto const strides = toArray(getPitchesInBytes(view));
696 layout_stride::mapping<decltype(extents)> m{extents, strides};
697 return mdspan<Element, decltype(extents), layout_stride, detail::ByteIndexedAccessor<Element>>{
698 ptr,
699 m};
700 }
701
702 ALPAKA_FN_HOST static auto getMdSpanTransposed(TView& view)
703 {
704 constexpr auto dim = Dim<TView>::value;
705 using Element = Elem<TView>;
706 auto extents = detail::makeExtents(view, std::make_index_sequence<dim>{});
707 auto* ptr = reinterpret_cast<std::byte*>(getPtrNative(view));
708 auto strides = toArray(getPitchesInBytes(view));
709 std::reverse(begin(strides), end(strides));
710 layout_stride::mapping<decltype(extents)> m{extents, strides};
711 return mdspan<Element, decltype(extents), layout_stride, detail::ByteIndexedAccessor<Element>>{
712 ptr,
713 m};
714 }
715 };
716 } // namespace traits
717
718 //! Gets a std::mdspan from the given view. The memory layout is determined by the pitches of the view.
719 template<typename TView>
720 ALPAKA_FN_HOST auto getMdSpan(TView& view)
721 {
722 return traits::GetMdSpan<TView>::getMdSpan(view);
723 }
724
725 //! Gets a std::mdspan from the given view. The memory layout is determined by the reversed pitches of the
726 //! view. This effectively also reverses the extents of the view. In order words, if you create a transposed
727 //! mdspan on a 10x5 element view, the mdspan will have an iteration space of 5x10.
728 template<typename TView>
729 ALPAKA_FN_HOST auto getMdSpanTransposed(TView& view)
730 {
731 return traits::GetMdSpan<TView>::getMdSpanTransposed(view);
732 }
733
734 template<typename TElem, typename TIdx, typename TDim>
735 using MdSpan = alpaka::experimental::mdspan<
736 TElem,
737 alpaka::experimental::dextents<TIdx, TDim::value>,
738 alpaka::experimental::layout_stride,
739 alpaka::experimental::traits::detail::ByteIndexedAccessor<TElem>>;
740 } // namespace experimental
741#endif
742} // namespace alpaka
#define ALPAKA_UNREACHABLE(...)
Before CUDA 11.5 nvcc is unable to correctly identify return statements in 'if constexpr' branches....
A n-dimensional vector.
Definition Vec.hpp:38
ALPAKA_FN_HOST_ACC constexpr auto back() -> TVal &
Definition Vec.hpp:141
#define ALPAKA_FN_HOST
Definition Common.hpp:43
#define ALPAKA_FN_HOST_ACC
Definition Common.hpp:42
auto getDeviceFromProvider(TDeviceProvider const &provider)
Definition Traits.hpp:516
ALPAKA_FN_HOST_ACC constexpr auto calculatePitchesFromExtents(Vec< TDim, TIdx > const &extent)
Calculate the pitches purely from the extents.
Definition Traits.hpp:91
ALPAKA_FN_HOST_ACC constexpr auto calculatePitchesFromExtentsAndPitch(Vec< TDim, TIdx > const &extent, std::size_t pitch)
Calculate the pitches from the extents and the one-dimensional pitch.
Definition Traits.hpp:112
ALPAKA_FN_HOST auto end(TView &view) -> Iterator< TView >
Definition Iterator.hpp:133
ALPAKA_FN_HOST auto begin(TView &view) -> Iterator< TView >
Definition Iterator.hpp:127
The alpaka accelerator library.
typename trait::IdxType< T >::type Idx
Definition Traits.hpp:29
ALPAKA_FN_HOST auto memcpy(TQueue &queue, alpaka::detail::DevGlobalImplGeneric< TTag, TTypeDst > &viewDst, TViewSrc const &viewSrc) -> void
ALPAKA_FN_HOST auto getPitchBytesVecEnd(TView const &view=TView()) -> Vec< TDim, Idx< TView > >
Definition Traits.hpp:563
ALPAKA_FN_HOST_ACC constexpr auto toArray(Vec< TDim, TVal > const &v) -> std::array< TVal, TDim::value >
Converts a Vec to a std::array.
Definition Vec.hpp:536
ALPAKA_FN_HOST auto getPitchesInBytes(TView const &view) -> Vec< Dim< TView >, Idx< TView > >
Definition Traits.hpp:293
auto getPitchBytesVec(TView const &view) -> Vec< Dim< TView >, Idx< TView > >
Definition Traits.hpp:555
ALPAKA_FN_HOST auto createTaskMemcpy(TViewDstFwd &&viewDst, TViewSrc const &viewSrc, TExtent const &extent)
Creates a memory copy task.
Definition Traits.hpp:378
typename trait::DevType< T >::type Dev
The device type trait alias template to remove the ::type.
Definition Traits.hpp:56
auto createSubView(TView &view, TExtent const &extent, TOffsets const &offset=TExtent())
Creates a sub view to an existing view.
Definition Traits.hpp:641
ALPAKA_FN_HOST auto createTaskFill(TViewFwd &&view, TValue const &value, TExtent const &extent)
Definition Traits.hpp:321
ALPAKA_FN_HOST auto print(TView const &view, std::ostream &os, std::string const &elementSeparator=", ", std::string const &rowSeparator="\n", std::string const &rowPrefix="[", std::string const &rowSuffix="]") -> void
Prints the content of the view to the given queue.
Definition Traits.hpp:534
ALPAKA_FN_HOST auto getPtrNative(TView const &view) -> Elem< TView > const *
Gets the native pointer of the memory view.
Definition Traits.hpp:233
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
ALPAKA_FN_HOST auto memset(TQueue &queue, TViewFwd &&view, std::uint8_t const &byte, TExtent const &extent) -> void
Sets the bytes of the memory of view, described by extent, to the given value.
Definition Traits.hpp:344
ALPAKA_FN_HOST auto fill(TQueue &queue, TViewFwd &&view, TValue const &value) -> void
Definition Traits.hpp:361
ALPAKA_FN_HOST auto getDev(T const &t)
Definition Traits.hpp:68
ALPAKA_FN_HOST auto enqueue(TQueue &queue, TTask &&task) -> void
Queues the given task in the given queue.
Definition Traits.hpp:47
ALPAKA_FN_HOST auto getPtrDev(TView const &view, TDev const &dev) -> Elem< TView > const *
Gets the pointer to the view on the given device.
Definition Traits.hpp:254
std::integral_constant< std::size_t, N > DimInt
ALPAKA_FN_HOST auto createTaskMemset(TViewFwd &&view, std::uint8_t const &byte, TExtent const &extent)
Create a memory set task.
Definition Traits.hpp:304
ALPAKA_FN_HOST auto getPitchBytes(TView const &view) -> Idx< TView >
Definition Traits.hpp:273
auto createView(TDev const &dev, TElem *pMem, TExtent const &extent)
Creates a view to a device pointer.
Definition Traits.hpp:577
typename trait::DimType< T >::type Dim
The dimension type trait alias template to remove the ::type.
Definition Traits.hpp:19
static ALPAKA_FN_HOST auto print(TView const &, Elem< TView > const *const ptr, Vec< Dim< TView >, Idx< TView > > const &extent, std::ostream &os, std::string const &elementSeparator, std::string const &, std::string const &rowPrefix, std::string const &rowSuffix) -> void
Definition Traits.hpp:486
static ALPAKA_FN_HOST auto print(TView const &view, Elem< TView > const *const ptr, Vec< Dim< TView >, Idx< TView > > const &extent, std::ostream &os, std::string const &elementSeparator, std::string const &rowSeparator, std::string const &rowPrefix, std::string const &rowSuffix) -> void
Definition Traits.hpp:446
The sub view creation trait.
The memory copy task trait.
Definition Traits.hpp:217
The memory set task trait.
Definition Traits.hpp:208
The device memory view creation trait.
Definition Traits.hpp:221
The pitch in bytes. This is the distance in bytes in the linear memory between two consecutive elemen...
Definition Traits.hpp:161
static ALPAKA_FN_HOST auto getPitchBytes(TView const &view) -> ViewIdx
Definition Traits.hpp:164
Customization point for getPitchesInBytes. The default implementation uses the extent to calculate th...
Definition Traits.hpp:197
ALPAKA_FN_HOST_ACC constexpr auto operator()(TView const &view) const
Definition Traits.hpp:198
The pointer on device get trait.
Definition Traits.hpp:152
The native pointer get trait.
Definition Traits.hpp:148