Cuda编程之基于Cublas实现矩阵乘法运算Y=X@W(一)

目录

一.难点所在

 二.难点解析

三.公式解析与函数调用

四.cublas结果与numpy计算结果对比


一.难点所在

        解决了困扰我很久的cublas默认列主序load和store数据的结算结果不对齐的问题。

git clone https://gitee.com/xukang888/cublas-sgeem.git
#include <stdio.h>
#include <cuda_runtime.h>
#include <cublas_v2.h>

#define M 2
#define N 2
#define K 3

int main() {
    cublasHandle_t handle;
    cublasCreate(&handle);
    // A: 2×3 (行主序)
    float A[6] = {1, 2, 3, 4, 5, 6}; 
    // B: 3×2 (行主序)
    float B[6] = {7, 8, 9, 10, 11, 12}; 
    // C: 2×2 结果矩阵
    float C[4] = {0};
    float alpha = 1.0f, beta = 0.0f;
    // 分配 GPU 内存
    float *d_A, *d_B, *d_C;
    cudaMalloc(&d_A, sizeof(A));
    cudaMalloc(&d_B, sizeof(B));
    cudaMalloc(&d_C, sizeof(C));
    cudaMemcpy(d_A, A, sizeof(A), cudaMemcpyHostToDevice);
    cudaMemcpy(d_B, B, sizeof(B), cudaMemcpyHostToDevice);
    cudaMemset(d_C, 0, sizeof(C));

    // A 和 B 都是行主序,因此使用 CUBLAS_OP_T
    cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,N,M,K,&alpha,d_B,N,d_A,K,&beta,d_C,N); 
    // 拷贝结果回主机
    cudaMemcpy(C, d_C, sizeof(C), cudaMemcpyDeviceToHost);
    // 输出结果
    printf("Result matrix C:\n");
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
            printf("%f ", C[i * M + j]);
        }
    }
    printf("\n");
    cudaFree(d_A);
    cudaFree(d_B);
    cudaFree(d_C);
    cublasDestroy(handle);

    return 0;
}

 二.难点解析

        C++默认以行主序进行存储和读取,但是cublas默认利用列主序进行读取和存储如果我们利用行主序的数据输入cublas最终得到的结果会与预期结果不符合。

三.公式解析与函数调用

        cublas默认列主序,那么我们如果预期Y=X@W;其实计算的是Y.T=X.T@W.T;geem运算结束之后,c++以默认行主序进行读取得到结果其实是Y=W@X;因此参数列表里面,权重矩阵W和变量X的位置应该互换;

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

        在cublasSgeem参数列表里面d_B处于d_A之前;实际运算方式为Y.T = W.T@X.T;此时c++再以行主序进行访存,得到的结果就是(Y.T).T = Y=X@W;

四.cublas结果与numpy计算结果对比

root@ubuntu:/***/# nvcc 2.cublasSgemmA\@B.cu -lcublas -o geemA@B && ./geemA@B
Result matrix C:
58.000000 64.000000 139.000000 154.000000 
>>> a = np.array([1, 2, 3, 4, 5, 6]).reshape(2,3)
>>> b = np.array([7, 8, 9, 10, 11, 12]).reshape(3,2)
>>> a@b
array([[ 58,  64],
       [139, 154]])

        实现cublas在不对数据进行手动转换行主序到列主序的情况下,实现计算结果对齐。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值