cudaMemcpy2D将值设置为0

时间:2013-07-30 15:23:48

标签: cuda

我正在尝试使用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);

1 个答案:

答案 0 :(得分:3)

尽管名称如此,但cudaMemcpy2D并未将双重订阅的C主机阵列(**)复制到双下标(**)设备阵列。你会注意到它希望将单指针(*)传递给它,而不是双指针(**)。 cudaMemcpy2D用于复制平坦的跨步阵列,而不是2维阵列。 strided access的概念有两个固有的维度,即名称的来源。

通常,尝试将2D阵列从主机复制到设备比单个API调用更复杂。建议您展平数组,以便可以使用单个指针(*)对其进行引用,然后API调用将起作用。有很多关于在SO上正确使用cudaMemcpy2D的例子,只需要搜索它们。

此外,只要您遇到CUDA代码有困难,就应该对所有cuda API调用和内核调用执行cuda error checking

如果您确实想直接复制2D数组,请查看this question/answer以获取有用的示例。这不是微不足道的。