- 人工智能
- 指令集
- 算子库
- CANN
- Ascend
【免费下载链接】pto-isa
Parallel Tile Operation (PTO) is a virtual instruction set architecture designed by Ascend CANN, focusing on tile-level operations. This repository offers high-performance, cross-platform tile operations across Ascend platforms.
TABS(Tile Absolute)是 Ascend CANN pto-isa 虚拟指令集(Parallel Tile Operation Instruction Set Architecture)中面向向量(Vec)Tile 的逐元素一元运算指令,用于对 Tile 有效区域内的每个元素求绝对值。本文以 docs/isa/TABS.md 为主体,结合 CPU 仿真、Costmodel 与 NPU(A3/A5)三端源码实现及测试用例,完整讲解该指令的数学语义、SSA/DPS 两级汇编语法、C++ 内建接口、各后端约束与端到端验证方法,帮助开发者在算子开发中正确使用并验证 TABS。
指令概述与数学语义
TABS 对源 Tilesrc有效区域内的每个元素取绝对值,并将结果写入目标 Tiledst。在 docs/isa/TABS.md 中,其数学语义定义为:对有效区域内的每个元素(i, j),有
$$ \mathrm{dst}{i,j} = \left|\mathrm{src}{i,j}\right| $$
这是一个典型的逐元素(element-wise)一元运算,输入输出均为同一形状的 Tile。从实现分类上看,TABS 与 TLOG、TSQRT、TRELU、TNEG 等同属一元向量运算族,在 NPU 后端统一由TUnaryOp.hpp中的公共模板与检查逻辑驱动(见下文"后端实现")。
该指令在 docs/menu/unary_zh.md(一元运算菜单)中被归类为 Unary 运算,适用于激活、归一化、量化等算子中对张量取绝对值的场景。
汇编语法:同步形式与两级抽象
TABS 的汇编表达覆盖了 pto-isa 从高层 SSA 到底层 DPS 的两级抽象,其同步形式为:
%dst = tabs %src : !pto.tile<...> -> !pto.tile<...>AS Level 1(SSA 形式)
Level 1 使用命名空间限定的pto.tabs操作,输入输出均为!pto.tile<...>类型,由编译器负责 Tile 资源的放置与调度:
%dst = pto.tabs %src : !pto.tile<...> -> !pto.tile<...>AS Level 2(DPS 形式)
Level 2 采用 DPS(Destination-Pass-Statements,显式指定输入输出缓冲区)形式,操作数类型为!pto.tile_buf<...>:
pto.tabs ins(%src : !pto.tile_buf<...>) outs(%dst : !pto.tile_buf<...>)两种抽象级别的差异在于资源管理粒度:Level 1 由编译器/运行时管理 Tile 的放置与调度,Level 2 则由开发者显式声明ins(输入)与outs(输出)缓冲区,为手工调度与优化留出空间。
C++ 内建接口
TABS 对外暴露的 C++ 接口声明位于 include/pto/common/pto_instr.hpp,公共包含头为<pto/pto-inst.hpp>(见 include/pto/pto-inst.hpp):
template <typename TileDataDst, typename TileDataSrc, typename... WaitEvents> PTO_INST RecordEvent TABS(TileDataDst &dst, TileDataSrc &src, WaitEvents &... events);接口要点
- 模板参数:
TileDataDst、TileDataSrc为目标与源 Tile 类型,可以是静态形状或动态形状的Tile<TileType::Vec, T, Rows, Cols, BLayout, ValidRow, ValidCol>;WaitEvents...为可选的事件同步参数,用于指令间的流水线依赖等待。 - 返回类型:
RecordEvent,配合set_flag/wait_flag用于 MTEd 与向量/标量流水之间的显式同步。 - 调用机制:该接口在函数体内先执行
detail::PtoWaitEvents(events...)完成事件等待,再通过MAP_INSTR_IMPL(TABS, dst, src)宏按编译目标(CPU 仿真 / Costmodel / NPU)分发到对应后端的TABS_IMPL实现。Costmodel 版本声明于 include/pto/costmodel/pto_instr.hpp,结构与公共声明一致。
三端后端实现:CPU 仿真、Costmodel 与 NPU
TABS 在仓库中拥有 CPU 仿真、Costmodel 与 NPU 三套实现,分别面向功能仿真、性能建模与真实硬件执行,体现出 pto-isa "跨平台、可仿真、可建模" 的设计理念。
CPU 仿真实现(功能正确性基准)
CPU 仿真的核心实现在 include/pto/cpu/TAbs.hpp:
template <typename TileDst, typename TileSrc> void TAbs_Impl(TileDst& dst, TileSrc& src, unsigned validRow, unsigned validCol) { for (size_t c = 0; c < validCol; c++) { for (size_t r = 0; r < validRow; r++) { const auto val = src.GetElement(r, c); dst.SetElement(r, c, val < 0 ? -val : val); } } }TABS_IMPL外层先做两重编译期/运行时检查:
static_assert要求dst与src的DType一致;static_assert限定数据类型必须为int32_t、int、int16_t、int8_t、half、bfloat16_t、float之一;- 运行时通过
PTO_ASSERT校验src.GetValidRow() == dst.GetValidRow()且src.GetValidCol() == dst.GetValidCol(),不满足则触发断言失败。
随后以dst的有效区域(GetValidRow()/GetValidCol())为迭代域,逐元素执行val < 0 ? -val : val,即数学语义dst = |src|的直接实现。
Costmodel 实现(性能建模)
Costmodel 端口的TABS声明同样以MAP_INSTR_IMPL(TABS, dst, src)分发,见 include/pto/costmodel/pto_instr.hpp。其类型约束较 CPU 仿真略有差异,允许的数据类型为int32_t、int16_t、int8_t、uint8_t、half、float(注意此处允许uint8_t,但不含bfloat16_t与int64_t),相关建模与代价估算由 include/pto/costmodel/lightweight_costmodel.hpp 与 include/pto/costmodel/perf_sim/costmodel_provider.hpp 支撑。该实现用于在真实硬件运行前对指令开销进行预评估,配合 docs/costmodel/perf-sim-user-guide.md 中描述的性能仿真流程使用。
NPU 实现(A3 与 A5)
NPU 端 TABS 位于一元运算族中,由两个平台文件分别实现:
- A5(及 A6)平台:include/pto/npu/a5/TUnaryOp.hpp 中定义
AbsOp算子类,底层调用向量指令vabs(dstReg, srcReg, pReg, MODE_ZEROING):
template <typename T> struct AbsOp { PTO_INTERNAL static void UnaryInstr(RegTensor<T>& dstReg, RegTensor<T>& srcReg, MaskReg& pReg) { vabs(dstReg, srcReg, pReg, MODE_ZEROING); } };对int64_t元素走独立的Int64Unary<Int64Op::Abs, ...>路径(A5 支持 64 位整数绝对值);其余类型经TUnaryOp模板按行/列二维展开为向量指令序列。TABS_IMPL调用TUnaryCheck<DstTile, SrcTile, false>()后断言dst/src有效行列一致,再发射TAbs。
- A3(a2a3)平台:include/pto/npu/a2a3/TUnaryOp.hpp 中
AbsOp直接以块步长形式调用底层vabs(dst, src, repeat, 1, 1, dstStride, srcStride),经TUNARY_IMPL<AbsOp<T>>统一调度。A3 平台的数据类型检查由TunaryCheck的floatOnly模板参数控制(默认为 true 时仅允许浮点类型)。
这种"公共接口 + 平台私有实现"的结构,使同一份算子源码可跨 A3、A5 及 CPU 仿真平台编译运行。
约束与检查规则汇总
结合文档与源码,TABS 的约束可归纳如下:
| 后端 | 数据类型约束 | 关键检查 |
|---|---|---|
| CPU 仿真 | int32_t、int、int16_t、int8_t、half、bfloat16_t、float | 类型一致;有效行列相等(运行时断言);迭代域取dst有效区域 |
| Costmodel | int32_t、int16_t、int8_t、uint8_t、half、float | TileData::DType静态检查 |
| NPU A3 | float、half | 行主序、Loc == TileType::Vec、有效边界 ≤ 物理形状、有效行列相等 |
| NPU A5 | float、half、int32_t、int16_t、int8_t、int64_t | 同上;int64_t走专用 Int64 路径 |
其他共性约束(来自文档与TunaryCheck/TUnaryCheck实现):
- Tile 位置:
dst与src必须位于向量单元,即TileData::Loc == TileType::Vec; - 布局:必须是行主序(
TileData::isRowMajor),否则编译期static_assert失败; - 静态有效边界:
TileData::ValidRow <= TileData::Rows且TileData::ValidCol <= TileData::Cols(NPU 静态断言); - 运行时形状:
src.GetValidRow() == dst.GetValidRow()且src.GetValidCol() == dst.GetValidCol()。
有效区域(Valid Region)语义
TABS 以dst.GetValidRow()/dst.GetValidCol()作为迭代域。在此基础上,文档明确允许dst与src使用不同的 C++ Tile 类型——包括混用静态与动态ValidRow/ValidCol模板参数——只要元素类型一致即可。CPU_SIM 会按每个操作数自身的 Tile 布局与物理形状独立计算地址,因此静态形状与动态形状的操作数可以自由配对。
编程示例
以下示例均来自 docs/isa/TABS.md,可直接在算子工程中以<pto/pto-inst.hpp>为公共头编译。
Auto 模式(编译器管理资源)
#include <pto/pto-inst.hpp> using namespace pto; void example_auto() { using TileT = Tile<TileType::Vec, float, 16, 16>; TileT src, dst; TABS(dst, src); }Auto 模式:混用静态与动态有效形状
动态 Tile 的ValidRow/ValidCol模板参数为-1,需在构造时传入实际有效行列;静态 Tile 则在模板中直接给定:
#include <pto/pto-inst.hpp> using namespace pto; void example_mixed_valid_shape() { using DynamicTile = Tile<TileType::Vec, int32_t, 16, 16, BLayout::RowMajor, -1, -1>; using StaticTile = Tile<TileType::Vec, int32_t, 16, 16, BLayout::RowMajor, 16, 16>; DynamicTile dst(16, 16); StaticTile src; TABS(dst, src); }Manual 模式(显式绑定缓冲区地址)
手动模式下,需先通过TASSIGN将 Tile 绑定到具体的片上缓冲区地址,再发射指令:
#include <pto/pto-inst.hpp> using namespace pto; void example_manual() { using TileT = Tile<TileType::Vec, float, 16, 16>; TileT src, dst; TASSIGN(src, 0x1000); TASSIGN(dst, 0x2000); TABS(dst, src); }汇编形式示例
Auto 模式
# Auto mode: compiler/runtime-managed placement and scheduling. %dst = pto.tabs %src : !pto.tile<...> -> !pto.tile<...>Manual 模式
# Manual mode: resources must be bound explicitly before issuing the instruction. # Optional for tile operands: # pto.tassign %arg0, @tile(0x1000) # pto.tassign %arg1, @tile(0x2000) %dst = pto.tabs %src : !pto.tile<...> -> !pto.tile<...>PTO 汇编形式与 AS Level 2
%dst = tabs %src : !pto.tile<...> -> !pto.tile<...> # AS Level 2 (DPS) pto.tabs ins(%src : !pto.tile_buf<...>) outs(%dst : !pto.tile_buf<...>)端到端测试与验证
仓库为 TABS 提供了覆盖 CPU 仿真与 NPU 各平台(a2a3、a5、kirin 系列)的完整测试用例,目录结构一致,均包含main.cpp(测试框架与 golden 对比)、tabs_kernel.cpp(AICORE 内核)、gen_data.py(数据生成):
- CPU 仿真:tests/cpu/st/testcase/tabs/
- NPU A3:tests/npu/a2a3/src/st/testcase/tabs/
- NPU A5:tests/npu/a5/src/st/testcase/tabs/
以 tests/cpu/st/testcase/tabs/tabs_kernel.cpp 为例,内核展示了 TABS 在真实流水中的完整用法:TASSIGN绑定缓冲区 →TLOAD从 GlobalTensor 加载 →set_flag(PIPE_MTE2, PIPE_V, EVENT_ID0)/wait_flag(...)等待数据就绪 →TABS计算 →set_flag/wait_flag同步 →TSTORE写回。其中混用动态/静态有效形状的runTAbsMixedValidShape正是文档"混用静态与动态有效形状"示例的落地实现:
using DynamicTile = Tile<TileType::Vec, int32_t, kRows, kCols, BLayout::RowMajor, -1, -1>; using StaticTile = Tile<TileType::Vec, int32_t, kRows, kCols, BLayout::RowMajor, kRows, kCols>; StaticTile srcTile; DynamicTile dstTile(kRows, kCols); // ... TLOAD / 流水同步 ... TABS(dstTile, srcTile);测试用例 tests/cpu/st/testcase/tabs/main.cpp 通过test_tabs<T, ...>模板覆盖了float、int32_t、int16_t、int8_t、half(以及开启CPU_SIM_BFLOAT_ENABLED时的bfloat16_t)等数据类型,流程为:从input1.bin读取输入 → 设备侧执行内核 → 写出output.bin→ 与golden.bin参考结果以ResultCmp(容差 0.001f)逐元素比对。case_int32_64x64_mixed_static_valid专门验证了静态源 Tile + 动态目标 Tile 的混用场景。
运行这些用例可参考 tests/run_st.sh 与 tests/script/run_st.py 提供的统一测试脚本入口。
总结
TABS 作为 pto-isa 向量一元运算族的典型成员,具备清晰的三层表达(SSA 汇编 → DPS 汇编 → C++ 内建接口)与四端实现(CPU 仿真 / Costmodel / NPU A3 / NPU A5)。开发者在实际使用时需重点把握三点:数据类型与形状必须前后端一致、Tile 必须为行主序向量 Tile、有效区域以dst为准且允许静态/动态形状混用。配套的 CPU 与 NPU 多平台测试用例提供了可直接借鉴的内核编写范式与 golden 验证流程,可作为其他一元向量指令(如 TLOG、TSQRT、TRELU)开发与验证的参考模板。
- 人工智能
- 指令集
- 算子库
- CANN
- Ascend
【免费下载链接】pto-isa
Parallel Tile Operation (PTO) is a virtual instruction set architecture designed by Ascend CANN, focusing on tile-level operations. This repository offers high-performance, cross-platform tile operations across Ascend platforms.
相关推荐
PTO-ISA TABS 指令完全指南:Tile 逐元素绝对值运算的语义、约束与跨平台实现
PTO ISA TABS 指令完全指南:Tile 逐元素绝对值运算的语义、约束与跨平台实现 本文是 CANN pto isa 项目虚拟指令集(Parallel
人工智能指令集算子库CANNAscendCANN PTO-ISA 指令详解:TADD 双 Tile 逐元素加法
CANN PTO ISA 指令详解:TADD 双 Tile 逐元素加法 TADD(Tile ADD)是 CANN PTO ISA 向量指令集中的核心二元运算指令
人工智能指令集算子库CANNAscendCANN PTO-ISA 指令详解:TAND 逐元素按位与(Tile Bitwise AND)运算
CANN PTO ISA 指令详解:TAND 逐元素按位与(Tile Bitwise AND)运算 TAND 是 CANN PTO ISA(Parallel T
人工智能指令集算子库CANNAscend
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考