NIVIDIA高性能计算CUDA笔记(二)—cuBLAS库简介

NIVIDIA高性能计算CUDA笔记(二)—cuBLAS库简介

1.什么是cuBLAS?

\(cuBLAS\) 是NIVIDIA提供的GPU加速线性代数库,基于CUDA实现BLAS(基本线性代数子程序),广泛应用于科学计算、机器学习、工程仿真等领域。本笔记调研cuBLAS库的基本情况,将详细介绍产品的功能、算子列表及API列表。

\(cuBLAS\) 具备以下特点:

  • 高性能优化:高度优化、底层使用\(Tensor \space Core\)共享内存、流水调度等技术进行深度优化;
  • 完整性:完整支持\(BLAS\) Level 1/2/3接口,覆盖所有标准BLAS例程(152个);
  • 易用性: 提供与表征\(BLAS\) 兼容的接口,开发者可以轻松从CPU实现迁移到GPU端,支持主机端调用,适合与现有框架集成;
  • 支持多种数据类型:FP32、FP64、FP16、BF16、INT8等;
  • 灵活性:支持流(stream)、异步执行、Tensor Core运算等高级特性;提供扩展功能(BLAS-Extension),支持混合精度和批处理操作;

\(cuBLAS\) 适用场景:

  • 深度学习:加速神经网络中的矩阵乘法(GEMM),如卷积神经网络(CNN)和 变换器(Transformer);
  • 科学计算:处理物理模拟、量子化学等需要密集线性代数计算领域;
  • 高性能计算(HPC):在GPU集群中执行大规模矩阵运算;
  • 通用线性代数:适用于需要标准 BLAS 功能的任何应用。

2.cuBLAS分级概述

分类 算子个数 API个数
Level-1算子 13 54
Level-2算子 16 58
Level-3算子 5 34
Extension 算子 23 48
helpfer function / 22
总计 57 216

大多数用于计算的\(cuBLAS\)函数名字内都包含了数据类型,表明这个函数专门用于处理float、double还是什么数据类型。

处理的数据类型 标识符号 含义
float ‘s’ or ‘S’ 单浮点精度实数(real-single-precision)
double ‘d’ or ‘D’ 双浮点精度实数 (real-Double-precision)
cuComplex ‘c’ or ‘C’ 单浮点精度复数 (complex-single-precision)
cuDoubleComplex 'z' or 'Z' 双浮点精度复数 (complex-Double-precision)

2.1 算子列表

(1) Level-1 算子(向量-向量操作):这些算子处理向量之间的基本操作。

Level-1 算子 描述 API
axpy 向量加法,将标量乘以向量并加到另一个向量 cublasSaxpy, cublasDaxpy, cublasCaxpy, cublasZaxpy
copy 向量复制,将一个向量复制到另一个向量 cublasScopy, cublasDcopy, cublasCcopy, cublasZcopy
dot 点积,计算两个向量的点积(复数区分共轭/非共轭) cublasSdot, cublasDdot, cublasCdotu, cublasCdotc, cublasZdotu, cublasZdotc
nrm2 欧几里得范数,计算向量的二范数 cublasSnrm2, cublasDnrm2, cublasScnrm2, cublasDznrm2
asum 绝对值和,计算向量元素绝对值之和 cublasSasum, cublasDasum, cublasScasum, cublasDzasum
iamax 最大绝对值索引,返回绝对值最大元素的索引 cublasIsamax, cublasIdamax, cublasIcamax, cublasIzamax
iamin 最小绝对值索引,返回绝对值最小元素的索引 cublasIsamin, cublasIdamin, cublasIcamin, cublasIzamin
rot 应用Givens旋转,对两个向量应用旋转变换 cublasSrot, cublasDrot, cublasCrot, cublasCsrot, cublasZrot, cublasZdrot
rotg 构造 Givens 旋转,生成旋转参数 cublasSrotg, cublasDrotg, cublasCrotg, cublasZrotg
rotm 应用修改后的 Givens 旋转,使用预定义参数执行旋转 cublasSrotm, cublasDrotm
rotmg 构造修改后的 Givens 旋转,生成修改后的旋转参数 cublasSrotmg, cublasDrotmg
scal 缩放,将向量乘以标量 cublasSscal, cublasDscal, cublasCscal, cublasCsscal, cublasZscal, cublasZdscal
swap 交换向量 cublasSswap, cublasDswap, cublasCswap, cublasZswap

