CANN pto-isa TABS 指令详解:Tile 逐元素绝对值运算的语法、后端实现与验证
2026/9/20 14:54:06 网站建设 项目流程
  • 人工智能
  • 指令集
  • 算子库
  • 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.

项目地址:https://gitcode.com/cann/pto-isa
点击查看免费下载

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);

接口要点

  • 模板参数TileDataDstTileDataSrc为目标与源 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要求dstsrcDType一致;
  • static_assert限定数据类型必须为int32_tintint16_tint8_thalfbfloat16_tfloat之一;
  • 运行时通过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_tint16_tint8_tuint8_thalffloat(注意此处允许uint8_t,但不含bfloat16_tint64_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 平台的数据类型检查由TunaryCheckfloatOnly模板参数控制(默认为 true 时仅允许浮点类型)。

这种"公共接口 + 平台私有实现"的结构,使同一份算子源码可跨 A3、A5 及 CPU 仿真平台编译运行。

约束与检查规则汇总

结合文档与源码,TABS 的约束可归纳如下:

后端数据类型约束关键检查
CPU 仿真int32_tintint16_tint8_thalfbfloat16_tfloat类型一致;有效行列相等(运行时断言);迭代域取dst有效区域
Costmodelint32_tint16_tint8_tuint8_thalffloatTileData::DType静态检查
NPU A3floathalf行主序、Loc == TileType::Vec、有效边界 ≤ 物理形状、有效行列相等
NPU A5floathalfint32_tint16_tint8_tint64_t同上;int64_t走专用 Int64 路径

其他共性约束(来自文档与TunaryCheck/TUnaryCheck实现):

  • Tile 位置dstsrc必须位于向量单元,即TileData::Loc == TileType::Vec
  • 布局:必须是行主序(TileData::isRowMajor),否则编译期static_assert失败;
  • 静态有效边界TileData::ValidRow <= TileData::RowsTileData::ValidCol <= TileData::Cols(NPU 静态断言);
  • 运行时形状src.GetValidRow() == dst.GetValidRow()src.GetValidCol() == dst.GetValidCol()

有效区域(Valid Region)语义

TABS 以dst.GetValidRow()/dst.GetValidCol()作为迭代域。在此基础上,文档明确允许dstsrc使用不同的 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, ...>模板覆盖了floatint32_tint16_tint8_thalf(以及开启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.

项目地址:https://gitcode.com/cann/pto-isa
点击查看免费下载

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

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

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

立即咨询