ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PTO ISA 行归约指令 TROWSUM 完全指南:语义、约束、临时空间与跨后端实现

PTO ISA 行归约指令 TROWSUM 完全指南:语义、约束、临时空间与跨后端实现 人工智能指令集算子库CANNAscend【免费下载链接】pto-isaParallel 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点击查看免费下载TROWSUM是 CANN PTOParallel Tile Operation虚拟指令集中的行方向归约指令对 Tile 的每一行沿列求和将[R, C]的源 Tile 归约为[R, 1]的结果。本文以其指令规范文档 docs/isa/TROWSUM.md中文版见 docs/isa/TROWSUM_zh.md为主体结合 A2A3、A5 与 CPU_SIM 三套后端的源码实现完整讲解它的数学语义、汇编语法、C 内建接口、布局与类型约束、tmp临时空间的使用规则以及多后端数值差异。读完本文你将能够正确地在自动模式与手动模式下调用TROWSUM为不同类型含 64 位整数的 Tile 选择合法布局与tmp尺寸并理解各后端归约顺序带来的数值差异。指令概览与数学语义TROWSUM完成逐行求和这一最常用的归约操作。设R src.GetValidRow()、C src.GetValidCol()对每个有效行0 i R$$ \mathrm{dst}{i,0} \sum{j0}^{C-1} \mathrm{src}_{i,j} $$即输出 Tile 的每一行只保留第 0 列一个元素其值等于源 Tile 对应整行C个元素的累加和。因此源 Tile 是任意宽度的矩阵而目标 Tile 在行数上保持不变、列数退化为 1。这一指令在 PTO 中属于 Vec向量域的规约类操作与TROWMAX、TROWMIN、TROWPROD等同属一族源码中三者共享同一套行归约基础设施见下文源码级实现。下图展示了TROWSUM的 Tile 操作示意来自 docs/figures/isa/TROWSUM.svg汇编语法与三级表示TROWSUM在 PTO 虚拟 ISA 的不同抽象层级上有三种表示形式其中同步形式是最高层、对用户最友好的写法降低lowering过程中可能引入内部临时 Tile——这也是 C 内建接口要求显式传入tmp操作数的原因。同步形式%dst trowsum %src : !pto.tile... - !pto.tile...AS Level 1SSA 形式降低后出现显式的tmp操作数%dst pto.trowsum %src, %tmp : (!pto.tile..., !pto.tile...) - !pto.tile...AS Level 2DPS 形式数据平面调度Data Plane Schedule级别使用ins/outs显式声明输入输出缓冲区pto.trowsum ins(%src, %tmp : !pto.tile_buf..., !pto.tile_buf...) outs(%dst : !pto.tile_buf...)三种形式的核心信息一致src与tmp为输入tmp作为归约暂存dst为输出。C 内建接口TROWSUM的 C 内建接口声明位于 include/pto/common/pto_instr.hpp公共包含头为pto/pto-inst.hpptemplate typename TileDataOut, typename TileDataIn, typename TileDataTmp, typename... WaitEvents PTO_INST RecordEvent TROWSUM(TileDataOut dst, TileDataIn src, TileDataTmp tmp, WaitEvents ... events);从实现看include/pto/common/pto_instr.hpp#L1960-L1966该接口先通过detail::PtoWaitEvents(events...)等待传入的事件完成再经MAP_INSTR_IMPL(TROWSUM, dst, src, tmp)宏分派到当前后端的TROWSUM_IMPL实现最后返回一个RecordEvent供下游指令做依赖同步。可变参数WaitEvents使指令天然支持异步流水线编程调用方可以把前序TLOAD等指令返回的事件传入实现跨指令依赖的显式表达。约束与合法性检查TROWSUM的约束分三层通用约束描述 NPU 后端行为、各后端A2A3 / A5专属检查、以及 CPU_SIM 的检查与兼容性例外。通用约束dst和src必须均为TileType::Vec向量 Tile。src必须使用标准 ND 布局行主序且非分形BLayout::RowMajor、SLayout::NoneBox。dst必须为非分形布局且满足以下两种之一ND 布局BLayout::RowMajor、SLayout::NoneBox或列数严格为 1 的 DN 布局BLayout::ColMajor、SLayout::NoneBox、Cols 1。dst与src的元素类型必须一致。运行时有效区域valid region检查src.GetValidRow() ! 0src.GetValidCol() ! 0src.GetValidRow() dst.GetValidRow()内建接口签名要求显式传入tmp操作数。上述约束在 A5 后端源码 include/pto/npu/a5/TRowReduce.hpp#L456-L471 的TRowReduceCheck中有完全对应的实现static_assert在编译期校验类型一致、TileType::Vec、输入 ND 行主序、输出 ND 或单列 DNPTO_ASSERT在运行期校验输入非空与行数保持。A2A3 实现检查支持的元素类型half、float、int32_t、int16_t。这一集合与 include/pto/npu/a2a3/TRowSum.hpp 的实现一致并在测试 tests/npu/a2a3/src/st/testcase/trowsum/ 中得到覆盖。A5 实现检查支持的元素类型half、float、int32_t、int64_t、uint64_t、int16_t。对int64_t/uint64_t的额外要求输出有效列数应为 1只写入每个有效行的第 0 列其余物理填充padding保持不变。ND 输出要求物理Cols % 4 0DN 输出要求物理Cols 1且Rows % 4 0。有效行数不必是 4 的倍数。行步长row stride由物理形状决定详见 docs/isa/conventions.md 的形状与布局约定。A5 的 64 位归约在 include/pto/npu/a5/TRowReduce.hpp#L79-L162 的Int64RowSum中实现将 64 位整数拆为低 32 位/高 32 位两部分用vcadd分组累加、vaddc/vaddcs处理进位实现不经过浮点转换的精确整数归约当输出行为 32 字节不对齐DstCols 1时还会把 4 行结果通过vintlv交错打包成一次对齐存储。CPU_SIM 实现检查CPU_SIM 的目标架构取自调用线程的内存模型而不是宿主机硬件设置方式见 docs/coding/cpu_sim.md#selecting-the-simulated-architecture。A5 路径输入输出类型必须相同支持half、float、int16_t、int32_t、int64_t、uint64_t不支持原生 BF16 与混合输入输出类型。上述 Vec、ND/DN 布局、输入非空、有效行数相等的约束均在运行时检查输入输出的物理行数可以不同。对应实现见 include/pto/cpu/TRowSum.hpp#L99-L133 的CheckRSValid。A2A3 兼容路径支持的输入/输出类型组合为half/half、half/float、bfloat16_t/bfloat16_t、bfloat16_t/float、float/float、int16_t/int16_t、int16_t/int32_t、int32_t/int32_t。物理行数必须相等但不执行 A5 专用的布局与有效区域断言这些兼容性放宽不扩展 A2A3 NPU 的接口约束。两条 CPU 路径都不支持的类型组合在编译期拒绝仅所选架构不支持的类型组合在运行时拒绝。架构相关断言失败会终止进程定义NDEBUG不会关闭这些检查使用PTO_CPU_ASSERT。调用方须保证动态有效形状位于物理 Tile 内并提供覆盖全部输出行及第零列的目标存储与有效区域。实现不检查dst.GetValidCol()也不提供通用动态形状边界检查两条路径都只写被处理行的第零列保持其余目标元素与有效形状元数据不变。数值差异A5 与 A2A3 的归约方式不同A5浮点路径采用分组二叉树归约见 include/pto/cpu/TRowSum.hpp#L23-L48 的rowSumTree以 256 字节向量为单位分组组内两两相加直到剩一个元素每次加法后转换回元素类型整数路径采用模运算累加rowSumModular按输出位宽回绕、不饱和。A2A3保留传统累加循环half/bfloat16_t输出在float中累加后转换其余类型用自身类型累加未采用 A5 的无符号模运算溢出处理行主序循环的向量化提示PTO_CPU_VECTORIZE_LOOP可能重排浮点加法即使未启用-ffast-math也不保证严格从左到右的累加顺序与跨编译器的逐位一致。不承诺与真机逐位等价A5 的 NaN payload、非正规数/flush-to-zero 等浮点细节尚未证明等价A2A3 路径仅用于兼容。依赖 A5 归约顺序时不应启用-ffast-math等允许浮点重结合的选项。分组顺序、舍入及 BF16 占位类型的更多说明见 docs/coding/cpu_sim.md#trowsum-implementation-notes。临时空间tmp的使用规则tmp的语义因后端而异这是使用TROWSUM时最需要留意的一点。A2A3tmp被实际用作归约暂存整数类型int32_t、int16_ttmp用作逐行累加器缓冲区1 个块。对每一行tmp先初始化为 0再通过vadd累加src的各个块最终和值在标量模式下从tmp读取。tmp至少需要 1 行、BLOCK_BYTE_SIZE / sizeof(T)列int32_t为 8 列int16_t为 16 列。对应实现见 include/pto/npu/a2a3/TRowSum.hpp#L114-L148vector_dup清零tmp、逐块vadd累加、SumLastBlockElements在标量域把块内元素逐个相加后写回dst[0]。浮点类型float、halftmp用于vcadd/vcgadd的二叉树归约所需大小取决于每行的 repeat 块数安全的默认设置是把tmp设为与src相同的形状。其二叉树折叠逻辑FillTmp首轮两两相加 TmpProc循环对半折叠见 include/pto/npu/a2a3/TRowSum.hpp#L46-L86。A5tmp被接受但不使用A5 后端含 64 位整数路径执行精确整数归约不需要浮点转换的暂存因此tmp仅为接口兼容而接受。CPU_SIM两条路径都接受tmp但不访问其存储跨后端编写的 kernel 仍必须提供其目标 NPU 后端要求的临时空间以保证在真实 NPU 上同样可运行。编程示例以下示例片段展示调用与存储绑定方式非完整可运行程序归约前须先初始化源数据。在 CPU_SIM 下编译需定义__CPU_SIM自动模式示例还需定义__PTO_AUTO__。要验证 A5 路径需在应用启动阶段按 CPU_SIM 指南选择 A5这些函数自身不选择架构否则使用配置的默认架构初始为 A2A3。自动模式Auto编译器/运行时负责资源放置与调度只需声明 Tile 并直接调用#include cstddef #include cstdint #include pto/pto-inst.hpp using namespace pto; void example_auto() { using SrcT TileTileType::Vec, float, 16, 16; using DstT TileTileType::Vec, float, 16, 1, BLayout::ColMajor; using TmpT TileTileType::Vec, float, 16, 16; SrcT src; DstT dst; TmpT tmp; TROWSUM(dst, src, tmp); }手动模式Manual手动模式需先用TASSIGN显式绑定各 Tile 的物理存储地址再发射指令#include cstddef #include cstdint #include pto/pto-inst.hpp using namespace pto; void example_manual() { using SrcT TileTileType::Vec, float, 16, 16; using DstT TileTileType::Vec, float, 16, 1, BLayout::ColMajor; using TmpT TileTileType::Vec, float, 16, 16; SrcT src; DstT dst; TmpT tmp; TASSIGN(src, 0x1000); TASSIGN(dst, 0x2000); TASSIGN(tmp, 0x3000); TROWSUM(dst, src, tmp); }64 位 ND 输出A564 位整数输出要求 ND 输出物理列数Cols % 4 0。下例中输出物理形状为[64,4]、有效形状为[64,1]即每隔 32 字节写入一个 8 字节结果。在 CPU_SIM 中使用 64 位整数TROWSUM前须先选择 A5 架构#include cstdint #include pto/pto-inst.hpp using namespace pto; void example_int64() { using SrcT TileTileType::Vec, int64_t, 64, 16; using DstT TileTileType::Vec, int64_t, 64, 4, BLayout::RowMajor, 64, 1; SrcT src, tmp; DstT dst; TROWSUM(dst, src, tmp); }注意这里DstT通过模板参数64, 1显式指定了有效区域valid rows 64valid cols 1与src的[64,16]有效形状满足行数相等约束。汇编形式示例自动模式# 自动模式由编译器/运行时负责资源放置与调度。 %dst pto.trowsum %src, %tmp : (!pto.tile..., !pto.tile...) - !pto.tile...手动模式# 手动模式先显式绑定资源再发射指令。 # 可选当该指令包含 tile 操作数时 # pto.tassign %arg0, tile(0x1000) # pto.tassign %arg1, tile(0x2000) %dst pto.trowsum %src, %tmp : (!pto.tile..., !pto.tile...) - !pto.tile...PTO 汇编形式%dst trowsum %src : !pto.tile... - !pto.tile... # AS Level 2 (DPS) pto.trowsum ins(%src, %tmp : !pto.tile_buf..., !pto.tile_buf...) outs(%dst : !pto.tile_buf...)源码级实现与测试佐证A2A3 后端两套归约路径include/pto/npu/a2a3/TRowSum.hpp 将整数与浮点分成两条实现路径整数路径以BLOCK_BYTE_SIZE / sizeof(T)为块粒度逐行累加块内剩余元素用set_vector_mask掩码处理最后在标量域完成块内求和SumLastBlockElements对应文档整数tmp用作逐行累加器、最终标量读取的描述。浮点路径TRowSumOp封装vadd两两相加、vcadd块内归约、vcgadd分组归约三类指令FillTmp/TmpProc完成二叉树的构建与折叠对应文档tmp用于vcadd/vcgadd二叉树归约的描述。A5 后端共享行归约基础设施include/pto/npu/a5/TRowReduce.hpp 中TROWSUM、TROWMAX、TROWMIN共用TRowReduceCheck编译期/运行期约束校验、TRowReduceProc逐行vlds加载、归约、vsts存储与TROWREDUCE_IMPL_COMMON按元素类型分派64 位走Int64RowSum其余走通用归约。ROWSUM结构体还通过TOUT把int16_t加宽为int32_t累加这与 CPU_SIM A2A3 兼容路径中int16_t/int32_t的输入输出组合相呼应。CPU_SIM 后端架构感知的双路径include/pto/cpu/TRowSum.hpp 通过memory.GetArch() NPUArch::A5决定走 A5 归约rowSumTree分组二叉树 rowSumModular模运算累加还是 A2A3 兼容路径行主序向量化累加并用cpu::parallel_for_1d按行并行是文档目标架构取自调用线程内存模型的直接证据。测试覆盖A5 NPU 测试 tests/npu/a5/src/st/testcase/trowsum/trowsum_kernel.cpp 覆盖了float/half/int32_t/int16_t/int64_t/uint64_t/uint32_t/uint16_t等类型、ND 与 DN 两种输出布局、各种有效/物理形状组合以及 case 100–107 对 64 位输出 padding 与相邻内存保护的守卫测试launchTROWSUMGuard在归约前把输出视图连同 padding 一起TLOAD归约后整体TSTORE回读验证非第 0 列与无效行不被改写。A2A3 与 CPU 侧测试分别位于 tests/npu/a2a3/src/st/testcase/trowsum/ 与 tests/cpu/st/testcase/trowsum/配合gen_data.py生成黄金数据做数值校验。使用要点速查项目要求Tile 域dst、src必须均为TileType::Vec源布局ND 行主序BLayout::RowMajor、SLayout::NoneBox目标布局NDRowMajor/NoneBox或单列 DNColMajor/NoneBox、Cols 1元素类型A2A3half/float/int32_t/int16_tA5 增加int64_t/uint64_t有效区域输入非空且src.GetValidRow() dst.GetValidRow()tmp语义A2A3 实际使用整数 1 块累加器浮点二叉树暂存A5 与 CPU_SIM 接受但不访问数值注意A5 分组二叉树归约A2A3 传统累加循环两者不保证逐位一致依赖 A5 顺序时禁用-ffast-math掌握以上约束与各后端差异后即可在 PTO 编程模型下正确使用TROWSUM完成 softmax、LayerNorm 等算子中的行求和步骤并为 64 位整数场景正确预留物理形状与输出 padding。赞分享人工智能指令集算子库CANNAscend【免费下载链接】pto-isaParallel 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点击查看免费下载相关推荐PTO-ISA TROWPROD 指令深度解析逐行乘积归约的语义、约束与跨平台实现PTO ISA TROWPROD 指令深度解析逐行乘积归约的语义、约束与跨平台实现 TROWPRODTile Row Product是 Ascend CA人工智能指令集算子库CANNAscendCANN PTO-ISA TCOLPROD 指令详解列归约乘积跨行乘积的语义、约束与源码实现CANN PTO ISA TCOLPROD 指令详解列归约乘积跨行乘积的语义、约束与源码实现 导读 TCOLPROD 是 Ascend CANN 并行 T人工智能指令集算子库CANNAscendOpenVoice语音克隆用30秒音频创造个性化语音的完整指南OpenVoice语音克隆用30秒音频创造个性化语音的完整指南 OpenVoice是一个革命性的即时语音克隆技术它能够仅凭一段30秒的音频样本精确复制任何人工智能指令集算子库CANNAscend上一篇Tambo AI React SDK 线程与会话输入完全指南Threads、Suggestions、语音与图片附件下一篇OpenCloud sse 服务实战Server-Sent Events 实时事件通道的实现与配置创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表