CUDA: Matrix + Matrix, ошибка сегментации при печати матрицы решения на хосте - PullRequest
0 голосов
/ 05 января 2019

Я пытаюсь выполнить простую операцию по добавлению матрицы к другой в CUDA, но у меня возникает ошибка сегментации, когда я пытаюсь проверить результат, вот код:

/* Includes, system */
#include <stdio.h>

#include <cuda.h>
#include <cuda_runtime.h>
#define N 15000

/* DEVICE CODE */
__global__ void sumaMatrices(int *d_matrix1, int *d_matrix2, int *d_matrixSolucion){

    int idThread = blockIdx.x*blockDim.x + threadIdx.x;

    if (idThread < N)
    {
        d_matrixSolucion[idThread] = d_matrix1[idThread] + d_matrix2[idThread];
    }
}

__host__ void printMatrix(int **matrix) 
{
    int i, j;
    //only 4 so the file is not too big
    for (i = 0; i < 4; i++) 
    {
        for (j = 0; j < 4; j++)
        {
            printf("%d", matrix[i][j]);
            printf("  ");
        }
        printf("\n");
    }
    printf("\n");
}

/* HOST CODE*/
int main(int argc, char** argv)
{
    int i;

    int **h_matrix1;
    int **h_matrix2;
    int **h_matrixSolucion;

    int *d_matrix1;
    int *d_matrix2;
    int *d_matrixSolucion;

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

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

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

    cudaMalloc((void**)& d_matrix1,N*N*sizeof(int));
    cudaMalloc((void**)& d_matrix2,N*N*sizeof(int));
    cudaMalloc((void**)& d_matrixSolucion,N*N*sizeof(int));

    fillMatrix(h_matrix1);
    fillMatrix(h_matrix2);
    fillMatrixTo0(h_matrixSolucion);

    for(i = 0; i < N; i++) 
    {
        cudaMemcpy(&d_matrix1[i*N], h_matrix1[i], N*sizeof(int), cudaMemcpyHostToDevice);
        cudaMemcpy(&d_matrix2[i*N], h_matrix2[i], N*sizeof(int), cudaMemcpyHostToDevice);
    }

    int tamBloque = 256;
    int tamGrid = N/tamBloque + 1;
    sumaMatrices<<<tamGrid, tamBloque>>>(d_matrix1, d_matrix2, d_matrixSolucion);

    //nos traemos la información del device
cudaThreadSynchronize();
for(i = 0; i < N; i++) 
{
    cudaMemcpy(h_matrixSolucion[i], &d_matrixSolucion[i*N],tamGrid*sizeof(h_matrixSolucion[0]),cudaMemcpyDeviceToHost);
}

    printMatrix(h_matrix1);
    printMatrix(h_matrix2);
    printMatrix(h_matrixSolucion);
}

Если я прокомментирую эту последнюю строку, то прогамы не выдают никакой ошибки.

Полагаю, проблема в том, что я неправильно храню информацию в ядре (эта строка: d_matrixSolucion [idThread] = d_matrix1 [idThread] + d_matrix2 [idThread];), но я довольно новичок в CUDA и Я действительно не знаю, как это решить.

РЕДАКТИРОВАТЬ: Теперь, когда я изменил способ получения информации с устройства, это то, что печатает:

0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6

2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8

2 4 6 8
0 0 0 0
0 0 0 0
0 0 0 0

Первые 2 матрицы - это те, которые содержат информацию, а другая - решение, но заполнена только 1 строка.

1 Ответ

0 голосов
/ 05 января 2019

В вашем коде множество ошибок.

  1. Не было определения для fillMatrix
  2. Распределение базового хоста, выполняемое с помощью malloc, не обязательно является непрерывным, поэтому вы не можете перенести данные обратно в одну операцию cudaMemcpy, но вы должны использовать цикл, такой как цикл, который вы использовали для передачи данных в графический процессор
  3. Ваше распределение хостов не совсем правильно, но они не представляют реальной проблемы. Это:

    h_matrix1[i] = (int*)malloc(N * sizeof(int*));
    

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

    h_matrix1[i] = (int*)malloc(N * sizeof(int));
    

    и аналогично для других подобных случаев.

  4. Размер вашей сетки (общее количество потоков) неверен. Ваше ядро ​​использует один поток для выполнения одного поэлементного сложения. Поэтому для матрицы NxN вам нужны потоки NxN, а не просто N, которые вы создаете и проверяете.

В следующем коде эти проблемы исправлены и, кажется, работают правильно:

$ cat t2.cu
/* Includes, system */
#include <stdio.h>

#include <cuda.h>
#include <cuda_runtime.h>
#define N 15000

/* DEVICE CODE */
__global__ void sumaMatrices(int *d_matrix1, int *d_matrix2, int *d_matrixSolucion){

    int idThread = blockIdx.x*blockDim.x + threadIdx.x;

    if (idThread < N*N)
    {
        d_matrixSolucion[idThread] = d_matrix1[idThread] + d_matrix2[idThread];
    }
}

__host__ void printMatrix(int **matrix)
{
    int i, j;
    //only 4 so the file is not too big
    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            printf("%d", matrix[i][j]);
            printf("  ");
        }
        printf("\n");
    }
    printf("\n");
}

/* HOST CODE*/
int main(int argc, char** argv)
{
    int i;

    int **h_matrix1;
    int **h_matrix2;
    int **h_matrixSolucion;

    int *d_matrix1;
    int *d_matrix2;
    int *d_matrixSolucion;

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

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

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

    cudaMalloc((void**)& d_matrix1,N*N*sizeof(int));
    cudaMalloc((void**)& d_matrix2,N*N*sizeof(int));
    cudaMalloc((void**)& d_matrixSolucion,N*N*sizeof(int));


    for(i = 0; i < N; i++)
    {
        cudaMemcpy(&d_matrix1[i*N], h_matrix1[i], N*sizeof(int), cudaMemcpyHostToDevice);
        cudaMemcpy(&d_matrix2[i*N], h_matrix2[i], N*sizeof(int), cudaMemcpyHostToDevice);
    }

    int tamBloque = 256;
    int tamGrid = (N*N)/tamBloque + 1;
    sumaMatrices<<<tamGrid, tamBloque>>>(d_matrix1, d_matrix2, d_matrixSolucion);

    cudaThreadSynchronize();
    for(i = 0; i < N; i++)
    {
        cudaMemcpy(h_matrixSolucion[i],&d_matrixSolucion[i*N],N*sizeof(int),cudaMemcpyDeviceToHost);
    }

    printMatrix(h_matrix1);
    printMatrix(h_matrix2);
    printMatrix(h_matrixSolucion);
}
$ nvcc -o t2 t2.cu
$ cuda-memcheck ./t2
========= CUDA-MEMCHECK
1  1  1  1
1  1  1  1
1  1  1  1
1  1  1  1

2  2  2  2
2  2  2  2
2  2  2  2
2  2  2  2

3  3  3  3
3  3  3  3
3  3  3  3
3  3  3  3

========= ERROR SUMMARY: 0 errors
$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...