2016-01-03 73 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