对于我的 GPU 编程课程,我们的任务是完成非方阵乘法程序的某些部分。具体来说,内核函数和初始化线程块和内核网格维度。
我的代码基于 CUDA C 编程指南的矩阵乘法代码,但我没有像他们那样使用结构,而是修改了我的代码以仅使用给定的参数(因为我们不允许更改参数)。我们得到了 3 个矩阵 A、B 和 C,以及它们的维度——mxk、kxn 和 mxn。在结构使用 A.height 的地方,我使用了维度 m,在它使用 B.width 的地方,我使用了维度 n,等等。
我遇到了几个问题,第一个是我的程序没有通过包含的测试,它验证了乘积矩阵 C 的正确性。我假设我的矩阵乘法代码有问题,然后,问题可能来自我调整结构代码。
#include <stdio.h>
__global__ void mysgemm(int m, int n, int k, const float *A, const float *B,
float* C) {
/********************************************************************
*
* Compute C = A x B
* where A is a (m x k) matrix
* where B is a (k x n) matrix
* where C is a (m x n) matrix
*
********************************************************************/
// INSERT KERNEL CODE HERE
// Each thread computes one element of C
// by accumulating results into Cvalue
float Cvalue = 0;
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
for (int e = 0; e < k; ++e){
Cvalue += (A[row * k + e]) * (B[e * n + col]);
}
C[row * n + col] = Cvalue;
}
我的另一个问题,我什至不太确定,涉及初始化线程块和内核网格尺寸的代码。
// Initialize thread block and kernel grid dimensions ---------------------
const unsigned int BLOCK_SIZE = 16; // Use 16x16 thread blocks
//INSERT CODE HERE
dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
dim3 dimGrid(n / dimBlock.x, m / dimBlock.y);
// Invoke CUDA kernel -----------------------------------------------------
//INSERT CODE HERE
mysgemm<<<dimGrid, dimBlock>>>(m, n, k, A, B, C);
我了解dimBlock,但我不了解dimGrid,并且不知道将什么用作它的参数。当我按原样运行代码时,如果我传入的矩阵的维度不是 2 的幂,那么内核甚至都不会启动。如果我确实使用了 2 的幂,测试仍然会失败。
如果我太啰嗦了,我很抱歉。这是我的第一篇文章,我想提供尽可能多的细节。希望有人可以帮助我解决这些问题。