PTO TTRANS 指令详解Tile 转置、内存布局转换与临时空间计算CANN pto-isa【免费下载链接】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-isaTTRANS 是 CANN pto-isa 虚拟指令集中负责Tile 转置与内存布局转换的核心指令覆盖二维 Tile 的行列转置、NCHW/NC1HWC0/GNCHW 等卷积布局互转以及向 FRACTAL_Z / Fractal_Z_3D 计算友好格式的转换。本文以 TTRANS.md 与 TTRANS_zh.md 为主体结合仓库内 A2A3、A5 平台的源码实现与测试用例系统讲解其数学语义、汇编/内建接口用法、各平台约束、不同路径下临时 Tiletmp空间的计算公式与完整示例帮助开发者在编写算子内核时正确使用该指令并避免 UB 内存溢出。TTRANS 指令的 Tile 操作示意来自 docs/figures/isa/TTRANS.svg一、指令概述与数学语义TTRANS 的功能是“使用实现定义的临时 Tile 进行转置”Transpose with an implementation-defined temporary tile。与普通逐元素转置不同该指令允许且通常要求调用方显式提供一个临时缓冲tmp用于存放转置过程中的中间结果从而在不破坏源数据的前提下完成布局重排。对于二维 Tile在有效转置域effective transpose domain上其数学语义为$$ \mathrm{dst}{i,j} \mathrm{src}{j,i} $$即输出 Tile 的第(i, j)个元素等于输入 Tile 第(j, i)个元素。需要注意的是确切的形状、内存布局以及转置域的范围取决于目标硬件平台见“约束”一节不同平台上实现路径不同转置的有效区域以src.GetValidRow()/src.GetValidCol()为准。从指令流水归属看TTRANS 是向量PIPE_V指令——在 include/pto/common/event.hpp 中通过PTO_DEFINE_OP_PIPE(Op::TTRANS, PIPE_V)将其绑定到向量流水因此在手动模式下手动同步通常需要围绕PIPE_V建立依赖。二、汇编语法Assembly SyntaxTTRANS 在 PTO 汇编中同时存在同步形式与两级抽象AS形式。2.1 同步形式%dst ttrans %src : !pto.tile... - !pto.tile...编译器的降级Lowering阶段可能引入内部 scratch tile但C 内建接口要求显式传入tmp操作数因此在实际内核代码中临时空间总是由开发者规划。2.2 AS Level 1SSA 形式%dst pto.ttrans %src : !pto.tile... - !pto.tile...2.3 AS Level 2DPS 形式pto.ttrans ins(%src : !pto.tile_buf...) outs(%dst : !pto.tile_buf...)DPSDestructive/Declarative Place Schedule形式将输入ins与输出outs显式分离供编译后端进行资源放置与调度。三、C 内建接口TTRANS 的 C 内建接口声明于 include/pto/common/pto_instr.hpptemplate typename TileDataDst, typename TileDataSrc, typename TileDataTmp, typename... WaitEvents PTO_INST RecordEvent TTRANS(TileDataDst dst, TileDataSrc src, TileDataTmp tmp, WaitEvents ... events);接口要点公共头文件为pto/pto-inst.hpp内部声明位于pto/common/pto_instr.hpp。内核代码中只需#include pto/pto-inst.hpp并using namespace pto;。三个模板参数分别对应输出 Tile、输入 Tile 与临时 Tile 的类型WaitEvents...为可选的事件参数用于指令间依赖同步detail::PtoWaitEvents会在发射前等待事件。函数返回RecordEvent可捕获指令事件供后续指令等待从而实现流水级并行。tmp为必选参数即使某些路径如NC1HWC0 - FRACTAL_Z实际不消耗临时空间接口签名仍要求传入。从源码实现看TTRANS 的发射通过宏MAP_INSTR_IMPL(TTRANS, dst, src, tmp)分发到具体平台A2A3/A5/CPU的实现平台相关的实现文件分别位于 include/pto/npu/a2a3/TTrans.hpp、include/pto/npu/a5/TTrans.hpp 与 include/pto/cpu/TTrans.hppCPU 侧用于仿真/单测与 NPU 侧保持同一接口。四、平台约束Implementation ChecksTTRANS 对不同目标平台有独立的编译期/运行期检查。从源码结构看约束分为 A2A3 与 A5 两套实现。4.1 A2A3Atlas A2/A3 训练与推理系列产品输入输出元素类型大小必须一致sizeof(TileDataSrc::DType) sizeof(TileDataDst::DType)。源布局必须为行主序TileDataSrc::isRowMajor。元素大小必须为1、2或4字节。支持的元素类型按元素宽度限定4 字节uint32_t、int32_t、float2 字节uint16_t、int16_t、half、bfloat16_t1 字节uint8_t、int8_t转置大小取自src.GetValidRow()/src.GetValidCol()。4.2 A5Ascend 950PR / Ascend 950DT输入输出元素类型大小必须一致。源布局必须为行主序TileDataSrc::isRowMajor。32 字节对齐约束作用于输入输出的列维度TileDataSrc::Cols * sizeof(T) % 32 0且TileDataDst::Cols * sizeof(U) % 32 0。支持的元素类型与 A2A3 相同按 4/2/1 字节宽度限定。转置大小取自src.GetValidRow()/src.GetValidCol()。上述 A5 约束在 include/pto/npu/a5/TTrans.hpp 的TTRANS_IMPL中以static_assert形式落地sizeof(T) 4 || sizeof(T) 2 || sizeof(T) 1、sizeof(T) sizeof(U)、TileDataSrc::isRowMajor、Cols * sizeof(T) % 32 0等同时在TTransTile中还会静态检查 gather/scatter 索引是否可能溢出对应位宽的寄存器b32 用uint32_t索引、b16/b8 用uint16_t索引一旦 Tile 尺寸超出索引表达范围会直接编译报错。五、临时 Tiletmp空间计算C API 强制要求tmp且tmp 空间的大小必须由开发者按公式预先规划否则可能导致越界写或 UB 内存溢出。仓库的调试断言如 include/pto/npu/a2a3/TTrans.hpp 的CheckConvTile/CheckConv3DTile还会校验(srcSize dstSize tmpSize) * sizeof(T) UB_SIZEA2A3 为 192 KBA5 为 256 KB超出即断言失败。5.1 基础参数RowStrideb8 类型为 32b16/b32 类型为 16对应实现常量Y_ELEM_B8与Y_ELEM_OTHER。ElemPerBlock32 / sizeof(T)即每个 32 字节块容纳的元素个数。b8 指uint8_t/int8_tb16 指uint16_t/int16_t/half/bfloat16_tb32 指uint32_t/int32_t/float。tmpStridetmpStride ceil(H / RowStride) × RowStride即将行数 H 向上对齐到 RowStride。在 include/pto/npu/a2a3/TTrans.hpp 的TTransOperation中tmpStride正是按(validRow yTileSizeElem - 1) / yTileSizeElem * yTileSizeElem计算yTileSizeElem对 b8 取 32、其余取 16与文档公式一一对应。5.2 二维 Tile 转置 [H, W] - [W, H]二维转置按对齐情况有三种路径tmp 大小公式各不相同1b16 vtranspose 快路径当validRow % 16 0且validCol % 16 0时按 16×16 块调用vtranspose。用户tmp需容纳两个 16×16 区域$$ \text{tmpSize} \ge 2 \times 16 \times 16 \times \text{sizeof(DType)} 1024 \text{ bytes} $$2对齐 vnchwconv 路径当dstStride % RowStride 0时将整个 Tile 转置到用户tmp再通过copy_ubuf_to_ubuf搬运到 dst$$ \text{tmpSize} W \times \text{tmpStride} \times \text{sizeof(DType)} W \times \lceil\frac{H}{\text{RowStride}}\rceil \times \text{RowStride} \times \text{sizeof(DType)} $$其中 W 为validCol列数H 为validRow行数。源码中对应的搬运实现为pto_copy_ubuf_to_ubuf(dstPtr, tmpPtr, validCol, lenBurst, srcGap, dstGap)。3非对齐路径TransTail2DTiles当dstStride % RowStride ! 0时每个子块转置到用户tmp再通过带 mask 的vcopy或标量拷贝写回 dst。由于各子块复用同一块 tmp$$ \text{tmpSize} \text{ElemPerBlock} \times \text{tmpStride} \times \text{sizeof(DType)} \text{ElemPerBlock} \times \lceil\frac{H}{\text{RowStride}}\rceil \times \text{RowStride} \times \text{sizeof(DType)} $$路径选择与分配建议若编译期无法确定走哪条路径应按上述适用公式取最大值分配b16 还需额外保证tmpSize ≥ 1024字节。5.3 NCHW - NC1HWC0 双向转换对齐路径正向 [N, C, H, W] - [N, C1, H, W, C0]$$ \text{tmpSize} H \times W \times \lceil\frac{C0}{\text{RowStride}}\rceil \times \text{RowStride} \times \text{sizeof(DType)} $$其中C1 (C C0 - 1) / C0转置域为 C0 行、H×W 列。反向 [N, C1, H, W, C0] - [N, C, H, W]$$ \text{tmpSize} C0 \times \lceil\frac{H \times W}{\text{RowStride}}\rceil \times \text{RowStride} \times \text{sizeof(DType)} $$转置域为 H×W 行、C0 列。5.4 GNCHW - GNC1HWC0 双向转换对齐路径正向 [G, N, C, H, W] - [G, N, C1, H, W, C0]$$ \text{tmpSize} H \times W \times \lceil\frac{C0}{\text{RowStride}}\rceil \times \text{RowStride} \times \text{sizeof(DType)} $$反向 [G, N, C1, H, W, C0] - [G, N, C, H, W]$$ \text{tmpSize} C0 \times \lceil\frac{H \times W}{\text{RowStride}}\rceil \times \text{RowStride} \times \text{sizeof(DType)} $$与 NCHW 情况相比仅多了分组维度 G 的外层循环核心转置域相同。5.5 NC1HWC0 - FRACTAL_Z 与 GNC1HWC0 - FRACTAL_Z这两种转换不需要 tmp 空间直接执行内存重排操作对应实现为TTransConvNC1HWC02C1HWNC0/TTransConvGNC1HWC02GC1HWNC0其中 C1HW 拼接后按 N0 维度做 stride 搬运见 include/pto/npu/a2a3/TTrans.hpp。此时tmp参数仅用于占位可分配极小空间。5.6 NCDHW - Fractal_Z_3D[N, C, D, H, W] - [D, C1, H, W, N1, N0, C0]$$ \text{tmpSize} (N \times C1 \times C0 \times H \times W \max(N \times C1 \times C0 \times H \times W,\ H \times W \times \lceil\frac{C0}{\text{RowStride}}\rceil \times \text{RowStride})) \times \text{sizeof(DType)} $$其中C1 (C C0 - 1) / C0N1 (N N0 - 1) / N0RowStride 对 8-bit 数据为 32、对 16/32-bit 数据为 16。该转换分两阶段执行对应 include/pto/npu/a2a3/TTrans.hpp 的TTransConvNCDHW2FractalZ3D第一阶段按 d 平面提取 NCDHW - NCHW 格式需要N*C1*C0*H*W空间作为planePtr第二阶段要么把结果写入secondPtr需要N*C1*C0*H*W要么把secondPtr当作转置的 tmp需要H*W*ceil(C0/RowStride)*RowStride。由于路径在运行时才确定secondPtr需取两者最大值。六、ConvTile 上的格式转换约束当源 Tile 为ConvTileTileType::Vec时TTRANS 支持一系列卷积布局转换约束如下元素大小必须为1、2或4字节支持元素类型为uint32_t、int32_t、float、uint16_t、int16_t、half、bfloat16_t、uint8_t、int8_t。NCHW - NC1HWC0C1 (C C0 - 1)/C0HW 满足对齐约束H*W*sizeof(T)%320C0 对应c0_size满足C0 * sizeof(T) 32C0 也可以取 4。NC1HWC0 - FRACTAL_ZN1 (N N0 - 1)/N0其中 N0 应为 16。NCDHW - FRACTAL_Z_3D目标形状为[D * C1 * H * W, N1, N0, C0]其中C1 (C C0 - 1)/C0、N1 (N N0 - 1)/N0N0 为 16C0 取决于元素宽度——4-bit 数据为 648-bit 数据为 3216-bit 数据为 1632-bit 数据为 8。tmp 大小按上文“临时 Tile”章节公式计算。源码中TTransImplConvTileA5 实现见 include/pto/npu/a5/TTrans.hpp会根据TileDataSrc::layout与TileDataDst::layout的组合分派到TTransConvNCHW2NC1HWC0、TTransConvNC1HWC02C1HWNC0、TTransConvGNCHW2GNC1HWC0、TTransConvGNC1HWC02GC1HWNC0等具体函数且对齐/非对齐路径各自有独立实现。七、使用示例7.1 Auto自动模式示例自动模式下资源放置与调度由编译器/运行时管理只需声明 Tile 并调用接口#include pto/pto-inst.hpp using namespace pto; void example_auto() { using SrcT TileTileType::Vec, float, 16, 16; using DstT TileTileType::Vec, float, 16, 16; using TmpT TileTileType::Vec, float, 16, 16; SrcT src; DstT dst; TmpT tmp; TTRANS(dst, src, tmp); }7.2 Manual手动模式示例手动模式下需先用TASSIGN显式绑定各 Tile 的 UB 地址再发射指令#include pto/pto-inst.hpp using namespace pto; void example_manual() { using SrcT TileTileType::Vec, float, 16, 16; using DstT TileTileType::Vec, float, 16, 16; using TmpT TileTileType::Vec, float, 16, 16; SrcT src; DstT dst; TmpT tmp; TASSIGN(src, 0x1000); TASSIGN(dst, 0x2000); TASSIGN(tmp, 0x3000); TTRANS(dst, src, tmp); }7.3 汇编形式示例自动模式编译器/运行时管理资源放置与调度%dst pto.ttrans %src : !pto.tile... - !pto.tile...手动模式先显式绑定资源再发射指令tile 操作数可用pto.tassign绑定# pto.tassign %arg0, tile(0x1000) # pto.tassign %arg1, tile(0x2000) %dst pto.ttrans %src : !pto.tile... - !pto.tile...PTO 汇编形式含 AS Level 2 DPS 形式%dst ttrans %src : !pto.tile... - !pto.tile... pto.ttrans ins(%src : !pto.tile_buf...) outs(%dst : !pto.tile_buf...)八、源码级实现与测试验证8.1 A2A3 实现基于 vnchwconv 的分块转置A2A3 平台include/pto/npu/a2a3/TTrans.hpp采用scatter_vnchwconv系列底层指令完成转置核心TransB8Instrb8 按[32,8] - [8,32]分块组合 4 次scatter_vnchwconv_b8TransB16Instrb16 按[16,16] - [16,16]调用scatter_vnchwconv_b16TransB32Instrb32 按[16,8] - [8,16]调用scatter_vnchwconv_b32。TTransOperation在满足 stride 对齐时走“整块转置到 tmp pto_copy_ubuf_to_ubuf搬运回 dst”的路径不满足时退化为TransTailTiles的标量双循环拷贝带PIPE_V/PIPE_S等待标志保证流水同步。此外还针对 Y 方向尾部TransYTailTiles/TransB8YTailTiles单独处理保证任意有效行数都能覆盖。8.2 A5 实现基于 gather/scatter 的行列向转置A5 平台include/pto/npu/a5/TTrans.hpp不依赖 vnchwconv而是按行/列两种方向分别实现TTransB32/B16/B8RowWise逐行vlds读入连续数据构造索引后vscatter按列写出适合行数少于列数的 Tile即Rows ColsTTransB32/B16/B8ColWise构造索引后vgather2按列读入再vsts连续写出适合列数少于行数的 Tile。TTransTile根据TileDataSrc::Rows TileDataSrc::Cols在编译期选择 RowWise 或 ColWise 路径并对索引溢出做static_assert防护b32 用 32 位索引b16/b8 用 16 位索引。对齐路径的判定条件Cols * sizeof(T) % 32 0与文档中 A5 的 32 字节对齐约束完全一致。8.3 测试用例与成本模型仓库为 TTRANS 提供了覆盖多平台的完整测试NPU 侧tests/npu/a2a3/src/st/testcase/ttrans/ttrans_kernel.cpp 展示了含动态形状Shape-1,...的真实内核写法先按alignedSrcTileSize等计算各 Tile 的静态大小并做static_assert(... 192*1024)防 UB 溢出再依次TASSIGN→TLOAD→ 同步set_flag(PIPE_MTE2, PIPE_V)/wait_flag→TTRANS→ 同步PIPE_V→PIPE_MTE3→TSTOREtmp Tile 的宽度按tmpStride对齐规则推导是 7.2 节手动模式的完整形态卷积布局转换有独立用例目录ttrans_convNCHW/NC1HWC0/FRACTAL_Z 组合、3D 转换有ttrans_3dCPU 侧对应 tests/cpu/st/testcase/ttrans/gtest golden 数据 gen_data.py用于无 NPU 环境的数值验证成本模型侧 tests/costmodel/st/testcase/ttrans/ 验证了 TTRANS 在性能仿真perf-sim中的延迟建模相关实现位于 include/pto/costmodel/perf_sim/latency.hpp 等成本模型文件中可据此在写码阶段预估转置开销。九、总结与使用建议TTRANS 是 PTO 中同时承担“数值转置”与“布局转换”双重职责的关键向量指令数值转置二维 Tile 满足dst[i][j] src[j][i]A2A3 走 vnchwconv 分块路径、A5 走 gather/scatter 行列路径转置域由GetValidRow()/GetValidCol()决定布局转换覆盖 NCHW↔NC1HWC0、GNCHW↔GNC1HWC0、NC1HWC0/GNC1HWC0→FRACTAL_Z、NCDHW→Fractal_Z_3D以及 ConvTile 上的各类组合必须显式提供 tmp按“临时 Tile 空间计算”章节的公式区分 2D 转置三路径、NCHW 族双向转换、NCDHW 两阶段在编译期计算并核对src dst tmp UB_SIZEA2A3 192KB / A5 256KBb16 场景下 2D 转置至少保证 1024 字节先查约束再编码A2A3 要求行主序、元素宽度 1/2/4 字节A5 额外要求输入输出列维度 32 字节对齐两者均限制元素类型集合误用会在编译期static_assert或调试断言阶段暴露。遵循上述约束与公式开发者便能在 Auto/Manual 两种模式下安全、高效地使用 TTRANS 完成转置与布局重排并可参考 docs/isa/README.md 与其他指令文档如 TMOV.md、TCONCAT.md构建完整的 Tile 级数据搬移方案。【免费下载链接】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创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考