已合并
【社区任务】aclblasCsymm 算子设计文档(Ascend 950PR) #1237
ConanYao创建于 10 天前
【社区任务】aclblasCsymm 算子设计文档(Ascend 950PR) #1237
已合并
共 1 个文件变更+378-0
| @@ -0,0 +1,378 @@ | |||
| 1 | +# aclblasCsymm 算子设计文档 | ||
| 2 | + | ||
| 3 | +| 项目 | 详情 | | ||
| 4 | +|------|------| | ||
| 5 | +| 算子名称 | aclblasCsymm | | ||
| 6 | +| 开发语言 | Ascend C | | ||
| 7 | +| 适配硬件 | Ascend 950PR | | ||
| 8 | +| NPU 架构 | DAV_3510 / arch35 | | ||
| 9 | +| CANN 版本 | CANN 9.1.0 | | ||
| 10 | +| 对齐基准 | cuBLAS `cublasCsymm` / Netlib BLAS `csymm` | | ||
| 11 | +| 最终合入仓 | ops-blas 开源仓,`blas/symm/arch35/` | | ||
| 12 | + | ||
| 13 | +# 1 需求背景(required) | ||
| 14 | + | ||
| 15 | +## 1.1 需求来源 | ||
| 16 | + | ||
| 17 | +本任务来源于 CANN 社区任务 2026,目标是在 Ascend 950PR 上使用 Ascend C 开发单精度复数对称矩阵乘 BLAS 算子 `aclblasCsymm`,并最终合入 `cann/ops-blas` 开源仓。 | ||
| 18 | + | ||
| 19 | +## 1.2 背景介绍 | ||
| 20 | + | ||
| 21 | +`aclblasCsymm` 对齐 BLAS `csymm` 语义,用于计算复数对称矩阵与普通复数矩阵的乘加: | ||
| 22 | + | ||
| 23 | +- `side = ACLBLAS_SIDE_LEFT` 时,`C = alpha * A * B + beta * C` | ||
| 24 | +- `side = ACLBLAS_SIDE_RIGHT` 时,`C = alpha * B * A + beta * C` | ||
| 25 | + | ||
| 26 | +其中 `A` 为复数对称矩阵,满足 `A = A^T`,不是 Hermitian 矩阵,不执行共轭处理,对角元素虚部也不置零。调用方只提供 `uplo` 指定的上三角或下三角有效数据,另一半由对称性隐含。 | ||
| 27 | + | ||
| 28 | +本算子面向 ops-blas 句柄式接口,依赖 `aclblasHandle_t` 中绑定的 stream 进行异步 Kernel 直调。接口声明需新增到 `include/cann_ops_blas.h`,与其他产品线共享同一个 `aclblasCsymm` API,不定义 Ascend 950PR 私有接口。 | ||
| 29 | + | ||
| 30 | +# 2 需求分析(required) | ||
| 31 | + | ||
| 32 | +## 2.1 需求描述 | ||
| 33 | + | ||
| 34 | +使用 Ascend C kernel 直调方式实现 `aclblasCsymm`,支持 `COMPLEX64` 输入输出,支持 `side`、`uplo` 两个 BLAS 枚举,支持列主序矩阵和 `lda/ldb/ldc` 前导维度。算子需完整实现 BLAS quick return 和特殊标量语义,并满足任务书给出的精度、性能和异常返回要求。 | ||
| 35 | + | ||
| 36 | +## 2.2 需求拆解 | ||
| 37 | + | ||
| 38 | +| 序号 | 需求项 | 详细描述 | 优先级 | | ||
| 39 | +|------|--------|----------|:------:| | ||
| 40 | +| 1 | 接口声明 | 在 `include/cann_ops_blas.h` 新增 `aclblasCsymm` 声明,参数顺序对齐 cuBLAS | P0 | | ||
| 41 | +| 2 | BLAS 语义 | 支持 LEFT/RIGHT,UPPER/LOWER,列主序 `lda/ldb/ldc` | P0 | | ||
| 42 | +| 3 | 复数计算 | `aclblasComplex` 实部、虚部均为 float32,按 complex64 乘加 | P0 | | ||
| 43 | +| 4 | 对称矩阵读取 | 仅引用 `uplo` 指定三角,另一侧按 `A = A^T` 映射,不共轭 | P0 | | ||
| 44 | +| 5 | 标量语义 | 支持 `alpha`、`beta` 复数标量,处理 `alpha=0`、`beta=0/1` quick return | P0 | | ||
| 45 | +| 6 | 参数校验 | 校验 handle、枚举、维度、指针和前导维,返回指定状态码 | P0 | | ||
| 46 | +| 7 | arch35 直调 | 实现目录为 `blas/symm/arch35/`,适配 Ascend 950PR / DAV_3510 | P0 | | ||
| 47 | +| 8 | 精度验收 | real/imag 分量按 FLOAT32 混合容差判定 | P0 | | ||
| 48 | +| 9 | 性能验收 | 满足 256/1024 典型性能 case 标杆耗时 | P0 | | ||
| 49 | + | ||
| 50 | +## 2.3 外部组件依赖 | ||
| 51 | + | ||
| 52 | +| 组件 | 说明 | 是否必需 | | ||
| 53 | +|------|------|:--------:| | ||
| 54 | +| CANN 9.1.0 | Ascend C 编译、运行和 BLAS 仓测试环境 | 是 | | ||
| 55 | +| ops-blas | 句柄、状态码、公共复数类型、测试框架和合入目标仓 | 是 | | ||
| 56 | +| cblas / Netlib BLAS | 自测 golden 生成,参考 `csymm` 行为 | 是 | | ||
| 57 | +| Blaze / tensor_api | Ascend 950 / DAV_3510 MatMul 类算子推荐路径,可用于 Cube 矩阵乘 tile 组织 | 是 | | ||
| 58 | + | ||
| 59 | +# 3 详细设计(required) | ||
| 60 | + | ||
| 61 | +## 3.1 算子分析 | ||
| 62 | + | ||
| 63 | +### 3.1.1 数学公式 | ||
| 64 | + | ||
| 65 | +设 `A` 为对称复数矩阵,`B`、`C` 为 `m x n` 复数矩阵,全部按列主序存储。 | ||
| 66 | + | ||
| 67 | +`side = LEFT`: | ||
| 68 | + | ||
| 69 | +$$C_{i,j} = \alpha \sum_{k=0}^{m-1} A_{i,k} B_{k,j} + \beta C_{i,j}$$ | ||
| 70 | + | ||
| 71 | +`side = RIGHT`: | ||
| 72 | + | ||
| 73 | +$$C_{i,j} = \alpha \sum_{k=0}^{n-1} B_{i,k} A_{k,j} + \beta C_{i,j}$$ | ||
| 74 | + | ||
| 75 | +复数乘法展开为: | ||
| 76 | + | ||
| 77 | +$$ (a_r + i a_i)(b_r + i b_i) = (a_r b_r - a_i b_i) + i(a_r b_i + a_i b_r) $$ | ||
| 78 | + | ||
| 79 | +累加使用 float32 分量完成,不引入共轭,不对对角线虚部做特殊处理。 | ||
| 80 | + | ||
| 81 | +### 3.1.2 支持数据类型 | ||
| 82 | + | ||
| 83 | +| 参数 | dtype | 说明 | | ||
| 84 | +|------|-------|------| | ||
| 85 | +| alpha | COMPLEX64 | Host 侧复数标量 | | ||
| 86 | +| beta | COMPLEX64 | Host 侧复数标量 | | ||
| 87 | +| A | COMPLEX64 | Device 侧只读,对称矩阵 | | ||
| 88 | +| B | COMPLEX64 | Device 侧只读,普通矩阵 | | ||
| 89 | +| C | COMPLEX64 | Device 侧原地输出 | | ||
| 90 | + | ||
| 91 | +### 3.1.3 支持形状与格式 | ||
| 92 | + | ||
| 93 | +| 参数 | side=LEFT | side=RIGHT | 格式 | | ||
| 94 | +|------|-----------|------------|------| | ||
| 95 | +| A | `m x m` | `n x n` | ND,Column-Major | | ||
| 96 | +| B | `m x n` | `m x n` | ND,Column-Major | | ||
| 97 | +| C | `m x n` | `m x n` | ND,Column-Major | | ||
| 98 | + | ||
| 99 | +`lda` 在 LEFT 场景要求 `lda >= max(1, m)`,在 RIGHT 场景要求 `lda >= max(1, n)`;`ldb >= max(1, m)`;`ldc >= max(1, m)`。本批次不支持超出 BLAS 前导维语义的非连续 tensor。 | ||
| 100 | + | ||
| 101 | +## 3.2 使能方式 | ||
| 102 | + | ||
| 103 | +| 上层框架 | 涉及勾选 | 说明 | | ||
| 104 | +|----------|----------|------| | ||
| 105 | +| TF训练/推理 | | 不涉及 | | ||
| 106 | +| Pytorch训练/推理 | | 不涉及 | | ||
| 107 | +| ATC推理 | | 不涉及 | | ||
| 108 | +| Aclnn直调 | √ | ops-blas 句柄式 API 直调 | | ||
| 109 | +| OPAT调优 | | 不涉及 | | ||
| 110 | +| SGAT子图切分 | | 不涉及 | | ||
| 111 | + | ||
| 112 | +## 3.3 Host 侧设计 | ||
| 113 | + | ||
| 114 | +Host 侧负责 BLAS 参数校验、quick return 判定、Tiling 计算和 Kernel launch,不承担矩阵计算。 | ||
| 115 | + | ||
| 116 | +### 3.3.1 API 原型 | ||
| 117 | + | ||
| 118 | +```cpp | ||
| 119 | +aclblasStatus_t aclblasCsymm( | ||
| 120 | + aclblasHandle_t handle, | ||
| 121 | + aclblasSideMode_t side, | ||
| 122 | + aclblasFillMode_t uplo, | ||
| 123 | + int m, int n, | ||
| 124 | + const aclblasComplex* alpha, | ||
| 125 | + const aclblasComplex* A, int lda, | ||
| 126 | + const aclblasComplex* B, int ldb, | ||
| 127 | + const aclblasComplex* beta, | ||
| 128 | + aclblasComplex* C, int ldc); | ||
| 129 | +``` | ||
| 130 | + | ||
| 131 | +### 3.3.2 参数校验顺序 | ||
| 132 | + | ||
| 133 | +| 校验项 | 条件 | 返回值 | | ||
| 134 | +|--------|------|--------| | ||
| 135 | +| handle | `handle == nullptr` | `ACLBLAS_STATUS_HANDLE_IS_NULLPTR` | | ||
| 136 | +| side | 非 LEFT/RIGHT | `ACLBLAS_STATUS_INVALID_ENUM` | | ||
| 137 | +| uplo | 非 UPPER/LOWER | `ACLBLAS_STATUS_INVALID_ENUM` | | ||
| 138 | +| m/n | `m < 0` 或 `n < 0` | `ACLBLAS_STATUS_INVALID_VALUE` | | ||
| 139 | +| alpha/beta | 任一为空 | `ACLBLAS_STATUS_INVALID_VALUE` | | ||
| 140 | +| lda | LEFT: `lda < max(1,m)`;RIGHT: `lda < max(1,n)` | `ACLBLAS_STATUS_INVALID_VALUE` | | ||
| 141 | +| ldb | `ldb < max(1,m)` | `ACLBLAS_STATUS_INVALID_VALUE` | | ||
| 142 | +| ldc | `ldc < max(1,m)` | `ACLBLAS_STATUS_INVALID_VALUE` | | ||
| 143 | +| A/B | `m > 0 && n > 0` 且为空 | `ACLBLAS_STATUS_INVALID_VALUE` | | ||
| 144 | +| C | `m > 0 && n > 0 && beta != 0` 且为空 | `ACLBLAS_STATUS_INVALID_VALUE` | | ||
| 145 | + | ||
| 146 | +校验通过后,若 `m == 0 || n == 0`,直接返回 `ACLBLAS_STATUS_SUCCESS`。若 `alpha == (0,0) && beta == (1,0)`,直接返回成功,不启动 Kernel。若 `alpha == (0,0)` 且 `beta != (1,0)`,进入 C 缩放/清零分支。 | ||
| 147 | + | ||
| 148 | +### 3.3.3 TilingKey 规划 | ||
| 149 | + | ||
| 150 | +TilingKey 按以下维度编码,便于 Kernel 侧选择轻量分支: | ||
| 151 | + | ||
| 152 | +| 字段 | 取值 | 说明 | | ||
| 153 | +|------|------|------| | ||
| 154 | +| side | LEFT / RIGHT | 决定 K 维为 m 或 n,以及 A 的物理寻址方式 | | ||
| 155 | +| uplo | UPPER / LOWER | 决定读取 A 上三角或下三角 | | ||
| 156 | +| alphaBetaMode | GENERAL / ALPHA_ZERO / BETA_ZERO / BETA_ONE | 标量 epilogue 快路径 | | ||
| 157 | +| shapeClass | SMALL / MEDIUM / LARGE | 小矩阵向量化路径或大矩阵 Cube 路径 | | ||
| 158 | +| leadingDimMode | COMPACT / PADDED | `lda/ldb/ldc` 是否等于最小前导维 | | ||
| 159 | + | ||
| 160 | +### 3.3.4 Tiling 数据 | ||
| 161 | + | ||
| 162 | +Host 侧生成以下核心 TilingData: | ||
| 163 | + | ||
| 164 | +| 字段 | 说明 | | ||
| 165 | +|------|------| | ||
| 166 | +| `m`, `n`, `k` | `k = (side == LEFT ? m : n)` | | ||
| 167 | +| `lda`, `ldb`, `ldc` | Column-Major 前导维 | | ||
| 168 | +| `alphaReal`, `alphaImag` | alpha 标量 | | ||
| 169 | +| `betaReal`, `betaImag` | beta 标量 | | ||
| 170 | +| `side`, `uplo` | BLAS 枚举 | | ||
| 171 | +| `blockM`, `blockN`, `blockK` | 矩阵乘 tile 尺寸 | | ||
| 172 | +| `usedCubeCoreNum`, `usedVectorCoreNum` | 实际使用核数,运行时从平台获取 | | ||
| 173 | +| `workspaceSize` | 可选 workspace 大小,用于 A 对称 tile 展开和中间累加 | | ||
| 174 | +| `tailM`, `tailN`, `tailK` | 尾块信息 | | ||
| 175 | + | ||
| 176 | +`blockM/blockN/blockK` 需满足 DAV_3510 Cube 阵列 16x16x16、L0A/L0B 64KB、L0C 256KB、L1 512KB、UB 248KB 等资源约束,并通过 `PlatformAscendC` 获取实际核数和 Buffer 容量,避免硬编码具体板卡核数。 | ||
| 177 | + | ||
| 178 | +## 3.4 Kernel 侧设计 | ||
| 179 | + | ||
| 180 | +### 3.4.1 总体方案 | ||
| 181 | + | ||
| 182 | +`aclblasCsymm` 属于 MatMul 类算子。Ascend 950PR 对应 DAV_3510 / arch35,设计采用 Blaze / tensor_api 风格的矩阵乘 tile 组织作为主路径,并在同一个 Device Kernel 中完成以下步骤: | ||
| 183 | + | ||
| 184 | +1. 根据 `side/uplo` 对 A 执行对称寻址; | ||
| 185 | +2. 将 `COMPLEX64` 拆分为 real/imag 分量参与 float32 乘累加; | ||
| 186 | +3. 完成 `A*B` 或 `B*A` 的分块累加; | ||
| 187 | +4. 在 epilogue 中融合 `alpha`、`beta` 和 C 原地写回; | ||
| 188 | +5. 处理尾块、padding 前导维和小尺寸场景。 | ||
| 189 | + | ||
| 190 | +对称 A 不在 Host 侧展开。Kernel 侧按 tile 将所需 A 面板搬入片上存储;若当前 tile 访问到未显式存储的一侧,则根据 `uplo` 映射到显式三角中的对称位置。 | ||
| 191 | + | ||
| 192 | +### 3.4.2 A 矩阵对称寻址 | ||
| 193 | + | ||
| 194 | +Column-Major 下,矩阵元素地址为 `base + row + col * ld`。 | ||
| 195 | + | ||
| 196 | +`uplo = UPPER` 时: | ||
| 197 | + | ||
| 198 | +```text | ||
| 199 | +A(i, k) = (i <= k) ? A_gm[i + k * lda] : A_gm[k + i * lda] | ||
| 200 | +``` | ||
| 201 | + | ||
| 202 | +`uplo = LOWER` 时: | ||
| 203 | + | ||
| 204 | +```text | ||
| 205 | +A(i, k) = (i >= k) ? A_gm[i + k * lda] : A_gm[k + i * lda] | ||
| 206 | +``` | ||
| 207 | + | ||
| 208 | +`side = RIGHT` 时同理访问 `A(k, j)`,其中 A 的维度为 `n x n`。该映射只交换下标,不做 conjugate,不改变对角元素虚部。 | ||
| 209 | + | ||
| 210 | +### 3.4.3 复数矩阵乘策略 | ||
| 211 | + | ||
| 212 | +主计算可按 real/imag 分量拆成四个实数乘累加: | ||
| 213 | + | ||
| 214 | +```text | ||
| 215 | +tmpReal = Ar * Br - Ai * Bi | ||
| 216 | +tmpImag = Ar * Bi + Ai * Br | ||
| 217 | +``` | ||
| 218 | + | ||
| 219 | +对于每个输出 tile,Kernel 在 K 维循环累加 `tmpReal/tmpImag`,最后执行: | ||
| 220 | + | ||
| 221 | +```text | ||
| 222 | +outReal = alphaReal * tmpReal - alphaImag * tmpImag | ||
| 223 | + + betaReal * oldReal - betaImag * oldImag | ||
| 224 | + | ||
| 225 | +outImag = alphaReal * tmpImag + alphaImag * tmpReal | ||
| 226 | + + betaReal * oldImag + betaImag * oldReal | ||
| 227 | +``` | ||
| 228 | + | ||
| 229 | +当 `beta == (0,0)` 时,跳过旧 C 读取;当 `beta == (1,0)` 时,旧 C 直接加到 epilogue;当 `alpha == (0,0)` 时,跳过 A/B 乘累加,仅处理 C 的缩放或清零。 | ||
| 230 | + | ||
| 231 | +### 3.4.4 多核切分策略 | ||
| 232 | + | ||
| 233 | +输出矩阵 C 按二维 tile 分配到 CubeCore: | ||
| 234 | + | ||
| 235 | +- LEFT 场景:输出 tile 维度为 `M x N`,K 维为 `m`; | ||
| 236 | +- RIGHT 场景:输出 tile 维度为 `M x N`,K 维为 `n`; | ||
| 237 | +- 每个 CubeCore 负责若干个输出 tile,优先按 tile 网格均匀分配; | ||
| 238 | +- 小尺寸或 tile 数少于 CubeCore 数时,减少 `usedCubeCoreNum`,避免空核调度开销; | ||
| 239 | +- 尾块通过 `curM/curN/curK` 表达逻辑有效范围,硬件 `blockM/blockN/blockK` 保持合法对齐粒度。 | ||
| 240 | + | ||
| 241 | +对于性能典型 case: | ||
| 242 | + | ||
| 243 | +| case | 策略 | | ||
| 244 | +|------|------| | ||
| 245 | +| 256x256 LEFT UPPER | 使用较小 tile 增强并行度,减少 A 对称搬运重复 | | ||
| 246 | +| 1024x1024 LEFT LOWER | 使用 full CubeCore 并行,K 维分块累加,A 面板按下三角映射 | | ||
| 247 | +| 1024x1024 RIGHT UPPER | 输出按 N 维 tile 展开,优化 B 连续列访问和 A 上三角映射 | | ||
| 248 | + | ||
| 249 | +### 3.4.5 UB/L1/L0 Buffer 规划 | ||
| 250 | + | ||
| 251 | +DAV_3510 的典型片上资源为 L1 512KB、L0A 64KB、L0B 64KB、L0C 256KB、UB 248KB。设计遵循运行时查询实际容量的原则。 | ||
| 252 | + | ||
| 253 | +| Buffer | 用途 | 生命周期 | | ||
| 254 | +|--------|------|----------| | ||
| 255 | +| L1 A panel | 对称 A tile 展开后的 real/imag 面板 | K tile 内复用 | | ||
| 256 | +| L1 B panel | B tile real/imag 面板 | K tile 内复用 | | ||
| 257 | +| L0A/L0B | Cube 计算输入分块 | 单次 MMAD | | ||
| 258 | +| L0C | real/imag 累加临时结果 | 输出 tile 生命周期 | | ||
| 259 | +| UB tmp | A 三角到 dense tile 的重排、C epilogue、tail mask | 分阶段复用 | | ||
| 260 | +| GM workspace | 可选,用于较大 tile 或调试路径保存中间结果 | 按 TilingData 配置 | | ||
| 261 | + | ||
| 262 | +UB 复用策略: | ||
| 263 | + | ||
| 264 | +- A 对称展开 buffer 与 C epilogue buffer 生命周期不重叠,可复用同一 TBuf; | ||
| 265 | +- `beta == 0` 分支不申请旧 C 读入 buffer; | ||
| 266 | +- 小矩阵路径尽量将 C tile 保持在 UB 中完成 alpha/beta epilogue; | ||
| 267 | +- tile size 选择以不超过 `GetCoreMemSize(UB)` 返回容量为硬约束,目标是提升 UB 利用率,同时保留尾块 mask 和流水同步空间。 | ||
| 268 | + | ||
| 269 | +### 3.4.6 分支场景覆盖 | ||
| 270 | + | ||
| 271 | +| 分支 | 处理策略 | | ||
| 272 | +|------|----------| | ||
| 273 | +| LEFT + UPPER | A 访问 `A(i,k)`,当 `i > k` 时映射到 `A(k,i)` | | ||
| 274 | +| LEFT + LOWER | A 访问 `A(i,k)`,当 `i < k` 时映射到 `A(k,i)` | | ||
| 275 | +| RIGHT + UPPER | A 访问 `A(k,j)`,当 `k > j` 时映射到 `A(j,k)` | | ||
| 276 | +| RIGHT + LOWER | A 访问 `A(k,j)`,当 `k < j` 时映射到 `A(j,k)` | | ||
| 277 | +| alpha = 0, beta = 1 | Host quick return,不启动 Kernel | | ||
| 278 | +| alpha = 0, beta = 0 | C 置零分支;若任务口径允许 C 为空,则直接成功返回 | | ||
| 279 | +| alpha = 0, beta = general | 仅执行复数 C 缩放 | | ||
| 280 | +| beta = 0 | 跳过旧 C 读取,直接写 `alpha * prod` | | ||
| 281 | +| padded leading dimension | 按 `lda/ldb/ldc` 计算 GM 地址,不假设紧凑连续 | | ||
| 282 | +| tail M/N/K | 使用逻辑 `curM/curN/curK` 和 mask 避免越界 | | ||
| 283 | + | ||
| 284 | +## 3.5 异常与边界设计 | ||
| 285 | + | ||
| 286 | +| 场景 | 行为 | | ||
| 287 | +|------|------| | ||
| 288 | +| `m == 0 || n == 0` | 合法 no-op,返回 `ACLBLAS_STATUS_SUCCESS` | | ||
| 289 | +| 非法枚举 | 返回 `ACLBLAS_STATUS_INVALID_ENUM` | | ||
| 290 | +| 负维度 | 返回 `ACLBLAS_STATUS_INVALID_VALUE` | | ||
| 291 | +| 非法前导维 | 返回 `ACLBLAS_STATUS_INVALID_VALUE` | | ||
| 292 | +| `alpha/beta == nullptr` | 返回 `ACLBLAS_STATUS_INVALID_VALUE` | | ||
| 293 | +| `A/B == nullptr` 且非空矩阵 | 返回 `ACLBLAS_STATUS_INVALID_VALUE` | | ||
| 294 | +| `C == nullptr` 且 `beta != 0` | 返回 `ACLBLAS_STATUS_INVALID_VALUE` | | ||
| 295 | +| Inf/NaN 输入 | 按 float32 复数算术自然传播,与 Netlib/cblas golden 对齐 | | ||
| 296 | + | ||
| 297 | +# 4 支持硬件 | ||
| 298 | + | ||
| 299 | +| 支持的芯片版本 | 涉及勾选 | | ||
| 300 | +|----------------|----------| | ||
| 301 | +| Ascend 950PR | √ | | ||
| 302 | + | ||
| 303 | +# 5 算子约束限制 | ||
| 304 | + | ||
| 305 | +| 约束项 | 内容 | | ||
| 306 | +|--------|------| | ||
| 307 | +| 数据类型 | 仅支持 `COMPLEX64` | | ||
| 308 | +| 数据格式 | 仅支持 Column-Major ND | | ||
| 309 | +| 对称性 | 调用方保证 A 满足 `A = A^T`,Kernel 不校验输入是否对称 | | ||
| 310 | +| 三角读取 | 仅引用 `uplo` 指定三角,未引用三角内容不参与计算 | | ||
| 311 | +| 共轭语义 | 不共轭,区别于 Hermitian `hemm` | | ||
| 312 | +| 对角处理 | 对角元素虚部不置零、不修正 | | ||
| 313 | +| 非连续 Tensor | 不支持超出 `lda/ldb/ldc` 语义的任意 stride/view | | ||
| 314 | +| 动态 shape | `m/n` 为运行时参数,不要求图模式动态 shape | | ||
| 315 | +| 原地语义 | C 原地覆写 | | ||
| 316 | +| 确定性 | 不要求 bit-exact,按任务精度阈值验收 | | ||
| 317 | + | ||
| 318 | +# 6 可维可测分析 | ||
| 319 | + | ||
| 320 | +## 6.1 精度标准 | ||
| 321 | + | ||
| 322 | +Golden 使用 cblas / Netlib BLAS `csymm` 生成。`COMPLEX64` 的实部和虚部分别按 FLOAT32 混合容差判定: | ||
| 323 | + | ||
| 324 | +| 数据类型 | rtol | atol | required_matched_ratio | max_abs_error_limit | | ||
| 325 | +|----------|------|------|------------------------|---------------------| | ||
| 326 | +| COMPLEX64 分量 FLOAT32 | 2^-10 (9.77e-4) | 2^-16 (1.53e-5) | 0.99 | 1e-2 或 32 * ULP | | ||
| 327 | + | ||
| 328 | +逐元素通过条件: | ||
| 329 | + | ||
| 330 | +$$ |actual - golden| \leq atol + rtol \times |golden| $$ | ||
| 331 | + | ||
| 332 | +用例级通过条件为 `matched_ratio >= 0.99` 且 `max_abs_error <= max_abs_error_limit`。 | ||
| 333 | + | ||
| 334 | +## 6.2 性能标准 | ||
| 335 | + | ||
| 336 | +性能测试在 Ascend 950PR 上执行,先 warmup,再有效采样 50 次以上取平均。任务书给定性能门槛如下: | ||
| 337 | + | ||
| 338 | +| case | m | n | side | uplo | 标杆耗时 Avg time | | ||
| 339 | +|------|---|---|------|------|-------------------| | ||
| 340 | +| 1 | 256 | 256 | LEFT | UPPER | 7.53 us | | ||
| 341 | +| 2 | 1024 | 1024 | LEFT | LOWER | 89.27 us | | ||
| 342 | +| 3 | 1024 | 1024 | RIGHT | UPPER | 86.34 us | | ||
| 343 | + | ||
| 344 | +优化重点: | ||
| 345 | + | ||
| 346 | +- 用 Cube 路径承担主矩阵乘累加,避免纯 Vector 标量循环; | ||
| 347 | +- 利用 `beta == 0/1` 和 `alpha == 0` 分支减少 GM 读取和复数乘法; | ||
| 348 | +- 对紧凑前导维性能 case 使用连续 GM 访问和 tile 级 A/B 面板复用; | ||
| 349 | +- 对 padded 前导维保持正确寻址,性能用例优先覆盖 compact 模式; | ||
| 350 | +- 小矩阵减少启动核数,避免调度开销吞噬计算收益。 | ||
| 351 | + | ||
| 352 | +## 6.3 自测设计 | ||
| 353 | + | ||
| 354 | +随任务提供的 `csymm_test.csv` 覆盖 1200 条用例,其中精度 1000 条、性能/内存 200 条。设计验收时需覆盖: | ||
| 355 | + | ||
| 356 | +| 类别 | 覆盖内容 | | ||
| 357 | +|------|----------| | ||
| 358 | +| 基础功能 | LEFT/RIGHT 与 UPPER/LOWER 正交组合 | | ||
| 359 | +| 尺寸扫描 | 0、1、小质数、2 的幂、2 的幂 ±1、非对齐值、大尺寸 | | ||
| 360 | +| 标量特殊值 | `alpha/beta` 为 0、1、-1、纯虚数、大值 | | ||
| 361 | +| 矩形矩阵 | 宽矩阵、窄矩阵 | | ||
| 362 | +| 前导维 | `lda/ldb/ldc` 等于最小值和 padding 场景 | | ||
| 363 | +| 输入分布 | 均匀、正态、全零、交替、极值、Inf、NaN | | ||
| 364 | +| 负向用例 | 空指针、非法枚举、非法前导维、负维度 | | ||
| 365 | +| 性能用例 | 任务书 3 条典型性能 case 及扩展性能扫描 | | ||
| 366 | + | ||
| 367 | +## 6.4 兼容性分析 | ||
| 368 | + | ||
| 369 | +`aclblasCsymm` 是 ops-blas 中新增 API。接口声明放入公共头文件 `include/cann_ops_blas.h`,状态码和 `aclblasComplex` 复用 `include/cann_ops_blas_common.h`,不影响现有 `aclblasSsymm` 等接口。实现文件限定在 `blas/symm/arch35/`,后续如扩展其他产品线,应在同一 API 下增加对应 arch 实现,而不是新增私有接口。 | ||
| 370 | + | ||
| 371 | +# 7 开发交付规划 | ||
| 372 | + | ||
| 373 | +| 阶段 | 交付件 | 仓库 | | ||
| 374 | +|------|--------|------| | ||
| 375 | +| 设计评审 | `tasklist/08-aclblasCsymm-950/JaneConan/docs/design.md` | cann-ops-competitions | | ||
| 376 | +| 算子实现 | `include/cann_ops_blas.h`、`blas/symm/arch35/` | ops-blas fork | | ||
| 377 | +| 测试代码 | `test/symm/csymm/arch35/`、CSV 用例、README | ops-blas fork | | ||
| 378 | +| 自测报告 | 精度、性能、内存占用和截图 | 验收系统附件 | | ||