本章既讲算子怎么写,也讲“什么证据才算算子真的编译并在 NPU 上执行”。后一层是本次双板记录没有完成的边界。
先给出本讲路线图;后续每一段都对应这里的一行,最后回到路线收束。
自定义算子不是默认选项。先确认内置算子、图优化或模型改写不能解决问题,再承担编译、注册和验收成本。
把“算力”拆成计算单元与数据搬运。很多算子瓶颈不是 Cube 算得慢,而是数据无法及时、安全地进入片上缓冲。
明确两条路线的抽象层级。TBE 代码短不代表平台自动完成 NPU 编译,Ascend C 源码存在也不代表已在硬件运行。
从上到下带读计算描述层、调度层、编译层、TVM 和 CCE 后端。图展示的是设计路径,不等于本次双板已经完成对应硬件编译。
让学生先写接口卡片,再写代码。OpType、输入输出、属性和信息库必须一致,否则后面编译和注册会脱节。
分清 add.py 和 run.py。前者描述算子实现与编译入口,后者验证等价 TBE DSL 计算;两者都不能代替 Ascend C 自定义算子包安装。
注意 run.py 使用 TBE testing/debug 环境。它证明等价 DSL 计算的数值断言通过,不是 Ascend C 算子包加载或 NPU 执行证据。
日志只保留关键行。两个板的随机输入不同,但都在各自输入上完成数值断言,不能据此比较速度或硬件能力。
将 Ascend C 的控制点与 TBE 自动调度对比。重点是开发者要负责数据搬运与多核分配,而不只是写一个加法表达式。
这段源码证明实现骨架存在,不证明它已通过 msopgen、自定义算子包安装、ACL 加载和 NPU 执行。
用矩阵加法的 128×256 数据说明:数据超出 UB 时需要分片;Ascend C 的 Tiling 参数由 Host 计算并传给 Kernel。
这是最容易误读的一页。输出里的 PASSED 和 TBE DSL auto-tiling 必须连在一起读,不能把它升级为手写 Ascend C Tiling 已在两板通过。
这张表把结论封死:三个脚本、两块板都通过,但三行都是 TBE DSL 层。Ascend C 未完成 msopgen、算子包安装、ACL 加载和 NPU 执行,必须写 untested。
给出可执行的闭环。每步都要产物和日志;仅生成 C++ 源码、打印 PASSED 或运行 TBE DSL 等价脚本都不够。
最终要求学生按证据层逐项勾选。当前能勾的只有 TBE DSL 功能,Ascend C 编译与 NPU 执行都必须保留为 untested。