(2)Level-2 算子(矩阵-向量操作):这些算子涉及矩阵与向量之间的操作

算子 描述 API
gemv 一般矩阵-向量乘法,矩阵与向量乘法加向量 cublasSgemv, cublasDgemv, cublasCgemv, cublasZgemv
gbmv 带状矩阵-向量乘法 cublasSgbmv, cublasDgbmv, cublasCgbmv, cublasZgbmv
ger 秩-1更新,用于向量外积更新矩阵 cublasSger, cublasDger, cublasCgeru, cublasCgerc, cublasZgeru, cublasZgerc
sbmv 对称带状矩阵-向量乘法,对称带状矩阵与向量乘法 cublasSsbmv, cublasDsbmv
spmv 对称压缩矩阵-向量乘法,压缩格式对称矩阵与向量乘法 cublasSspmv, cublasDspmv
spr 对称压缩秩-1 更新,压缩格式对称矩阵更新 cublasSspr, cublasDspr
spr2 对称压缩秩-2 更新,压缩格式对称矩阵秩-2 更新 cublasSspr2, cublasDspr2
symv 对称矩阵-向量乘法,对称矩阵与向量乘法 cublasSsymv, cublasDsymv, cublasChemv, cublasZhemv
syr 对称秩-1 更新,对称矩阵的秩-1 更新 cublasSsyr, cublasDsyr, cublasCsyr, cublasZsyr, cublasCher, cublasZher
syr2 对称秩-2 更新,对称矩阵的秩-2 更新 cublasSsyr2, cublasDsyr2, cublasCsyr2, cublasZsyr2, cublasCher2, cublasZher2
tbmv 三角带状矩阵-向量乘法,三角带状矩阵与向量乘法 cublasStbmv, cublasDtbmv, cublasCtbmv, cublasZtbmv
tbsv 三角带状矩阵求解,三角带状矩阵系统求解 cublasStbsv, cublasDtbsv, cublasCtbsv, cublasZtbsv
tpmv 三角压缩矩阵-向量乘法,压缩格式三角矩阵与向量乘法 cublasStpmv, cublasDtpmv, cublasCtpmv, cublasZtpm
tpsv 三角压缩矩阵求解,压缩格式三角矩阵系统求解 cublasStpsv, cublasDtpsv, cublasCtpsv, cublasZtpsv
trmv 三角矩阵-向量乘法,三角矩阵与向量乘法 cublasStrmv, cublasDtrmv, cublasCtrmv, cublasZtrm
trsv 三角矩阵求解,三角矩阵系统求解 cublasStrsv, cublasDtrsv, cublasCtrsv, cublasZtrsv

(3)Level-3算子(矩阵-矩阵操作):这些算子处理矩阵与矩阵之间的操作,包括处理的变体

算子 描述 API
gemm 一般矩阵-矩阵乘法,矩阵乘法加矩阵,包括批处理版本 cublasSgemm, cublasDgemm, cublasCgemm, cublasZgemm, cublasSgemmBatched, cublasDgemmBatched, cublasCgemmBatched, cublasZgemmBatched
syrk 对称秩-k 更新,对称矩阵的秩-k 更新 cublasSsyrk, cublasDsyrk, cublasCsyrk, cublasZsyrk, cublasCherk, cublasZherk
syr2k 对称秩-2k 更新,对称矩阵的秩-2k 更新 cublasSsyr2k, cublasDsyrk, cublasCsyr2k, cublasZsyr2k, cublasCher2k, cublasZher2k
trmm 三角矩阵-矩阵乘法,三角矩阵与矩阵乘法 cublasStrmm, cublasDtrmm, cublasCtrmm, cublasZtrmm
trsm 三角求解,三角矩阵系统求解,包括批处理版本 cublasStrsm, cublasDtrsm, cublasCtrsm, cublasZtrsm, cublasStrsmBatched, cublasDtrsmBatched, cublasCtrsmBatched, cublasZtrsmBatched

