在尝试了解cudaMalloc()对于二维矩阵的工作原理时,我遇到了以下帖子:

Using cudaMalloc to allocate a matrix

我想澄清一些由on爪给出的答案,因此创建了这个单独的帖子。 Talonmies提供了以下解决方案。

float **pa;
float **pah = (float **)malloc(pah, N * sizeof(float *));
cudaMalloc((void***)&pa,  N*sizeof(float*));
for(i=0; i<N; i++) {
    cudaMalloc((void**) &(pah[i]), N*sizeof(float));
    cudaMemcpy (pah[i], A[i], N*sizeof(float), cudaMemcpyHostToDevice);
}
cudaMemcpy (pa, pah, N*sizeof(float *), cudaMemcpyHostToDevice);


第5行中的代码:

cudaMalloc((void**) &(pah[i]), N*sizeof(float));


在设备存储器中创建一个块N * float空间,并将设备存储器的第i个块的起始地址放入pah [i]。 pah [i]驻留在主机内存中,但是每个pah [i]的内容都是在设备中创建的内存的地址。

问题1>以上理解正确吗?

第6行中的代码:

 cudaMemcpy (pah[i], A[i], N*sizeof(float), cudaMemcpyHostToDevice);


将A [i]从主机复制到pah [i]的内容(pah [i]的内容是N * float块中每个块的起始地址)。

问题2>对主机内存如何复制到设备内存的上述理解正确吗?

为了像二维数组一样访问设备中的(N,N)个内存块(由上面的第5行创建),我们现在需要将所有pah [i]的内容复制到指针中。设备。因此,首先通过第3行中的代码在设备中创建N个浮点指针,然后使用第8行中的代码将N * float块的地址从pah [i]复制到pa。之后,我们将能够访问位于主机中的A [i] [j]和位于设备中的pa [i] [j]的内容。

问题3>以上理解正确吗?

现在说我生成N * N线程,并使用每个线程的线程ID更改pa [i] [j]的内容。然后,我想将驻留在设备中的pa [i] [j]的内容复制回驻留在主机中的A [i] [j]。下面的代码行会完成这项工作吗,还是我犯了任何错误?

for (i=0; i<N; i++)
  cudaMemcpy(A[i], pa[i], N*sizeof(float), cudaMemcpyDeviceToHost);


在此先感谢所有帮助我阐明这些疑问/问题的人。

最好

最佳答案

问题1>以上理解正确吗?


是。


  问题2>对主机内存如何复制到设备内存的上述理解正确吗?


也许。我会说:“将N * sizeof(float)字节从A[i]中包含的(主机)地址开始,从主机复制到设备,并从pah[i]中包含的设备地址开始。”


  问题3>以上理解正确吗?


是的,我可能在措辞上有些不同,但所做的更改似乎很小。我想你已经明白了。


  下面的代码行能完成这项工作吗,还是我犯错了?


它应该是:

for (i=0; i<N; i++)
  cudaMemcpy(A[i], pah[i], N*sizeof(float), cudaMemcpyDeviceToHost);


您实际上是想撤消第6行中包含的操作。
  当您遇到CUDA代码问题时,请不要忘记使用proper cuda error checking

09-07 00:08