使用以下简单的删除器
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) );
}
答案 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 );
}