我厌倦了查看将数据复制到设备的所有样板cuda代码,所以我编写了这个包装函数:
void allocateAndCopyToDevice(void* device_array, const void* host_array, const size_t &count)
{
gpuErrchk(cudaMalloc((void**)&device_array, count));
gpuErrchk(cudaMemcpy(device_array, host_array, count, cudaMemcpyHostToDevice));
}
但由于某种原因,每当使用以这种方式初始化的数组时,这会导致超出内存访问。我使用的初始化代码如下所示:
cuDoubleComplex *d_cmplx;
allocateAndCopyToDevice(d_cmplx,cmplx,size*sizeof(cuDoubleComplex));
有人可以解释为什么这不起作用吗?
在看到immibis的评论之后,我意识到cudaMalloc需要一个指向指针的指针,所以我通过值传递指向指针的指针:
void allocateAndCopyToDevice(void** device_array, const void* host_array, const size_t &count)
{
gpuErrchk(cudaMalloc(device_array, count));
gpuErrchk(cudaMemcpy(*device_array, host_array, count, cudaMemcpyHostToDevice));
}
,初始化现在看起来像这样:
cuDoubleComplex *d_cmplx;
allocateAndCopyToDevice((void **)&d_cmplx,cmplx,size*sizeof(cuDoubleComplex));
它有效,但我仍然想知道是否有更好的方法可以做到这一点?其他人如何使用cuda代码处理内存传输?
答案 0 :(得分:3)
我会做像
这样的事情template <typename T>
T* allocateAndCopyToDevice(const T* host_array, std::size_t count)
{
// some static_assert for allowed types: pod and built-in.
T* device_array = nullptr;
gpuErrchk(cudaMalloc(&device_array, count * sizeof(T)));
gpuErrchk(cudaMemcpy(device_array, host_array, count * sizeof(T), cudaMemcpyHostToDevice));
return device_array;
}
并使用它:
cuDoubleComplex *d_cmplx = allocateAndCopyToDevice(cmplx, size);