alpaka
Abstraction Library for Parallel Kernel Acceleration
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 
7 #include "alpaka/dim/Traits.hpp"
10 
11 #include <cstdint>
12 #include <sstream>
13 #include <stdexcept>
14 #include <type_traits>
15 #include <utility>
16 
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<
27  Idx<TView>,
28  Dim<TView>,
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
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC auto all(TWarp const &warp, std::int32_t predicate) -> std::int32_t
Evaluates predicate for all active threads of the warp and returns non-zero if and only if predicate ...
Definition: Traits.hpp:114
typename trait::IdxType< T >::type Idx
Definition: Traits.hpp:29
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 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
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