(4)BLAS-like算子列表

算子 描述 API
geam 矩阵加法或转置加法,将两个矩阵相加,支持转置选项 cublasSgeam, cublasDgeam, cublasCgeam, cublasZgeam
dgmm 对角矩阵乘法,将对角矩阵与一般矩阵相乘 cublasSdgmm, cublasDdgmm, cublasCdgmm, cublasZdgmm
getrfBatched 批处理 LU分解,对多个矩阵执行 LU 分解 cublasSgetrfBatched, cublasDgetrfBatched, cublasCgetrfBatched, cublasZgetrfBatched
getrsBatched 批处理线性系统求解,使用 LU 分解结果求解多个线性系统 cublasSgetrsBatched, cublasDgetrsBatched, cublasCgetrsBatched, cublasZgetrsBatched
getriBatched 批处理矩阵求逆,使用 LU 分解结果求多个矩阵的逆 cublasSgetriBatched, cublasDgetriBatched, cublasCgetriBatched, cublasZgetriBatched
matinvBatched 批处理矩阵求逆,直接求多个矩阵的逆 cublasSmatinvBatched, cublasDmatinvBatched, cublasCmatinvBatched, cublasZmatinvBatched
geqrfBatched 批处理 QR分解,对多个矩阵执行 QR 分解 cublasSgeqrfBatched, cublasDgeqrfBatched, cublasCgeqrfBatched, cublasZgeqrfBatched
gelsBatched 批处理最小二乘,求解多个最小二乘问题 cublasSgelsBatched, cublasDgelsBatched, cublasCgelsBatched, cublasZgelsBatched
tpttr 三角矩阵打包,将三角矩阵打包为压缩格式 cublasStpttr, cublasDtpttr, cublasCtpttr, cublasZtpttr
gemmEx 混合精度矩阵乘法,支持多种输入和输出数据类型 cublasGemmEx
gemmBatchedEx 批处理混合精度矩阵乘法,对多个矩阵执行混合精度计算 cublasGemmBatchedEx
gemmStridedBatchedEx 带步幅的批处理混合精度矩阵乘法,支持步幅参数的批处理 cublasGemmStridedBatchedEx
csyrkEx 混合精度对称秩-k 更新,更新对称矩阵 cublasCsyrkEx
csyrk3mEx 混合精度对称秩-k 更新,优化为三倍精度计算 cublasCsyrk3mEx
nrm2Ex 混合精度欧几里得范数,计算向量的二范数 cublasSnrm2Ex, cublasDnrm2Ex
axpyEx 混合精度向量加法,将标量乘以向量并加到另一向量上 cublasSaxpyEx, cublasDaxpyEx
dotEx 混合精度点积,计算两个向量的点积 cublasSdotEx, cublasDdotEx
rotEx 混合精度 Givens 旋转,对两个向量应用旋转变换 cublasSrotEx, cublasDrotEx
scalEx 混合精度缩放,将向量乘以标量 cublasSscalEx, cublasDscalEx

注意:cublasGemmEx 已经覆盖了 cublas<t>gemmEx

(5)Helper API 列表:

​ 算子 API 已在上文的算子列表中详细列出,共包括 Level-1、Level-2、Level-3 和扩展算子的所有变体,总数约为 180+ 个(因数据类型变体繁多)。以下是 Helper API 根据官方文档的功能分类,分为以下类别:

库管理(Library Management)

