2016-01-03 46 views
-2
包装函数

我生病的看着所有的数据复制到设备的样板CUDA代码,所以我写了这个包装函数:对cudaMalloc和cudaMemcpy

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代码中的内存传输?

+4

提示:为什么'无效F(INT X){X = 42;} INT主要(){诠释J ;缩略词); printf(“%d \ n”,j);返回0;}'不打印42? – immibis

+1

@immibis:可能是因为'j'没有被初始化。 – Olaf

+0

*我实际上并没有通过引用传递指针。* - 你还没有通过引用传递指针。你仍然在传递价值,但是这个值恰好是一个'void **'而不是(错误的)'void *'。在C++中通过引用传递意味着 - 传递引用(引用不是指针)。 – PaulMcKenzie

回答

2

我会做类似

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); 
+0

这比我所拥有的要好。为什么你需要使用nullptr? – zimzam

+1

我更喜欢总是初始化变量。 – Jarod42