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<cms::alpakatools::is_device_v<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<cms::alpakatools::is_device_v<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<is_queue_v<TQueue> and not std::is_array_v<T>, host_buffer<T>> make_host_buffer(TQueue const& queue) {
105  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
106  return allocCachedBuf<T, Idx>(host(), queue, Scalar{});
107  } else {
108  return alpaka::allocMappedBuf<alpaka::Pltf<alpaka::Dev<TQueue>>, T, Idx>(host(), Scalar{});
109  }
110  }
111 
112  template <typename T, typename TQueue>
113  std::enable_if_t<is_queue_v<TQueue> and cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>,
114  host_buffer<T>>
115  make_host_buffer(TQueue const& queue, Extent extent) {
116  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
117  return allocCachedBuf<std::remove_extent_t<T>, Idx>(host(), queue, Vec1D{extent});
118  } else {
119  return alpaka::allocMappedBuf<alpaka::Pltf<alpaka::Dev<TQueue>>, std::remove_extent_t<T>, Idx>(host(),
120  Vec1D{extent});
121  }
122  }
123 
124  template <typename T, typename TQueue>
125  std::enable_if_t<is_queue_v<TQueue> and cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>,
126  host_buffer<T>>
127  make_host_buffer(TQueue const& queue) {
128  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
129  return allocCachedBuf<std::remove_extent_t<T>, Idx>(host(), queue, Vec1D{std::extent_v<T>});
130  } else {
131  return alpaka::allocMappedBuf<alpaka::Pltf<alpaka::Dev<TQueue>>, std::remove_extent_t<T>, Idx>(
132  host(), Vec1D{std::extent_v<T>});
133  }
134  }
135 
136  // scalar and 1-dimensional host views
137 
138  template <typename T>
140 
141  template <typename T>
142  std::enable_if_t<not std::is_array_v<T>, host_view<T>> make_host_view(T& data) {
143  return alpaka::ViewPlainPtr<DevHost, T, Dim0D, Idx>(&data, host(), Scalar{});
144  }
145 
146  template <typename T>
148  return alpaka::ViewPlainPtr<DevHost, T, Dim1D, Idx>(data, host(), Vec1D{extent});
149  }
150 
151  template <typename T>
152  std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_view<T>>
154  return alpaka::ViewPlainPtr<DevHost, std::remove_extent_t<T>, Dim1D, Idx>(data, host(), Vec1D{extent});
155  }
156 
157  template <typename T>
158  std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_view<T>>
160  return alpaka::ViewPlainPtr<DevHost, std::remove_extent_t<T>, Dim1D, Idx>(data, host(), Vec1D{std::extent_v<T>});
161  }
162 
163  // scalar and 1-dimensional device buffers
164 
165  template <typename TDev, typename T, typename = std::enable_if_t<cms::alpakatools::is_device_v<TDev>>>
167 
168  template <typename TDev, typename T, typename = std::enable_if_t<cms::alpakatools::is_device_v<TDev>>>
169  using const_device_buffer = alpaka::ViewConst<device_buffer<TDev, T>>;
170 
171  // non-cached, scalar and 1-dimensional device buffers
172 
173  template <typename T, typename TDev>
174  std::enable_if_t<is_device_v<TDev> and not std::is_array_v<T>, device_buffer<TDev, T>> make_device_buffer(
175  TDev const& device) {
176  return alpaka::allocBuf<T, Idx>(device, Scalar{});
177  }
178 
179  template <typename T, typename TDev>
180  std::enable_if_t<is_device_v<TDev> and cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>,
181  device_buffer<TDev, T>>
182  make_device_buffer(TDev const& device, Extent extent) {
183  return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(device, Vec1D{extent});
184  }
185 
186  template <typename T, typename TDev>
187  std::enable_if_t<is_device_v<TDev> and cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>,
188  device_buffer<TDev, T>>
189  make_device_buffer(TDev const& device) {
190  return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(device, Vec1D{std::extent_v<T>});
191  }
192 
193  // potentially-cached, scalar and 1-dimensional device buffers with queue-ordered semantic
194 
195  template <typename T, typename TQueue>
196  std::enable_if_t<is_queue_v<TQueue> and not std::is_array_v<T>, device_buffer<alpaka::Dev<TQueue>, T>>
197  make_device_buffer(TQueue const& queue) {
198  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
199  return allocCachedBuf<T, Idx>(alpaka::getDev(queue), queue, Scalar{});
200  }
201  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
202  return alpaka::allocAsyncBuf<T, Idx>(queue, Scalar{});
203  }
204  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
205  return alpaka::allocBuf<T, Idx>(alpaka::getDev(queue), Scalar{});
206  }
207  }
208 
209  template <typename T, typename TQueue>
210  std::enable_if_t<is_queue_v<TQueue> and cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>,
211  device_buffer<alpaka::Dev<TQueue>, T>>
212  make_device_buffer(TQueue const& queue, Extent extent) {
213  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
214  return allocCachedBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), queue, Vec1D{extent});
215  }
216  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
217  return alpaka::allocAsyncBuf<std::remove_extent_t<T>, Idx>(queue, Vec1D{extent});
218  }
219  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
220  return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), Vec1D{extent});
221  }
222  }
223 
224  template <typename T, typename TQueue>
225  std::enable_if_t<is_queue_v<TQueue> and cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>,
226  device_buffer<alpaka::Dev<TQueue>, T>>
227  make_device_buffer(TQueue const& queue) {
228  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
229  return allocCachedBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), queue, Vec1D{std::extent_v<T>});
230  }
231  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
232  return alpaka::allocAsyncBuf<std::remove_extent_t<T>, Idx>(queue, Vec1D{std::extent_v<T>});
233  }
234  if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
235  return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), Vec1D{std::extent_v<T>});
236  }
237  }
238 
239  // scalar and 1-dimensional device views
240 
241  template <typename TDev, typename T, typename = std::enable_if_t<cms::alpakatools::is_device_v<TDev>>>
243 
244  template <typename T, typename TDev>
245  std::enable_if_t<not std::is_array_v<T>, device_view<TDev, T>> make_device_view(TDev const& device, T& data) {
246  return alpaka::ViewPlainPtr<TDev, T, Dim0D, Idx>(&data, device, Scalar{});
247  }
248 
249  template <typename T, typename TDev>
250  device_view<TDev, T[]> make_device_view(TDev const& device, T* data, Extent extent) {
251  return alpaka::ViewPlainPtr<TDev, T, Dim1D, Idx>(data, device, Vec1D{extent});
252  }
253 
254  template <typename T, typename TDev>
255  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>>
256  make_device_view(TDev const& device, T& data, Extent extent) {
257  return alpaka::ViewPlainPtr<TDev, std::remove_extent_t<T>, Dim1D, Idx>(data, device, Vec1D{extent});
258  }
259 
260  template <typename T, typename TDev>
261  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>>
262  make_device_view(TDev const& device, T& data) {
263  return alpaka::ViewPlainPtr<TDev, std::remove_extent_t<T>, Dim1D, Idx>(data, device, Vec1D{std::extent_v<T>});
264  }
265 
266 } // namespace cms::alpakatools
267 
268 #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< not std::is_array_v< T >, device_view< TDev, T > > make_device_view(TDev const &device, T &data)
Definition: memory.h:245
typename detail::view_type< TDev, T >::type device_view
Definition: memory.h:242
std::enable_if_t< not std::is_array_v< T >, host_buffer< T > > make_host_buffer()
Definition: memory.h:64
std::enable_if_t< is_device_v< TDev > and not std::is_array_v< T >, device_buffer< TDev, T > > make_device_buffer(TDev const &device)
Definition: memory.h:174
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:139
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
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:142
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:166
alpaka::ViewConst< device_buffer< TDev, T > > const_device_buffer
Definition: memory.h:169