检测我的代码中的问题时遇到问题| CUDA c

问题描述

我很难理解代码中的错误在哪里。

该项目的目的是将两个矩阵相乘并比较顺序和并行之间的时间。

当我打印矩阵时,我看到设备矩阵基本上是空的。

此外,我将矩阵视为大小为n * n的数组。

谢谢!

//This program computes the multiplication of two Matrices  GPU using CUDA

#include <stdio.h>
#include <cassert>


__global__ void matrixMul(int * m,int * n,int * p,int size)
{
    //Calculate Row and Column
   int row=threadIdx.y*blockDim.y+threadIdx.y;
    int column=threadIdx.x*blockDim.x+threadIdx.x;
   int p_sum=0;

   for (int i = 0; i < size; i++)
   {
      p_sum += m[row*size + i] * n[i*size +column];

   }
   p[row*size + column] = p_sum;

}

void matrixMul_seq(int * m,int size){
    for(int i = 0; i < size; i++){
        for(int j = 0; j < size; j++){
            for(int k = 0; k < size; k++){
                p[i*size +j] += m[i*size +k] +n[k*size +j];
            }
        }
    }
}



//Initialize matricies
void init_matricies(int * mat,int n){
    for(int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++)
        {
            mat[i*n+j]=rand()%1024;
        }
        
    }
}

int main(int argc,char **argv)
{

   //Set our problem Size(Default = 2^10 == 1024)
   int n = 1<<10;
   printf("Square Matrix of size:%d\n",n);

   //Size in Bytes
   size_t bytes=n*n*sizeof(bytes);

   //Host matricies
   int *h_m;
   int *h_p;    
   int *h_n;
   int *h_p_seq;
   //Host matricies
   int *d_m;
   int *d_p;    
   int *d_n;


   //Memory allocation for Host Matricies
   h_m=(int*)malloc(bytes);
   h_n=(int*)malloc(bytes);
   h_p=(int*)malloc(bytes);
   h_p_seq=(int*)malloc(bytes);



   init_matricies(h_m,n);
   init_matricies(h_n,n);

   //Allocate memory on device side
   cudaMalloc(&d_n,bytes);
   cudaMalloc(&d_m,bytes);
   cudaMalloc(&d_p,bytes);

   //Copy data to Device
   cudaMemcpy(d_m,h_m,bytes,cudaMemcpyHostToDevice);
   cudaMemcpy(d_n,h_n,cudaMemcpyHostToDevice); 

    
   int threads_per_block =16;
   dim3 block_size(threads_per_block,threads_per_block);
   dim3 grid_size( n / block_size.x,n / block_size.y);

   printf("Grid size  X:%d,Grid size y:%d\n",grid_size.x,grid_size.y);
   printf("THE RESULT OF THE SIZES: 2^6 * 2^4 * 2^6 * 2^4  \n");

   matrixMul <<<grid_size,block_size>>>(d_m,d_n,d_p,n);
   matrixMul_seq(h_m,h_p_seq,n);
   cudaMemcpy(h_p,cudaMemcpyDeviceToHost);   

    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
        //printf("Grid size  X:%d,h_p[ n * i + j],h_p_seq[ n * i + j]);

            assert(h_p[ n * i + j]==h_p_seq[ n * i + j]);
    }
 }
    free(h_m);
    free(h_p);
    free(h_n);
    free(h_p_seq);

    cudaFree(d_m);
    cudaFree(d_n);
    cudaFree(d_p);
  

     return 0;
  

}

解决方法

您的代码中存在各种问题:

  1. 您正在错误地计算内核索引变量。这是不正确的:

    int row=threadIdx.y*blockDim.y+threadIdx.y;
    int column=threadIdx.x*blockDim.x+threadIdx.x;
    

    应该是:

    int row=blockIdx.y*blockDim.y+threadIdx.y;
    int column=blockIdx.x*blockDim.x+threadIdx.x;
    
  2. 您的计算函数中的矩阵运算不匹配。内核:

    p_sum += m[row*size + i] * n[i*size +column];
                             ^
                             multiplication
    

    主机代码:

    p[i*size +j] += m[i*size +k] +n[k*size +j];
                                 ^
                                 addition
    

    我们还从上面观察到,宿主代码对输出变量(+=求和,而内核在做赋值 em>到输出变量(=):

    p[row*size + column] = p_sum;
    

    这与下一个问题有关。

  3. malloc不初始化数据。由于此操作正在创建将由宿主代码使用的输出数组,并对其求和,因此我们必须将此分配初始化为零:

    h_p_seq=(int*)malloc(bytes);
    memset(h_p_seq,bytes);  // must add this line to initialize to zero
    
  4. 以字节为单位的数组大小的计算太大。您已将数组定义为int类型。但是您的尺寸计算是这样的:

    size_t bytes=n*n*sizeof(bytes);
    

    int是4字节的数量,而size_t之类的bytes变量是8字节的数量。这不会引起实际问题,但是不必要。我建议将其更改为:

    size_t bytes=n*n*sizeof(int);
    

解决了以上问题,您的代码对我而言正确运行。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...