alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
Traits.hpp
Go to the documentation of this file.
1/* Copyright 2024 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 return pitchBytes;
101 }
102
103 //! Calculate the pitches from the extents and the one-dimensional pitch.
104 template<typename TElem, typename TDim, typename TIdx>
106 Vec<TDim, TIdx> const& extent,
107 std::size_t pitch)
108 {
109 Vec<TDim, TIdx> pitchBytes{};
110 constexpr auto dim = TIdx{TDim::value};
111 if constexpr(dim > 0)
112 pitchBytes.back() = static_cast<TIdx>(sizeof(TElem));
113 if constexpr(dim > 1)
114 {
115 if(pitch == 0)
116 pitchBytes[TDim::value - 2] = extent.back() * pitchBytes.back();
117 else
118 pitchBytes[TDim::value - 2] = static_cast<TIdx>(
119 (static_cast<std::size_t>(extent.back() * pitchBytes.back()) + pitch - 1) / pitch * pitch);
120 }
121 if constexpr(dim > 2)
122 for(TIdx i = TDim::value - 2; i > 0; i--)
123 pitchBytes[i - 1] = extent[i] * pitchBytes[i];
124 return pitchBytes;
125 }
126
127 } // namespace detail
128
129 //! The view traits.
130 namespace trait
131 {
132 //! The native pointer get trait.
133 template<typename TView, typename TSfinae = void>
135
136 //! The pointer on device get trait.
137 template<typename TView, typename TDev, typename TSfinae = void>
138 struct GetPtrDev;
139
140 //! The pitch in bytes.
141 //! This is the distance in bytes in the linear memory between two consecutive elements in the next higher
142 //! dimension (TIdx-1).
143 //!
144 //! The default implementation uses the extent to calculate the pitch.
145 template<typename TIdx, typename TView, typename TSfinae = void>
146 struct [[deprecated("Use GetPitchesInBytes instead")]] GetPitchBytes
147 {
149
150 ALPAKA_FN_HOST static auto getPitchBytes(TView const& view) -> ViewIdx
151 {
152 return getPitchBytesDefault(view);
153 }
154
155 private:
156 static auto getPitchBytesDefault(TView const& view) -> ViewIdx
157 {
158 constexpr auto idx = TIdx::value;
159 constexpr auto viewDim = Dim<TView>::value;
160 if constexpr(idx < viewDim - 1)
161 {
162#if ALPAKA_COMP_CLANG || ALPAKA_COMP_GNUC
163# pragma GCC diagnostic push
164# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
165#endif
166 return getExtents(view)[idx] * GetPitchBytes<DimInt<idx + 1>, TView>::getPitchBytes(view);
167#if ALPAKA_COMP_CLANG || ALPAKA_COMP_GNUC
168# pragma GCC diagnostic pop
169#endif
170 }
171 else if constexpr(idx == viewDim - 1)
172 return getExtents(view)[viewDim - 1] * static_cast<ViewIdx>(sizeof(Elem<TView>));
173 else
174 return static_cast<ViewIdx>(sizeof(Elem<TView>));
176 }
177 };
178
179 //! Customization point for \ref getPitchesInBytes.
180 //! The default implementation uses the extent to calculate the pitches.
181 template<typename TView, typename TSfinae = void>
183 {
184 ALPAKA_FN_HOST_ACC constexpr auto operator()(TView const& view) const
185 {
186 return alpaka::detail::calculatePitchesFromExtents<Elem<TView>>(getExtents(view));
187 }
188 };
189
190 //! The memory set task trait.
191 //!
192 //! Fills the view with data.
193 template<typename TDim, typename TDev, typename TSfinae = void>
195
196 template<typename TDim, typename TDev, typename TSfinae = void>
198
199 //! The memory copy task trait.
200 //!
201 //! Copies memory from one view into another view possibly on a different device.
202 template<typename TDim, typename TDevDst, typename TDevSrc, typename TSfinae = void>
204
205 //! The device memory view creation trait.
206 template<typename TDev, typename TSfinae = void>
208
209 //! The sub view creation trait.
210 template<typename TDev, typename TSfinae = void>
211 struct CreateSubView;
212 } // namespace trait
213
214 //! Gets the native pointer of the memory view.
215 //!
216 //! \param view The memory view.
217 //! \return The native pointer.
218 template<typename TView>
219 ALPAKA_FN_HOST auto getPtrNative(TView const& view) -> Elem<TView> const*
220 {
222 }
223
224 //! Gets the native pointer of the memory view.
225 //!
226 //! \param view The memory view.
227 //! \return The native pointer.
228 template<typename TView>
230 {
232 }
233
234 //! Gets the pointer to the view on the given device.
235 //!
236 //! \param view The memory view.
237 //! \param dev The device.
238 //! \return The pointer on the device.
239 template<typename TView, typename TDev>
240 ALPAKA_FN_HOST auto getPtrDev(TView const& view, TDev const& dev) -> Elem<TView> const*
241 {
243 }
244
245 //! Gets the pointer to the view on the given device.
246 //!
247 //! \param view The memory view.
248 //! \param dev The device.
249 //! \return The pointer on the device.
250 template<typename TView, typename TDev>
251 ALPAKA_FN_HOST auto getPtrDev(TView& view, TDev const& dev) -> Elem<TView>*
252 {
254 }
255
256 //! \return The pitch in bytes. This is the distance in bytes between two consecutive elements in the given
257 //! dimension.
258 template<std::size_t Tidx, typename TView>
259 [[deprecated("Use getPitchesInBytes instead")]] ALPAKA_FN_HOST auto getPitchBytes(TView const& view) -> Idx<TView>
260 {
261#if ALPAKA_COMP_CLANG || ALPAKA_COMP_GNUC
262# pragma GCC diagnostic push
263# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
264#endif
266#if ALPAKA_COMP_CLANG || ALPAKA_COMP_GNUC
267# pragma GCC diagnostic pop
268#endif
269 }
270
271 //! \return The pitches in bytes as an alpaka::Vec. This is the distance in bytes between two consecutive elements
272 //! in the given dimension.
273 //! E.g. for a 3D view without padding, the 0-dim pitch is the distance in bytes to jump from one element to the
274 //! next within the same row, the 1-dim pitch (aka. the row pitch) is the distance in bytes to jump from one
275 //! element to the neighboring element on the next row. The 2-dim pitch (aka. the slice pitch) is the distance in
276 //! bytes to jump from one element to the neighboring element on the next slice.
277 //! E.g. a 3D view of floats without padding and the extents {42, 10, 2}, would have a pitch vector of {80, 8, 4}.
278 template<typename TView>
280 {
281 return trait::GetPitchesInBytes<TView>{}(view);
282 }
283
284 //! Create a memory set task.
285 //!
286 //! \param view The memory view to fill.
287 //! \param byte Value to set for each element of the specified view.
288 //! \param extent The extent of the view to fill.
289 template<typename TExtent, typename TViewFwd>
290 ALPAKA_FN_HOST auto createTaskMemset(TViewFwd&& view, std::uint8_t const& byte, TExtent const& extent)
291 {
292 using TView = std::remove_reference_t<TViewFwd>;
293 static_assert(!std::is_const_v<TView>, "The view must not be const!");
294 static_assert(
296 "The view and the extent are required to have the same dimensionality!");
297
298 assert((extent <= getExtents(view)).all() && "The memset extent must not be larger than the view's extent!");
299
301 std::forward<TViewFwd>(view),
302 byte,
303 extent);
304 }
305
306 template<typename TExtent, typename TViewFwd, typename TValue>
307 ALPAKA_FN_HOST auto createTaskFill(TViewFwd&& view, TValue const& value, TExtent const& extent)
308 {
309 using TView = std::remove_reference_t<TViewFwd>;
310 static_assert(!std::is_const_v<TView>, "The view must not be const!");
311 static_assert(
313 "The view and the extent are required to have the same dimensionality!");
314
315 assert((extent <= getExtents(view)).all() && "The fill extent must not be larger than the view's extent!");
316
318 std::forward<TViewFwd>(view),
319 value,
320 extent);
321 }
322
323 //! Sets the bytes of the memory of view, described by extent, to the given value.
324 //!
325 //! \param queue The queue to enqueue the view fill task into.
326 //! \param[in,out] view The memory view to fill. May be a temporary object.
327 //! \param byte Value to set for each element of the specified view.
328 //! \param extent The extent of the view to fill.
329 template<typename TExtent, typename TViewFwd, typename TQueue>
330 ALPAKA_FN_HOST auto memset(TQueue& queue, TViewFwd&& view, std::uint8_t const& byte, TExtent const& extent) -> void
331 {
332 enqueue(queue, createTaskMemset(std::forward<TViewFwd>(view), byte, extent));
333 }
334
335 //! Sets each byte of the memory of the entire view to the given value.
336 //!
337 //! \param queue The queue to enqueue the view fill task into.
338 //! \param[in,out] view The memory view to fill. May be a temporary object.
339 //! \param byte Value to set for each element of the specified view.
340 template<typename TViewFwd, typename TQueue>
341 ALPAKA_FN_HOST auto memset(TQueue& queue, TViewFwd&& view, std::uint8_t const& byte) -> void
342 {
343 enqueue(queue, createTaskMemset(std::forward<TViewFwd>(view), byte, getExtents(view)));
344 }
345
346 template<typename TViewFwd, typename TValue, typename TQueue>
347 ALPAKA_FN_HOST auto fill(TQueue& queue, TViewFwd&& view, TValue const& value) -> void
348 {
349 enqueue(queue, createTaskFill(std::forward<TViewFwd>(view), value, getExtents(view)));
350 }
351
352 template<typename TExtent, typename TViewFwd, typename TValue, typename TQueue>
353 ALPAKA_FN_HOST auto fill(TQueue& queue, TViewFwd&& view, TValue const& value, TExtent const& extent) -> void
354 {
355 enqueue(queue, createTaskFill(std::forward<TViewFwd>(view), value, extent));
356 }
357
358 //! Creates a memory copy task.
359 //!
360 //! \param viewDst The destination memory view.
361 //! \param viewSrc The source memory view.
362 //! \param extent The extent of the view to copy.
363 template<typename TExtent, typename TViewSrc, typename TViewDstFwd>
364 ALPAKA_FN_HOST auto createTaskMemcpy(TViewDstFwd&& viewDst, TViewSrc const& viewSrc, TExtent const& extent)
365 {
366 using TViewDst = std::remove_reference_t<TViewDstFwd>;
367 using SrcElem = Elem<TViewSrc>;
368 using DstElem = Elem<TViewDst>;
369
370 static_assert(!std::is_const_v<TViewDst>, "The destination view must not be const!");
371 static_assert(!std::is_const_v<DstElem>, "The destination view's element type must not be const!");
372 static_assert(
374 "The source and the destination view must have the same dimensionality!");
375 static_assert(
377 "The destination view and the extent must have the same dimensionality!");
378 static_assert(
379 std::is_same_v<DstElem, std::remove_const_t<SrcElem>>,
380 "The source and destination view must have the same element type!");
381
382 assert(
383 (extent <= getExtents(viewSrc)).all()
384 && "The memcpy extent must not be larger than the source view's extent!");
385 assert(
386 (extent <= getExtents(viewDst)).all()
387 && "The memcpy extent must not be larger than the destination view's extent!");
388
390 std::forward<TViewDstFwd>(viewDst),
391 viewSrc,
392 extent);
393 }
394
395 //! Copies memory from a part of viewSrc to viewDst, described by extent. Possibly copies between different memory
396 //! spaces.
397 //!
398 //! \param queue The queue to enqueue the view copy task into.
399 //! \param[in,out] viewDst The destination memory view. May be a temporary object.
400 //! \param viewSrc The source memory view. May be a temporary object.
401 //! \param extent The extent of the view to copy.
402 template<typename TExtent, typename TViewSrc, typename TViewDstFwd, typename TQueue>
403 ALPAKA_FN_HOST auto memcpy(TQueue& queue, TViewDstFwd&& viewDst, TViewSrc const& viewSrc, TExtent const& extent)
404 -> void
405 {
406 enqueue(queue, createTaskMemcpy(std::forward<TViewDstFwd>(viewDst), viewSrc, extent));
407 }
408
409 //! Copies the entire memory of viewSrc to viewDst. 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 template<typename TViewSrc, typename TViewDstFwd, typename TQueue>
416 ALPAKA_FN_HOST auto memcpy(TQueue& queue, TViewDstFwd&& viewDst, TViewSrc const& viewSrc) -> void
417 {
418 enqueue(queue, createTaskMemcpy(std::forward<TViewDstFwd>(viewDst), viewSrc, getExtents(viewSrc)));
419 }
420
421 namespace detail
422 {
423 template<typename TDim, typename TView>
424 struct Print
425 {
427 TView const& view,
428 Elem<TView> const* const ptr,
429 Vec<Dim<TView>, Idx<TView>> const& extent,
430 std::ostream& os,
431 std::string const& elementSeparator,
432 std::string const& rowSeparator,
433 std::string const& rowPrefix,
434 std::string const& rowSuffix) -> void
435 {
436 os << rowPrefix;
437
438 auto const pitch = getPitchesInBytes(view)[TDim::value + 1];
439 auto const lastIdx(extent[TDim::value] - 1u);
440 for(auto i(decltype(lastIdx)(0)); i <= lastIdx; ++i)
441 {
443 view,
444 reinterpret_cast<Elem<TView> const*>(reinterpret_cast<std::uint8_t const*>(ptr) + i * pitch),
445 extent,
446 os,
447 elementSeparator,
448 rowSeparator,
449 rowPrefix,
450 rowSuffix);
451
452 // While we are not at the end of a row, add the row separator.
453 if(i != lastIdx)
454 {
455 os << rowSeparator;
456 }
457 }
458
459 os << rowSuffix;
460 }
461 };
462
463 template<typename TView>
464 struct Print<DimInt<Dim<TView>::value - 1u>, TView>
465 {
467 TView const& /* view */,
468 Elem<TView> const* const ptr,
469 Vec<Dim<TView>, Idx<TView>> const& extent,
470 std::ostream& os,
471 std::string const& elementSeparator,
472 std::string const& /* rowSeparator */,
473 std::string const& rowPrefix,
474 std::string const& rowSuffix) -> void
475 {
476 os << rowPrefix;
477
478 auto const lastIdx(extent[Dim<TView>::value - 1u] - 1u);
479 for(auto i(decltype(lastIdx)(0)); i <= lastIdx; ++i)
480 {
481 // Add the current element.
482 os << *(ptr + i);
483
484 // While we are not at the end of a line, add the element separator.
485 if(i != lastIdx)
486 {
487 os << elementSeparator;
488 }
489 }
490
491 os << rowSuffix;
492 }
493 };
494 } // namespace detail
495
496 //! Prints the content of the view to the given queue.
497 // \TODO: Add precision flag.
498 // \TODO: Add column alignment flag.
499 template<typename TView>
501 TView const& view,
502 std::ostream& os,
503 std::string const& elementSeparator = ", ",
504 std::string const& rowSeparator = "\n",
505 std::string const& rowPrefix = "[",
506 std::string const& rowSuffix = "]") -> void
507 {
509 view,
510 getPtrNative(view),
511 getExtents(view),
512 os,
513 elementSeparator,
514 rowSeparator,
515 rowPrefix,
516 rowSuffix);
517 }
518
519 //! \return The pitch vector.
520 template<typename TView>
521 [[deprecated("Use getPitchesInBytes instead")]] auto getPitchBytesVec(TView const& view)
523 {
524 return getPitchesInBytes(view);
525 }
526
527 //! \return The pitch but only the last N elements.
528 template<typename TDim, typename TView>
529 ALPAKA_FN_HOST auto getPitchBytesVecEnd(TView const& view = TView()) -> Vec<TDim, Idx<TView>>
530 {
531 return subVecEnd<TDim>(getPitchesInBytes(view));
532 }
533
534 //! Creates a view to a device pointer
535 //!
536 //! \param dev Device from where pMem can be accessed.
537 //! \param pMem Pointer to memory. The pointer must be accessible from the given device.
538 //! \param extent Number of elements represented by the pMem.
539 //! Using a multi dimensional extent will result in a multi dimension view to the memory represented
540 //! by pMem.
541 //! \return A view to device memory.
542 template<typename TDev, typename TElem, typename TExtent>
543 auto createView(TDev const& dev, TElem* pMem, TExtent const& extent)
544 {
547 auto const extentVec = Vec<Dim, Idx>(extent);
549 dev,
550 pMem,
551 extentVec,
552 detail::calculatePitchesFromExtents<TElem>(extentVec));
553 }
554
555 //! Creates a view to a device pointer
556 //!
557 //! \param dev Device from where pMem can be accessed.
558 //! \param pMem Pointer to memory. The pointer must be accessible from the given device.
559 //! \param extent Number of elements represented by the pMem.
560 //! Using a multi dimensional extent will result in a multi dimension view to the memory represented
561 //! by pMem.
562 //! \param pitch Pitch in bytes for each dimension. Dimensionality must be equal to extent.
563 //! \return A view to device memory.
564 template<typename TDev, typename TElem, typename TExtent, typename TPitch>
565 auto createView(TDev const& dev, TElem* pMem, TExtent const& extent, TPitch pitch)
566 {
567 return trait::CreateViewPlainPtr<TDev>::createViewPlainPtr(dev, pMem, extent, pitch);
568 }
569
570 //! Creates a view to a contiguous container of device-accessible memory.
571 //!
572 //! \param dev Device from which the container can be accessed.
573 //! \param con Contiguous container. The container must provide a `data()` method. The data held by the container
574 //! must be accessible from the given device. The `GetExtent` trait must be defined for the container.
575 //! \return A view to device memory.
576 template<typename TDev, typename TContainer>
577 auto createView(TDev const& dev, TContainer& con)
578 {
579 return createView(dev, std::data(con), getExtents(con));
580 }
581
582 //! Creates a view to a contiguous container of device-accessible memory.
583 //!
584 //! \param dev Device from which the container can be accessed.
585 //! \param con Contiguous container. The container must provide a `data()` method. The data held by the container
586 //! must be accessible from the given device. The `GetExtent` trait must be defined for the container.
587 //! \param extent Number of elements held by the container. Using a multi-dimensional extent will result in a
588 //! multi-dimensional view to the memory represented by the container.
589 //! \return A view to device memory.
590 template<typename TDev, typename TContainer, typename TExtent>
591 auto createView(TDev const& dev, TContainer& con, TExtent const& extent)
592 {
593 return createView(dev, std::data(con), extent);
594 }
595
596 //! Creates a sub view to an existing view.
597 //!
598 //! \param view The view this view is a sub-view of.
599 //! \param extent Number of elements the resulting view holds.
600 //! \param offset Number of elements skipped in view for the new origin of the resulting view.
601 //! \return A sub view to a existing view.
602 template<typename TView, typename TExtent, typename TOffsets>
603 auto createSubView(TView& view, TExtent const& extent, TOffsets const& offset = TExtent())
604 {
606 }
607
608#ifdef ALPAKA_USE_MDSPAN
609 namespace experimental
610 {
611 namespace traits
612 {
613 namespace detail
614 {
615 template<typename ElementType>
616 struct ByteIndexedAccessor
617 {
618 using offset_policy = ByteIndexedAccessor;
619 using element_type = ElementType;
620 using reference = ElementType&;
621
622 using data_handle_type
623 = std::conditional_t<std::is_const_v<ElementType>, std::byte const*, std::byte*>;
624
625 constexpr ByteIndexedAccessor() noexcept = default;
626
627 ALPAKA_FN_HOST_ACC constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept
628 {
629 return p + i;
630 }
631
632 ALPAKA_FN_HOST_ACC constexpr reference access(data_handle_type p, size_t i) const noexcept
633 {
634 assert(i % alignof(ElementType) == 0);
635 return *reinterpret_cast<ElementType*>(__builtin_assume_aligned(p + i, alignof(ElementType)));
636 }
637 };
638
639 template<typename TView, std::size_t... Is>
640 ALPAKA_FN_HOST auto makeExtents(TView const& view, std::index_sequence<Is...>)
641 {
642 auto const ex = getExtents(view);
643 return dextents<Idx<TView>, Dim<TView>::value>{ex[Is]...};
644 }
645 } // namespace detail
646
647 //! Customization point for getting an mdspan from a view.
648 template<typename TView, typename TSfinae = void>
649 struct GetMdSpan
650 {
651 ALPAKA_FN_HOST static auto getMdSpan(TView& view)
652 {
653 constexpr auto dim = Dim<TView>::value;
654 using Element = Elem<TView>;
655 auto extents = detail::makeExtents(view, std::make_index_sequence<dim>{});
656 auto* ptr = reinterpret_cast<std::byte*>(getPtrNative(view));
657 auto const strides = toArray(getPitchesInBytes(view));
658 layout_stride::mapping<decltype(extents)> m{extents, strides};
659 return mdspan<Element, decltype(extents), layout_stride, detail::ByteIndexedAccessor<Element>>{
660 ptr,
661 m};
662 }
663
664 ALPAKA_FN_HOST static auto getMdSpanTransposed(TView& view)
665 {
666 constexpr auto dim = Dim<TView>::value;
667 using Element = Elem<TView>;
668 auto extents = detail::makeExtents(view, std::make_index_sequence<dim>{});
669 auto* ptr = reinterpret_cast<std::byte*>(getPtrNative(view));
670 auto strides = toArray(getPitchesInBytes(view));
671 std::reverse(begin(strides), end(strides));
672 layout_stride::mapping<decltype(extents)> m{extents, strides};
673 return mdspan<Element, decltype(extents), layout_stride, detail::ByteIndexedAccessor<Element>>{
674 ptr,
675 m};
676 }
677 };
678 } // namespace traits
679
680 //! Gets a std::mdspan from the given view. The memory layout is determined by the pitches of the view.
681 template<typename TView>
682 ALPAKA_FN_HOST auto getMdSpan(TView& view)
683 {
684 return traits::GetMdSpan<TView>::getMdSpan(view);
685 }
686
687 //! Gets a std::mdspan from the given view. The memory layout is determined by the reversed pitches of the
688 //! view. This effectively also reverses the extents of the view. In order words, if you create a transposed
689 //! mdspan on a 10x5 element view, the mdspan will have an iteration space of 5x10.
690 template<typename TView>
691 ALPAKA_FN_HOST auto getMdSpanTransposed(TView& view)
692 {
693 return traits::GetMdSpan<TView>::getMdSpanTransposed(view);
694 }
695
696 template<typename TElem, typename TIdx, typename TDim>
697 using MdSpan = alpaka::experimental::mdspan<
698 TElem,
699 alpaka::experimental::dextents<TIdx, TDim::value>,
700 alpaka::experimental::layout_stride,
701 alpaka::experimental::traits::detail::ByteIndexedAccessor<TElem>>;
702 } // namespace experimental
703#endif
704} // 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
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:105
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:529
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:279
auto getPitchBytesVec(TView const &view) -> Vec< Dim< TView >, Idx< TView > >
Definition Traits.hpp:521
ALPAKA_FN_HOST auto createTaskMemcpy(TViewDstFwd &&viewDst, TViewSrc const &viewSrc, TExtent const &extent)
Creates a memory copy task.
Definition Traits.hpp:364
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:603
ALPAKA_FN_HOST auto createTaskFill(TViewFwd &&view, TValue const &value, TExtent const &extent)
Definition Traits.hpp:307
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:500
ALPAKA_FN_HOST auto getPtrNative(TView const &view) -> Elem< TView > const *
Gets the native pointer of the memory view.
Definition Traits.hpp:219
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:330
ALPAKA_FN_HOST auto fill(TQueue &queue, TViewFwd &&view, TValue const &value) -> void
Definition Traits.hpp:347
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:240
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:290
ALPAKA_FN_HOST auto getPitchBytes(TView const &view) -> Idx< TView >
Definition Traits.hpp:259
auto createView(TDev const &dev, TElem *pMem, TExtent const &extent)
Creates a view to a device pointer.
Definition Traits.hpp:543
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:466
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:426
The sub view creation trait.
The memory copy task trait.
Definition Traits.hpp:203
The memory set task trait.
Definition Traits.hpp:194
The device memory view creation trait.
Definition Traits.hpp:207
The pitch in bytes. This is the distance in bytes in the linear memory between two consecutive elemen...
Definition Traits.hpp:147
static ALPAKA_FN_HOST auto getPitchBytes(TView const &view) -> ViewIdx
Definition Traits.hpp:150
Customization point for getPitchesInBytes. The default implementation uses the extent to calculate th...
Definition Traits.hpp:183
ALPAKA_FN_HOST_ACC constexpr auto operator()(TView const &view) const
Definition Traits.hpp:184
The pointer on device get trait.
Definition Traits.hpp:138
The native pointer get trait.
Definition Traits.hpp:134