0

所以我试图将一个锯齿状数组从主机复制到设备。首先这里是我目前对cudaMalloc和cudaMemcpy的理解:

cudaMalloc 获取指向内存块指针的指针。

cudaMemcpy 需要一个指向要复制到或从中复制的内存块的指针。

如果我错了,请纠正我。

现在这是我的代码不起作用(编译正常但没有输出):

__global__ void kernel(int** arr)
{
    for (int i=0; i<3; i++)
    printf("%d\n", arr[i][0]);
}

int main()
{
    int arr[][3] = {{1},{2},{3}}; // 3 arrays, 1 element each

    int **d_arr;

    cudaMalloc((void**)(&d_arr), sizeof(int*)*3); // allocate for 3 int pointers

    for (int i=0; i<3; i++)
    {
    cudaMalloc( (void**)  &(d_arr[i]), sizeof(int) * 1 ); // allocate for 1 int in each int pointer

    cudaMemcpy(d_arr[i], arr[i], sizeof(int) * 1, cudaMemcpyHostToDevice); // copy data
    }

    kernel<<<1,1>>>(d_arr);

    cudaDeviceSynchronize();
    cudaDeviceReset();
}

那么我在这里做错了什么?干杯

4

2 回答 2

1

我发现了原因,这是因为 cudaMalloc 和 cudaMemcpy 期望指针存在于主机上而不是设备上。

在我的 for 循环中,我试图在主机上运行的代码中填充设备上存在的指针!

正确的方法是创建一个中间变量,一个指向设备内存的主机指针,用整数填充它,然后将该指针复制到锯齿状数组中(指针上的指针)!

这是正确的版本:

__global__ void kernel(int** arr)
{
    for (int i=0; i<3; i++)
        printf("%d\n", arr[i][0]);
}

int main()
{
    int arr[][3] = {{1},{2},{3}}; // 3 arrays, 1 element each

    int **d_arr;

    cudaMalloc((void***)(&d_arr), sizeof(int*)*3); // allocate for 3 int pointers

    for (int i=0; i<3; i++)
    {

        int* temp;

        cudaMalloc( (void**)  &(temp), sizeof(int) * 1 ); // allocate for 1 int in each int pointer

        cudaMemcpy(temp, arr[i], sizeof(int) * 1, cudaMemcpyHostToDevice); // copy data

        cudaMemcpy(d_arr+i, &temp, sizeof(int*), cudaMemcpyHostToDevice);
    }

    kernel<<<1,1>>>(d_arr);

    cudaDeviceSynchronize();
    cudaDeviceReset();
}
于 2013-04-17T13:01:23.027 回答
0
  1. 您的内核调用printf(),它曾经是(直到 CC2.0)一个主机函数。这里一切正常。;)

  2. cudaMemcpy((void*)d_arr, (void*)arr, sizeof(int*)*3, cudaMemcpyHostToDevice);将主机上阵列的内存地址复制到设备。这是没有意义的。因为您现在有指向设备上主机内存的指针。

  3. 您不能在 CUDA 中以特定方式分配二维数组。请参阅http://www.stevenmarkford.com/allocating-2d-arrays-in-cuda/

于 2013-04-17T13:11:37.560 回答