文档 / 简体中文查看源码 ↗

ruSPARSE 用户指南

计算库 · English | 日本語 | Deutsch | Русский

1. 概述

ruSPARSE 负责稀疏计算。

2. 数据描述

类型 用途
CsrMatrix、CsrMatrixOwned CSR 借用视图与自有存储
CooMatrix、CooMatrixOwned COO 表示
CscMatrix、CscMatrixOwned CSC 表示
BsrMatrix、EllMatrix 块稀疏与 ELL 表示
DenseMatrix、DenseMatrixOwned 稠密矩阵描述
SparseVector 稀疏向量
IndexBase Zero 或 One 索引基准
DenseOrder RowMajor 或 ColumnMajor
Operation None、Transpose、ConjugateTranspose

数据的索引基准、布局和操作类型是显式契约,不能只根据数组长度猜测。名称中的 Owned 区分自有数据与借用视图,不表示自动分配通用 GPU 存储。

3. 运算组织

现有实现按矩阵向量乘、矩阵乘、稀疏矩阵乘/加、稀疏向量内积、SDDMM 和格式转换组织。执行层包含 SparsePlan、SparseError 及不同操作的执行结果类型。

CSR 矩阵向量乘采用 alpha、op(A)、x、beta、y 的运算契约;迁移调用时需要同时匹配索引基准、转置方式和数据布局,不是只替换库名前缀。

4. CUDA CSR 矩阵向量乘

Cargo package 名为 ruSPARSE,Rust 导入名为 rusparse。tensor feature 启用 rusparse::tensor,cuda 同时启用设备张量和 CUDA 依赖。在源码根目录运行:

cargo run --locked -p ruSPARSE --features cuda --example csrmv

这个示例计算 0.5 × A × x + 2 × y:

use ruda_core::tensor::data::TensorData;
use ruda_driver_cuda::{CudaDevice, CudaRuntime};
use ruda_kernel::tensor::{readback::into_data_sync, transfer::from_data};
use rusparse::{
    CsrMatrix, IndexBase, Operation,
    tensor::{CsrTensor, csrmv},
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let device = CudaDevice::default();
    let host = CsrMatrix::new(
        3, 3,
        &[0, 2, 3, 4],
        &[0, 1, 1, 2],
        &[2., 1., -1., 5.],
        IndexBase::Zero,
    )?;
    let matrix = CsrTensor::<CudaRuntime>::from_csr(host, Operation::None, &device)?;
    let x = from_data(TensorData::new(vec![3f32, 4., 5.], [3]), &device);
    let y = from_data(TensorData::new(vec![1f32, 2., 3.], [3]), &device);
    let output = into_data_sync(csrmv(&matrix, 0.5, x, 2., y)?).to_vec::<f32>()?;
    assert_eq!(output, [7., 2., 18.5]);
    println!("alpha * A * x + beta * y = {output:?}");
    Ok(())
}

CsrMatrix::new 的参数依次是行数、列数、行偏移、列索引、非零值和索引基准。本例第一行存储两项,第二、第三行各一项;结果为 [7.0, 2.0, 18.5]。

CsrTensor::from_csr 上传结构和值;转置在此处用 Operation::Transpose 指定。csrmv(&matrix, alpha, x, beta, y) 的 x 长度为矩阵列数,y 长度为行数;稠密输入非量化、dtype 为 F32,且与矩阵位于同一设备。返回新设备张量,复用矩阵时不必再次上传 CSR 结构。

稀疏/稠密矩阵乘使用 csrmm(&matrix, operation_b, alpha, b, beta, c, output_order),其中 c 为可选张量,输出布局使用 DenseOrder 指定。仅更新非零值时,调用 matrix.with_values(values),新 values 为长度 nnz 的 F32 设备张量,结构保持不变。

5. 张量框架中的 CSR

ruda_tensor::api::CsrTensor<B> 面向实现 SparseOps 的 Backend,与上一节的 rusparse::tensor::CsrTensor<R> 是不同类型。用 CsrTensor::<B>::from_data(&data, &device) 创建,data 类型为该 Backend 的 B::CsrData。

方法 用法
matmul(rhs)、transpose_matmul(rhs) 稀疏矩阵或其转置乘二维稠密张量
sparse_matmul(&rhs) 稀疏矩阵相乘,生成结果结构
add(&rhs)、add_scaled(&rhs, alpha, beta) 稀疏加法或带系数加法
gather(dense) 按当前 CSR 位置提取稠密值,返回一维张量
scatter_add() 将存储值加到对应稠密位置
mul_dense(rhs) 在当前 CSR 位置与稠密矩阵逐项相乘
sampled_matmul(lhs, rhs) 只在当前 CSR 位置计算稠密矩阵乘结果
sampled_sparse_matmul(&lhs, &rhs) 只在当前 CSR 位置计算稀疏矩阵乘结果
transpose()、to_dense() 转置或转换为稠密张量
with_values(values) 替换一维值张量并保留结构
to_data().await 异步回读为 B::CsrData

这些计算方法返回 Result;框架稀疏运算的值张量必须非量化。

接口参考:设备 CSR、框架 CSR。