Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:49:26

0001 #ifndef HeterogeneousCore_CUDAUtilities_interface_host_unique_ptr_h
0002 #define HeterogeneousCore_CUDAUtilities_interface_host_unique_ptr_h
0003 
0004 #include <memory>
0005 #include <functional>
0006 
0007 #include "HeterogeneousCore/CUDAUtilities/interface/allocate_host.h"
0008 
0009 namespace cms {
0010   namespace cuda {
0011     namespace host {
0012       namespace impl {
0013         // Additional layer of types to distinguish from host::unique_ptr
0014         class HostDeleter {
0015         public:
0016           void operator()(void *ptr) { cms::cuda::free_host(ptr); }
0017         };
0018       }  // namespace impl
0019 
0020       template <typename T>
0021       using unique_ptr = std::unique_ptr<T, impl::HostDeleter>;
0022 
0023       namespace impl {
0024         template <typename T>
0025         struct make_host_unique_selector {
0026           using non_array = cms::cuda::host::unique_ptr<T>;
0027         };
0028         template <typename T>
0029         struct make_host_unique_selector<T[]> {
0030           using unbounded_array = cms::cuda::host::unique_ptr<T[]>;
0031         };
0032         template <typename T, size_t N>
0033         struct make_host_unique_selector<T[N]> {
0034           struct bounded_array {};
0035         };
0036       }  // namespace impl
0037     }    // namespace host
0038 
0039     // Allocate pinned host memory
0040     template <typename T>
0041     typename host::impl::make_host_unique_selector<T>::non_array make_host_unique(cudaStream_t stream) {
0042       static_assert(std::is_trivially_constructible<T>::value,
0043                     "Allocating with non-trivial constructor on the pinned host memory is not supported");
0044       void *mem = allocate_host(sizeof(T), stream);
0045       return typename host::impl::make_host_unique_selector<T>::non_array{reinterpret_cast<T *>(mem)};
0046     }
0047 
0048     template <typename T>
0049     typename host::impl::make_host_unique_selector<T>::unbounded_array make_host_unique(size_t n, cudaStream_t stream) {
0050       using element_type = typename std::remove_extent<T>::type;
0051       static_assert(std::is_trivially_constructible<element_type>::value,
0052                     "Allocating with non-trivial constructor on the pinned host memory is not supported");
0053       void *mem = allocate_host(n * sizeof(element_type), stream);
0054       return typename host::impl::make_host_unique_selector<T>::unbounded_array{reinterpret_cast<element_type *>(mem)};
0055     }
0056 
0057     template <typename T, typename... Args>
0058     typename host::impl::make_host_unique_selector<T>::bounded_array make_host_unique(Args &&...) = delete;
0059 
0060     // No check for the trivial constructor, make it clear in the interface
0061     template <typename T>
0062     typename host::impl::make_host_unique_selector<T>::non_array make_host_unique_uninitialized(cudaStream_t stream) {
0063       void *mem = allocate_host(sizeof(T), stream);
0064       return typename host::impl::make_host_unique_selector<T>::non_array{reinterpret_cast<T *>(mem)};
0065     }
0066 
0067     template <typename T>
0068     typename host::impl::make_host_unique_selector<T>::unbounded_array make_host_unique_uninitialized(
0069         size_t n, cudaStream_t stream) {
0070       using element_type = typename std::remove_extent<T>::type;
0071       void *mem = allocate_host(n * sizeof(element_type), stream);
0072       return typename host::impl::make_host_unique_selector<T>::unbounded_array{reinterpret_cast<element_type *>(mem)};
0073     }
0074 
0075     template <typename T, typename... Args>
0076     typename host::impl::make_host_unique_selector<T>::bounded_array make_host_unique_uninitialized(Args &&...) = delete;
0077   }  // namespace cuda
0078 }  // namespace cms
0079 
0080 #endif