Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-09-07 02:51:59

0001 #ifndef HeterogeneousCore_AlpakaInterface_interface_memory_h
0002 #define HeterogeneousCore_AlpakaInterface_interface_memory_h
0003 
0004 #include <type_traits>
0005 
0006 #include <alpaka/alpaka.hpp>
0007 
0008 #include "HeterogeneousCore/AlpakaInterface/interface/AllocatorPolicy.h"
0009 #include "HeterogeneousCore/AlpakaInterface/interface/CachedBufAlloc.h"
0010 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
0011 #include "HeterogeneousCore/AlpakaInterface/interface/traits.h"
0012 
0013 namespace cms::alpakatools {
0014 
0015   // for Extent, Dim1D, Idx
0016   using namespace alpaka_common;
0017 
0018   // type deduction helpers
0019   namespace detail {
0020 
0021     template <typename TDev, typename T, typename = std::enable_if_t<cms::alpakatools::is_device_v<TDev>>>
0022     struct buffer_type {
0023       using type = alpaka::Buf<TDev, T, Dim0D, Idx>;
0024     };
0025 
0026     template <typename TDev, typename T>
0027     struct buffer_type<TDev, T[]> {
0028       using type = alpaka::Buf<TDev, T, Dim1D, Idx>;
0029     };
0030 
0031     template <typename TDev, typename T, int N>
0032     struct buffer_type<TDev, T[N]> {
0033       using type = alpaka::Buf<TDev, T, Dim1D, Idx>;
0034     };
0035 
0036     template <typename TDev, typename T, typename = std::enable_if_t<cms::alpakatools::is_device_v<TDev>>>
0037     struct view_type {
0038       using type = alpaka::ViewPlainPtr<TDev, T, Dim0D, Idx>;
0039     };
0040 
0041     template <typename TDev, typename T>
0042     struct view_type<TDev, T[]> {
0043       using type = alpaka::ViewPlainPtr<TDev, T, Dim1D, Idx>;
0044     };
0045 
0046     template <typename TDev, typename T, int N>
0047     struct view_type<TDev, T[N]> {
0048       using type = alpaka::ViewPlainPtr<TDev, T, Dim1D, Idx>;
0049     };
0050 
0051   }  // namespace detail
0052 
0053   // scalar and 1-dimensional host buffers
0054 
0055   template <typename T>
0056   using host_buffer = typename detail::buffer_type<DevHost, T>::type;
0057 
0058   template <typename T>
0059   using const_host_buffer = alpaka::ViewConst<host_buffer<T>>;
0060 
0061   // non-cached, non-pinned, scalar and 1-dimensional host buffers
0062 
0063   template <typename T>
0064   std::enable_if_t<not std::is_array_v<T>, host_buffer<T>> make_host_buffer() {
0065     return alpaka::allocBuf<T, Idx>(host(), Scalar{});
0066   }
0067 
0068   template <typename T>
0069   std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_buffer<T>>
0070   make_host_buffer(Extent extent) {
0071     return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(host(), Vec1D{extent});
0072   }
0073 
0074   template <typename T>
0075   std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_buffer<T>>
0076   make_host_buffer() {
0077     return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(host(), Vec1D{std::extent_v<T>});
0078   }
0079 
0080   // non-cached, pinned, scalar and 1-dimensional host buffers
0081   // the memory is pinned according to the device associated to the platform
0082 
0083   template <typename T, typename TPlatform>
0084   std::enable_if_t<not std::is_array_v<T>, host_buffer<T>> make_host_buffer() {
0085     return alpaka::allocMappedBuf<TPlatform, T, Idx>(host(), Scalar{});
0086   }
0087 
0088   template <typename T, typename TPlatform>
0089   std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_buffer<T>>
0090   make_host_buffer(Extent extent) {
0091     return alpaka::allocMappedBuf<TPlatform, std::remove_extent_t<T>, Idx>(host(), Vec1D{extent});
0092   }
0093 
0094   template <typename T, typename TPlatform>
0095   std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_buffer<T>>
0096   make_host_buffer() {
0097     return alpaka::allocMappedBuf<TPlatform, std::remove_extent_t<T>, Idx>(host(), Vec1D{std::extent_v<T>});
0098   }
0099 
0100   // potentially cached, pinned, scalar and 1-dimensional host buffers, associated to a work queue
0101   // the memory is pinned according to the device associated to the queue
0102 
0103   template <typename T, typename TQueue>
0104   std::enable_if_t<is_queue_v<TQueue> and not std::is_array_v<T>, host_buffer<T>> make_host_buffer(TQueue const& queue) {
0105     if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0106       return allocCachedBuf<T, Idx>(host(), queue, Scalar{});
0107     } else {
0108       return alpaka::allocMappedBuf<alpaka::Pltf<alpaka::Dev<TQueue>>, T, Idx>(host(), Scalar{});
0109     }
0110   }
0111 
0112   template <typename T, typename TQueue>
0113   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>>,
0114                    host_buffer<T>>
0115   make_host_buffer(TQueue const& queue, Extent extent) {
0116     if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0117       return allocCachedBuf<std::remove_extent_t<T>, Idx>(host(), queue, Vec1D{extent});
0118     } else {
0119       return alpaka::allocMappedBuf<alpaka::Pltf<alpaka::Dev<TQueue>>, std::remove_extent_t<T>, Idx>(host(),
0120                                                                                                      Vec1D{extent});
0121     }
0122   }
0123 
0124   template <typename T, typename TQueue>
0125   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>>,
0126                    host_buffer<T>>
0127   make_host_buffer(TQueue const& queue) {
0128     if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0129       return allocCachedBuf<std::remove_extent_t<T>, Idx>(host(), queue, Vec1D{std::extent_v<T>});
0130     } else {
0131       return alpaka::allocMappedBuf<alpaka::Pltf<alpaka::Dev<TQueue>>, std::remove_extent_t<T>, Idx>(
0132           host(), Vec1D{std::extent_v<T>});
0133     }
0134   }
0135 
0136   // scalar and 1-dimensional host views
0137 
0138   template <typename T>
0139   using host_view = typename detail::view_type<DevHost, T>::type;
0140 
0141   template <typename T>
0142   std::enable_if_t<not std::is_array_v<T>, host_view<T>> make_host_view(T& data) {
0143     return alpaka::ViewPlainPtr<DevHost, T, Dim0D, Idx>(&data, host(), Scalar{});
0144   }
0145 
0146   template <typename T>
0147   host_view<T[]> make_host_view(T* data, Extent extent) {
0148     return alpaka::ViewPlainPtr<DevHost, T, Dim1D, Idx>(data, host(), Vec1D{extent});
0149   }
0150 
0151   template <typename T>
0152   std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_view<T>>
0153   make_host_view(T& data, Extent extent) {
0154     return alpaka::ViewPlainPtr<DevHost, std::remove_extent_t<T>, Dim1D, Idx>(data, host(), Vec1D{extent});
0155   }
0156 
0157   template <typename T>
0158   std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_view<T>>
0159   make_host_view(T& data) {
0160     return alpaka::ViewPlainPtr<DevHost, std::remove_extent_t<T>, Dim1D, Idx>(data, host(), Vec1D{std::extent_v<T>});
0161   }
0162 
0163   // scalar and 1-dimensional device buffers
0164 
0165   template <typename TDev, typename T, typename = std::enable_if_t<cms::alpakatools::is_device_v<TDev>>>
0166   using device_buffer = typename detail::buffer_type<TDev, T>::type;
0167 
0168   template <typename TDev, typename T, typename = std::enable_if_t<cms::alpakatools::is_device_v<TDev>>>
0169   using const_device_buffer = alpaka::ViewConst<device_buffer<TDev, T>>;
0170 
0171   // non-cached, scalar and 1-dimensional device buffers
0172 
0173   template <typename T, typename TDev>
0174   std::enable_if_t<is_device_v<TDev> and not std::is_array_v<T>, device_buffer<TDev, T>> make_device_buffer(
0175       TDev const& device) {
0176     return alpaka::allocBuf<T, Idx>(device, Scalar{});
0177   }
0178 
0179   template <typename T, typename TDev>
0180   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>>,
0181                    device_buffer<TDev, T>>
0182   make_device_buffer(TDev const& device, Extent extent) {
0183     return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(device, Vec1D{extent});
0184   }
0185 
0186   template <typename T, typename TDev>
0187   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>>,
0188                    device_buffer<TDev, T>>
0189   make_device_buffer(TDev const& device) {
0190     return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(device, Vec1D{std::extent_v<T>});
0191   }
0192 
0193   // potentially-cached, scalar and 1-dimensional device buffers with queue-ordered semantic
0194 
0195   template <typename T, typename TQueue>
0196   std::enable_if_t<is_queue_v<TQueue> and not std::is_array_v<T>, device_buffer<alpaka::Dev<TQueue>, T>>
0197   make_device_buffer(TQueue const& queue) {
0198     if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0199       return allocCachedBuf<T, Idx>(alpaka::getDev(queue), queue, Scalar{});
0200     }
0201     if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
0202       return alpaka::allocAsyncBuf<T, Idx>(queue, Scalar{});
0203     }
0204     if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
0205       return alpaka::allocBuf<T, Idx>(alpaka::getDev(queue), Scalar{});
0206     }
0207   }
0208 
0209   template <typename T, typename TQueue>
0210   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>>,
0211                    device_buffer<alpaka::Dev<TQueue>, T>>
0212   make_device_buffer(TQueue const& queue, Extent extent) {
0213     if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0214       return allocCachedBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), queue, Vec1D{extent});
0215     }
0216     if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
0217       return alpaka::allocAsyncBuf<std::remove_extent_t<T>, Idx>(queue, Vec1D{extent});
0218     }
0219     if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
0220       return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), Vec1D{extent});
0221     }
0222   }
0223 
0224   template <typename T, typename TQueue>
0225   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>>,
0226                    device_buffer<alpaka::Dev<TQueue>, T>>
0227   make_device_buffer(TQueue const& queue) {
0228     if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0229       return allocCachedBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), queue, Vec1D{std::extent_v<T>});
0230     }
0231     if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
0232       return alpaka::allocAsyncBuf<std::remove_extent_t<T>, Idx>(queue, Vec1D{std::extent_v<T>});
0233     }
0234     if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
0235       return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), Vec1D{std::extent_v<T>});
0236     }
0237   }
0238 
0239   // scalar and 1-dimensional device views
0240 
0241   template <typename TDev, typename T, typename = std::enable_if_t<cms::alpakatools::is_device_v<TDev>>>
0242   using device_view = typename detail::view_type<TDev, T>::type;
0243 
0244   template <typename T, typename TDev>
0245   std::enable_if_t<not std::is_array_v<T>, device_view<TDev, T>> make_device_view(TDev const& device, T& data) {
0246     return alpaka::ViewPlainPtr<TDev, T, Dim0D, Idx>(&data, device, Scalar{});
0247   }
0248 
0249   template <typename T, typename TDev>
0250   device_view<TDev, T[]> make_device_view(TDev const& device, T* data, Extent extent) {
0251     return alpaka::ViewPlainPtr<TDev, T, Dim1D, Idx>(data, device, Vec1D{extent});
0252   }
0253 
0254   template <typename T, typename TDev>
0255   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>>
0256   make_device_view(TDev const& device, T& data, Extent extent) {
0257     return alpaka::ViewPlainPtr<TDev, std::remove_extent_t<T>, Dim1D, Idx>(data, device, Vec1D{extent});
0258   }
0259 
0260   template <typename T, typename TDev>
0261   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>>
0262   make_device_view(TDev const& device, T& data) {
0263     return alpaka::ViewPlainPtr<TDev, std::remove_extent_t<T>, Dim1D, Idx>(data, device, Vec1D{std::extent_v<T>});
0264   }
0265 
0266 }  // namespace cms::alpakatools
0267 
0268 #endif  // HeterogeneousCore_AlpakaInterface_interface_memory_h