为什么nvcc失败允许将类型为T *的指针强制转换为void *?

时间:2013-02-19 12:49:05

标签: cuda nvcc

使用以下简单的删除器

struct CudaDeleter{ void operator()(void * ptr) { cudaFree( ptr ); } };

在使用nvcc编译的代码中使用删除器时出现以下错误。相同的删除程序与vs2012编译器

一起正常工作
warning : "std::unique_ptr<_Ty, _Dx>::unique_ptr(
const std::unique_ptr<_Ty, _Dx>::_Myt &)
[with _Ty=const int, _Dx=cuda::CudaDeleter]"

error : function "cuda::CudaDeleter::operator()"
cannot be called with the given argument list

warning : "std::unique_ptr<_Ty, _Dx>::unique_ptr(
const std::unique_ptr<_Ty, _Dx>::_Myt &)
[with _Ty=float, _Dx=cuda::CudaDeleter]"

@talonmies:仅使用此功能构建智能指针

template <typename T>
std::unique_ptr<T, CudaDeleter> make_unique(size_t size)
{
    void * pMemory = nullptr;
    check( cudaMalloc(&pMemory, size) );
    return std::unique_ptr<T, CudaDeleter>( static_cast<T*>(pMemory) );
}

2 个答案:

答案 0 :(得分:5)

以下适用于我。尝试下面的独立代码,如果它有效,那么你需要确定代码的差异,如果没有,那么你的设置就会有所不同。

#include <iostream>
#include <memory>

struct CudaDeleter
{
    void operator()(void *p)
    {
        std::cout << "Free..." << std::endl;
        cudaError_t res = cudaFree(p);
        if (res != cudaSuccess)
        {
            std::cout << "Error freeing: " << cudaGetErrorString(res) << std::endl;
        }
    }
};

template <typename T>
std::unique_ptr<T, CudaDeleter> make_unique(size_t size)
{
    void *pMemory = nullptr;
    std::cout << "Allocate..." << std::endl;
    cudaError_t res = cudaMalloc(&pMemory, size);
    if (res != cudaSuccess)
    {
        std::cout << "Error allocating pMemory: " << cudaGetErrorString(res) << std::endl;
        throw;
    }
    return std::unique_ptr<T, CudaDeleter>(static_cast<T*>(pMemory));
}

int main(void)
{
    {
        std::cout << "Create..." << std::endl;
        std::unique_ptr<float, CudaDeleter> x = make_unique<float>(100*sizeof(float));
        std::cout << "Destroy..." << std::endl;
    }
    std::cout << "Done." << std::endl;
}

答案 1 :(得分:0)

我发现了我遇到的问题,最后这是我的错误

并不是任何T *都不能被转换为void *但是const T *不能被转换为void *。

此外,cudaFree无法释放指向const的指针,这意味着Eric的建议

template<class T> struct CudaDeleter{ void operator()(T* ptr){...}}

不行。

这样的东西会起作用

template <typename T>
std::unique_ptr<typename std::remove_const<T>::type, CudaDeleter> make_unique(size_t size)
{
    typename std::remove_const<T>::type * pMemory = nullptr;
    check( cudaMalloc(&pMemory, size) );
    return std::unique_ptr<typename std::remove_const<T>::type, CudaDeleter>( pMemory );
}