【问题标题】:CUDA copying array from device to host using cudaMemcpy2D使用 cudaMemcpy2D 将 CUDA 数组从设备复制到主机
【发布时间】:2016-04-27 00:20:04
【问题描述】:

cudaMemcpy2D 没有按照我的预期进行复制。在阅读了有关cudaMallocPitch 的手册后,我尝试编写一些代码来了解发生了什么。但是,我遇到了一个问题。

我做了这样的简单程序:

int main()
{
    double *d_A;
    size_t d_pitch;

    cudaMallocPitch((void**)&d_A, &d_pitch, sizeof(double) * SIZE, SIZE);

    dim3 blocks(4, 4);
    dim3 threads(16, 16);

    doStuff<<<blocks, threads>>>(d_A, d_pitch);

    double *A;
    size_t pitch = sizeof(double) * SIZE;

    A = (double*)malloc(sizeof(double) * SIZE * SIZE);

    cudaMemcpy2D(A, pitch, d_A, d_pitch, sizeof(double) * SIZE, SIZE, cudaMemcpyDeviceToHost);

    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) printf("%f ", A[sizeof(double) * i + j]);
        printf("\n");
    }
}

而doStuff 是:

__global__ void doStuff(double *d_A, size_t d_pitch)
{
    unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;
    unsigned int j = blockIdx.y * blockDim.y + threadIdx.y;
    double *target = ( (double*)(((char*)d_A) + (d_pitch * i)) ) + j;

    if (i < SIZE && j < SIZE)
        *target = (i + 1) * (j + 1) + 0.0;
}

所以doStuff 与d_A[i][j] = (i+1)*(j+1) 相同。如果SIZE 是 5,我的预期是:

1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25

双精度。但是,当我编译并运行时,我得到了:

1 2 3 4 5
8 10 3 6 9
8 12 16 20 5
25 0 0 0 0
0 0 0 0 0

似乎对于每一行,cudaMemcpy2D 都会覆盖以前的数据。我试图找出改变间距和宽度的问题,但我找不到。

那么我的代码发生了什么?

【问题讨论】:

    标签: c cuda nvidia


    【解决方案1】:

    错误在这一行:

        for (int j = 0; j < SIZE; j++) printf("%f ", A[sizeof(double) * i + j]);
    

    应该是:

        for (int j = 0; j < SIZE; j++) printf("%f ", A[SIZE * i + j]);
    

    您希望将行索引 (i) 缩放为以元素为单位的行大小(而不是以字节为单位的元素大小)。

    这当然与 CUDA 无关。

    【讨论】:

    • 哇...好尴尬 :(你说的对
    猜你喜欢
    • 2017-08-27
    • 2018-03-15
    • 2023-03-14
    • 2013-09-20
    • 2011-08-24
    • 2013-03-25
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多