Cuda编程之Cublas矩阵乘法运算cublasSgemm参数列表解析(三)

1.cublasSgem参数列表解析

Cuda编程之基于Cublas实现矩阵乘法运算(一)

Cuda编程之基于Cublas实现矩阵乘法运算(二)

        在我的前两篇文章里面写到了基于cublasSgemm实现y=x@w和y=x@w.T,并且实现了在不改变原始数据的行列顺序的情况下实现CUDA库函数调用且与CPU行优先计算库Numpy计算结果保持一致。

        今天我们基于上面两个公式的实现来讲一下cublasSgemm的参数列表,参数的含义;废话不多说,相关参数的数据类型和应该传入的数值我已经用中文注释了。

cublasStatus_t cublasSgemm(
    cublasHandle_t handle,  // cuBLAS 句柄
    cublasOperation_t transa, // A 是否需要转置
    cublasOperation_t transb, // B 是否需要转置
    int m,  // 结果矩阵 C 的行数
    int n,  // 结果矩阵 C 的列数
    int k,  // A 的列数 / B 的行数
    const float *alpha,  // 标量 α
    const float *A,  // 矩阵 A 的设备指针
    int lda,  // A 的 leading dimension(行主序存储时是 A 的列数)
    const float *B,  // 矩阵 B 的设备指针
    int ldb,  // B 的 leading dimension(行主序存储时是 B 的列数)
    const float *beta,  // 标量 β
    float *C,  // 结果矩阵 C 的设备指针
    int ldc   // C 的 leading dimension(行主序存储时是 C 的列数)
);

2.cublasSgemm实现y=x@w参数含义

cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,N,M,K,&alpha,d_B,N,d_A,K,&beta,d_C,N); 

        这里我们计算的是y.T=w.T@x.T;转置是因为cublas默认列优先进行数据访存,不是cublasOperation_t参数影响的哦,我们这里不需要做任何转置所以都是CUBLAS_OP_N

        很多文章里面写的m,n,k解释是m是A矩阵的行,n是B矩阵的列,k是A矩阵的列同时也是B矩阵的行,这是因为他是基于Trasformer里面多头注意力机制Q@K.T进行定义的,在这里我感觉容易给大家造成混淆并且难以与这里的cublas多种维度进行结合。

        这里我们从结果矩阵C出发,m是结果矩阵的行,n是结果矩阵的列,k是左矩阵的列也是右矩阵的行;那么问题来了,是依次传入M,N,K吗,当然不是啦,我们用逆向思维思考一下,我们在cublas调用结束之后用c++默认行主序进行读取的结果矩阵C是[M,N]维度,那么在cublas中列主序,它的维度是不是应该是[N,M]呀,因此这里传入N,M,K

        y.T=w.T@x.T中左矩阵是权重矩阵维度是[N,K],因此leading dimension是N;右矩阵是X矩阵维度是[K,M],因此leading dimension是K;结果矩阵的维度是[N,M]因此leading dimension是N;看到这儿大家应该都明白了吧,嘿嘿嘿。

3.cublasSgemm实现y=x@w参数含义

        如果大家还对上面的参数列表的定义存在疑惑,那么接下来我们在基于nn.liear的计算来验证一下上面的解释。

cublasSgemm(handle, CUBLAS_OP_T, CUBLAS_OP_N, 4, 2, 3, &alpha, d_B, 3, d_A, 3, &beta, d_C, 4);

        我们的x矩阵的维度是[2,3];w矩阵的维度是[4,3],很显然这样的维度是不能直接y=x@w的,需要进行转置;y = x@w.T-->y.T=w@x.T;在这儿对权重矩阵进行转置我们不手动进行数据行列转换,直接用cublasSgemm里面的转置参数就好,如果左右矩阵都不进行转置计算的就是y.T=w.T@x.T;这儿我需要再次强调一下,这里转置不是cublasOperation_t影响的,是因为cublas默认列主序。我们这里w需要进行转置,那么则需要将左矩阵设定为CUBLAS_OP_T,右矩阵不需要转置为CUBLAS_OP_N

        结果C矩阵是[4,2],因此m,n,k依次是4,2,3;w左矩阵在进行trans_op之前维度是[3,4],x右矩阵维度是[3,2],结果矩阵维度是[4,2]-->因此leading dimension分别是3,3,4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值