我正在尝试做一个简单的操作,将一个矩阵添加到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行。
答案 0 :(得分:1)
您的代码中存在各种错误。
fillMatrix
的定义malloc
执行的基础主机分配是连续的,因此您不能通过单个cudaMemcpy
操作来回传数据,但是必须使用一个循环,例如使用的循环将数据传输到GPU 您的主机分配不是很正确,但是它们并不构成实际问题。这个:
h_matrix1[i] = (int*)malloc(N * sizeof(int*));
应该是这样:
h_matrix1[i] = (int*)malloc(N * sizeof(int));
,其他类似实例也是如此。
您的网格(线程总数)大小不正确。您的内核使用一个线程执行一个元素级加法。因此,对于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
$