簡體   English   中英

CUDA kernel 代碼在使用共享 memory 時不執行

[英]CUDA kernel code does not execute when using shared memory

我正在學習使用共享 memory 來優化 cuda 代碼。 我遵循了 Nvidia 材料中的大部分實現。 但我發現我的設備代碼從未執行過。 任何人都可以幫我弄清楚為什么? 我錯過了什么? 謝謝。

#include <stdio.h>
#include <cuda_runtime.h>
#include <chrono>
#define BLOCKSIZE 16

typedef struct {
    int height;
    int width;
    int stride;
    float *element;
} Matrix;

void initData(float *p, int size){
    for (int t=0; t<size; t++){
        p[t] = (float)(rand()&0xffff)/1000.0f;
    }
}

__device__ float getElement(Matrix a, int row, int col)
{
    return a.element[row*a.stride+col];
}

__device__ Matrix getSubM(Matrix a, int row, int col)
{
    Matrix res;
    res.height = BLOCKSIZE;
    res.width = BLOCKSIZE;
    res.stride = a.width;
    res.element = &a.element[row*BLOCKSIZE*a.stride+col*BLOCKSIZE];

    return res;
}

__device__ void setElement(Matrix a, int row, int col, float val)
{
    a.element[row*a.stride+col] = val;
}

__global__ void shmMM(Matrix a, Matrix b, Matrix c)
{

    int blockRow = blockDim.y;
    int blockCol = blockDim.x;

    Matrix Csub = getSubM(c, blockRow, blockCol);

    int row = threadIdx.y;
    int col = threadIdx.x;

    float tmp = 0;

    for (int i=0; i < a.width/BLOCKSIZE; i++)
    {   
        Matrix a_sub = getSubM(a, blockRow, i);
        Matrix b_sub = getSubM(b, i, blockCol);
        __shared__ float A[BLOCKSIZE][BLOCKSIZE];
        __shared__ float B[BLOCKSIZE][BLOCKSIZE];

        A[row][col] = getElement(a, row, col);
        B[row][col] = getElement(b, row, col); 
        __syncthreads();
        for (int e = 0; e < BLOCKSIZE; e++)
        {
            tmp += A[row][e]*B[e][col];
        }
        __syncthreads();
    }
    //printf("debug: %f.\n", tmp);
    setElement(Csub, row, col, tmp);
}

int main()
{
    Matrix a, b, c;
    int size = 1<<12;
    a.height = a.width = size;
    b.height = b.width = size;
    c.height = c.width = size;
    a.stride = a.width;
    b.stride = b.width;
    c.stride = c.width;
    float *a_h, *b_h, *c_h;
    cudaMallocHost((float**)&a_h, a.height*a.width*sizeof(float));
    cudaMallocHost((float**)&b_h, b.height*b.width*sizeof(float));
    initData(a_h, a.height*a.width);
    initData(b_h, b.height*b.width);
    c_h = (float*)malloc(c.height*c.width*sizeof(float));
    float *a_d, *b_d, *c_d;
    cudaMalloc((float**)&a.element, a.height*a.width*sizeof(float));
    cudaMalloc((float**)&b.element, b.height*b.width*sizeof(float));
    cudaMalloc((float**)&c.element, c.height*c.width*sizeof(float));
    cudaMemcpy(a.element, a_h, a.height*a.width*sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(b.element, b_h, b.height*b.width*sizeof(float), cudaMemcpyHostToDevice);
    dim3 block(BLOCKSIZE, BLOCKSIZE);
    dim3 grid((b.width-1)/block.x+1, (a.height-1)/block.y+1);
    //naiveMM<<<block, grid>>>(a, b, c);
    shmMM<<<block, grid>>>(a, b, c);
    cudaMemcpy(c_h, c.element, c.height*c.width*sizeof(float), cudaMemcpyDeviceToHost);

    cudaDeviceSynchronize();

    cudaFree(a_h);
    cudaFree(b_h);
    free(c_h);
    cudaFree(a.element);
    cudaFree(b.element);
    cudaFree(c.element);
    return 0;
}

我無法弄清楚,因為沒有報告編譯錯誤和運行時錯誤。

因為沒有報告編譯錯誤和運行時錯誤。

如果您未能使用正確的 CUDA 錯誤檢查,您將不會收到任何報告的運行時錯誤。 我建議您在遇到 CUDA 代碼問題的任何時候。 根據您的 GPU,使用諸如cuda-memcheckcompute-sanitizer之類的清理程序運行代碼也是一種很好的做法。

如果您執行了上述任何操作,您將在 kernel 啟動時收到無效的配置參數錯誤。 那本來應該或應該將您的注意力集中在此代碼上:

dim3 block(BLOCKSIZE, BLOCKSIZE);
dim3 grid((b.width-1)/block.x+1, (a.height-1)/block.y+1);
//naiveMM<<<block, grid>>>(a, b, c);
shmMM<<<block, grid>>>(a, b, c);

那里的問題是您的塊和網格 arguments 顛倒了,它應該是:

shmMM<<<grid, block>>>(a, b, c);

我並不是說我已經完全調試了您的應用程序。 但這就是原因的來源:

CUDA kernel 代碼不執行

這些代碼行也不正確:

cudaFree(a_h);
cudaFree(b_h);

但這不是您要問的問題的根源。 cudaMallocHost對應的空閑操作是cudaFreeHost這里提到

暫無
暫無

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

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