cublasSgemm 行主要乘法

Posted

技术标签:

【中文标题】cublasSgemm 行主要乘法【英文标题】:cublasSgemm row-major multiplication 【发布时间】:2019-09-26 08:27:37 【问题描述】:

我正在尝试使用 cublasSgemm 将两个以行优先顺序存储的非方形矩阵相乘。我知道这个函数有一个参数,您可以在其中指定是否要转置矩阵(CUBLAS_OP_T),但结果以列优先顺序存储,我也需要以行优先顺序。

另外,我的代码不能将非方阵与参数 CUBLAS_OP_T 相乘。仅使用 CUBLAS_OP_N 的正方形或非正方形。

此外,我知道可以选择使用

按列顺序声明矩阵
define IDX2C(i,j,ld) (((j)*(ld))+(i)) 

但这不是一个选项,因为我必须使用的矩阵将在其他程序中设置。

我想互联网上有很多信息,但我无法找到我的问题的任何答案。

我的代码如下:


    int m = 2;
    int k = 3;
    int n = 4;
    int print = 1;
    cudaError_t cudaStat; // cudaMalloc status
    cublasStatus_t stat; // CUBLAS functions status
    cublasHandle_t handle; // CUBLAS context

    int i,j;

    float *a, *b,*c;

    //malloc for a,b,c...

    // define a mxk matrix a row by row
    int ind =11;                               
    for(j=0;j<m*k;j++)                     
        a[j]=(float)ind++;                                    
                                            

    // define a kxn matrix b column by column
    ind =11;                               
    for(j=0;j<k*n;j++)                     
        b[j]=(float)ind++;                                    
                                            


    // DEVICE
    float *d_a, *d_b, *d_c; 

    //cudaMalloc for d_a, d_b, d_c...

    stat = cublasCreate(&handle); // initialize CUBLAS context

    stat = cublasSetMatrix(m,k, sizeof(*a), a, m, d_a, m);
    stat = cublasSetMatrix(k,n, sizeof(*b), b, k, d_b, k); 

    float al =1.0f;
    float bet =0.0f; 

    stat=cublasSgemm(handle,CUBLAS_OP_T,CUBLAS_OP_T,m,n,k,&al,d_a,m,d_b,k,&bet,d_c,m);

    stat = cublasGetMatrix (m,n, sizeof (*c) ,d_c ,m,c,m); // cp d_c - >c

    if(print == 1) 
    printf ("\nc after Sgemm :\n");
        for(i=0;i<m*n;i++)
                printf ("%f ",c[i]); // print c after Sgemm
        
    

    cudaFree (d_a); 
    cudaFree (d_b); 
    cudaFree (d_c);
    cublasDestroy (handle); // destroy CUBLAS context
    free (a); 
    free (b); 
    free (c); 

    return EXIT_SUCCESS ;

输出是A * B相乘的转置,即:(A * B)T。

但我想要的是 C = A * B 的行优先顺序。

我希望有人可以帮助我。

【问题讨论】:

This 可能感兴趣。 【参考方案1】:

正如您所说,cuBLAS 将矩阵解释为列优先排序,因此当您执行cublasSgemm(handle,CUBLAS_OP_T,CUBLAS_OP_T,m,n,k,&amp;al,d_a,m,d_b,k,&amp;bet,d_c,m) 时,您正确地转置了每个输入(以行优先形式创建)以准备列优先解释。问题是 cuBLAS 还以列优先顺序转储结果。

我们将欺骗 cuBLAS 计算 ,它将以列主要顺序输出,因此当我们以行主要顺序巧妙地解释它时,它看起来像 。因此,我们不计算 AB = C,而是计算 = 。幸运的是, 和 我们已经通过按行优先顺序创建 A 和 B 的操作获得了,所以我们可以简单地绕过 CUBLAS_OP_N 的转置。所以将行改为cublasSgemm(handle,CUBLAS_OP_N,CUBLAS_OP_N,n,m,k,&amp;al,d_b,n,d_a,k,&amp;bet,d_c,n)


您提供的示例代码应该计算出来

在对cublasSgemm 进行更新调用后,我们得到:

c after Sgemm :
548.000000 584.000000 620.000000 656.000000 683.000000 728.000000 773.000000 818.000000 

【讨论】:

以上是关于cublasSgemm 行主要乘法的主要内容,如果未能解决你的问题,请参考以下文章

使用 cublas gemm 函数 (cublasSgemm) 的乘法矩阵大小上限

cblas_sgemm和cublasSgemm参数详解

行主要与列主要矩阵乘法

乘法和比较大数字

向量乘法(矩阵乘法)奇数输出的向量

CUDA性能优化经典问题