- 人工智能
- 指令集
- 算子库
- 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.
TXOR(Tile XOR)是 CANN PTO-ISA 虚拟指令集中用于对两个 Tile 执行逐元素按位异或(bitwise XOR)的矢量指令,常见于位掩码、奇偶校验、图像/编码类算子的 Tile 级实现中。本文以 docs/isa/TXOR.md 为主干,结合 A2A3(Atlas A2/A3 训练与推理系列)与 A5(Ascend 950PR/950DT)两套 NPU 后端实现、CPU 仿真实现及 ST 测试用例,完整讲解 TXOR 的数学语义、三级汇编语法、C++ 内建接口、类型与形状约束、临时空间差异,并给出可直接落地的调用示例。
指令示意图
简介
TXOR 完成两个 Tile 的逐元素按位异或(Elementwise Bitwise XOR)。与算术运算类指令(如 TADD、TMUL)不同,TXOR 属于逻辑/位运算家族,与 TAND、TOR、TNOT 等指令同族,在 docs/menu/binary_logic_zh.md 中被归入"逻辑运算"菜单。它天然具备可逆性(a ^ b ^ b == a),因此在异或加密、校验和计算、双缓冲数据交换等场景中具有独特价值,也是仓库内核示例(如tests/cpu/st/testcase/hashfind/hashfind_kernel.cpp)中位运算类算子的基础构件。
数学语义
TXOR 对有效区域(valid region)内的每个元素(i, j)执行:
$$ \mathrm{dst}{i,j} = \mathrm{src0}{i,j} \oplus \mathrm{src1}_{i,j} $$
其中dst、src0、src1均为!pto.tile<...>类型的 Tile 操作数,运算在整数位层面逐位进行:某一位上两个输入同为0或同为1时结果位为0,否则为1。注意异或(^)与逻辑或(|)在语义上不同:1 ^ 1 = 0而1 | 1 = 1,这也决定了 A2A3 后端在实现上不能直接复用 OR 指令,而需要额外的组合逻辑(详见下文"临时空间"一节)。
运算的迭代范围由输出 Tile 决定,即dst.GetValidRow()/dst.GetValidCol()所界定的有效行、列区域;src0、src1的有效形状必须与之完全一致(见"约束"一节)。
汇编语法
同步形式(PTO 汇编)
%dst = txor %src0, %src1 : !pto.tile<...>这是指令最直观的 SSA 形式:两个输入 Tile 产生一个输出 Tile,类型标注为!pto.tile<...>(尖括号内为该指令支持的整数元素类型,见"约束")。
AS Level 1(SSA)
%dst = pto.txor %src0, %src1 : (!pto.tile<...>, !pto.tile<...>) -> !pto.tile<...>在 Level 1 层级,指令以pto.txor命名,操作数通过 SSA 值引用,函数签名明确写出两个输入类型与一个输出类型。
AS Level 2(DPS)
pto.txor ins(%src0, %src1 : !pto.tile_buf<...>, !pto.tile_buf<...>) outs(%dst : !pto.tile_buf<...>)在 Level 2(Data Placement Specification)层级,操作数显式区分为ins(...)输入区与outs(...)输出区,且 Tile 类型变为带存储视图的!pto.tile_buf<...>,反映了资源(buffer)已确定后的指令形态。三级语法从"无资源约束的纯数据流"逐步过渡到"绑定具体 tile buffer 的指令发射",完整规范可参考 docs/isa/conventions.md 及 docs/isa/README.md。
C++ 内建接口
TXOR 的 C++ 内建函数声明于 include/pto/common/pto_instr.hpp,公共包含头为<pto/pto-inst.hpp>:
template <typename TileDataDst, typename TileDataSrc0, typename TileDataSrc1, typename TileDataTmp, typename... WaitEvents> PTO_INST RecordEvent TXOR(TileDataDst &dst, TileDataSrc0 &src0, TileDataSrc1 &src1, TileDataTmp &tmp, WaitEvents &... events);从声明可以看出几个要点:
- 四个模板 Tile 参数:
dst、src0、src1之外还要求一个tmp临时 Tile。tmp的存在是为了兼容 A2A3 后端的分解式实现(见"临时空间"),即使 A5 后端不使用它,接口签名仍然保留,以保证跨平台 API 一致。 WaitEvents&... events可变参数:用于指令间的同步等待。在 include/pto/common/pto_instr.hpp 的实现中,接口先调用detail::PtoWaitEvents(events...)等待前序事件,再通过MAP_INSTR_IMPL(TXOR, dst, src0, src1, tmp)宏映射到具体平台(A2A3/A5/CPU)的TXOR_IMPL实现,返回RecordEvent以便后续指令依赖。- 相关标量变体为TXORS(Tile XOR Scalar),声明于同一文件(include/pto/common/pto_instr.hpp),签名多出一个标量操作数:
TXORS(dst, src0, scalar, tmp, ...),用于"Tile 与标量逐元素异或"的场景。
约束
TXOR 在不同平台上执行不同的实现检查(Implementation Checks),可分为 A5 与 A2A3 两套。
通用约束
- 运算迭代范围固定为
dst.GetValidRow()/dst.GetValidCol()。
实现检查(A5:Ascend 950PR / Ascend 950DT)
dst、src0、src1的元素类型必须一致。- 支持的元素类型为:
uint8_t、int8_t、uint16_t、int16_t、uint32_t、int32_t、int64_t、uint64_t。 dst、src0、src1必须为行主序(row-major)。src0.GetValidRow()/GetValidCol()与src1.GetValidRow()/GetValidCol()必须与dst一致。
上述检查在 include/pto/npu/a5/TXor.hpp 的TXorCheck中以static_assert(类型、布局)与PTO_ASSERT(有效形状)两种方式落地:类型不符会直接编译报错"Fix: TXOR has invalid data type.",形状不符则在运行时断言"Fix: TXOR input tile src0 valid shape mismatch with output tile dst shape."。
实现检查(A2A3:Atlas A2/A3 训练系列产品 / Atlas A2/A3 推理系列产品)
dst、src0、src1、tmp的元素类型必须一致。- 支持的元素类型为:
uint8_t、int8_t、uint16_t、int16_t、uint32_t、int32_t(不含 64 位类型,这是与 A5 的显著差异)。 dst、src0、src1、tmp必须为行主序。src0、src1、tmp的有效形状必须与dst一致。- 手动模式下,
dst、src0、src1、tmp的内存区域不得重叠。
对应检查见 include/pto/npu/a2a3/TXor.hpp 的TXorCheck。其中内存不重叠检查被#ifndef __PTO_AUTO__宏包裹:即在**自动模式(Auto Mode)下由编译器/运行时统一管理资源放置,允许绕过该检查;而在手动模式(Manual Mode)**下必须由开发者保证四个操作数指向互不重叠的内存(dst.data() != src0.data()等逐对断言)。
临时空间:A2A3 与 A5 的关键差异
TXOR 是"接口统一、实现分化"的典型:tmp参数在不同平台上扮演完全不同的角色。
A2A3:tmp被用作中间暂存
A2A3 硬件没有单条 XOR 向量指令,因此 include/pto/npu/a2a3/TXor.hpp 通过分解式计算实现 XOR,利用恒等式:
$$ \mathrm{XOR}(a,b) = \mathrm{AND}(\mathrm{NOT}(\mathrm{AND}(a,b)),\ \mathrm{OR}(a,b)) $$
具体执行序列为:
TOR_IMPL(tmp, src0, src1); // tmp = src0 | src1 pipe_barrier(PIPE_V); // 矢量流水线屏障 TAND_IMPL(dst, src0, src1); // dst = src0 & src1 pipe_barrier(PIPE_V); TNOT_IMPL(dst, dst); // dst = NOT(dst) pipe_barrier(PIPE_V); TAND_IMPL(dst, dst, tmp); // dst = dst & tmp即先用TOR_IMPL把中间结果OR(a, b)暂存到tmp,再用TAND_IMPL、TNOT_IMPL、TAND_IMPL组合出最终结果,每一步之间通过pipe_barrier(PIPE_V)保证矢量流水线(PIPE_V)上的读写顺序。因此 A2A3 对tmp的要求是:
tmp元素类型与dst/src0/src1相同;tmp必须为行主序;tmp有效形状与dst一致(tmp.GetValidRow() == dst.GetValidRow()且tmp.GetValidCol() == dst.GetValidCol());- 手动模式下
tmp不得与dst、src0、src1内存重叠。
A5:tmp被接受但未使用
A5 后端拥有原生vxor向量指令,include/pto/npu/a5/TXor.hpp 中的XorOp::BinInstr直接将vxor映射为底层指令,无需暂存 Tile:
- 对于 64 位元素(
int64_t/uint64_t),走Int64Binary<Int64Op::Xor, ...>专门路径; - 其余类型走
BinaryInstr<XorOp<T>, ...>通用二元指令路径,elementsPerRepeat = CCE_VL / sizeof(T)、blockSizeElem = BLOCK_BYTE_SIZE / sizeof(T)由元素位宽自动推导。
因此 A5 上tmp不被使用,仅为了与 A2A3 保持 API 兼容而保留在接口签名中——调用时传一个与dst同形状的 Tile 即可,其内容不会被读写。CPU 仿真实现同样忽略tmp:include/pto/cpu/ElementTileOp.h 中(void)tmp;后直接调用BinaryElementTileOp_Impl<ElementOp::OP_XOR>完成逐元素异或,保证三端(A2A3/A5/CPU)行为一致。
使用示例
以下示例来自 docs/isa/TXOR.md,演示如何用 C++ 内建接口在 16×16 的uint32_t矢量 Tile 上执行逐元素异或:
#include <pto/pto-inst.hpp> using namespace pto; void example() { using TileDst = Tile<TileType::Vec, uint32_t, 16, 16>; using TileSrc0 = Tile<TileType::Vec, uint32_t, 16, 16>; using TileSrc1 = Tile<TileType::Vec, uint32_t, 16, 16>; using TileTmp = Tile<TileType::Vec, uint32_t, 16, 16>; TileDst dst; TileSrc0 src0; TileSrc1 src1; TileTmp tmp; TXOR(dst, src0, src1, tmp); }关键点:
- 四个 Tile 的元素类型必须统一(此处均为
uint32_t),否则触发 A5/A2A3 实现的static_assert编译错误; Tile<TileType::Vec, ...>表示矢量(Vector)Tile,16, 16为形状参数;若需要跨指令调度,可将TXOR返回的RecordEvent作为WaitEvents传入后续指令。
ASM 形式示例
自动模式(Auto Mode)
自动模式下,Tile 的物理资源放置与指令调度由编译器/运行时统一管理,开发者只需描述数据流:
# Auto mode: compiler/runtime-managed placement and scheduling. %dst = pto.txor %src0, %src1 : (!pto.tile<...>, !pto.tile<...>) -> !pto.tile<...>手动模式(Manual Mode)
手动模式下,资源必须先显式绑定(通过pto.tassign将 SSA 值分配到指定 tile 地址),再发射指令:
# 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.txor %src0, %src1 : (!pto.tile<...>, !pto.tile<...>) -> !pto.tile<...>手动模式下必须自行保证dst/src0/src1(以及 A2A3 上的tmp)分配到互不重叠的内存,否则会触发上文所述的运行时断言。
PTO 汇编形式
%dst = txor %src0, %src1 : !pto.tile<...> # AS Level 2 (DPS) pto.txor ins(%src0, %src1 : !pto.tile_buf<...>, !pto.tile_buf<...>) outs(%dst : !pto.tile_buf<...>)测试与验证
仓库为 TXOR 提供了完整的跨平台 ST(System Test)覆盖,可用于验证本文所述语义与约束:
- NPU 测试:
tests/npu/a2a3/src/st/testcase/txor/、tests/npu/a5/src/st/testcase/txor/、tests/npu/kirin9030/src/st/testcase/txor/、tests/npu/kirinDev0000/src/st/testcase/txor/各目录均含main.cpp(gtest 用例)、txor_kernel.cpp(算子内核)与gen_data.py(数据生成脚本); - CPU 测试:
tests/cpu/st/testcase/txor/提供 CPU 仿真侧的对照用例; - 标量变体 TXORS:
tests/npu/a2a3/src/st/testcase/txors/、tests/npu/a5/src/st/testcase/txors/等目录覆盖 Tile 与标量异或。
以 tests/npu/a2a3/src/st/testcase/txor/main.cpp 为例,测试通过test_txor<T, dstTileH, dstTileW, src0TileH, src0TileW, src1TileH, src1TileW, vRows, vCols>模板驱动:先经 ACL 接口初始化设备与流(aclInit/aclrtCreateStream),读取input1.bin/input2.bin作为src0/src1,发射 TXOR 内核后将输出写回并与golden.bin金标准逐元素比对(ResultCmp<T>(golden, devFinal, 0.001f))。用例覆盖int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t六种类型,并包含源 Tile 与目标 Tile 形状不同(如src1为 32×256 而dst为 32×128)以及非对齐列宽 127等边界场景,用于验证有效区域(valid region)语义与形状约束断言。
总结
TXOR 是 PTO-ISA 逻辑运算指令族中语义最简单、但跨平台实现差异最典型的指令之一:
- 语义:
dst = src0 ^ src1,逐元素按位异或,迭代范围由dst的有效区域决定; - 语法:从
txor汇编形式、pto.txorSSA(Level 1)到ins/outsDPS(Level 2)三级递进; - 平台差异:A5 直接使用原生
vxor(支持 8/16/32/64 位),A2A3 通过AND(NOT(AND), OR)分解实现(仅支持 8/16/32 位)并需要tmp暂存中间结果,CPU 仿真通过ElementOp::OP_XOR保持一致行为; - 约束:类型统一、行主序、形状对齐是硬性要求,手动模式下 A2A3 还要求四个操作数内存互不重叠。
理解这些约束与平台差异,是编写可在 A2A3 与 A5 之间无缝迁移的位运算内核的前提。进一步可阅读 docs/isa/TXOR.md 英文原档、docs/isa/TAND.md 与 docs/isa/TOR.md 姊妹指令文档,以及 docs/isa/conventions.md 中的通用约定。
- 人工智能
- 指令集
- 算子库
- 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 TXOR 指令详解:Tile 逐元素按位异或的跨平台实现与约束
PTO ISA TXOR 指令详解:Tile 逐元素按位异或的跨平台实现与约束 TXOR(Tile XOR)是 CANN PTO(Parallel Tile O
人工智能指令集算子库CANNAscendCANN PTO-ISA TRELU 指令详解:Tile 逐元素 ReLU 的数学语义、汇编语法与跨平台实现
CANN PTO ISA TRELU 指令详解:Tile 逐元素 ReLU 的数学语义、汇编语法与跨平台实现 导读 本文围绕 CANN pto isa 开源仓库
人工智能指令集算子库CANNAscendCANN pto-isa TXORS 指令详解:Tile 与标量逐元素按位异或的跨平台实现
CANN pto isa TXORS 指令详解:Tile 与标量逐元素按位异或的跨平台实现 导读 本文深入解析 CANN pto isa(Parallel Ti
人工智能指令集算子库CANNAscend
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考