API 说明
cublasCreate 创建 cuBLAS 句柄,用于初始化库
cublasDestroy 销毁 cuBLAS 句柄,释放资源
cublasGetVersion 获取 cuBLAS 库的版本号
cublasSetStream 设置 cuBLAS 句柄关联的 CUDA 流
cublasGetStream 获取 cuBLAS 句柄当前关联的 CUDA 流
cublasSetWorkspace 设置工作空间内存,用于某些操作
cublasSetPointerMode 设置指针模式(主机或设备),影响参数传递方式
cublasGetPointerMode 获取当前指针模式
cublasSetMathMode 设置数学模式(如启用张量核心加速)
cublasGetMathMode 获取当前数学模式

数据传输(Data Transfer)

API 说明
cublasSetVector 将向量数据从主机传输到设备
cublasGetVector 将向量数据从设备传输到主机
cublasSetMatrix 将矩阵数据从主机传输到设备
cublasGetMatrix 将矩阵数据从设备传输到主机
cublasSetVectorAsync 异步将向量数据从主机传输到设备
cublasGetVectorAsync 异步将向量数据从设备传输到主机
cublasSetMatrixAsync 异步将矩阵数据从主机传输到设备
cublasGetMatrixAsync 异步将矩阵数据从设备传输到主机

日志配置(Logging)

API 说明
cublasLoggerConfigure 配置 cuBLAS 的日志记录功能
cublasSetLoggerCallback 设置用户定义的日志回调函数
cublasGetLoggerCallback 获取当前日志回调函数

属性查询(Property Queries)

API 说明
cublasGetProperty 查询 cuBLAS 库的属性(如版本号)

2.2 cublas的矩阵乘法案例

​ 在本小节中,我们给出一个代码中以矩阵乘法为例来展示如何使用cuBLAS库进行矩阵乘法运算,CUBLAS的库的使用步骤如下:

  • Step one:定义CUBLAS库对象;
  • Step two: 在显存中为待运算的数据以及需要存放结果的变量开辟显存空间;(cudaMalloc函数实现)
  • Step three:将待运算的数据传输进显存;(cudaMemcpycublasSetVecotor等函数实现)
  • Step four: 调用CUBLAS的处理函数;(根据 CUBLAS 手册调用需要的函数)
  • Step five: 从显存中获取结果变量;(cudaMemcpy,cublasGetVector等函数实现)
  • Step six: 释放申请的显存空间以及CUBLAS库的对象;(cudaFree 及 cublasDestroy 函数实现 )

 如下程序使用 CUBLAS 库进行矩阵乘法运算,请仔细阅读注释,尤其是 API 的参数说明:

// CUDA runtime 库 + CUBLAS 库
#include "cuda_runtime.h"
#include "cublas_v2.h"

#include <time.h>
#include <iostream>

using namespace std;

// 定义测试矩阵的维度
int const M = 5;
int const N = 10;

