// // Created by postaron on 25/03/24. // #ifndef RAIISAFECUDA_MALLOC_UNMANAGED_HPP #define RAIISAFECUDA_MALLOC_UNMANAGED_HPP #include #include #include #include namespace safe_cuda { enum class allocType : std::uint8_t { Unmanaged = 0, Managed = 1, Host = 2, }; template struct destroyType { void operator()(T *ptr) const noexcept { (void) cudaFree(ptr); } }; template struct destroyType { void operator()(T *ptr) const noexcept { (void) cudaFree(ptr); } }; template struct destroyType { void operator()(T *ptr) const noexcept { (void) cudaFreeHost(ptr); } }; template > requires std::integral || std::floating_point using safePtrType = std::unique_ptr; /** * \brief It allocates unmanaged memory with cuda runtime API. * * It can allocate unmanaged memory on device and on Host for pinned memory. * \tparam T bare and built-in type. * \tparam alloc_type Type of allocation: Managed (default), Unmanage, Host. * \param byteDataSize * \return */ template std::pair, cudaError_t> cuda_malloc(const std::size_t byteDataSize) noexcept { T *ptr_tmp = nullptr; cudaError_t error = cudaSuccess; switch (alloc_type) { case allocType::Unmanaged: error = cudaMalloc(reinterpret_cast(&ptr_tmp), byteDataSize); return { safePtrType{ ptr_tmp, destroyType{} }, error }; case allocType::Host: error = cudaMallocHost(reinterpret_cast(&ptr_tmp), byteDataSize); return { safePtrType{ ptr_tmp, destroyType{} }, error }; case allocType::Managed: error = cudaMallocManaged(reinterpret_cast(&ptr_tmp), byteDataSize); return { safePtrType{ ptr_tmp, destroyType{} }, error }; } } } #endif //RAIISAFECUDA_MALLOC_UNMANAGED_HPP