[英]Copying a dynamically allocated 2D array from host to device in CUDA
我想將動態分配的2D數組從主機復制到設備,以獲取其離散傅立葉變換。
我正在使用下面的代碼將數組復制到設備
cudaMalloc((void**)&array_d, sizeof(cufftComplex)*NX*(NY/2+1));
cudaMemcpy(array_d, array_h, sizeof(float)*NX*NY, cudaMemcpyHostToDevice);
這與靜態數組很好地工作,我從我的fft獲得預期的輸出。 但是它不適用於動態數組。 經過一些搜索后,我了解到無法將這樣的動態數組從主機復制到設備。 所以我找到了這個解決方案。
cudaMalloc((void**)&array_d, sizeof(cufftComplex)*NX*(NY/2+1));
for(int i=0; i<NX; ++i){
cudaMemcpy(array_d+ i*NY, array_h[i], sizeof(float)*NY, cudaMemcpyHostToDevice);
}
但是由於我從fft中獲取了錯誤的值,因此它也無法正確執行任務。
下面是我的fft代碼。
cufftPlanMany(&plan, NRANK, n,NULL, 1, 0,NULL, 1, 0,CUFFT_R2C,BATCH);
cufftSetCompatibilityMode(plan, CUFFT_COMPATIBILITY_NATIVE);
cufftExecR2C(plan, (cufftReal*)data, data);
cudaThreadSynchronize();
cudaMemcpy(c, data, sizeof(float)*NX*NY, cudaMemcpyDeviceToHost);
我該如何克服這個問題?
編輯
下面給出的是代碼
#define NX 4
#define NY 5
#define NRANK 2
#define BATCH 10
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <cufft.h>
#include <stdio.h>
#include <iostream>
int check();
int main()
{
// static array
float b[NX][NY] ={
{0.7943 , 0.6020 , 0.7482 , 0.9133 , 0.9961},
{0.3112 , 0.2630 , 0.4505 , 0.1524 , 0.0782},
{0.5285 , 0.6541 , 0.0838 , 0.8258 , 0.4427},
{0.1656 , 0.6892 , 0.2290 , 0.5383 , 0.1067}
};
// dynamic array
float **a = new float*[NX];
for (int r = 0; r < NX; ++r)
{
a[r] = new float[NY];
for (int c = 0; c < NY; ++c)
{
a[r][c] = b[r][c];
}
}
// arrray to store the results - host side
float c[NX][NY] = { 0 };
cufftHandle plan;
cufftComplex *data;
int n[NRANK] = {NX, NY};
cudaMalloc((void**)&data, sizeof(cufftComplex)*NX*(NY/2+1));
cudaMemcpy(data, b, sizeof(float)*NX*NY, cudaMemcpyHostToDevice);
/* Create a 2D FFT plan. */
cufftPlanMany(&plan, NRANK, n,NULL, 1, 0,NULL, 1, 0,CUFFT_R2C,BATCH);
cufftSetCompatibilityMode(plan, CUFFT_COMPATIBILITY_NATIVE);
cufftExecR2C(plan, (cufftReal*)data, data);
cudaThreadSynchronize();
cudaMemcpy(c, data, sizeof(float)*NX*NY, cudaMemcpyDeviceToHost);
cufftDestroy(plan);
cudaFree(data);
return 0;
}
data
是cufftComplex
類型,它是一系列typedef,最終導致float2
。 這意味着data + n
將使data
前進float2
類型的n
對象,或float
類型2 * n
對象。 這使您的“動態數組”復制不正確; 您必須將data
增量減半。
編輯
查看參數cufftExecR2C()
,我認為這應該工作:
for(int i=0; i<NX; ++i){
cudaMemcpy(reinterpret_cast<float*>(data) + i*NY, a[i], sizeof(float)*NY, cudaMemcpyHostToDevice);
}
旁注:您實際上沒有動態2D數組(該數組為new float[NX * NY]
)。 您擁有的是一個動態指針數組,該指針指向浮點數的動態數組。 我相信使用真正的2D數組對您來說更有意義,這也使您可以保留靜態大小寫的復制代碼。
並且,由於已經標記了此C ++,因此您應該認真考慮使用std::vector
而不是手動管理動態內存。 也就是說,更改a
像這樣的:
std::vector<float> a(NX * NY);
當您使用它時,我建議將NX
, NY
等從宏轉換為常量:
const size_t NX = 4;
const size_t NY = 5;
等等
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.