int main()
{
    // 定义状态变量
    cublasStatus_t status;

    // 在 内存 中为将要计算的矩阵开辟空间
    float *h_A = (float*)malloc (N*M*sizeof(float));
    float *h_B = (float*)malloc (N*M*sizeof(float));

    // 在 内存 中为将要存放运算结果的矩阵开辟空间
    float *h_C = (float*)malloc (M*M*sizeof(float));

    // 为待运算矩阵的元素赋予 0-10 范围内的随机数
    for (int i=0; i<N*M; i++) {
        h_A[i] = (float)(rand()%10+1);
        h_B[i] = (float)(rand()%10+1);

    }

    // 打印待测试的矩阵
    cout << "矩阵 A :" << endl;
    for (int i=0; i<N*M; i++){
        cout << h_A[i] << " ";
        if ((i+1)%N == 0) cout << endl;
    }
    cout << endl;
    cout << "矩阵 B :" << endl;
    for (int i=0; i<N*M; i++){
        cout << h_B[i] << " ";
        if ((i+1)%M == 0) cout << endl;
    }
    cout << endl;

    /*
    ** GPU 计算矩阵相乘
    */

    // 创建并初始化 CUBLAS 库对象
    cublasHandle_t handle;
    status = cublasCreate(&handle);

    if (status != CUBLAS_STATUS_SUCCESS)
    {
        if (status == CUBLAS_STATUS_NOT_INITIALIZED) {
            cout << "CUBLAS 对象实例化出错" << endl;
        }
        getchar ();
        return EXIT_FAILURE;
    }

    float *d_A, *d_B, *d_C;
    // 在 显存 中为将要计算的矩阵开辟空间
    cudaMalloc (
        (void**)&d_A,    // 指向开辟的空间的指针
        N*M * sizeof(float)    // 需要开辟空间的字节数
    );
    cudaMalloc (
        (void**)&d_B,
        N*M * sizeof(float)
    );

    // 在 显存 中为将要存放运算结果的矩阵开辟空间
    cudaMalloc (
        (void**)&d_C,
        M*M * sizeof(float)
    );

    // 将矩阵数据传递进 显存 中已经开辟好了的空间
    cublasSetVector (
        N*M,    // 要存入显存的元素个数
        sizeof(float),    // 每个元素大小
        h_A,    // 主机端起始地址
        1,    // 连续元素之间的存储间隔
        d_A,    // GPU 端起始地址
        1    // 连续元素之间的存储间隔
    );
    cublasSetVector (
        N*M,
        sizeof(float),
        h_B,
        1,
        d_B,
        1
    );

    // 同步函数
    cudaThreadSynchronize();

    // 传递进矩阵相乘函数中的参数,具体含义请参考函数手册。
    float a=1; float b=0;
    // 矩阵相乘。该函数必然将数组解析成列优先数组
    cublasSgemm (
        handle,    // blas 库对象
        CUBLAS_OP_T,    // 矩阵 A 属性参数
        CUBLAS_OP_T,    // 矩阵 B 属性参数
        M,    // A, C 的行数
        M,    // B, C 的列数
        N,    // A 的列数和 B 的行数
        &a,    // 运算式的 α 值
        d_A,    // A 在显存中的地址
        N,    // lda
        d_B,    // B 在显存中的地址
        M,    // ldb
        &b,    // 运算式的 β 值
        d_C,    // C 在显存中的地址(结果矩阵)
        M    // ldc
    );

    // 同步函数
    cudaThreadSynchronize();

    // 从 显存 中取出运算结果至 内存中去
    cublasGetVector (
        M*M,    //  要取出元素的个数
        sizeof(float),    // 每个元素大小
        d_C,    // GPU 端起始地址
        1,    // 连续元素之间的存储间隔
        h_C,    // 主机端起始地址
        1    // 连续元素之间的存储间隔
    );

    // 打印运算结果
    cout << "计算结果的转置 ( (A*B)的转置 ):" << endl;

    for (int i=0;i<M*M; i++){
            cout << h_C[i] << " ";
            if ((i+1)%M == 0) cout << endl;
    }

    // 清理掉使用过的内存
    free (h_A);
    free (h_B);
    free (h_C);
    cudaFree (d_A);
    cudaFree (d_B);
    cudaFree (d_C);

    // 释放 CUBLAS 库对象
    cublasDestroy (handle);

    getchar();

    return 0;
}

输出结果:

281135122447740

3.总 结

​ cuBLAS 主库是一个功能全面、高性能的线性代数库,覆盖所有标准 BLAS 例程,适用于深度学习、科学计算和高性能计算等场景。它通过 GPU 加速和 Tensor Core 优化提供高效计算能力,是 cuBLAS 家族中最通用的组件。开发者可以结合官方文档和示例,利用 CUDA Toolkit 集成 cuBLAS 主库。

posted @ 2026-01-06 16:37  GeoFXR  阅读(142)  评论(0)    收藏  举报