CUDA 加速的稀疏矩阵计算库cuSPARSE
cuSPARSE 是 NVIDIA 提供的 GPU 加速稀疏矩阵计算库,包含一系列用于处理稀疏矩阵的基本线性代数子程序。
cuSPARSE 核心功能
1. 稀疏矩阵存储格式支持
-
CSR (Compressed Sparse Row)
-
CSC (Compressed Sparse Column)
-
COO (Coordinate Format)
-
Blocked ELL (ELLPACK)
-
HYB (Hybrid)
-
BSR (Block Sparse Row)
2. 主要计算操作
-
稀疏矩阵-向量乘法 (SpMV)
-
稀疏矩阵-矩阵乘法 (SpMM)
-
稀疏三角求解
-
稀疏矩阵转置
-
格式转换
-
稀疏矩阵的稠密化/稀疏化
cuSPARSE API 层次结构
cuSPARSE 提供三个层次的 API:
-
Level 1 - 稀疏向量操作
-
Level 2 - 稀疏矩阵-向量操作
-
Level 3 - 稀疏矩阵-矩阵操作
基本使用模式
1. 初始化和资源管理
cpp
#include <cusparse.h>cusparseHandle_t handle;
cusparseCreate(&handle); // 创建句柄// 创建矩阵描述符
cusparseMatDescr_t descr;
cusparseCreateMatDescr(&descr);
cusparseSetMatType(descr, CUSPARSE_MATRIX_TYPE_GENERAL);
cusparseSetMatIndexBase(descr, CUSPARSE_INDEX_BASE_ZERO);// ...执行运算...// 清理资源
cusparseDestroyMatDescr(descr);
cusparseDestroy(handle);
2. CSR 格式稀疏矩阵-向量乘法示例
cpp
// 矩阵数据 (CSR格式)
int m = 3, n = 3, nnz = 4;
float h_csrVal[] = {1.0, 2.0, 3.0, 4.0};
int h_csrRowPtr[] = {0, 2, 3, 4};
int h_csrColInd[] = {0, 1, 1, 2};
float h_x[] = {1.0, 1.0, 1.0};
float h_y[m] = {0};// 设备内存分配
float *d_csrVal, *d_x, *d_y;
int *d_csrRowPtr, *d_csrColInd;
cudaMalloc(&d_csrVal, nnz*sizeof(float));
cudaMalloc(&d_csrRowPtr, (m+1)*sizeof(int));
cudaMalloc(&d_csrColInd, nnz*sizeof(int));
cudaMalloc(&d_x, n*sizeof(float));
cudaMalloc(&d_y, m*sizeof(float));// 数据传输到设备
cudaMemcpy(d_csrVal, h_csrVal, nnz*sizeof(float), cudaMemcpyHostToDevice);
cudaMemcpy(d_csrRowPtr, h_csrRowPtr, (m+1)*sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(d_csrColInd, h_csrColInd, nnz*sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(d_x, h_x, n*sizeof(float), cudaMemcpyHostToDevice);// 执行SpMV (y = α*A*x + β*y)
float alpha = 1.0, beta = 0.0;
cusparseScsrmv(handle, CUSPARSE_OPERATION_NON_TRANSPOSE,m, n, nnz, &alpha,descr, d_csrVal, d_csrRowPtr, d_csrColInd,d_x, &beta, d_y);// 结果取回主机
cudaMemcpy(h_y, d_y, m*sizeof(float), cudaMemcpyDeviceToHost);// 释放设备内存
cudaFree(d_csrVal); cudaFree(d_csrRowPtr); cudaFree(d_csrColInd);
cudaFree(d_x); cudaFree(d_y);
关键函数分类
1. 格式转换
-
cusparse<t>csr2csc()
: CSR 转 CSC -
cusparse<t>dense2csr()
: 稠密矩阵转 CSR -
cusparse<t>csr2dense()
: CSR 转稠密矩阵
2. 稀疏矩阵-向量运算
-
cusparse<t>csrmv()
: CSR 矩阵-向量乘法 -
cusparse<t>hybmv()
: HYB 矩阵-向量乘法 -
cusparse<t>bsrmv()
: BSR 矩阵-向量乘法
3. 稀疏矩阵-矩阵运算
-
cusparse<t>csrmm()
: CSR 矩阵-矩阵乘法 -
cusparse<t>csrmm2()
: 扩展的 CSR 矩阵-矩阵乘法
4. 三角求解
-
cusparse<t>csrsv_analysis()
: 分析阶段 -
cusparse<t>csrsv_solve()
: 求解阶段
高级特性
1. 通用 SpMM (稀疏矩阵-稠密矩阵乘法)
cpp
// 使用CSR格式计算 C = A*B (A稀疏,B稠密)
cusparseScsrmm2(handle,CUSPARSE_OPERATION_NON_TRANSPOSE,CUSPARSE_OPERATION_NON_TRANSPOSE,m, n, k, nnz,&alpha,descr, d_csrVal, d_csrRowPtr, d_csrColInd,d_B, ldb,&beta,d_C, ldc);
2. 批处理稀疏矩阵运算
cpp
// 批处理CSR矩阵-向量乘法
cusparseScsrmvBatched(handle,CUSPARSE_OPERATION_NON_TRANSPOSE,m, n,alpha,descr,d_csrVal, d_csrRowPtr, d_csrColInd,d_x,beta,d_y,batchCount);
3. 混合格式 (HYB)
cpp
// 创建HYB矩阵
cusparseHybMat_t hybA;
cusparseCreateHybMat(&hybA);// 将CSR转换为HYB格式
cusparseScsr2hyb(handle, m, n, descr,d_csrVal, d_csrRowPtr, d_csrColInd,hybA, 0, CUSPARSE_HYB_PARTITION_AUTO);// 使用HYB格式进行矩阵-向量乘法
cusparseShybmv(handle, CUSPARSE_OPERATION_NON_TRANSPOSE,&alpha, descr, hybA,d_x, &beta, d_y);// 销毁HYB矩阵
cusparseDestroyHybMat(hybA);
cuSPARSE 和 cuSOLVER区别
cuSPARSE 和 cuSOLVER 都是 NVIDIA 提供的 CUDA 加速线性代数库,但它们的定位和功能有显著区别。以下是两者的详细对比:
核心定位
库 | 主要用途 |
---|---|
cuSPARSE | 专注于稀疏矩阵的基本运算(如SpMV/SpMM)和格式转换,提供低级别稀疏计算原语 |
cuSOLVER | 提供高级线性代数求解功能(如分解、系统求解),支持稠密和稀疏矩阵,包含更复杂的数值算法 |
应用场景
库 | 适用场景 |
---|---|
cuSPARSE | - 迭代法求解稀疏线性系统(如共轭梯度法) - 图算法(如PageRank) - 稀疏神经网络推理 |
cuSOLVER | - 直接法求解线性系统(如有限元分析) - 最小二乘拟合 - 特征值问题(如量子化学计算) |
性能优化建议
-
选择合适的存储格式:
-
结构化稀疏:BSR
-
非结构化稀疏:CSR/CSC
-
非常稀疏:HYB
-
-
重用分析信息:
-
对固定模式的矩阵,保存分析结果
-
-
批处理小矩阵:
-
使用批处理API提高小矩阵运算效率
-
-
异步执行:
-
使用CUDA流重叠计算和通信
-
-
利用纹理内存:
-
对某些操作可以使用纹理内存加速
-
cuSPARSE 特别适合处理大规模稀疏线性代数问题,如图像处理、有限元分析、推荐系统和图计算等领域。与稠密矩阵运算相比,稀疏矩阵运算可以节省大量内存和计算资源。