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