CMS 3D CMS Logo

memory.h
Go to the documentation of this file.
1 #ifndef HeterogeneousCore_AlpakaInterface_interface_memory_h
2 #define HeterogeneousCore_AlpakaInterface_interface_memory_h
3 
4 #include <type_traits>
5 
6 #include <alpaka/alpaka.hpp>
7 
12 
13 namespace cms::alpakatools {
14 
15  // for Extent, Dim1D, Idx
16  using namespace alpaka_common;
17 
18  // type deduction helpers
19  namespace detail {
20 
21  template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
22  struct buffer_type {
23  using type = alpaka::Buf<TDev, T, Dim0D, Idx>;
24  };
25 
26  template <typename TDev, typename T>
27  struct buffer_type<TDev, T[]> {
28  using type = alpaka::Buf<TDev, T, Dim1D, Idx>;
29  };
30 
31  template <typename TDev, typename T, int N>
32  struct buffer_type<TDev, T[N]> {
33  using type = alpaka::Buf<TDev, T, Dim1D, Idx>;
34  };
35 
36  template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
37  struct view_type {
38  using type = alpaka::ViewPlainPtr<TDev, T, Dim0D, Idx>;
39  };
40 
41  template <typename TDev, typename T>
42  struct view_type<TDev, T[]> {
43  using type = alpaka::ViewPlainPtr<TDev, T, Dim1D, Idx>;
44  };
45 
46  template <typename TDev, typename T, int N>
47  struct view_type<TDev, T[N]> {
48  using type = alpaka::ViewPlainPtr<TDev, T, Dim1D, Idx>;
49  };
50 
51  } // namespace detail
52 
53  // scalar and 1-dimensional host buffers
54 
55  template <typename T>
57 
58  template <typename T>
59  using const_host_buffer = alpaka::ViewConst<host_buffer<T>>;
60 
61  // non-cached, non-pinned, scalar and 1-dimensional host buffers
62 
63  template <typename T>
64  std::enable_if_t<not std::is_array_v<T>, host_buffer<T>> make_host_buffer() {
65  return alpaka::allocBuf<T, Idx>(host(), Scalar{});
66  }
67 
68  template <typename T>
69  std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_buffer<T>>
71  return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(host(), Vec1D{extent});
72  }
73 
74  template <typename T>
75  std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_buffer<T>>
77  return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(host(), Vec1D{std::extent_v<T>});
78  }
79 
80  // non-cached, pinned, scalar and 1-dimensional host buffers
81  // the memory is pinned according to the device associated to the platform
82 
83  template <typename T, typename TPlatform>
84  std::enable_if_t<not std::is_array_v<T>, host_buffer<T>> make_host_buffer() {
85  return alpaka::allocMappedBuf<TPlatform, T, Idx>(host(), Scalar{});
86  }
87 
88  template <typename T, typename TPlatform>
89  std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_buffer<T>>
91  return alpaka::allocMappedBuf<TPlatform, std::remove_extent_t<T>, Idx>(host(), Vec1D{extent});
92  }
93 
94  template <typename T, typename TPlatform>
95  std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_buffer<T>>
97  return alpaka::allocMappedBuf<TPlatform, std::remove_extent_t<T>, Idx>(host(), Vec1D{std::extent_v<T>});
98  }
99 
100  // potentially cached, pinned, scalar and 1-dimensional host buffers, associated to a work queue
101  // the memory is pinned according to the device associated to the queue
102 
103  template <typename T, typename TQueue>
104  std::enable_if_t<alpaka::isQueue<TQueue> and not std::is_array_v<T>, host_buffer<T>> make_host_buffer(
105  TQueue const& queue) {
106  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
107  return allocCachedBuf<T, Idx>(host(), queue, Scalar{});
108  } else {
109  return alpaka::allocMappedBuf<alpaka::Pltf<alpaka::Dev<TQueue>>, T, Idx>(host(), Scalar{});
110  }
111  }
112 
113  template <typename T, typename TQueue>
114  std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_unbounded_array_v<T> and
115  not std::is_array_v<std::remove_extent_t<T>>,
116  host_buffer<T>>
117  make_host_buffer(TQueue const& queue, Extent extent) {
118  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
119  return allocCachedBuf<std::remove_extent_t<T>, Idx>(host(), queue, Vec1D{extent});
120  } else {
121  return alpaka::allocMappedBuf<alpaka::Pltf<alpaka::Dev<TQueue>>, std::remove_extent_t<T>, Idx>(host(),
122  Vec1D{extent});
123  }
124  }
125 
126  template <typename T, typename TQueue>
127  std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_bounded_array_v<T> and
128  not std::is_array_v<std::remove_extent_t<T>>,
129  host_buffer<T>>
130  make_host_buffer(TQueue const& queue) {
131  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
132  return allocCachedBuf<std::remove_extent_t<T>, Idx>(host(), queue, Vec1D{std::extent_v<T>});
133  } else {
134  return alpaka::allocMappedBuf<alpaka::Pltf<alpaka::Dev<TQueue>>, std::remove_extent_t<T>, Idx>(
135  host(), Vec1D{std::extent_v<T>});
136  }
137  }
138 
139  // scalar and 1-dimensional host views
140 
141  template <typename T>
143 
144  template <typename T>
145  std::enable_if_t<not std::is_array_v<T>, host_view<T>> make_host_view(T& data) {
146  return alpaka::ViewPlainPtr<DevHost, T, Dim0D, Idx>(&data, host(), Scalar{});
147  }
148 
149  template <typename T>
151  return alpaka::ViewPlainPtr<DevHost, T, Dim1D, Idx>(data, host(), Vec1D{extent});
152  }
153 
154  template <typename T>
155  std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_view<T>>
157  return alpaka::ViewPlainPtr<DevHost, std::remove_extent_t<T>, Dim1D, Idx>(data, host(), Vec1D{extent});
158  }
159 
160  template <typename T>
161  std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_view<T>>
163  return alpaka::ViewPlainPtr<DevHost, std::remove_extent_t<T>, Dim1D, Idx>(data, host(), Vec1D{std::extent_v<T>});
164  }
165 
166  // scalar and 1-dimensional device buffers
167 
168  template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
170 
171  template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
172  using const_device_buffer = alpaka::ViewConst<device_buffer<TDev, T>>;
173 
174  // non-cached, scalar and 1-dimensional device buffers
175 
176  template <typename T, typename TDev>
177  std::enable_if_t<alpaka::isDevice<TDev> and not std::is_array_v<T>, device_buffer<TDev, T>> make_device_buffer(
178  TDev const& device) {
179  return alpaka::allocBuf<T, Idx>(device, Scalar{});
180  }
181 
182  template <typename T, typename TDev>
183  std::enable_if_t<alpaka::isDevice<TDev> and cms::is_unbounded_array_v<T> and
184  not std::is_array_v<std::remove_extent_t<T>>,
185  device_buffer<TDev, T>>
186  make_device_buffer(TDev const& device, Extent extent) {
187  return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(device, Vec1D{extent});
188  }
189 
190  template <typename T, typename TDev>
191  std::enable_if_t<alpaka::isDevice<TDev> and cms::is_bounded_array_v<T> and
192  not std::is_array_v<std::remove_extent_t<T>>,
193  device_buffer<TDev, T>>
194  make_device_buffer(TDev const& device) {
195  return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(device, Vec1D{std::extent_v<T>});
196  }
197 
198  // potentially-cached, scalar and 1-dimensional device buffers with queue-ordered semantic
199 
200  template <typename T, typename TQueue>
201  std::enable_if_t<alpaka::isQueue<TQueue> and not std::is_array_v<T>, device_buffer<alpaka::Dev<TQueue>, T>>
202  make_device_buffer(TQueue const& queue) {
203  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
204  return allocCachedBuf<T, Idx>(alpaka::getDev(queue), queue, Scalar{});
205  }
206  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
207  return alpaka::allocAsyncBuf<T, Idx>(queue, Scalar{});
208  }
209  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
210  return alpaka::allocBuf<T, Idx>(alpaka::getDev(queue), Scalar{});
211  }
212  }
213 
214  template <typename T, typename TQueue>
215  std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_unbounded_array_v<T> and
216  not std::is_array_v<std::remove_extent_t<T>>,
217  device_buffer<alpaka::Dev<TQueue>, T>>
218  make_device_buffer(TQueue const& queue, Extent extent) {
219  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
220  return allocCachedBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), queue, Vec1D{extent});
221  }
222  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
223  return alpaka::allocAsyncBuf<std::remove_extent_t<T>, Idx>(queue, Vec1D{extent});
224  }
225  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
226  return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), Vec1D{extent});
227  }
228  }
229 
230  template <typename T, typename TQueue>
231  std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_bounded_array_v<T> and
232  not std::is_array_v<std::remove_extent_t<T>>,
233  device_buffer<alpaka::Dev<TQueue>, T>>
234  make_device_buffer(TQueue const& queue) {
235  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
236  return allocCachedBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), queue, Vec1D{std::extent_v<T>});
237  }
238  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
239  return alpaka::allocAsyncBuf<std::remove_extent_t<T>, Idx>(queue, Vec1D{std::extent_v<T>});
240  }
241  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
242  return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), Vec1D{std::extent_v<T>});
243  }
244  }
245 
246  // scalar and 1-dimensional device views
247 
248  template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
250 
251  template <typename T, typename TDev>
252  std::enable_if_t<not std::is_array_v<T>, device_view<TDev, T>> make_device_view(TDev const& device, T& data) {
253  return alpaka::ViewPlainPtr<TDev, T, Dim0D, Idx>(&data, device, Scalar{});
254  }
255 
256  template <typename T, typename TDev>
257  device_view<TDev, T[]> make_device_view(TDev const& device, T* data, Extent extent) {
258  return alpaka::ViewPlainPtr<TDev, T, Dim1D, Idx>(data, device, Vec1D{extent});
259  }
260 
261  template <typename T, typename TDev>
262  std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, device_view<TDev, T>>
263  make_device_view(TDev const& device, T& data, Extent extent) {
264  return alpaka::ViewPlainPtr<TDev, std::remove_extent_t<T>, Dim1D, Idx>(data, device, Vec1D{extent});
265  }
266 
267  template <typename T, typename TDev>
268  std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, device_view<TDev, T>>
269  make_device_view(TDev const& device, T& data) {
270  return alpaka::ViewPlainPtr<TDev, std::remove_extent_t<T>, Dim1D, Idx>(data, device, Vec1D{std::extent_v<T>});
271  }
272 
273 } // namespace cms::alpakatools
274 
275 #endif // HeterogeneousCore_AlpakaInterface_interface_memory_h
alpaka::ViewPlainPtr< TDev, T, Dim1D, Idx > type
Definition: memory.h:48
Vec< Dim1D > Vec1D
Definition: config.h:24
uint32_t Idx
Definition: config.h:13
alpaka::Buf< TDev, T, Dim1D, Idx > type
Definition: memory.h:33
std::enable_if_t< alpaka::isDevice< TDev > and not std::is_array_v< T >, device_buffer< TDev, T > > make_device_buffer(TDev const &device)
Definition: memory.h:177
std::enable_if_t< not std::is_array_v< T >, device_view< TDev, T > > make_device_view(TDev const &device, T &data)
Definition: memory.h:252
typename detail::view_type< TDev, T >::type device_view
Definition: memory.h:249
std::enable_if_t< not std::is_array_v< T >, host_buffer< T > > make_host_buffer()
Definition: memory.h:64
alpaka::DimInt< 1u > Dim1D
Definition: config.h:18
alpaka::DevCpu const & host()
Definition: host.h:24
typename detail::buffer_type< DevHost, T >::type host_buffer
Definition: memory.h:56
alpaka::Buf< TDev, T, Dim1D, Idx > type
Definition: memory.h:28
#define N
Definition: blowfish.cc:9
alpaka::Buf< TDev, T, Dim0D, Idx > type
Definition: memory.h:23
Vec< Dim0D > Scalar
Definition: config.h:27
alpaka::ViewConst< host_buffer< T > > const_host_buffer
Definition: memory.h:59
typename detail::view_type< DevHost, T >::type host_view
Definition: memory.h:142
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
alpaka::ViewPlainPtr< TDev, T, Dim1D, Idx > type
Definition: memory.h:43
uint32_t Extent
Definition: config.h:14
constexpr AllocatorPolicy allocator_policy
std::enable_if_t< not std::is_array_v< T >, host_view< T > > make_host_view(T &data)
Definition: memory.h:145
long double T
alpaka::ViewPlainPtr< TDev, T, Dim0D, Idx > type
Definition: memory.h:38
typename detail::buffer_type< TDev, T >::type device_buffer
Definition: memory.h:169
alpaka::ViewConst< device_buffer< TDev, T > > const_device_buffer
Definition: memory.h:172