已合并
【社区任务】aclblasCsyr2算子设计文档 #1271
KousakaReina创建于 9月1日
【社区任务】aclblasCsyr2算子设计文档 #1271
已合并
共 1 个文件变更+292-0
| @@ -0,0 +1,292 @@ | |||
| 1 | +# 需求背景(required) | ||
| 2 | + | ||
| 3 | +## 需求来源 | ||
| 4 | + | ||
| 5 | +本需求来自 CANN 2026 年 8 月社区任务第 43 号“aclblasCsyr2 算子开发(A2/A3)”。目标是在昇腾 NPU 的 Atlas A2/A3 系列产品上,基于 `cann/ops-blas` 工程和 Ascend C Kernel 直调模式,实现单精度复数对称秩 2 更新接口 `aclblasCsyr2`。 | ||
| 6 | + | ||
| 7 | +接口的参数序列和核心行为对齐 cuBLAS `cublasCsyr2`;三角引用、负步长起点和 quick return 语义参考 Netlib `ssyr2`,并按复数普通乘法推广。开发完成后,实现代码归档到 `blas/syr2/arch22/`,测试代码归档到 `test/syr2/csyr2/arch22/`,公共接口声明新增到 `include/cann_ops_blas.h`。 | ||
| 8 | + | ||
| 9 | +## 背景介绍 | ||
| 10 | + | ||
| 11 | +### aclblasCsyr2 算子功能 | ||
| 12 | + | ||
| 13 | +`aclblasCsyr2` 属于 BLAS Level-2,对列主序复数对称矩阵执行原地秩 2 更新: | ||
| 14 | + | ||
| 15 | +```text | ||
| 16 | +A := alpha * x * y^T + alpha * y * x^T + A | ||
| 17 | +``` | ||
| 18 | + | ||
| 19 | +其中: | ||
| 20 | + | ||
| 21 | +- `alpha` 为单精度复数标量; | ||
| 22 | +- `x`、`y` 为逻辑长度为 `n` 的单精度复数向量; | ||
| 23 | +- `A` 为 `n × n` 单精度复数对称矩阵,按列主序存储; | ||
| 24 | +- `uplo` 决定只引用和更新 `A` 的上三角或下三角;另一侧三角不读不写; | ||
| 25 | +- 对称语义是普通转置 `A = A^T`,不是共轭转置,对角元素虚部按普通复数乘加更新。 | ||
| 26 | + | ||
| 27 | +函数原型如下: | ||
| 28 | + | ||
| 29 | +```cpp | ||
| 30 | +aclblasStatus_t aclblasCsyr2( | ||
| 31 | + aclblasHandle_t handle, | ||
| 32 | + aclblasFillMode_t uplo, | ||
| 33 | + int n, | ||
| 34 | + const aclblasComplex* alpha, | ||
| 35 | + const aclblasComplex* x, int incx, | ||
| 36 | + const aclblasComplex* y, int incy, | ||
| 37 | + aclblasComplex* A, int lda); | ||
| 38 | +``` | ||
| 39 | + | ||
| 40 | +### 现有基础与差异 | ||
| 41 | + | ||
| 42 | +`ops-blas` 已有实数同族接口 `aclblasSsyr2`,可复用句柄、stream、错误码、Host 直调和工程组织方式;但不能直接复用实数计算 Kernel,原因如下: | ||
| 43 | + | ||
| 44 | +1. `aclblasCsyr2` 的每个元素包含实部、虚部,需要展开普通复数乘加; | ||
| 45 | +2. Netlib/cblas 没有复数 symmetric syr2,测试 golden 需要按 `ssyr2` 的三角、步长和列主序语义自实现; | ||
| 46 | +3. 性能用例的矩阵规模较大,纯逐元素 Vector 更新难以达到任务书门槛,需要利用秩 2 更新的低秩结构构造 Cube 主路径; | ||
| 47 | +4. 仍需保留覆盖负步长、非紧凑 `lda`、非对齐尺寸和任意 `alpha` 的通用路径。 | ||
| 48 | + | ||
| 49 | +工程落点如下: | ||
| 50 | + | ||
| 51 | +| 项目 | 设计落点 | | ||
| 52 | +| --- | --- | | ||
| 53 | +| 公共声明 | `include/cann_ops_blas.h` 新增 `aclblasCsyr2`,不定义产品私有平行 API | | ||
| 54 | +| Host/Kernel | `blas/syr2/arch22/` | | ||
| 55 | +| 测试 | `test/syr2/csyr2/arch22/`,CSV 驱动 GTest | | ||
| 56 | +| 数据类型 | `aclblasComplex`,实部和虚部均为 FLOAT32 | | ||
| 57 | +| 目标产品 | Atlas A2/A3;性能验收设备为 Atlas 800I A2(Ascend 910B3) | | ||
| 58 | +| CANN | 9.1.0 | | ||
| 59 | + | ||
| 60 | +# 需求分析(required) | ||
| 61 | + | ||
| 62 | +## 需求描述 | ||
| 63 | + | ||
| 64 | +使用 Ascend C 实现 `aclblasCsyr2`,支持 UPPER/LOWER、正负步长、`lda` padding、参数异常处理和 quick return;在指定三角内完成普通复数对称秩 2 更新,未指定三角保持不变。实现需满足任务书精度标准,并在 910B3 上达到三条性能门槛。 | ||
| 65 | + | ||
| 66 | +## 需求拆解 | ||
| 67 | + | ||
| 68 | +1. 新增公共 `aclblasCsyr2` 声明,参数顺序与 cuBLAS 对标接口一致。 | ||
| 69 | +2. 支持 `ACLBLAS_UPPER` 和 `ACLBLAS_LOWER`,只读写指定三角。 | ||
| 70 | +3. 支持 COMPLEX64,采用普通复数乘法,不执行共轭。 | ||
| 71 | +4. 支持 `incx`、`incy` 的正负步长,拒绝零步长。 | ||
| 72 | +5. 支持 `lda >= max(1, n)`,包括列尾 padding。 | ||
| 73 | +6. `n = 0` 或 `alpha = (0, 0)` 时合法 quick return,不启动 Kernel、不访问 Device 数据。 | ||
| 74 | +7. 参数错误返回任务书指定状态码;Host 不隐式同步 stream。 | ||
| 75 | +8. 提供通用 AIV 路径和满足资源/工作量条件时的 Cube–Vector 协同路径,不按某个精确 shape 写专用分支。 | ||
| 76 | +9. 使用任务书提供的官方 CSV/GTest 自验;官方工具保持原样,额外性能与随机测试以新增文件提供。 | ||
| 77 | +10. 精度按 matched-ratio/max-abs 规则验收,性能按 `msprof --task-time=on` 的 Kernel Task Duration 验收。 | ||
| 78 | + | ||
| 79 | +# 详细设计(required) | ||
| 80 | + | ||
| 81 | +## 算子分析 | ||
| 82 | + | ||
| 83 | +### 数学公式 | ||
| 84 | + | ||
| 85 | +对指定三角中的元素 `(i, j)`: | ||
| 86 | + | ||
| 87 | +```text | ||
| 88 | +A(i, j) := A(i, j) | ||
| 89 | + + alpha * x(i) * y(j) | ||
| 90 | + + alpha * y(i) * x(j) | ||
| 91 | +``` | ||
| 92 | + | ||
| 93 | +复数乘法展开为: | ||
| 94 | + | ||
| 95 | +```text | ||
| 96 | +(a + b*i) * (c + d*i) = (a*c - b*d) + (a*d + b*c)*i | ||
| 97 | +``` | ||
| 98 | + | ||
| 99 | +列主序地址为: | ||
| 100 | + | ||
| 101 | +```text | ||
| 102 | +A(i, j) -> A[i + j * lda] | ||
| 103 | +``` | ||
| 104 | + | ||
| 105 | +三角范围为: | ||
| 106 | + | ||
| 107 | +- UPPER:`0 <= i <= j < n`; | ||
| 108 | +- LOWER:`0 <= j <= i < n`。 | ||
| 109 | + | ||
| 110 | +负步长采用 Netlib 起点规则。0-based 下: | ||
| 111 | + | ||
| 112 | +```text | ||
| 113 | +xStart = 0 , incx > 0 | ||
| 114 | +xStart = (n - 1) * (-incx) , incx < 0 | ||
| 115 | +``` | ||
| 116 | + | ||
| 117 | +`yStart` 同理,逻辑元素 `i` 的物理地址为 `start + i * inc`。 | ||
| 118 | + | ||
| 119 | +### 支持数据类型 | ||
| 120 | + | ||
| 121 | +| 操作数 | 数据类型 | 说明 | | ||
| 122 | +| --- | --- | --- | | ||
| 123 | +| `alpha` | `aclblasComplex` | Host 侧 complex64 标量 | | ||
| 124 | +| `x`、`y` | `aclblasComplex` | Device 侧 complex64 向量 | | ||
| 125 | +| `A` | `aclblasComplex` | Device 侧 complex64 矩阵,原地更新 | | ||
| 126 | +| `n`、`incx`、`incy`、`lda` | `int` | Host 侧维数和步长 | | ||
| 127 | +| `uplo` | `aclblasFillMode_t` | 上/下三角枚举 | | ||
| 128 | + | ||
| 129 | +### 支持形状 | ||
| 130 | + | ||
| 131 | +| 对象 | 逻辑形状 | 物理约束 | | ||
| 132 | +| --- | --- | --- | | ||
| 133 | +| `x` | `[n]` | 至少 `1 + (n-1)*abs(incx)` 个 complex64 元素 | | ||
| 134 | +| `y` | `[n]` | 至少 `1 + (n-1)*abs(incy)` 个 complex64 元素 | | ||
| 135 | +| `A` | `[n, n]` | 列主序,至少 `lda*n` 个 complex64 元素 | | ||
| 136 | + | ||
| 137 | +`n` 为运行时参数;不涉及广播和三维以上高维 shape。非连续访问由 `incx`、`incy` 和 `lda` 表达。 | ||
| 138 | + | ||
| 139 | +## 算子实现 | ||
| 140 | + | ||
| 141 | +### 实现方案 | ||
| 142 | + | ||
| 143 | +整体采用“通用 AIV 路径 + 连续大工作量 Cube–Vector 协同路径”的分层设计。Host 根据接口参数、有效三角 tile 数、芯片 AIV/AIC 数量、对齐条件和 workspace 容量选择路径;选择条件来自工作量与硬件资源,不使用 `n == 某个值` 的精确 shape 特化。 | ||
| 144 | + | ||
| 145 | +#### Host 侧设计 | ||
| 146 | + | ||
| 147 | +1. 参数检查顺序: | ||
| 148 | + - `handle == nullptr` 返回 `ACLBLAS_STATUS_HANDLE_IS_NULLPTR`; | ||
| 149 | + - 非法 `uplo` 返回 `ACLBLAS_STATUS_INVALID_ENUM`; | ||
| 150 | + - `n < 0`、零步长或非法 `lda` 返回 `ACLBLAS_STATUS_INVALID_VALUE`; | ||
| 151 | + - `n == 0` 直接成功返回; | ||
| 152 | + - `alpha == nullptr` 返回 `ACLBLAS_STATUS_INVALID_VALUE`; | ||
| 153 | + - `alpha == (0,0)` 直接成功返回; | ||
| 154 | + - 之后检查 `x`、`y`、`A` 和 stream。 | ||
| 155 | +2. 填充 tiling data:保存 `n/lda/uplo/incx/incy/alpha`、输入输出地址、路径类型、活跃核数、Cube K 深度和 workspace 信息。 | ||
| 156 | +3. 通用路径按逻辑三角任务数限制 AIV 核数,避免启动超过有效工作量的空核。 | ||
| 157 | +4. Cube 路径需要单位步长、紧凑列主序、满足 Cube tile 对齐、有效三角 tile 足够且 workspace 可用;条件不满足时回退 AIV 路径。 | ||
| 158 | +5. 活跃 AIC 数根据有效三角输出 tile 数和“每核目标 tile 数”计算,并同时满足配套 AIV 预处理任务量;不直接绑定某个矩阵规模。 | ||
| 159 | +6. 通过 handle 绑定的 stream 异步启动 Kernel,Host 不做 `aclrtSynchronizeStream`。 | ||
| 160 | + | ||
| 161 | +#### 通用 AIV Kernel | ||
| 162 | + | ||
| 163 | +通用路径覆盖任意合法 `alpha`、正负步长、非紧凑 `lda` 和非对齐 `n`: | ||
| 164 | + | ||
| 165 | +1. 将指定三角按列或三角 tile 唯一分配给 AIV,避免多核写冲突; | ||
| 166 | +2. 对单位步长使用 UB tile 和批量 DataCopy,对正负非单位步长使用标量/分段 gather 语义; | ||
| 167 | +3. 在 UB 中展开复数乘法,完成 CopyIn → Compute → CopyOut; | ||
| 168 | +4. 使用双缓冲或独立队列重叠 MTE2、Vector 和 MTE3;尾块使用 mask/padding 处理; | ||
| 169 | +5. 未指定三角完全不读不写,`lda` padding 不修改。 | ||
| 170 | + | ||
| 171 | +#### Cube–Vector 协同 Kernel | ||
| 172 | + | ||
| 173 | +SYR2 是两个外积之和,可把复数乘加展开为小 K 实数矩阵乘。对于满足工作量和布局条件的连续大问题,采用 MIX Kernel: | ||
| 174 | + | ||
| 175 | +1. AIV 预处理: | ||
| 176 | + - 按固定 packet 从 GM 读取 `x/y`; | ||
| 177 | + - 把交错 complex64 拆成 Cube 友好的实数平面; | ||
| 178 | + - 将 `alpha` 融合进平面系数; | ||
| 179 | + - 写入共享 workspace 的 left/right 面板。 | ||
| 180 | +2. AIV 完成共享输入后,以物理 MIX 核对为单位同步并释放对应 AIC;只让实际活跃核参与同步。 | ||
| 181 | +3. AIC 主体: | ||
| 182 | + - 把三角主体划分为矩形 Cube tile; | ||
| 183 | + - 通过 GM→L1→L0 双槽流水预取下一 tile; | ||
| 184 | + - 小 K MMAD 计算两个外积的实部/虚部组合; | ||
| 185 | + - 采用多 CO1 槽交错 MMAD 与 Fixpipe,减少 M/FixedPipe 空泡; | ||
| 186 | + - 通过原子 Fixpipe 累加到目标矩阵,保证 AIV 边界带与 AIC 主体可安全合并。 | ||
| 187 | +4. AIV 收尾: | ||
| 188 | + - 处理对角、三角边界以及不适合完整 Cube tile 的带状区域; | ||
| 189 | + - 保证另一三角和 padding 不被写入。 | ||
| 190 | +5. 负载均衡: | ||
| 191 | + - 先按压缩三角的 tile ordinal 均分; | ||
| 192 | + - 当余数 tile 少于活跃 AIC 的一半时,将重核的尾 tile 按通用半 tile 拆给空闲核; | ||
| 193 | + - 拆分条件仅由 `totalTiles % activeCores` 决定,不检查精确 shape。 | ||
| 194 | + | ||
| 195 | +#### UB/L1/L0 与流水设计 | ||
| 196 | + | ||
| 197 | +- AIV packet 大小由 UB 容量、输入平面数、双缓冲和临时转置空间共同决定,避免过小搬运导致带宽利用率不足; | ||
| 198 | +- AIC 使用两组 L1/L0 输入槽,使下一 tile 的 MTE2/MTE1 与当前 MMAD/Fixpipe 重叠; | ||
| 199 | +- CO1 使用多槽轮转,按 `MMAD(q0/q1/...) → Fixpipe(q0/...)` 交错发射; | ||
| 200 | +- 尾 tile 只搬运其实际使用的输入半面板,减少无效 GM→L1 和 L1→L0 数据量; | ||
| 201 | +- 所有同步均限定在参与当前路径的有效核,避免空核扩大启动和 barrier 开销。 | ||
| 202 | + | ||
| 203 | +### Tiling 通用性 | ||
| 204 | + | ||
| 205 | +Tiling 的输入是:数据布局、对齐、可用 workspace、AIC/AIV 核数、完整三角 tile 数、每核目标 tile 数和余数分布。以下做法明确禁止: | ||
| 206 | + | ||
| 207 | +- `if (n == 1024)`、`if (n == 2048)` 等精确规模分支; | ||
| 208 | +- 为单个验收 case 写固定 core map; | ||
| 209 | +- 依赖未声明的输入值分布决定正确性路径。 | ||
| 210 | + | ||
| 211 | +性能用例可触发同一套 size-class 规则,但其它满足相同资源和工作量条件的 shape 也会复用该路径。 | ||
| 212 | + | ||
| 213 | +## 支持硬件 | ||
| 214 | + | ||
| 215 | +| 芯片版本 | 支持情况 | 验证计划 | | ||
| 216 | +| --- | --- | --- | | ||
| 217 | +| Atlas 800I/T A2(Ascend 910B3) | 支持 | CANN 9.1.0;功能、精度及任务书性能门槛正式验证 | | ||
| 218 | +| Atlas A3(arch22) | 支持 | 使用同一 API/Kernel 源码完成构建、功能与边界验证,并重新评估资源参数 | | ||
| 219 | + | ||
| 220 | +## 算子约束限制 | ||
| 221 | + | ||
| 222 | +1. 仅支持 COMPLEX64,不支持混合精度。 | ||
| 223 | +2. `A` 为列主序方阵,只更新 `uplo` 指定三角。 | ||
| 224 | +3. `n >= 0`,`incx != 0`,`incy != 0`,`lda >= max(1,n)`。 | ||
| 225 | +4. `incx`、`incy` 支持负数,但不支持 0;实现需避免 `INT_MIN` 取绝对值溢出。 | ||
| 226 | +5. `A` 原地更新,调用方负责输入输出内存合法性及 stream 生命周期。 | ||
| 227 | +6. `n == 0` 或 `alpha == (0,0)` 为合法 no-op。 | ||
| 228 | +7. Cube 主路径允许使用 handle workspace;workspace 不足时回退正确的通用 AIV 路径。 | ||
| 229 | + | ||
| 230 | +# 可维可测分析 | ||
| 231 | + | ||
| 232 | +## 精度标准/性能标准 | ||
| 233 | + | ||
| 234 | +### 精度标准 | ||
| 235 | + | ||
| 236 | +golden 按 Netlib `ssyr2` 的列主序、三角和步长语义自实现复数版本。对指定三角的实部、虚部分别按 FLOAT32 判定: | ||
| 237 | + | ||
| 238 | +| 指标 | 标准 | | ||
| 239 | +| --- | --- | | ||
| 240 | +| `rtol` | `2^-10` | | ||
| 241 | +| `atol` | `2^-16` | | ||
| 242 | +| required matched ratio | `>= 0.99` | | ||
| 243 | +| max abs error | `<= 1e-2` 或 `<= 32 ULP` | | ||
| 244 | + | ||
| 245 | +逐元素条件为: | ||
| 246 | + | ||
| 247 | +```text | ||
| 248 | +abs(actual - golden) <= atol + rtol * abs(golden) | ||
| 249 | +``` | ||
| 250 | + | ||
| 251 | +同时检查: | ||
| 252 | + | ||
| 253 | +- 未指定三角保持原值; | ||
| 254 | +- `lda` padding 不被修改; | ||
| 255 | +- UPPER/LOWER、正负步长、quick return、非法参数和空指针状态码; | ||
| 256 | +- Inf/NaN 按任务测试规则处理。 | ||
| 257 | + | ||
| 258 | +### 性能标准 | ||
| 259 | + | ||
| 260 | +性能验收设备为 Atlas 800I A2(Ascend 910B3),CANN 9.1.0: | ||
| 261 | + | ||
| 262 | +| case | uplo | n | alpha | incx/incy | lda | 门槛 | | ||
| 263 | +| --- | --- | ---: | --- | --- | ---: | ---: | | ||
| 264 | +| 1 | UPPER | 512 | `(1,0)` | `1/1` | 512 | `<= 4.82 us` | | ||
| 265 | +| 2 | LOWER | 1024 | `(1,0)` | `1/1` | 1024 | `<= 6.22 us` | | ||
| 266 | +| 3 | UPPER | 2048 | `(1,0)` | `1/1` | 2048 | `<= 12.19 us` | | ||
| 267 | + | ||
| 268 | +开发和验收统一使用 `msprof --task-time=on` 导出的 Kernel `Task Duration(us)`:每轮先 warmup,再采集至少 60 个有效样本,取后 60 个样本均值;候选和基线至少做三轮相邻 A/B。ACL Event 或进程 wall time只用于快速诊断,不作为达标结论。 | ||
| 269 | + | ||
| 270 | +需要进一步归因时单独采集 PipeUtilization,观察 AIC/AIV 的 Scalar、MTE、Vector、Cube 和 Fixpipe;每轮保留原始 profile、代码 commit、动态库和汇总结果。 | ||
| 271 | + | ||
| 272 | +### 测试覆盖 | ||
| 273 | + | ||
| 274 | +| 类别 | 覆盖内容 | | ||
| 275 | +| --- | --- | | ||
| 276 | +| 基础功能 | UPPER/LOWER,`n=0/1`、小质数、2 的幂及 ±1、非对齐和大规模 | | ||
| 277 | +| 步长 | `incx/incy = ±1/±2/±3`,零步长负向用例 | | ||
| 278 | +| 前导维 | `lda=n` 和多种 `lda>n`,非法 `lda<n` | | ||
| 279 | +| 标量 | `(0,0)`、`(1,0)`、纯实、纯虚、一般复数和大值 | | ||
| 280 | +| 数据 | 均匀/正态分布、实虚独立、任务书指定特殊值 | | ||
| 281 | +| 接口 | 空 handle、非法枚举、负维度、空指针、未初始化 stream | | ||
| 282 | +| 内存 | 未选三角保护、padding 保护、workspace 边界 | | ||
| 283 | + | ||
| 284 | +官方测试脚本、CSV 和 golden 工具保持原样;重复 launch、随机输入、profile 汇总等能力通过新增辅助文件实现。 | ||
| 285 | + | ||
| 286 | +## 兼容性分析 | ||
| 287 | + | ||
| 288 | +1. API 兼容:只新增 `aclblasCsyr2` 公共符号,不修改现有结构体、状态码和其它接口。 | ||
| 289 | +2. 产品兼容:A2/A3 共用 `arch22` 实现;不新增产品私有接口,不影响 `arch35` 代码。 | ||
| 290 | +3. 行为兼容:参数序列与 cuBLAS `cublasCsyr2` 对齐;负步长、三角引用和 quick return 对齐 Netlib `ssyr2` 的语义推广。 | ||
| 291 | +4. 构建兼容:实现与实数 `aclblasSsyr2` 同族归档,按 ops-blas 现有 CMake 组织接入。 | ||
| 292 | +5. 性能兼容:通用路径始终可用,Cube–Vector 路径只在布局、工作量和资源条件满足时启用;workspace 不足时不影响功能正确性。 | ||