我正在尝试在CUDA中使用设备定义的全局内存。 此变量在.cuh文件中声明。
在另一个文件中.cu是我用来做cudaMallocs和cudaMemCpy的主要文件。
这是我的代码的一部分:
cudaMalloc((void**)&varOne,*tam_varOne * sizeof(cuComplex));
cudaMemcpy(varOne,C_varOne,*tam_varOne * sizeof(cuComplex),cudaMemcpyHostToDevice);
varOne在.cuh文件中声明如下:
__device__ cuComplex *varOne;
当我启动我的内核(我没有将varOne作为参数传递)并尝试使用调试器读取varOne时,它表示无法读取变量。指针指向它000..0,所以显然它是错误的。
那么,我如何在CUDA中声明和复制全局内存?
答案 0 :(得分:2)
您必须首先定义将保存将复制到CUDA的数据的指针:
在上面的示例中,我们将数组original_cpu_array
复制到CUDA全局内存。
int original_cpu_array[array_size];
int *array_cuda;
计算数据占用的大小。
int size = array_size * sizeof(int);
Cuda内存分配:
msg_erro[0] = cudaMalloc((void **)&array_cuda,size);
从CPU复制到GPU:
msg_erro[0] = cudaMemcpy(array_cuda, original_cpu_array,size,cudaMemcpyHostToDevice);
执行内核
从GPU复制到CPU:
msg_erro[0] = cudaMemcpy(original_cpu_array,array_cuda,size,cudaMemcpyDeviceToHost);
免费记忆:
cudaFree(array_cuda);
对于调试,我通常会在数组上保存函数的状态(cudaError_t msg_erro [var];)。但是,这不是绝对必要的,但如果在分配或内存转移期间发生错误,将节省您的时间。
如果发生错误,我会使用以下内容进行打印:
void printErros(cudaError_t *erros,int size, int flag)
{
for(int i = 0; i < size; i++)
if(erros[i] != 0)
{
if(flag == 0) printf("Alocacao de memoria");
if(flag == 1) printf("CPU -> GPU ");
if(flag == 2) printf("GPU -> CPU ");
printf("{%d} => %s\n",i ,cudaGetErrorString(erros[i]));
}
}
该标志主要用于指示代码中发生错误的部分。例如,在内存分配之后:
msg_erro[0] = cudaMalloc((void **)&array_cuda,size);
printErros(msg_erro,msg_erro_size, 0);
答案 1 :(得分:0)
我已经尝试了一些例子,发现你不能直接在内核中使用全局变量而不传递给它。即使您在.cuh文件中初始化,也需要在main()中初始化。
原因:
cudaMalloc((void**)&varOne,sizeof(cuComplex))
来分配内存。它只能在GPU上分配内存。声明__device__ cuComplex *varOne;
就像原型和变量声明一样。但是,在使用cudaMalloc((void**)&varOne,sizeof(cuComplex))
之前,不会分配内存。*varOne
初始化为Host指针。使用cudaMalloc()
后,它会知道指针是设备指针。步骤顺序为:(对于我测试过的代码)
int *Ad; //If you can allocate this in .cuh file, you dont need the shown code in main()
__global__ void Kernel(int *Ad){
....
}
int main(){
....
int size=100*sizeof(int);
cudaMalloc((void**)&Ad,size);
cudaMemcpy(Ad,A,size,cudaMemcpyHostToDevice);
....
}