Как создать матрицу в GPU и распечатать ее на CPU? - PullRequest
0 голосов
/ 19 апреля 2019

Это код для создания матрицы на GPU и распечатки ее на CPU.Может кто-нибудь сказать мне, где я иду не так.Спасибо.

# include <stdio.h>


__global__ void create(int **d_a){
    int i = threadIdx.x;
    int j = threadIdx.y;

    d_a[i][j] = 1;
}


void errorCheck(){
    cudaError_t error = cudaGetLastError();
    if(error != cudaSuccess){
        // print the CUDA error message and exit
        printf("CUDA error: %s\n", cudaGetErrorString(error));
        exit(-1);
    }
}

# define N 5
int main(){
    int **d_a, **a;

    a = (int**)malloc(N * sizeof(int*));

    for (int i =0; i < N; i++){
        a[i] = (int*)malloc(N*sizeof(int));
    }

    cudaMalloc((void***)&d_a, N*sizeof(int*));

    for (int i =0; i < N; i++){
        cudaMalloc((void**)&d_a,N*sizeof(int));
    }

    errorCheck();
    create <<<1, N>>>(d_a);
    errorCheck();
    cudaMemcpy(a, d_a, (N*N)*sizeof(int),cudaMemcpyDeviceToHost);


    for (int i =0; i < N; i++ ){
        for (int j = 0; j < N; j++ ){
            printf("%d", a[i][j]);
        }
        printf("\n");
    }

    cudaFree(d_a);
    free(a);

    return 0;
}

Что-то не так с распределением памяти или memcpy?

1 Ответ

1 голос
/ 19 апреля 2019

Что-то не так с распределением памяти или memcpy?

Да, по обоим пунктам.

Это:

cudaMalloc((void***)&d_a, N*sizeof(int*));
for (int i =0; i < N; i++){
    cudaMalloc((void**)&d_a,N*sizeof(int));
}

должно быть сделано так:

cudaMalloc((void***)&d_a, N*sizeof(int*));
for (int i=0; i < N; i++){
    int *row;
    cudaMalloc((void**)&row, N*sizeof(int));
    cudaMemcpy(d_a+i, &row, sizeof(int*), cudaMemcpyHostToDevice);
}

А потом вот это:

create <<<1, N>>>(d_a);
errorCheck();
cudaMemcpy(a, d_a, (N*N)*sizeof(int),cudaMemcpyDeviceToHost);

должно быть сделано так:

create <<<1, dim3(N,N)>>>(d_a);
errorCheck();
for(int i=0; i<N; i++) {
    int* row;
    cudaMemcpy(&row, d_a+i, sizeof(int*), cudaMemcpyDeviceToHost);
    cudaMemcpy(a[i], row, sizeof(int) * N, cudaMemcpyDeviceToHost);
}

[Весь код написан в браузере и не проверен, используйте на свой страх и риск]

Короче говоря, вы решили работать с массивом указателей. Это требует дополнительных операций API CUDA, потому что указатели строк в копии GPU не доступны на хосте при стандартном назначении. Вы должны использовать cudaMemcpy в каждом случае.

...