矩阵相乘在CUDA上给出错误结果

卡米尔T

我已经使用CUDA编写了一小段代码来乘以2个平方矩阵。但是,事实证明,大多数细胞都被错误地计算了。根据我使用的教程,一切应该正常。

__global__ void gpuMM(int *C, int *A, int *B, int N)
{
    int row = blockIdx.x*blockDim.x + threadIdx.x;
    int col = blockIdx.y*blockDim.y + threadIdx.y;
    int sum = 0;
    for (int n = 0; n < N; ++n)
        sum += A[row*N+n]*B[n*N+col];

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

#define ROW_SIZE 5
#define MATRIX_LENGTH ROW_SIZE*ROW_SIZE
#define BLOCK_SIZE 16

void MultiplyMatrixCUDA(int * pResult, int* pFactorA, int*pFactorB)
{
    int size = MATRIX_LENGTH*sizeof(int);
    int *dA,*dB,*dC;
    cudaMalloc(&dA,size);
    cudaMalloc(&dB,size);
    cudaMalloc(&dC,size);
    int K = 100;
    dim3 threadBlock(BLOCK_SIZE,BLOCK_SIZE);
    dim3 grid(K,K);

    printf("A:\n");
    DrawMatrix(pFactorA);
    printf("\n");

    printf("B:\n");
    DrawMatrix(pFactorB);
    printf("\n");

    // Copy matrices from the host to device
    cudaMemcpy(dA,pFactorA,size,cudaMemcpyHostToDevice);
    cudaMemcpy(dB,pFactorB,size,cudaMemcpyHostToDevice);

    //Execute the matrix multiplication kernel
    gpuMM<<<grid,threadBlock>>>(dC,dA,dB,ROW_SIZE);


    // Allocate memory to store the GPU answer on the host
    int *C;
    C = new int[MATRIX_LENGTH];

    // Now copy the GPU result back to CPU
    cudaMemcpy(C,dC,size,cudaMemcpyDeviceToHost);

    cudaFree(dA);
    cudaFree(dB);
    cudaFree(dC);

    printf("\nC from CUDA:\n");
    DrawMatrix(C);
    printf("\nC:\n");
    DrawMatrix(MultiplyWithCPU(pResult,pFactorA, pFactorB));  // the code of multiplying function is irrevelant, I'm sure it works fine (double-checked)

}

结果表明,矩阵乘以标准CPU方法是正确的,但CUDA是错误的: 在此处输入图片说明 在此处输入图片说明

第一行始终是正确的,但是所有其他部分都是完全随机的。有时他们是消极的,有时不是。有时它们接近实际价值,有时则完全不同。

我怎么了 我看不出失败的地方。该算法看起来不错,似乎正确传递了变量,但是某些操作无效。

- - 编辑

所有变量(pResult和两个pFactor)都在代码的其他部分初始化(然后删除)。

rod

由于每个块的线程数不等于输出矩阵中的元素数(您在16x16块上映射5x5矩阵),因此某些线程正在访问/写入无效的内存位置。

解决方案包括双重边界检查,以解决该问题。这将导致某些线程处于空闲状态。内核应如下所示:

__global__ void gpuMM(int *C, int *A, int *B, int N)
{
    int row = blockIdx.x*blockDim.x + threadIdx.x;
    int col = blockIdx.y*blockDim.y + threadIdx.y;

    if( (row < N) && (col < N))
    {
        int sum = 0;
        for (int n = 0; n < N; ++n){
            sum += A[row*N+n]*B[n*N+col];       
        }
        C[row*N+col] = sum;
    }
}

另一个解决方案-实际上更有效,具体取决于您的设备-每块启动更少的线程(在这种情况下为25)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

numpy.dot(a,b)在具有相似维数的矩阵相乘时给出错误结果

来自分类Dev

Python numpy:矩阵乘法给出错误的结果

来自分类Dev

GLM矩阵乘法矢量给出错误的结果

来自分类Dev

本征中的稀疏矩阵乘法给出错误的结果?

来自分类Dev

Python numpy:矩阵乘法给出错误的结果

来自分类Dev

使用矩阵旋转多维数据集给出错误的结果

来自分类Dev

本征C ++中的矩阵相乘给出错误的维数

来自分类Dev

IEqualityComparer给出错误的结果

来自分类Dev

filesize():给出错误的结果

来自分类Dev

IEqualityComparer给出错误的结果

来自分类Dev

矩阵结构给出错误的输出

来自分类Dev

在getElementById上给出错误

来自分类Dev

矩阵和向量相乘,输出错误的乘积

来自分类Dev

多线程求和给出错误的结果

来自分类Dev

AES解密给出错误的结果

来自分类Dev

WkWebView Cangoback给出错误的结果

来自分类Dev

PyTorch由于广播而给出错误的结果

来自分类Dev

为什么MomentJS给出错误的结果

来自分类Dev

MySQL查询给出错误的结果

来自分类Dev

未找到结果时给出错误

来自分类Dev

时间戳记给出错误的结果

来自分类Dev

AES解密给出错误的结果

来自分类Dev

排序算法给出错误的结果

来自分类Dev

左联接给出错误结果

来自分类Dev

SQL 2汇总给出错误的结果

来自分类Dev

算术运算给出错误的结果

来自分类Dev

函数给出错误的结果

来自分类Dev

RK4给出错误的结果

来自分类Dev

Linux反向排序给出错误结果