Cuda矩阵加法

时间:2016-04-13 04:10:10

标签: matrix parallel-processing cuda gpu

我已经编写了以下代码来汇总cuda中的两个4x4矩阵。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

__global__ void Matrix_add(double* a, double* b, double* c,int n)
{
   int row = blockIdx.x * blockDim.x + threadIdx.x;
   int col = blockIdx.y * blockDim.y + threadIdx.y;
   int index = row * n + col;
   if(col<n && row <n)
      c[index] = a[index] + b[index];
}
int main()
{

int n=4;

double **h_a;
double **h_b;
double **h_c;
double *d_a, *d_b, *d_c;

int size = n*n*sizeof(double);

h_a = (double **) malloc(n*sizeof(double*));
h_b = (double **) malloc(n*sizeof(double*));
h_c = (double **) malloc(n*sizeof(double*));

cudaMalloc((void**)&d_a,size);
cudaMalloc((void**)&d_b,size); 
cudaMalloc((void**)&d_c,size);

int t=0;
for (t=0;t<n;t++)
{   
        h_a[t]= (double *)malloc(n*sizeof(double));
        h_b[t]= (double *)malloc(n*sizeof(double));
        h_c[t]= (double *)malloc(n*sizeof(double));
}   

int i=0,j=0;

for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
     {
         h_a[i][j]=sin(i)*sin(i);
         h_b[i][j]=cos(i)*cos(i);
     }
}

cudaMemcpy(d_a,h_a+n,size,cudaMemcpyHostToDevice);
cudaMemcpy(d_b,h_b+n,size,cudaMemcpyHostToDevice);

dim3 dimBlock(4,4);
dim3 dimGrid(1,1);
Matrix_add<<<dimGrid, dimBlock>>>(d_a,d_b,d_c,n);
cudaMemcpy(h_c+n,d_c,size,cudaMemcpyDeviceToHost);

for(i=0;i<n;i++)
{
  for( j=0;j<n;j++)
        {
            printf("%f",h_c[i][j]);
            printf("\t");
        }
  printf("\n");
}

for(i=0;i<n;i++)
  {
        free(h_a[i]);
        free(h_b[i]);
        free(h_c[i]);
}
free(h_a);
free(h_b);
free(h_c);
cudaFree(d_a); cudaFree(d_b); cudaFree(d_c);
return 0;

}

这个加法的结果应该是一个2x2的全1矩阵,但结果矩阵的所有元素都是0.我得到结果后得到这个消息:

  

分段错误(核心转储)

任何人都可以帮我找出问题所在。

谢谢

1 个答案:

答案 0 :(得分:6)

您的主机阵列(h_a,h_b,h_c)在内存中不连续,因此您的初始cudaMemcpy()调用会将垃圾读入GPU内存(在您的情况下显然为零)。

原因是你的主机数组实际上并不是平的,而是表示为指针数组。我想用C伪造二维数组?在任何情况下,您都需要更加小心cudaMemcpy()并逐行复制主机数组,或者在主机上使用平面表示。