簡體   English   中英

Cuda進行矩陣乘法

[英]Cuda to make Matrix Multiplication

使用cuda進行矩陣乘法時遇到問題。 我必須做A * A * A * A並將其保存在hB中。 使用Cublas可以,但是我不能使用CUDA。 Dimension可能是一個很高的值,例如2000。這是我的代碼:

__global__ void CudaMM(float *A, float *B, int N)
{

    int row = blockIdx.y*blockDim.y + threadIdx.y;
    int col = blockIdx.x*blockDim.x + threadIdx.x;

    float sum = 0.f;
    for (int n = 0; n < N; ++n)
        sum += A[row*N+n]*A[n*N+col];

    B[row*N+col] = sum;
}

void CudaMult(int dimension,float *hMatrice,float *hB,float *d_A,float *d_B){
    int N,K;
    K = 100;            
    N = K*BLOCK_SIZE;

    dim3 threadBlock(BLOCK_SIZE,BLOCK_SIZE);
    dim3 grid(K,K);

    cudaMemcpy(d_A,hMatrice,dimension*dimension*sizeof(float),cudaMemcpyHostToDevice);

CudaMM<<<grid,threadBlock>>>(d_A,d_B,N);

cudaMemcpy(hB,d_B,dimension*dimension*sizeof(float),cudaMemcpyDeviceToHost);


}

void CublasFindConnect(int dimension,float* mat,float* B){


    float *d_A,*d_B;
    cudaMalloc(&d_A,dimension*dimension*sizeof(float));
    cudaMalloc(&d_B,dimension*dimension*sizeof(float));

    int w=0;
    while(w<5){

        CudaMult(dimension,mat,B,d_A,d_B);

          // Copy Matrix computed B to previous M

            for (m=0; m<dimension; m++) {

                for (n=0; n<dimension; n++) {
                    mat[m*dimension+n]=B[m*dimension+n];
                    B[m*dimension+n]=0;
                }
            }

     w++;
    }

cudaFree(d_A);
cudaFree(d_B);

}

我安裝了最新的CUDA 6,它不需要cudaMemCpy,因為共享內存。

  • 我建議您首先對顯示的代碼進行正確的cuda錯誤檢查 ,然后查看得到的結果。
  • 如果您還顯示完整的代碼,那就更好了。 例如,什么是BLOCK_SIZE 這個想法不是要告訴我BLOCK_SIZE是什么,而是要顯示完整的代碼。
  • cudaMallocManaged() ,您在CUDA 6中引用的功能具有您沒有滿足的特定要求(例如使用cudaMallocManaged() ),但是您的代碼並不依賴於統一內存,因此無關緊要。

我在您的代碼中看到的一個問題是您的dimension變量是任意的(您可以說它最多可以是2000),但是您的計算大小固定為N=K*BLOCK_SIZE; 大概,如果您的BLOCK_SIZE是某個值,例如16或32,那么它將滿足您大約2000的最大dimension

出現問題是因為您的網格大小可能大於有效數組的大小。 您正在啟動N x N網格,但是N可以大於dimension 這意味着某些啟動的線程可以嘗試在其有效維之外訪問矩陣( AB )。

您可以通過內核中的“線程檢查”來解決此問題,如下所示:

__global__ void CudaMM(float *A, float *B, int N)
{

    int row = blockIdx.y*blockDim.y + threadIdx.y;
    int col = blockIdx.x*blockDim.x + threadIdx.x;

    if ((row < N) && (col < N)) {

      float sum = 0.f;
      for (int n = 0; n < N; ++n)
        sum += A[row*N+n]*A[n*N+col];

      B[row*N+col] = sum;
    }
}

並且您需要將內核調用修改為:

CudaMM<<<grid,threadBlock>>>(d_A,d_B,dimension);

您可能還需要考慮根據實際dimension選擇網格大小,而不是固定為100*BLOCK_SIZE ,但這對於使代碼正常工作不是必需的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM