已关闭
[Requirement|需求建议]: 新增面向Ascend950的aclsparseCsr2cscEx2接口 #109
yuyuanfeng创建于  7月21日关闭于  7月25日
yuyuanfeng
yuyuanfeng成员
7月21日 创建

Background(背景信息)

aclsparseCsr2cscEx2 实现稀疏矩阵的 CSR(Compressed Sparse Row)到 CSC(Compressed Sparse Column)格式转换,核心功能等价于稀疏矩阵转置(CSC = CSR^T)。接口为 Legacy API 中的 type-generic 接口(通过 valType 参数分发),支持多种数据类型。

支持的稀疏格式:

  • 输入:CSR(Compressed Sparse Row),由 csrVal、csrRowPtr、csrColInd 三个数组定义
  • 输出:CSC(Compressed Sparse Column),由 cscVal、cscColPtr、cscRowInd 三个数组定义

支持的索引基址:ACL_SPARSE_INDEX_BASE_ZERO(0-based)和 ACL_SPARSE_INDEX_BASE_ONE(1-based)

操作模式:

  • ACL_SPARSE_ACTION_SYMBOLIC:仅计算 CSC 结构(cscColPtr + cscRowInd),不拷贝值
  • ACL_SPARSE_ACTION_NUMERIC:计算结构并拷贝值(cscVal)

接口签名

aclsparseStatus_t aclsparseCsr2cscEx2_bufferSize(
    aclsparseHandle_t handle, int m, int n, int nnz,
    const void *csrVal, const int *csrRowPtr, const int *csrColInd,
    void *cscVal, int *cscColPtr, int *cscRowInd,
    aclDataType valType, aclsparseAction_t copyValues,
    aclsparseIndexBase_t idxBase, aclsparseCsr2CscAlg_t alg,
    size_t *bufferSize);

aclsparseStatus_t aclsparseCsr2cscEx2(
    aclsparseHandle_t handle, int m, int n, int nnz,
    const void *csrVal, const int *csrRowPtr, const int *csrColInd,
    void *cscVal, int *cscColPtr, int *cscRowInd,
    aclDataType valType, aclsparseAction_t copyValues,
    aclsparseIndexBase_t idxBase, aclsparseCsr2CscAlg_t alg,
    void *buffer);

参数约束

参数 约束
handle 非 nullptr,否则返回 ACL_SPARSE_STATUS_HANDLE_IS_NULLPTR
m, n, nnz ≥ 0,否则返回 ACL_SPARSE_STATUS_INVALID_VALUE
csrRowPtr m > 0 时非 nullptr,size = m+1
csrColInd nnz > 0 时非 nullptr,size = nnz,元素值域 ∈ [idxBase, idxBase+n)
csrVal nnz > 0 且 copyValues == NUMERIC 时非 nullptr
cscColPtr 非 nullptr,size = n+1
cscRowInd nnz > 0 时非 nullptr,size = nnz
cscVal nnz > 0 且 copyValues == NUMERIC 时非 nullptr
valType 必须为 ACL_INT8 / ACL_FLOAT16 / ACL_BF16 / ACL_FLOAT 之一
copyValues 必须为 ACL_SPARSE_ACTION_SYMBOLIC 或 ACL_SPARSE_ACTION_NUMERIC
idxBase 必须为 ACL_SPARSE_INDEX_BASE_ZERO 或 ACL_SPARSE_INDEX_BASE_ONE
alg 必须为 ACL_SPARSE_CSR2CSC_ALG_DEFAULT 或 ACL_SPARSE_CSR2CSC_ALG1
buffer workspace 指针,大小 ≥ bufferSize 返回值;可为 nullptr,此时回退使用 handle 预置 workspace

特殊边界行为

场景 行为
nnz == 0 仅填充 cscColPtr 全部元素为 idxBase,不读写其余数组
m == 0 / n == 0 统一由 nnz == 0 路径处理
异步执行 函数异步执行,需 aclrtSynchronizeStream 同步

精度标准

格式转换算子不涉及浮点运算(仅数据搬运和索引重排),精度标准为位精确。支持数据类型:INT8、FP16、BF16、FP32。

Origin(信息来源)

ops-sparse 算子库功能补齐,对齐 cuSPARSE cusparseCsr2cscEx2 接口能力。

Benefit / Necessity(价值/作用)

  • 补齐 ops-sparse 库在稀疏格式转换算子方面的能力
  • 与现有 CSR/CSC 系列算子(csrgeam2、nnz 等)形成完整的稀疏矩阵操作链路
  • 应用场景:稀疏线性系统求解、图计算(邻接矩阵转置)、稀疏注意力/图神经网络预处理
  • SIMT 编程模型为 arch35(Ascend950)上的不规则访存类算子提供实现参考

Design(设计方案)

四 Kernel 串行 SIMT 架构(DAV_3510 / arch35):

阶段 Kernel 功能 并行度
1 CountCols 遍历 csrColInd,asc_atomic_add 统计每列 nnz + stripe 列直方图 多 Block grid-stride
2 PrefixSum exclusive prefix sum → cscColPtr 单 Block 单线程
3 StripeBase 各 stripe 列直方图按列前缀和 → 私有写游标基址 多 Block 按列
4 Scatter stripe 分段并行,段内按 k 升序写入 cscRowInd/cscVal(保序) stripeCount 个 Block

Scatter 保序设计:列 j 的 CSC 段被划分为各 stripe 的不重叠子段,子段按 k 序排列,stripe 内单线程严格按 k 升序写入,输出与 CSR 行优先顺序逐位一致。

Tiling 策略:

  • Kernel 1/4:numBlocks = min(CeilDiv(nnz, 256), aivCoreNum),核数经 GetAivCoreCount() 动态获取
  • Kernel 2:单 Block 单线程(O(n) 串行 scan)
  • Kernel 3:多 Block grid-stride 按列切分

Workspace:bufferSize = (2 + stripeCount) × (n + 1) × sizeof(int32_t)

特殊场景处理:

  • nnz == 0:idxBase=0 走 memset 快路径,idxBase=1 走 kernel 路径
  • SYMBOLIC 模式:Kernel 4 仅写 cscRowInd,跳过 cscVal
  • buffer == nullptr:回退使用 handle 预置 workspace,容量不足返回 INSUFFICIENT_RESOURCES

平台约束:目标架构 arch35(Ascend950),Kernel 使用 asc_atomic_add 原子操作。

likedislike
yuyuanfengyuyuanfeng成员
7月21日 关联了pull request:Feat: 新增 aclsparseCsr2cscEx2 算子
yuyuanfengyuyuanfeng成员
7月21日 修改了issue 的描述
yuyuanfengyuyuanfeng成员
7月21日 修改了issue 的描述
yuyuanfengyuyuanfeng成员
7月21日 修改了issue 的描述
yuyuanfengyuyuanfeng成员
7月21日 修改了issue 的描述
yuyuanfengyuyuanfeng成员
7月22日 修改标题为 “[Requirement|需求建议]: 新增面向Ascend950的aclsparseCsr2cscEx2接口”,原标题为“Feat: 新增面向Ascend950的aclsparseCsr2cscEx2接口”
yuyuanfengyuyuanfeng成员
7月25日 关闭了 issue
yuyuanfengyuyuanfeng成员
7月25日 issue状态由 进行中 改变为 已完成
CANN-robotCANN-robot成员
7月25日 添加了label:resolved