alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
ViewAccessOps.hpp
Go to the documentation of this file.
1/* Copyright 2023 Andrea Bocci, Bernhard Manfred Gruber, Jan Stephan
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
10
11#include <cstdint>
12#include <sstream>
13#include <stdexcept>
14#include <type_traits>
15#include <utility>
16
17namespace alpaka::internal
18{
19 template<typename T, typename SFINAE = void>
20 inline constexpr bool isView = false;
21
22 // TODO(bgruber): replace this by a concept in C++20
23 template<typename TView>
24 inline constexpr bool isView<
25 TView,
26 std::void_t<
29 decltype(getPtrNative(std::declval<TView>())),
30 decltype(getPitchesInBytes(std::declval<TView>())),
31 decltype(getExtents(std::declval<TView>()))>>
32 = true;
33
34 template<typename TView>
36 {
37 static_assert(isView<TView>);
38
39 private:
40 using value_type = Elem<TView>;
41 using pointer = value_type*;
42 using const_pointer = value_type const*;
43 using reference = value_type&;
44 using const_reference = value_type const&;
45 using Idx = alpaka::Idx<TView>;
46 using Dim = alpaka::Dim<TView>;
47
48 public:
49 ALPAKA_FN_HOST auto data() -> pointer
50 {
51 return getPtrNative(*static_cast<TView*>(this));
52 }
53
54 [[nodiscard]] ALPAKA_FN_HOST auto data() const -> const_pointer
55 {
56 return getPtrNative(*static_cast<TView const*>(this));
57 }
58
59 ALPAKA_FN_HOST auto operator*() -> reference
60 {
61 static_assert(Dim::value == 0, "operator* is only valid for Buffers and Views of dimension 0");
62 return *data();
63 }
64
65 ALPAKA_FN_HOST auto operator*() const -> const_reference
66 {
67 static_assert(Dim::value == 0, "operator* is only valid for Buffers and Views of dimension 0");
68 return *data();
69 }
70
71 ALPAKA_FN_HOST auto operator->() -> pointer
72 {
73 static_assert(Dim::value == 0, "operator-> is only valid for Buffers and Views of dimension 0");
74 return data();
75 }
76
77 ALPAKA_FN_HOST auto operator->() const -> const_pointer
78 {
79 static_assert(Dim::value == 0, "operator-> is only valid for Buffers and Views of dimension 0");
80 return data();
81 }
82
83 ALPAKA_FN_HOST auto operator[](Idx i) -> reference
84 {
85 static_assert(Dim::value == 1, "operator[i] is only valid for Buffers and Views of dimension 1");
86 return data()[i];
87 }
88
89 ALPAKA_FN_HOST auto operator[](Idx i) const -> const_reference
90 {
91 static_assert(Dim::value == 1, "operator[i] is only valid for Buffers and Views of dimension 1");
92 return data()[i];
93 }
94
95 private:
96 template<typename TIdx>
97 [[nodiscard]] ALPAKA_FN_HOST auto ptr_at([[maybe_unused]] Vec<Dim, TIdx> index) const -> const_pointer
98 {
99 static_assert(
100 std::is_convertible_v<TIdx, Idx>,
101 "the index type must be convertible to the index of the Buffer or View");
102
103 auto ptr = reinterpret_cast<std::uintptr_t>(data());
104 if constexpr(Dim::value > 0)
105 {
106 ptr += static_cast<std::uintptr_t>(
107 (getPitchesInBytes(*static_cast<TView const*>(this)) * castVec<Idx>(index)).sum());
108 }
109 return reinterpret_cast<const_pointer>(ptr);
110 }
111
112 public:
113 template<typename TIdx>
114 ALPAKA_FN_HOST auto operator[](Vec<Dim, TIdx> index) -> reference
115 {
116 return *const_cast<pointer>(ptr_at(index));
117 }
118
119 template<typename TIdx>
120 ALPAKA_FN_HOST auto operator[](Vec<Dim, TIdx> index) const -> const_reference
121 {
122 return *ptr_at(index);
123 }
124
125 template<typename TIdx>
126 ALPAKA_FN_HOST auto at(Vec<Dim, TIdx> index) -> reference
127 {
128 auto extent = getExtents(*static_cast<TView*>(this));
129 if(!(index < extent).all())
130 {
131 std::stringstream msg;
132 msg << "index " << index << " is outside of the Buffer or View extent " << extent;
133 throw std::out_of_range(msg.str());
134 }
135 return *const_cast<pointer>(ptr_at(index));
136 }
137
138 template<typename TIdx>
139 [[nodiscard]] ALPAKA_FN_HOST auto at(Vec<Dim, TIdx> index) const -> const_reference
140 {
141 auto extent = getExtents(*static_cast<TView const*>(this));
142 if(!(index < extent).all())
143 {
144 std::stringstream msg;
145 msg << "index " << index << " is outside of the Buffer or View extent " << extent;
146 throw std::out_of_range(msg.str());
147 }
148 return *ptr_at(index);
149 }
150 };
151} // namespace alpaka::internal
A n-dimensional vector.
Definition Vec.hpp:38
#define ALPAKA_FN_HOST
Definition Common.hpp:40
constexpr bool isView
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:196
ALPAKA_FN_HOST auto getPtrNative(TView const &view) -> Elem< TView > const *
Gets the native pointer of the memory view.
Definition Traits.hpp:136
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 operator[](Idx i) const -> const_reference
ALPAKA_FN_HOST auto data() const -> const_pointer
ALPAKA_FN_HOST auto at(Vec< Dim, TIdx > index) -> reference
ALPAKA_FN_HOST auto operator[](Vec< Dim, TIdx > index) const -> const_reference
ALPAKA_FN_HOST auto operator*() -> reference
ALPAKA_FN_HOST auto data() -> pointer
ALPAKA_FN_HOST auto operator->() -> pointer
ALPAKA_FN_HOST auto operator[](Vec< Dim, TIdx > index) -> reference
ALPAKA_FN_HOST auto operator[](Idx i) -> reference
ALPAKA_FN_HOST auto operator->() const -> const_pointer
ALPAKA_FN_HOST auto operator*() const -> const_reference
ALPAKA_FN_HOST auto at(Vec< Dim, TIdx > index) const -> const_reference