CANN ops-math 算子验收指南:用 AscendOpTest 官方工具完成 Polar 算子精度/性能测试
2026/9/20 0:29:23 网站建设 项目流程

CANN ops-math 算子验收指南:用 AscendOpTest 官方工具完成 Polar 算子精度/性能测试

【免费下载链接】ops-math本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-math

Polar 算子是 CANN ops-math 仓库中由极坐标(模长 input 与幅角 angle)构造复数张量的数学基础算子,本指南围绕 experimental/math/polar/tests/aot/README.md 展开,完整讲解如何基于官方 AscendOpTest 工具在 NPU 上对自定义 Polar 算子做精度与性能验收。读完本文,你将掌握测试资产(算子描述文件、用例 JSON、CPU 基准)的组织方式、complex64 精度阈值的显式配置方法,以及从算子部署、官方工具拉取到result.csv结果判读的完整可复现流程。

为什么精度验收必须用官方 AscendOpTest 工具

在 ops-math 的算子开发流程中,Polar 算子同时存在两套测试手段:仓库内自带的 pybind 测试框架(基于 torch_npu + pybind 复刻)与官方 AscendOpTest 工具。任务要求的精度判据是"满足 AscendOpTest 工具默认阈值",因此验收必须以官方工具实测结果为准,pybind 复刻只能作为开发期的快速冒烟手段。

本目录(tests/aot/)即为验收提前离线准备好的资产集合,确保在 NPU notebook 上可以一键复现官方验收:

文件作用
Polar.json算子描述文件(IR/原型),通过-i参数传入官方工具
polar_cases.json测试用例(6 例),通过-c参数传入
polar_golden.pyexpect_funcCPU 基准(numpy 广播实现 polar),被 case json 引用

算子描述文件:Polar.json

Polar.json 是 AscendOpTest 识别自定义算子的原型描述,声明了两个 float 类型 ND 格式的输入与一个 complex64 输出:

[ { "op": "Polar", "language": "cpp", "input_desc": [ { "name": "input", "param_type": "required", "format": ["ND"], "type": ["float"] }, { "name": "angle", "param_type": "required", "format": ["ND"], "type": ["float"] } ], "output_desc": [ { "name": "out", "param_type": "required", "format": ["ND"], "type": ["complex64"] } ] } ]

该描述与仓库中算子原型的实际注册完全一致。查看 polar_def.cpp 可以看到input/angle均为DT_FLOAT+FORMAT_NDout恒为DT_COMPLEX64,且通过AICore().AddConfig("ascend910b")AddConfig("ascend910_93")同时注册了 Atlas A2(910B)与 Atlas A3(910_93)两套平台配置——这正是官方工具跑--op-type custom时依赖的原型来源。

CPU 基准:polar_golden.py

polar_golden.py 是被 case json 中"expect_func"引用的 CPU 基准函数,完整实现了 Polar 的数学语义:

def polar(input, angle): a = np.asarray(input).astype(np.float32) th = np.asarray(angle).astype(np.float32) # numpy 广播(input.dim 与 angle.dim 可不一致,与算子 InferShape 对齐) a, th = np.broadcast_arrays(a, th) out = (a * (np.cos(th) + 1j * np.sin(th))).astype(np.complex64) return [np.ascontiguousarray(out)]

其约束与官方工具约定保持一致:参数名/顺序须与算子描述文件及 case 文件input_desc一致(input, angle);返回值必须是 list,元素为 numpy.ndarray,输出 dtype 必须是 complex64。公式polar(abs, angle) = abs * (cos(angle) + i*sin(angle))与仓库中 polar_infershape.cpp 的 numpy 右对齐广播推导、以及 kernel 侧Cos(angle)/Sin(angle)再乘 abs 的实现一一对应,构成"CPU 基准 ↔ NPU 实现"的可比对闭环。

关键点:complex64 无内置默认阈值,必须显式配置

这是整个验收中最容易踩坑的一步。AscendOpTest 的accuracy_config对常见 dtype 内置了默认误差阈值,但complex64 没有内置默认——若不显式配置,运行时会直接抛KeyError

解决方案在 polar_cases.json 中已落地:每个用例的output_desc都显式写入了"err_threshold":[0.0001,0.0001],其中第一个分量是绝对偏差(fp32 分量默认值),第二个分量是错误率。对应的判定逻辑(见 design.md 中"精度细化与实测"):compare_complex对实部、虚部各自做纯绝对误差判定,要求实/虚部分量误差 ≤ 1e-4,且错误元素数不超过size × 1e-4,否则判失败。

在 NPU notebook 上运行官方验收

以下步骤在 Atlas A2/A3(910B4 等)的 ModelArts notebook / Developer Space 环境中操作,本地无 NPU 无法运行。

0) 安装前置依赖

pip install ml_dtypes

1) 部署自定义 Polar 算子

构建并安装算子.run安装包(与仓库内S8/Polar的构建流程相同;在 ops-math 仓内则使用 build.sh 风格的--experimental构建,详见 测试步骤指导.md):

