CUDA中的非方矩阵乘法

CUDA中的非方矩阵乘法,cuda,matrix-multiplication,Cuda,Matrix Multiplication,我在CUDA中用于矩阵乘法的代码允许我对正方形和非正方形矩阵进行乘法,但是,宽度和高度必须是块大小的倍数 例如,我可以乘[3][6]*[6][3](使用blocksize=3),但我不能乘[3][2]*[2][3] 有人知道怎么做吗?这是我的内核: #include <stdio.h> #include <limits.h> #include <stdlib.h> #define blocksize 3 #define HM (1*blocksize)

我在CUDA中用于矩阵乘法的代码允许我对正方形和非正方形矩阵进行乘法,但是,宽度和高度必须是块大小的倍数

例如,我可以乘[3][6]*[6][3](使用blocksize=3),但我不能乘[3][2]*[2][3]

有人知道怎么做吗?这是我的内核:

#include <stdio.h>

#include <limits.h>

#include <stdlib.h>
#define blocksize 3
#define HM (1*blocksize) 
#define WM (2*blocksize) 
#define WN (1*blocksize)
#define HN WM 
#define WP WN   
#define HP HM  
#define PTH WM
#define PTW HM

__global__ void nonsquare(float*M, float*N, float*P, int uWM,int uWN)

{
__shared__ float MS[blocksize][blocksize];
__shared__ float NS[blocksize][blocksize];


int tx=threadIdx.x, ty=threadIdx.y, bx=blockIdx.x, by=blockIdx.y;
int rowM=ty+by*blocksize;
int colN=tx+bx*blocksize;
float Pvalue=0;


for(int m=0; m< uWM/blocksize;++m){
    MS[ty][tx]=M[rowM*uWM+(m*blocksize+tx)];
    NS[ty][tx]=M[colN + uWN*(m*blocksize+ty)];
    __syncthreads();

    for(int k=0;k<blocksize;k++)
        Pvalue+=MS[ty][k]*NS[k][tx];
    __syncthreads();
    P[rowM*WP+colN]=Pvalue;
     }
    }
#包括
#包括
#包括
#定义块大小3
#定义HM(1*块大小)
#定义WM(2*块大小)
#定义WN(1*块大小)
#定义HN-WM
#定义WP-WN
#定义HP HM
#定义PTH-WM
#定义PTW HM
__全局无效非方形(float*M,float*N,float*P,int-uWM,int-uWN)
{
__共享浮点数MS[blocksize][blocksize];
__共享浮点数NS[blocksize][blocksize];
int tx=threadIdx.x,ty=threadIdx.y,bx=blockIdx.x,by=blockIdx.y;
int rowM=ty+by*blocksize;
int colN=tx+bx*块大小;
浮点值=0;
对于(int m=0;m对于(int k=0;k我认为最简单的方法是在块的末尾加上零:

for(int m=0; m< uWM/blocksize;++m){
    colM = m*blocksize+tx;
    rowN = m*blocksize+ty;
    if (rowM > uWN || rowN > uWM || colM > uWM || colN > uWN) {
        MS[ty][tx]=0.;
        NS[ty][tx]=0.;
    } else {
        MS[ty][tx]=M[rowM*uWM+colM];
        NS[ty][tx]=N[colN + uWN*rowN];
    }
for(int m=0;muWN | | rowN>uWM | | colM>uWM | | colN>uWN){
MS[ty][tx]=0。;
NS[ty][tx]=0。;
}否则{
MS[ty][tx]=M[rowM*uWM+colM];
NS[ty][tx]=N[colN+uWN*rowN];
}
加号或减号。(那条NS线应该是N,而不是M,对吗?)


但是,既然我似乎是这里唯一一个提倡在可能的情况下使用现有优化库的人——为什么不使用或不使用自己的库呢?它们很快,并且经过数百名用户的测试。

这里的基本性能要求是共享内存的第一维度或第二维度“平铺”是16的整数倍-这是实现最佳全局内存带宽所必需的(即半扭曲合并事务)。它应该是磁贴的第一维度还是第二维度取决于矩阵是按列还是按行的主要顺序存储。没有什么说共享内存磁贴需要是正方形的,只是存储的前导维度(BLAS表示法中的LDA)是16的整数倍


您可以很容易地使用tile维度作为模板参数对内核进行模板化,并根据矩阵维度实例化多个版本。对于给定的体系结构,可能存在一个最佳tile维度来平衡占用率和指令级并行性解决此问题的方法可能是将矩阵乘法分解为两个操作——第一个操作以最佳分片大小执行大部分工作,第二个操作以不同的大小执行其余列。如果结果在乘积完成后直接返回主机内存,则第二个操作最好在h上执行ost使用优化的BLAS,与GPU内核重叠。这是UTK Magma库中许多例程使用的方法。

这似乎是一个好的观点,尽管由于我使用的是表示医学图像的矩阵,我不确定用零填充是否会影响图像。但我会尝试一下。至于使用CUBLAS、 我一直在读它,但我有点担心它有很多新语法(学习曲线高吗?),但我还是会尝试一下。谢谢你的回答;)数组只在矩阵乘法例程中被填充。它们不会被传回,也不会影响最终结果,因为您只是在矩阵元素中添加零。至于CUBLAS(或magma,或其他)--学习曲线是真实的,但之后你不必编写自己的线性代数例程,性能是一个卖点……我明白了……我很快就会处理的一件事情非常大(以至于不适合GPU卡内存)3D矩阵,CUBLAS库能否消除3D索引和内存分配的痛苦(我认为第一个问题比第二个问题更可行)?