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 に答える