PTO-ISA TXOR 指令详解:Tile 级逐元素按位异或的数学语义、汇编语法与跨平台实现
2026/9/20 9:58:30 网站建设 项目流程
  • 人工智能
  • 指令集
  • 算子库
  • 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
点击查看免费下载

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} $$

其中dstsrc0src1均为!pto.tile<...>类型的 Tile 操作数,运算在整数位层面逐位进行:某一位上两个输入同为0或同为1时结果位为0,否则为1。注意异或(^)与逻辑或(|)在语义上不同:1 ^ 1 = 01 | 1 = 1,这也决定了 A2A3 后端在实现上不能直接复用 OR 指令,而需要额外的组合逻辑(详见下文"临时空间"一节)。

运算的迭代范围由输出 Tile 决定,即dst.GetValidRow()/dst.GetValidCol()所界定的有效行、列区域;src0src1的有效形状必须与之完全一致(见"约束"一节)。

汇编语法

同步形式(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 参数dstsrc0src1之外还要求一个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)

  • dstsrc0src1元素类型必须一致
  • 支持的元素类型为:uint8_tint8_tuint16_tint16_tuint32_tint32_tint64_tuint64_t
  • dstsrc0src1必须为行主序(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 推理系列产品)

  • dstsrc0src1tmp元素类型必须一致
  • 支持的元素类型为:uint8_tint8_tuint16_tint16_tuint32_tint32_t(不含 64 位类型,这是与 A5 的显著差异)。
  • dstsrc0src1tmp必须为行主序。
  • src0src1tmp的有效形状必须与dst一致。
  • 手动模式下dstsrc0src1tmp的内存区域不得重叠

对应检查见 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_IMPLTNOT_IMPLTAND_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不得与dstsrc0src1内存重叠。

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 仿真侧的对照用例;
  • 标量变体 TXORStests/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_tuint8_tint16_tuint16_tint32_tuint32_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.

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

相关推荐

上一篇:一张消费级4090跑Qwen3-Coder-480B-A35B-Instruct?这份极限“抠门”的量化与显存优化指南请收好
下一篇:从语法解析到实战修复:DTStack/dt-sql-parser中FlinkSQL JSON_VALUE函数解析问题深度剖析

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

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

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

立即咨询