已关闭
[Requirement|需求建议]: 新增 SSYRKX (FP32) 算子 DAV_3510 架构实现 #337
陶贻坤创建于  7月29日关闭于  8月3日
陶贻坤
陶贻坤成员
7月29日 创建

Background(背景信息)

BLAS Level-3 对称秩-k 更新(变体)接口 aclblasSsyrkx 当前缺少 DAV_3510(ascend950)架构的支持。本次新增 arch35 实现,使 Ssyrkx 在 ascend950 上可用。

Ssyrkx 计算公式:

C = alpha * op(A) * op(B)^T + beta * C

其中 op(X) = X(trans=N)或 op(X) = X^T(trans=T),C 为 n×n 对称矩阵(仅更新 uplo 指定三角),A/B 为 n×k 或 k×n 矩阵(A≠B)。

实现采用两阶段流水线架构,与已有 aclblasSsyrk 路线保持一致:

  1. Phase 1 GEMM(AIC核, tensor_api):计算 temp_T = op(B)*op(A)^T(交换 left/right 使 fixpipe 直接输出转置结果),利用 DNExt/NDExt LayoutPtn 在 GM→L1 搬运时即时转置(无需独立 transpose kernel),L1 双缓冲 + L0A/L0B ping-pong + L0C ping-pong 三级流水线
  2. Phase 2 Scale(AIV核, SIMD):计算 C = alphatemp + betaC,利用 temp_T[j][i] = temp[i][j] 恒等式交换读取坐标消除 Gather 转置(无需对称性假设),向量化 Muls/Axpy + uplo 三角掩码

涉及新增文件:

  • blas/syrkx/arch35/ssyrkx_host.cpp — Host 侧入口(参数校验、Tiling 计算、kernel 调度)
  • blas/syrkx/arch35/ssyrkx_kernel.cpp — Kernel 侧实现(GEMM + Scale 两个 kernel)
  • blas/syrkx/arch35/ssyrkx_kernel.h — kernel 声明
  • blas/syrkx/arch35/ssyrkx_tiling_data.h — TilingData 结构体定义
  • blas/syrkx/README.md — 算子文档
  • test/syrkx/ssyrkx/arch35/ssyrkx_test.cpp — CSV 参数化精度 ST
  • test/syrkx/ssyrkx/arch35/ssyrkx_npu_wrapper.h — H2D/D2H 测试 wrapper(RAII 设备内存管理)
  • test/syrkx/ssyrkx/arch35/ssyrkx_test.csv — 50 条测试用例(含边界值和非法参数校验)
  • test/syrkx/ssyrkx/ssyrkx_golden.h — golden 计算参考
  • test/syrkx/ssyrkx/ssyrkx_param.h — 测试参数定义
  • test/syrkx/ssyrkx/CMakeLists.txt — 构建配置

Origin(信息来源)

cann开发者

Benefit / Necessity(价值/作用)

  1. 填补 aclblasSsyrkx 在 ascend950 (DAV_3510) 上的缺失,完善 BLAS Level-3 接口覆盖率
  2. tensor_api + SIMD 混合架构充分利用 ascend950 Cube+Vector 双硬件能力,与已有 aclblasSsyrk/aclblasSsyr2k 路线保持一致
  3. Phase 1 GEMM 交换 A/B 计算 temp_T = op(B)*op(A)^T,使 Phase 2 Scale 可用交换坐标读取消除 Gather 转置,无需对称性假设
  4. DNExt/NDExt 路内转置消除独立 transpose kernel,L1/L0A/L0B/L0C 四级 ping-pong 流水线
  5. Phase 2 Scale 向量化 Muls/Axpy 批量计算,uplo 三角掩码 + non-uplo 原值保留
  6. 支持 uplo=UPPER/LOWER、trans=N/T 全组合,alpha/beta 为 Device 指针,alpha=0/k=0 快速路径(跳过 GEMM 但仍运行 Scale)
  7. 50 条 ST 覆盖基本功能、边界值(n=0/k=0/alpha=0/beta=0)、uplo/trans 全组合、ld padding、非法参数校验等场景

Design(设计方案)

两阶段架构

阶段 执行核 编程模型 功能
Phase 1 GEMM AIC-only tensor_api temp_T = op(B) * op(A)^T
Phase 2 Scale AIV-only SIMD C = alphatemp + betaC(仅 uplo 三角)

Phase 1 GEMM Kernel (AIC-only, tensor_api)

四层循环结构:核级 tile → MN tile → K chunk → L0 K split

  • 交换 A/B 计算转置结果:GEMM 计算 temp_T = op(B)*op(A)^T(left=gmB, right=gmA),fixpipe 直接输出转置结果到 GM,0 额外 kernel/workspace
  • DNExt/NDExt 路内转置:trans=N 时 left=DNExt(ldb,K)、right=NDExt(K,lda),搬运时即时转置,无需独立 transpose kernel
  • L1 双缓冲:A-side 和 B-side 数据按 NZ/ZN 格式写入共享 L1 buffer,双 buffer ping-pong
  • L0A/L0B ping-pong:K chunk 按 BASE_K=8 切分到 L0 级,L0A/L0B 各 2 slot
  • L0C ping-pong:L0C 256KB 分两半(各 128KB),Mmad unitFlag=0 + 手动 FixpipeParams{0},FIX_M(0/1) 双标志
  • 四级流水线同步:MTE2(搬入L1) → MTE1(搬入L0) → M(MMAD) → FIX(搬出GM),SetFlag/WaitFlag 配对
  • Zigzag 遍历:奇数 M 行反转 N 方向,提升 L2 cache 局部性

Phase 2 Scale Kernel (AIV-only, SIMD)

  • 转置消除(无需对称性假设):temp_T = op(B)*op(A)^T,temp_T[j][i] = (op(A)*op(B)^T)[i][j] = temp[i][j],交换读取坐标 temp_T[jBase+c][iBase+r] = temp[iBase+r][jBase+c],DataCopyPad 产生列主序 UB 布局匹配 cInUb
  • 向量化计算:Muls/Axpy 批量缩放,isBetaZero 时 Muls(c, temp, alpha) 一步完成
  • uplo 三角掩码:isFullInterior 快速路径整块批量计算;边界块按列计算 uploCount/nonUploCount,非 uplo 区域 Muls(c, cIn, 1.0) 保留原值
  • HardEvent 同步:MTE2_V(GM→UB→SIMD)、V_MTE3(SIMD→UB→GM)精确跨管道同步

Host 侧

  • 参数校验(uplo/trans/n/k/lda/ldb/ldc/alpha/beta/A/B/C)
  • alpha/beta 从 device 拷贝到 host(aclrtMemcpy D2H),k=0/alpha=0 时跳过 GEMM 但仍运行 Scale
  • 动态核数分配(min(数据量, 硬件核数))
  • workspace = n × tempRowStride × sizeof(float)(单个 temp 缓冲区)
  • CMake 类型隔离:ENABLE_BLAS_SSYRKX 仅隔离 /syrkx/arch35/ssyrkx,不影响其他数据类型
likedislike
陶贻坤陶贻坤成员
7月29日 将 eternityk 设为负责人
CANN-robotCANN-robot成员
8月3日 关闭了 issue
CANN-robotCANN-robot成员
8月3日 添加了label:resolved