CANN PTO-ISA ConvTile 编程模型:卷积算子的片上 Tile 计算单元与地址绑定实战
2026/9/19 10:19:28 网站建设 项目流程

CANN PTO-ISA ConvTile 编程模型:卷积算子的片上 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

ConvTile 是 PTO(Parallel Tile Operation)指令集中面向卷积类算子的固定容量 2D~6D 片上缓冲对象,既是卷积计算的最小计算单元,也是TLOAD/TSTORE等数据搬运指令的主要操作对象。本文基于docs/coding/ConvTile_zh.md,并结合 pto_tile.hpp 源码与 TASSIGN 指令文档,完整讲解pto::ConvTile的类型定义、布局与形状约束、地址绑定机制,以及一段可直接编译运行的最小示例,帮助你用 PTO 编写第一个卷积类内核。

ConvTile 表示什么

从概念上说,ConvTile驻留在片上 Tile 存储中(类似寄存器文件或片上 SRAM),并通过TLOAD/TSTORE与全局内存(GM)之间搬运数据。与通用的二维Tile不同,ConvTile支持 2 到 6 个维度,专门服务于卷积类算子的多维度数据布局(如 batch、通道、高度、宽度等)。

一个ConvTile主要由五类属性定义:

属性说明示例
位置(Location)Tile 所属的逻辑存储类别(矩阵/立方寄存器等)TileType::MatTileType::Vec
元素类型(Element type)标量元素类型floathalfint8_t
缓冲区大小(Buffer size)ConvTile的静态缓冲容量4096(元素个数)
布局(Layout)指导 lowering 与目标相关优化路径NCHWNHWCNC1HWC0
形状(Shape)pto::ConvTileShape<...>,支持最多 6 个维度ConvTileShape<1, 1, 16, 16, 16>

这些属性的具体承载形式,就是下文的 C++ 模板类型pto::ConvTile,其定义位于 include/pto/common/pto_tile.hpp。

pto::ConvTile类型

ConvTile通过 C++ 模板类型声明,模板参数依次对应上述五类属性:

pto::ConvTile< pto::TileType Loc_, // 位置:Tile 的逻辑/物理存储类别 Element_, // 元素类型:标量类型 BufferSize_, // 静态容量 pto::Layout_ layout, // 布局枚举 pto::ConvTileShape Shape_ // 形状(最多 6 维) >;

从源码看(pto_tile.hpp),ConvTile结构体将这些模板参数公开为编译期常量,供后续指令特化使用:

