我刚刚开始 CUDA 编程,并且正在学习有关矩阵乘法的内核设计的知识。我复制了网上找到的主要代码,并添加了我的部分来实现 A(MxM) 和 B(MxN) 的矩阵乘法
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <cuda_runtime.h>
#include <cuComplex.h>
#include <cusp/complex.h>
using namespace std;
const int M=55, N=73;
typedef cusp::complex<double> Complex;
__global__ void kernelFunc(Complex* ad, Complex* bd, Complex* cd, int n)
{
int x = (blockIdx.x * blockDim.x) + threadIdx.x;
int y = (blockIdx.y * blockDim.y) + threadIdx.y;
if(x < n && y < n)
{
Complex v = Complex(0.0, 0.0);
for(int i=0; i<n; i++) v += ad[y * n + i] * bd[i * n + x];
cd[y * n + x] = v;
}
}
int main(int argc, char *argv[])
{
std::vector< Complex > _A(M*M);
std::vector< Complex > _B(M*N);
Complex *A, *B, *C;
cudaMalloc((void**)&A, M*M*sizeof(Complex));
cudaMalloc((void**)&B, M*N*sizeof(Complex));
cudaMalloc((void**)&C, M*N*sizeof(Complex));
for (int i=0; i<M*M; i++) _A[i] = Complex((double)i, (double)i);
for (int i=0; i<M*N; i++) _B[i] = Complex(1.0, 0.0);
cudaMemcpy( A, &_A[0], (M*M)*sizeof(Complex), cudaMemcpyHostToDevice );
cudaMemcpy( B, &_B[0], (M*N)*sizeof(Complex), cudaMemcpyHostToDevice );
dim3 block(32, 32);
dim3 grid((M+31)/32, (M+31)/32);
kernelFunc<<<grid, block>>>(A, B, C, M);
cudaMemcpy(&_B[0], &C[0], (M*N)*sizeof(Complex), cudaMemcpyDeviceToHost);
cudaFree(A);
cudaFree(B);
cudaFree(C);
return 0;
}
但是网上说涉及的矩阵一定是方阵,是不是说这段代码不能用在任意维数的矩阵上呢?我不明白如何定义块数和网格数以适应我的问题。我的问题中的矩阵的维度为 MxM,其中 M 为奇数。我尝试上面的小矩阵代码,它似乎有效,但我必须将它应用于相当大的矩阵。我不知道这是否也适用于大矩阵。