【问题标题】:cudaMemcpy2D setting values to 0cudaMemcpy2D 将值设置为 0
【发布时间】:2013-07-30 20:11:14
【问题描述】:

我正在尝试使用 cudaMallocPitch 和 cudaMemcpy2D 将二维数组从主机复制到设备,但我遇到了一个问题,它似乎将我的值设置为 0。

我将在浏览器中编写代码的基础知识。我知道我从内核打印的值不是 0。有什么想法吗?

__global__ void kernel(float **d_array) {
    printf("%f", d_array[0][0]);
}

void kernelWrapper(int rows, int cols, float **array) {
    float **d_array;
    size_t pitch;
    cudaMallocPitch((void**) &d_array, &pitch, rows*sizeof(float), cols);
    cudaMemcpy2D(d_array, pitch, array, rows*sizeof(float), rows*sizeof(float), cols, cudaMemcpyHostToDevice);
    kernel<<<1,1>>>(d_array);
}

由于某种原因,内核一直在打印 0.0000。我知道第一个元素不是 0,因为我测试了打印主机数组的第一个元素。发生了什么?

编辑: 我也尝试了这段代码,但出现了无效的指针错误。

cudaMalloc(d_array, rows*sizeof(float*));
for (int i = 0; i < rows; i++) {
    cudaMalloc((void**) &d_array[i], cols*sizeof(float));
}
cudaMemcpy(d_array, array, rows*sizeof(float*), cudaMemcpyHostToDevice);

【问题讨论】:

  • d_arrayfloat* 类型,而内核参数是 float** 类型。此外,cudaMemcpy2D 无法复制声明为 float** 的数组,因为它不会传染地存储在内存中。
  • 抱歉,d_array 声明是一个错字。好的,那么我如何将浮点**从 CPU 复制到 GPU。我尝试迭代分配内存,但我得到了无效指针错误。

标签: cuda


【解决方案1】:

尽管有它的名称,cudaMemcpy2D 不会将双下标 C 主机数组 (**) 复制到双下标 (**) 设备数组。您会注意到,它希望将单指针 (*) 传递给它,而不是双指针 (**)。 cudaMemcpy2D 用于复制平面跨步数组,而不是二维数组。跨步访问的概念有两个固有的维度,这就是名称的来源。

一般而言,尝试将二维数组从主机复制到设备比仅调用单个 API 更为复杂。建议您展平您的数组,以便您可以使用单个指针 (*) 引用它,然后 API 调用将起作用。有很多在 SO 上正确使用 cudaMemcpy2D 的示例,只需搜索它们即可。

此外,当您在使用 CUDA 代码时遇到困难时,您应该对所有 cuda API 调用和内核调用执行 cuda error checking

如果您真的想直接复制 2D 数组,请查看 this question/answer 的工作示例。这不是微不足道的。

【讨论】:

    猜你喜欢
    • 2020-11-07
    • 2020-10-28
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多