template <TileType Loc_, typename Element_, const int BufferSize_, Layout Layout_, typename Shape_> struct ConvTile { using DType = Element_; // 元素类型 using ShapeType = Shape_; // 形状类型 static constexpr TileType Loc = Loc_; // 位置 static constexpr int bufferSize = BufferSize_; // 静态容量 static constexpr Layout layout = Layout_; // 布局 ... };

位置(TileType

TileType表示 Tile 的逻辑/物理存储类别,同时参与指令重载选择和编译期检查。ConvTile常见的合法位置包括:

  • TileType::Vec:向量 Tile 存储(UB / 向量流水线)。
  • TileType::Mat:通用矩阵 Tile 存储(矩阵 L1)。

每条指令允许使用哪些位置,应以 docs/isa/ 下对应指令文档为准。例如TLOAD指令文档会说明其源/目的 Tile 的合法TileType组合。

容量(BufferSize_

BufferSize_定义了 Tile 对象的静态容量(以元素个数计)。多数指令要求 Tile 具备静态形状,以便在编译期进行特化和优化。ConvTile在声明时通过static_assert限制形状维数,见源码 pto_tile.hpp:

static constexpr int totalDimCount = ShapeType::totalDimCount; static_assert( totalDimCount >= 1 && totalDimCount <= ConvTileDetail::MAX_CONVTILE_DIM, "ConvTile only support 1D~6D Shapes!");

ConvTile仅支持 1D~6D 形状,越界会在编译期直接报错。

布局(pto::Layout

ConvTile包含一个布局枚举。文档中列举了卷积场景最常用的几种:

  • NCHW
  • NHWC
  • NC1HWC0
  • FRACTAL_Z
  • FRACTAL_Z_S16S8

在源码 type.hpp 中可以看到完整的Layout枚举,除上述卷积布局外还包括ND(行主序)、DN(列主序)、NZ(cube 分形)、GNC1HWC0GNCHWNDC1HWC0NCDHWFRACTAL_Z_3D以及 MX/HIF4 系列的专用布局(MX_A_ZZMX_B_NNHIF4_A_ZZHIF4_B_NN等)。布局信息会影响后端实现、lowering 路径以及特定目标上的快速路径选择。

形状(pto::ConvTileShape

pto::ConvTileShape<...Shapes>支持 1 到 6 个整型模板参数。每个维度既可以是编译期常量,也可以是pto::DYNAMIC(即-1,定义见 pto_tile.hpp)。

  • 静态维度保存在类型信息中,可通过ConvTileShape::staticShape[dim]获取。
  • 动态维度保存在运行时对象ConvTileShape::shape[dim]中,并由ConvTileShape(...)构造函数赋值。

源码中ConvTileShape的实现(pto_tile.hpp)提供了staticShape(6 个维度的编译期数组)、dynamicDimCount(动态维度数量)以及 1~6 参数的构造函数。构造函数通过static_assert检查"运行时传入参数个数是否与动态维度数量一致",例如:

PTO_INTERNAL ConvTileShape(int64_t n) { static_assert( dynamicDimCount == 1, "1-parameter constructors is only applicable to Shape with 1 dynamic dimension."); ... }

因此若构造参数不匹配(例如形状声明了 2 个动态维度却只传 1 个运行参数),会在编译期报错。

此外,ConvTile还提供了SetDynamicShape成员(pto_tile.hpp),用于在内核运行时按需设置动态维度,同样以static_assert校验参数个数与类型:

template <typename... Ints> PTO_INTERNAL void SetDynamicShape(Ints... vals) { static_assert(sizeof...(vals) == dynamicDimCount, "Number of dynamic values does not match dynamic dimension count!"); static_assert((std::is_same_v<Ints, int64_t> && ...), "Dynamic values must be int64_t type!"); ... }

卷积元数据:ConvTile 的隐藏字段

除模板参数外,源码中的ConvTile结构体还携带一组运行时卷积元数据(pto_tile.hpp),用于在手动放置流程中描述卷积计算的窗口参数,是编写卷积内核时常用的配套接口:

字段类型默认值含义
fmapH_/fmapW_uint16_t0特征图(feature map)高/宽
padList_[4]uint8_t{0,0,0,0}四方向 padding
filterH_/filterW_uint16_t1卷积核高/宽
dilationH_/dilationW_uint16_t1膨胀率
strideH_/strideW_uint16_t1卷积步长
padValue_DType0padding 填充值
channelSize_uint16_t0通道数
repeatStride_/repeatTime_/repeatMode_uint16_t/uint8_t0 / 1 / 0指令 repeat 相关参数
dstStride_/dstMposition_uint16_t0目标 stride / M 位置(A2A3 架构除外)
transpose_boolfalse是否转置
smallChannel_boolfalse小通道模式

对应的GetXxx/SetXxx接口(如SetFmapHSetPadListSetFilterHSetStrideHSetPadValueSetTranspose等)均已声明为PTO_INTERNAL,可直接在 PTO Lib 内核代码中调用。

地址绑定(TASSIGN

在手动放置流程中,TASSIGN(tile, addr)用于把一个ConvTile对象绑定到实现定义的片上地址;在自动模式(定义了__PTO_AUTO__)下,TASSIGN(tile, addr)可能被处理为 no-op。具体约束参考 docs/isa/TASSIGN.md。

两种调用形式

形式一:运行时地址(不做编译期越界检查,地址值在编译期不可知):

template <typename T, typename AddrType> PTO_INST void TASSIGN(T& obj, AddrType addr);

形式二:编译期地址(带静态越界检查,Addr是非类型模板参数,编译器通过static_assert执行检查):

template <std::size_t Addr, typename T> PTO_INST void TASSIGN(T& obj);

编译期检查项

形式二会触发以下编译期检查(断言 ID 对应 docs/coding/debug_zh.md 中的修复配方FIX-A12):

检查条件断言 ID错误信息
内存空间存在capacity > 0SA-0351Memory space is not available on this architecture.
Tile 放得下tile_size <= capacitySA-0352Tile storage size exceeds memory space capacity.
地址不越界Addr + tile_size <= capacitySA-0353addr + tile_size exceeds memory space capacity (out of bounds).
地址对齐Addr % alignment == 0SA-0354addr is not properly aligned for the target memory space.

内存空间、容量与对齐

内存空间、容量和对齐由 Tile 的TileType(即Loc模板参数)自动确定,各架构的默认容量见下表(A2A3 / A5 / Kirin9030 / KirinX90,对齐均为 32 B):

TileType内存A2A3A5Kirin9030KirinX90对齐
VecUB192KB256KB128KB128KB32 B
MatL1512KB512KB512KB1024KB32 B
LeftL0A64KB64KB32KB64KB32 B
RightL0B64KB64KB32KB64KB32 B
AccL0C128KB256KB64KB128KB32 B
BiasBias1KB4KB1KB1KB32 B
ScalingFBuffer2KB4KB7KB6KB32 B
ScaleLeftL0AN/A4KBN/AN/A32 B
ScaleRightL0BN/A4KBN/AN/A32 B

容量可在构建时通过-D宏覆盖(例如-DPTO_UBUF_SIZE_BYTES=262144),参见 include/pto/common/buffer_limits.hpp。

注意:该编译期检查重载仅对TileConvTile类型可用;对于GlobalTensor,应使用TASSIGN(obj, pointer)(形式一)。

约束

  • obj是 Tile(含ConvTile):
    • 手动模式(未定义__PTO_AUTO__):addr必须是整型,并被重新解释为 Tile 的存储地址。
    • 自动模式(定义了__PTO_AUTO__):TASSIGN(tile, addr)为 no-op。
  • objGlobalTensoraddr必须是指针类型,且指向的元素类型必须与GlobalTensor::DType匹配。

地址绑定示例

运行时地址(不做编译期检查):

#include <pto/pto-inst.hpp> using namespace pto; void example_runtime() { using TileT = Tile<TileType::Vec, float, 16, 16>; TileT a, b, c; TASSIGN(a, 0x1000); TASSIGN(b, 0x2000); TASSIGN(c, 0x3000); TADD(c, a, b); }

编译期地址(带静态越界检查):

void example_checked() { using TileT = Tile<TileType::Vec, float, 16, 16>; TileT a, b, c; TASSIGN<0x0000>(a); // OK: 0x0000 + 1024 <= 192KB TASSIGN<0x0400>(b); // OK: 0x0400 + 1024 <= 192KB TASSIGN<0x0800>(c); // OK: 0x0800 + 1024 <= 192KB TADD(c, a, b); }

越界示例(触发 SA-0352 / SA-0353):

// Tile<Vec, float, 256, 256> 占用 256*256*4 = 256KB using BigTile = Tile<TileType::Vec, float, 256, 256>; BigTile t; TASSIGN<0x0>(t); // 主要触发 [SA-0352]:tile_size(256KB) > UB 容量(192KB, A2A3)

最小示例

下面是一个完整的 ConvTile 使用示例:声明一个NC1HWC0布局、形状为<1, 1, 16, 16, 16>Mat位置half类型 ConvTile,构造对应的GlobalTensor视图,先TASSIGN绑定片上地址,再通过TLOAD从全局内存加载数据:

#include <pto/pto-inst.hpp> using namespace pto; void example(__gm__ half* in, __gm__ half* out) { using TileT = ConvTile<TileType::Mat, half, 4096, Layout::NC1HWC0, pto::ConvTileShape<1, 1, 16, 16, 16>>; using GShape = Shape<1, 1, 16, 16, 16>; using GStride = Stride<1 * 16* 16* 16, 16* 16* 16, 16 * 16, 16, 1>; using GT = GlobalTensor<half, GShape, GStride, Layout::NC1HWC0>; GT gin(in); TileT tile5d; TASSIGN(tile5d, 0x0); TLOAD(tile5d, gin); }

几点说明:

  • TileTBufferSize_(4096)对应形状1*1*16*16*16 = 4096half元素,即该 Tile 的静态容量;bufferSize以元素个数计,最终占用的字节数需乘以sizeof(half)
  • GShape/GStride定义了全局内存视图的形状与各维 stride,GStride的第一个维度1*16*16*16表示 batch 维步长,逐维递减直至最内层1GlobalTensor的详细语义参见 GlobalTensor_zh.md。
  • TASSIGN(tile5d, 0x0)在手动模式下把 Tile 绑定到片上地址0x0(此处为演示,实际应结合上文容量表规划地址布局,避免越界与未对齐)。
  • TLOAD(tile5d, gin)完成 GM 到片上 Tile 的数据搬运;TSTORE则负责反向写回。两个指令的完整语义见 TLOAD.md 与 TSTORE.md。

与相关概念的衔接

  • Tile的关系ConvTile与通用二维Tile(见 Tile_zh.md)同属于 PTO 的片上缓冲抽象,共享TileTypeTASSIGN等机制;区别在于ConvTile面向卷积场景,支持最多 6 维形状并携带卷积元数据字段。
  • GlobalTensor的关系GlobalTensor是全局内存(GM)的轻量级视图,ConvTile通过TLOAD/TSTOREGlobalTensor之间交换数据(见 GlobalTensor_zh.md)。
  • 编程模型上下文:Auto/Manual 两种开发风格、SPMD/MPMD 执行模型等背景概念,可参考 ProgrammingModel_zh.md;抽象执行模型见 abstract-machine_zh.md。

进一步阅读

  • ConvTile 英文原版
  • PTO 卷积类指令总览:逐条指令的 TileType 合法性、布局要求与数据流语义
  • TASSIGN 指令详解:含全部编译期检查项与各架构容量表
  • include/pto/common/pto_tile.hpp:ConvTile/ConvTileShape/Shape/Stride完整实现
  • include/pto/common/type.hpp:Layout枚举全集
  • include/pto/common/constants.hpp:C0_SIZE_BYTEFRACTAL_NZ_ROWMX_ROW_LEN等布局常量

【免费下载链接】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),仅供参考

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

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

立即咨询