cd ~/work/S8/Polar && bash build.sh && ./build_out/*.run --quiet

2) 使部署算子生效(README 红字强调的关键步骤)

source $ASCEND_HOME_PATH/opp/vendors/customize/bin/set_env.bash export LD_LIBRARY_PATH=$ASCEND_HOME_PATH/opp/vendors/customize/op_api/lib:$LD_LIBRARY_PATH

注:ops-math 仓内构建会强制 vendor 名为customize_math(与--vendor_name无关),此时上述路径中的customize需替换为customize_math,并配合--op-path $ASCEND_HOME_PATH/opp/vendors/customize_math/op_api参数使用。此步若跳过,工具将解析不到自定义实现。

3) 获取官方工具

git clone https://gitcode.com/HIT1920/AscendOpTest.git && cd AscendOpTest

4) 跑精度验收

python run_test.py \ -i /home/ma-user/work/S8/Polar.json \ -c /home/ma-user/work/case_910b/Polar/aot/polar_cases.json \ --op-type custom --build
  • --build:首次运行或改动用例后必须加,用于重新构建/编译;
  • --op-type custom:声明被测对象为自定义算子(非内置算子)。

若在 ops-math 仓内复现,-i-c直接指向仓内路径,并追加--op-path指定自定义 op_api 库目录。同时注意:polar_cases.json中的expect_func路径按/home/ma-user/work/case_910b/Polar/aot/polar_golden.py:polar写死,若上传路径不同,需同步修改polar_cases.json(仓内复现可用sed批量替换为$POLAR/tests/aot/polar_golden.py:polar)。

5) 跑性能验收(msprof 形式)

python run_test.py -i .../Polar.json -c .../polar_cases.json --op-type custom --msprof

性能模式以 msprof application 形式采集,聚合每个用例op_summary*.csv的 Task Duration 作为每调用设备时,与自测报告口径一致。

用例设计解析:6 个用例覆盖的核心矩阵

polar_cases.json 中的 6 个用例并非随机生成,而是围绕 Polar 算子的两大特性——逐元素极坐标构造NumPy 广播——刻意设计的覆盖矩阵:

用例名input shapeangle shape覆盖意图
Test_same_small[2, 6, 10][2, 6, 10]同 shape 小规模基础正确性
Test_same_16M[4096, 4096][4096, 4096]同 shape 16M 大规模(满核场景 + 非确定性复核)
Test_bcast_lowhigh[4, 1, 8][4, 5, 8]广播 低维→高维(input 低维广播到 angle 高维)
Test_bcast_scalar[1][3, 4, 5]标量×高维广播
Test_bcast_2way[8, 1][1, 7]双向多轴广播(两输入各有一维为 1)
Test_highdim_unalign[3, 5, 17, 269][3, 5, 17, 269]高维 + 非 32B 对齐内维(269 非对齐)

所有用例统一约定:

  • 角度angle取值[-3.14, 3.14](单周期,干净地验证正确性);
  • 模长abs取值[-10, 10](含负值,验证负 abs 翻号在数学上合法:(-a)·(cosθ+i·sinθ)等价于a·(cos(θ+π)+i·sin(θ+π)));
  • 输出 shape 为两输入广播后的 shape,与 polar_infershape.cpp 中右对齐逐轴取 max 的推导逻辑完全一致。

16M 用例的特殊使命

Test_same_16M用例专门用于让官方工具独立复核此前 standalone 测试中测出的 16M 规模非确定性问题(对应设计文档中的 ⚠️ 未决风险)。16M 是"所有核参与"的核心验收场景,design.md 中的实测数据也验证了这一规模的价值:16M 场景下本算子 937.98 µs 对 l0 参考 1665 µs,加速约 1.78×,是证明融合单 kernel 性能优势的关键证据。

运行约束与结果判读

运行前需核对以下一致性约束(当前资产已对齐):

  • input/angle/outname 与顺序必须与Polar.json、OpDef 一致,即(input, angle, out)——三者不一致会导致工具无法正确绑定输入输出;
  • 每个output_desc必须显式携带err_threshold(complex64 无内置默认,见上文关键点)。

运行结束后结果写入result.csv,每个用例一行 pass/fail。官方 AscendOpTest 实跑记录(见 测试步骤指导.md):6 个用例(Test_same_smallTest_same_16MTest_bcast_lowhighTest_bcast_scalarTest_bcast_2wayTest_highdim_unalign)在 Atlas A2(910B4)上全部 PASS,与 msopgen 产物精度一致、重构零回归。该结论与 design.md "可维可测分析"章节中"官方 AscendOpTest 实跑 6 用例全 PASS(含 16M [4096,4096])"的描述互相印证。

如需深入了解 Polar 算子的整体设计(融合 kernel 的 UB 布局、Gather+静态偏移表的复数交织选型、广播的矢量化 unravel 实现)与性能基线对比方法,可继续阅读 docs/design.md、docs/性能优化_inner_broadcast.md 以及 op_kernel/polar.h 的源码注释。

【免费下载链接】ops-math本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-math

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询