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_noncached_unique_ptr_h
0002 #define HeterogeneousCore_CUDAUtilities_interface_host_noncached_unique_ptr_h
0003 
0004 #include <memory>
0005 
0006 #include <cuda_runtime.h>
0007 
0008 #include "HeterogeneousCore/CUDAUtilities/interface/cudaCheck.h"
0009 
0010 namespace cms {
0011   namespace cuda {
0012     namespace host {
0013       namespace noncached {
0014         namespace impl {
0015           // Additional layer of types to distinguish from host::unique_ptr
0016           class HostDeleter {
0017           public:
0018             void operator()(void *ptr) { cudaCheck(cudaFreeHost(ptr)); }
0019           };
0020         }  // namespace impl
0021 
0022         template <typename T>
0023         using unique_ptr = std::unique_ptr<T, impl::HostDeleter>;
0024 
0025         namespace impl {
0026           template <typename T>
0027           struct make_host_unique_selector {
0028             using non_array = cms::cuda::host::noncached::unique_ptr<T>;
0029           };
0030           template <typename T>
0031           struct make_host_unique_selector<T[]> {
0032             using unbounded_array = cms::cuda::host::noncached::unique_ptr<T[]>;
0033           };
0034           template <typename T, size_t N>
0035           struct make_host_unique_selector<T[N]> {
0036             struct bounded_array {};
0037           };
0038         }  // namespace impl
0039       }    // namespace noncached
0040     }      // namespace host
0041 
0042     /**
0043    * The difference wrt. make_host_unique is that these
0044    * do not cache, so they should not be called per-event.
0045    */
0046     template <typename T>
0047     typename host::noncached::impl::make_host_unique_selector<T>::non_array make_host_noncached_unique(
0048         unsigned int flags = cudaHostAllocDefault) {
0049       static_assert(std::is_trivially_constructible<T>::value,
0050                     "Allocating with non-trivial constructor on the pinned host memory is not supported");
0051       void *mem;
0052       cudaCheck(cudaHostAlloc(&mem, sizeof(T), flags));
0053       return typename host::noncached::impl::make_host_unique_selector<T>::non_array(reinterpret_cast<T *>(mem));
0054     }
0055 
0056     template <typename T>
0057     typename host::noncached::impl::make_host_unique_selector<T>::unbounded_array make_host_noncached_unique(
0058         size_t n, unsigned int flags = cudaHostAllocDefault) {
0059       using element_type = typename std::remove_extent<T>::type;
0060       static_assert(std::is_trivially_constructible<element_type>::value,
0061                     "Allocating with non-trivial constructor on the pinned host memory is not supported");
0062       void *mem;
0063       cudaCheck(cudaHostAlloc(&mem, n * sizeof(element_type), flags));
0064       return typename host::noncached::impl::make_host_unique_selector<T>::unbounded_array(
0065           reinterpret_cast<element_type *>(mem));
0066     }
0067 
0068     template <typename T, typename... Args>
0069     typename host::noncached::impl::make_host_unique_selector<T>::bounded_array make_host_noncached_unique(Args &&...) =
0070         delete;
0071   }  // namespace cuda
0072 }  // namespace cms
0073 
0074 #endif