news 2026/9/20 6:18:02

PyPTO Pro 抽象硬件架构:AIV/AIC 计算资源、存储层级与数据同步全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PyPTO Pro 抽象硬件架构:AIV/AIC 计算资源、存储层级与数据同步全解析

PyPTO Pro 抽象硬件架构:AIV/AIC 计算资源、存储层级与数据同步全解析

【免费下载链接】pyptoPyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。项目地址: https://gitcode.com/cann/pypto

本文基于 PyPTO Pro 的 SIMD 编程范式,系统讲解 AI Core 的抽象硬件视图:AIV 的 Vector 资源与 AIC 的 Cube 资源、GM 与片上存储(UB、L1 Buffer、L0A/L0B/L0C Buffer)的层级关系,以及 Scalar 指令流、搬运/计算数据流与流水间同步的底层机制。读完本文,你将掌握选择 Tile 计算、Reg 计算或 Cube 计算的依据,并能据此正确组织数据搬运与同步,写出结构合理的 SIMD Kernel。

从抽象硬件架构理解三种 SIMD 计算方式

PyPTO Pro 的 SIMD(Single Instruction Multiple Data,单指令多数据)编程以数据块为基本编程对象,一条指令同时对多个同构数据元素执行相同操作。其底层计算资源分为两类:

  • AIV(Vector Core)上的 Vector 资源:执行矢量运算,是 Tile 矢量计算和 Reg 计算的执行资源;
  • AIC(Cube Core)上的 Cube 资源:执行矩阵运算,是 Cube 矩阵计算的执行资源。

理解这两类计算资源及其数据通路,是选择 Tile计算、Reg计算 或 Cube计算 的前提,也是正确组织数据搬运与同步的基础。SIMT 的线程执行资源属于另一套编程范式,参见 SIMT抽象硬件架构。

AI Core 的相关硬件可以从计算单元存储单元搬运单元三个方面理解。下图展示了 AIC、AIV 及其指令流和主要数据流的关系:

图中黑色实线表示主要数据流,橙色虚线表示指令流。图中的 SIMT 资源仅用于说明其在 AIV 中的位置,不属于本文讨论范围。

计算单元:Scalar、Vector 与 Cube 的分工

单元主要作用PyPTO Pro 计算方式
Scalar处理地址计算、循环控制等标量逻辑,向计算和搬运流水发射指令Kernel 中的控制逻辑
AIV 上的 Vector 单元执行矢量运算Tile计算、Reg计算
AIC 上的 Cube 单元执行矩阵运算Cube计算

三种计算方式在数据载体上存在本质差异:

  • Tile 计算以 UB 中的 Tile 为计算数据载体,通过pypto_pro.language.section_vector()执行域完成批量运算,适合逐元素、归约、数据类型转换和数据重排等通用矢量场景;
  • Reg 计算将 UB 中的数据加载到 Vector Register File,中间结果可以保留在寄存器中,适合计算链较长、需要减少 UB 往返访问的高性能场景;
  • Cube 计算从 L0A Buffer 和 L0B Buffer 读取矩阵操作数,将累加结果写入 L0C Buffer,通过一条矩阵指令并行完成一个矩阵分块的乘加运算。

各方式的接口和使用约束见对应的编程章节,本文从硬件视角解释其设计动机。

存储单元与搬运单元:数据在存储层级中的流转

GM 位于 AI Core 之外,用于保存 Kernel 输入、输出及 Workspace。AIV 和 AIC 各有片上存储,计算前需要将数据搬入相应的存储层级。不同执行侧的主要片上存储与典型数据路径如下:

执行侧主要片上存储典型数据路径
AIV Tile 计算UBGM → UB → Vector 单元 → UB → GM
AIV Reg 计算UB、Vector Register FileGM → UB → Vector Register File → UB → GM
AIC Cube 计算L1 Buffer、L0A Buffer、L0B Buffer、L0C BufferGM → L1 Buffer → L0A Buffer/L0B Buffer → Cube 单元 → L0C Buffer → GM

表中的路径表示一次计算所涉及的主要存储层级,不表示所有搬运和计算必须串行完成。Reg 计算的寄存器数据路径及硬件单元详见 Reg计算;AIC 各 Buffer 的作用、布局和搬运路径详见 Cube计算。

搬运单元:MTE 系列与 DMA

MTE(Memory Transfer Engine)等搬运单元负责 GM 与片上 Buffer 以及不同片上 Buffer 之间的数据流转,不同搬运路径由不同的搬运流水承担:

  • AIV 侧:GM 与 UB 之间的搬运主要使用MTE2(GM → UB)和MTE3(UB → GM);Reg 计算还使用DMA 单元在 UB 与 Vector Register File 之间搬运数据;
  • AIC 侧:矩阵数据通常经MTE2进入 L1 Buffer,再经MTE1进入 L0A Buffer、L0B Buffer;结果搬出由FIX流水负责。

从源码实现可以印证这种流水划分:framework/src/codegen/codegen_common.h中定义了完整的流水枚举PIPE_MTE1PIPE_MTE2PIPE_MTE3PIPE_V(Vector)、PIPE_M(矩阵)、PIPE_FIXPIPE_S(Scalar)等,并在PIPE_ID映射表中与"PIPE_MTE1""PIPE_MTE2""PIPE_MTE3"等字符串一一对应,代码生成阶段正是依据这些流水标识编排指令与同步。

具体接口及支持的搬运路径以 Tile创建和操作、Reg计算 和 Cube计算 为准。

存储层级的 PyPTO Pro 表达

PyPTO Pro 用不同的数据对象表示数据在存储层级中的位置,这一点在 SIMD编程范式 中有完整的对象-位置对应表:

数据对象数据位置作用
TensorGM描述 Kernel 输入、输出或 Workspace 中的多维数据视图
TileUB、L1 Buffer、L0A Buffer、L0B Buffer 和 L0C Buffer 等片上存储表示当前分块的数据,是 Tile 矢量计算和 Cube 计算的操作数
TileGroup与 Tile 相同管理一组轮转 Tile,用于单缓冲、双缓冲和 N 缓冲
RegTensor、MaskRegVector Register File保存 Reg 计算的输入、中间结果和输出

Tensor 表示全局数据,Tile 表示当前 AI Core 处理的局部数据块。开发者通过 Tiling 将大 Tensor 划分成多个 Tile,再由不同核和不同循环迭代处理这些 Tile。target_memory决定 Tile 绑定的物理缓冲区和可使用的数据路径,Tile创建和操作 中的MemorySpace枚举与 Buffer 的对应关系为:

pypto_pro.language.MemorySpace物理缓冲区典型用途
VecUB矢量数据的输入、输出和中间结果
MatL1 BufferGM 与 L0A Buffer/L0B Buffer 之间的矩阵暂存
LeftL0A Buffer矩阵乘左操作数
RightL0B Buffer矩阵乘右操作数
AccL0C Buffer矩阵乘累加结果
BiasBiasTable Buffer矩阵乘的融合偏置
ScalingFixpipe BufferFIX 数据通路的 per-channel 随路量化/反量化参数
ScaleLeftL0A_MX BufferMX 矩阵乘的左量化系数矩阵
ScaleRightL0B_MX BufferMX 矩阵乘的右量化系数矩阵

指令流、数据流与同步:源码顺序不等于硬件完成顺序

图 1 中的指令流与数据流含义不同:Scalar 将搬运和计算任务发射到相应流水;搬运单元和计算单元按各自的数据路径访问存储资源。不同流水可以异步执行,因此源码中的先后顺序不等同于硬件上的完成顺序——这是理解同步机制的核心前提。

当一条流水生产的数据要由另一条流水消费时,需要建立同步依赖。例如:

  • Vector 计算读取 UB 数据之前,相关搬入(MTE2)必须完成;
  • 将计算结果搬回 GM(MTE3)之前,相关 Vector 计算也必须完成。

需要强调的是,同步信号只约束执行顺序,不承担数据搬运。以 Cube 计算为例,四步操作分别对应 MTE2、MTE1、M、FIX 四条流水线,各自异步执行:

流水线含义典型操作
MTE2GM → L1 Buffer 搬运pypto_pro.language.load/pypto_pro.language.load_tile
MTE1L1 Buffer → L0A Buffer/L0B Buffer 搬运pypto_pro.language.move
M矩阵计算pypto_pro.language.matmul/pypto_pro.language.matmul_acc
FIXL0C Buffer → GM 搬运pypto_pro.language.store/pypto_pro.language.store_tile

同步的两种组织方式

PyPTO Pro 提供两种依赖管理方式:

  1. TileGroup 与自动 mutex:通过make_tile_group为每块 Tile 绑定mutex_id,配合@pypto_pro.language.jit(auto_mutex=True),框架根据 Tile 的使用关系和 mutex 元数据自动插入同步;
  2. 显式同步接口:使用pypto_pro.language.system.sync_src/pypto_pro.language.system.sync_dst成对指定生产流水与消费流水之间的依赖。

显式同步的典型用法是成对出现,sync_src由生产流水线 SET flag,sync_dst由消费流水线 WAIT flag,两者的set_pipewait_pipeevent_id必须一致。静态event_id取值范围为 [0, 7],动态整数 Scalar 的运行时数值也必须在该范围内;同一 ID 只能在上一次同步被消费后复用:

import pypto_pro.language as pl with pl.section_cube(): pl.load(a_l1, a, [0, 0]) pl.load(b_l1, b, [0, 0]) pl.system.sync_src( set_pipe=pl.PipeType.MTE2, wait_pipe=pl.PipeType.MTE1, event_id=0) pl.system.sync_dst( set_pipe=pl.PipeType.MTE2, wait_pipe=pl.PipeType.MTE1, event_id=0) pl.move(a_left, a_l1) pl.move(b_right, b_l1) pl.system.sync_src( set_pipe=pl.PipeType.MTE1, wait_pipe=pl.PipeType.M, event_id=1) pl.system.sync_dst( set_pipe=pl.PipeType.MTE1, wait_pipe=pl.PipeType.M, event_id=1) pl.matmul(acc, a_left, b_right) pl.system.sync_src( set_pipe=pl.PipeType.M, wait_pipe=pl.PipeType.FIX, event_id=2) pl.system.sync_dst( set_pipe=pl.PipeType.M, wait_pipe=pl.PipeType.FIX, event_id=2) pl.store(out, acc, [0, 0])

多核并行与执行域映射

多个 AIC 或 AIV 可以并行处理不同数据分片。核数配置、核索引以及混合 Kernel 中 AIC 与 AIV 的映射关系,参见 SIMD编程范式 中的“多核SPMD与核内SIMD”和 多核Tiling切分。

PyPTO Pro SIMD Kernel 采用"外层多核 SPMD + 内层单核 SIMD"的两级并行方式:Host 侧通过block_dim配置核数;Kernel 内使用pypto_pro.language.get_block_num()取得实际生效核数,使用pypto_pro.language.get_block_idx()取得当前执行域的核索引:

import pypto_pro.language as pl num_cores = pl.get_block_num() core_id = pl.get_block_idx() # 第core_id个核以num_cores为步长处理数据块。 for tile_idx in pl.range(core_id, tile_num, num_cores): ...

常用的跨步切分让各核处理的数据块数量最多相差 1,并避免由单个核串行遍历全部数据。block_dim的默认值、调用形式和不同 Kernel 类型下的含义参见 Kernel核函数。

按执行资源划分,SIMD Kernel 有三种类型:

Kernel 类型执行资源get_block_idx()的含义
纯 Vector KernelAIV当前 Vector 核的全局索引
纯 Cube KernelAIC当前 Cube 核的全局索引
Cube/Vector 混合 KernelAIC 和 AIV在各自执行域中返回相应的全局核索引

混合 Kernel 采用 AIC:AIV 为 1:2 的映射:每个 AI Core 执行组包含一个 AIC 和两个 AIV。当block_num = pypto_pro.language.get_block_num()时,Cube 执行域实际使用block_num个 AIC,Vector 执行域实际使用2 * block_num个 AIV。

从硬件视角回看三种计算方式的数据流

Tile 矢量计算:GM → UB → Vector → UB → GM

Tile 计算以 UB 中的二维 Tile 为计算对象,在section_vector()执行域中完成。一个完整算子的典型数据链路为:

Tensor → 数据搬入 → 输入Tile → Tile计算 → 输出Tile → 数据搬出 → Tensor

计算接口将结果写入预先准备的目的 Tile,不会创建或返回新的 Tile。例如:

import pypto_pro.language as pl with pl.section_vector(): pl.add(out_tile, lhs_tile, rhs_tile) pl.relu(out_tile, out_tile)

同一 Vector 计算流水上的相邻操作按依赖顺序执行,不需要在操作之间插入跨 Pipe 同步;Tile 在 MTE2、Vector 和 MTE3 等不同流水之间传递时,仍需通过基于 TileGroup mutex 元数据的自动同步或显式同步保证读写顺序。尾块(实际有效范围小于 Tile 物理 shape)场景需要在数据搬入前用pl.set_validshape设置有效区域,使随后的 load、计算和 store 使用同一有效区,避免越界读写。完整尾块示例可参考 Tile计算 的"二维加法的四类尾块"一节。

Reg 计算:GM → UB → Register File → UB → GM

Register File 位于 UB 之上,不能直接从 GM 加载或直接写回 GM。Reg 计算将一段连续计算保留在寄存器中,仅在计算链入口和出口与 UB 交互,通过@pypto_pro.language.vector_function定义 VF 函数,在函数内使用vf.*接口表达寄存器加载、计算和存储:

数据路径PyPTO Pro 表达
GM → UBpypto_pro.language.load/pypto_pro.language.load_tile
UB → Register Filevf.load/vf.load_align/vf.load_unalign
Register File 内计算vf.addvf.mulvf.reduce_sum
Register File → UBvf.store/vf.store_align/vf.store_unalign
UB → GMpypto_pro.language.store/pypto_pro.language.store_tile

参与 Reg 计算的硬件单元包括 Reg 矢量执行单元、DMA 单元(UB 与 Register File 之间搬运)和 Aux Scalar(VF 域内的地址、循环等标量计算)。GM ↔ UB 搬运与 Vector/VF 计算之间的跨 Pipe 依赖,由 TileGroup +auto_mutex=True自动管理,或使用sync_src/sync_dst手动管理。详见 Reg计算。

Cube 矩阵计算:GM → L1 → L0 → Cube → L0C → GM

Cube 矩阵计算的基本步骤为:创建 L1 Buffer、L0A Buffer、L0B Buffer 和 L0C Buffer → 将左、右矩阵从 GM 搬入 L1 Buffer → 将 L1 Buffer 数据搬入 L0A Buffer/L0B Buffer → 执行矩阵计算写入 L0C Buffer → 将结果写回 GM → 正确配置同步指令。这些步骤需要写在pypto_pro.language.section_cube()标记的 Cube 执行域中:

import pypto_pro.language as pl TILE_M = 128 TILE_K = 128 TILE_N = 128 # L1 Buffer使用双缓冲,L0 Buffer使用单缓冲,均由auto_mutex管理同步 a_l1 = pl.make_tile_group( type=pl.TileType(shape=[TILE_M, TILE_K], dtype=pl.DT_FP16, target_memory=pl.MemorySpace.Mat), addrs=0x00000, mutex_ids=[0, 1]) b_l1 = pl.make_tile_group( type=pl.TileType(shape=[TILE_K, TILE_N], dtype=pl.DT_FP16, target_memory=pl.MemorySpace.Mat), addrs=0x10000, mutex_ids=[2, 3]) a_left = pl.make_tile_group( type=pl.TileType(shape=[TILE_M, TILE_K], dtype=pl.DT_FP16, target_memory=pl.MemorySpace.Left), addrs=0x0000, mutex_ids=[4]) b_right = pl.make_tile_group( type=pl.TileType(shape=[TILE_K, TILE_N], dtype=pl.DT_FP16, target_memory=pl.MemorySpace.Right), addrs=0x0000, mutex_ids=[5]) acc = pl.make_tile_group( type=pl.TileType(shape=[TILE_M, TILE_N], dtype=pl.DT_FP32, target_memory=pl.MemorySpace.Acc), addrs=0x0000, mutex_ids=[6]) with pl.section_cube(): pl.load_tile(a_l1.next(), a, [0, 0]) pl.load_tile(b_l1.next(), b, [0, 0]) pl.move(a_left.current(), a_l1.current()) pl.move(b_right.current(), b_l1.current()) pl.matmul(acc.current(), a_left.current(), b_right.current()) pl.store_tile(out, acc.current(), [0, 0])

Cube 计算以分形(Fractal)为基本计算和搬运单位,load在搬运过程中自动完成 ND→NZ 格式转换,move自动完成 NZ→ZN(L0B Buffer)转换,store自动完成 NZ→ND 转换。矩阵分形、片上地址、数据搬运和计算接口的完整规则参见 Cube计算。

总结:硬件架构视角下的 Kernel 开发决策

抽象硬件架构最终落实到 SIMD Kernel 的开发流程中,可归纳为以下决策链:

  1. 确定计算方式:根据数据访问和计算特点选择 Tile 矢量(UB 载体)、Reg 矢量(Register File 载体)或 Cube 矩阵(L0/L1 Buffer 载体)计算;
  2. 设计多核与 Tile 切分:确定block_dim、各核的数据范围、Tile shape 和尾块处理方式;
  3. 声明 Tensor 参数:在 Kernel 签名中描述 GM 输入、输出和 Workspace 的数据类型、shape 及 layout;
  4. 规划片上数据:根据计算方式选择 Tile 所在的MemorySpace和数据排布(ND/NZ/ZN 等 layout、fractal、pad、compact);
  5. 编写执行域:在section_vector()section_cube()中表达相应的 SIMD 计算;
  6. 编译和启动:使用@pypto_pro.language.jit编译 Kernel,在 Host 侧通过kernelstream, block_dim启动。

核心要点回顾:

  • 指令流 ≠ 数据流:Scalar 发射任务,搬运/计算单元按各自数据路径异步执行,源码顺序不代表硬件完成顺序;
  • 数据跨越流水必须同步:同步只约束执行顺序、不搬运数据,推荐使用 TileGroup +auto_mutex=True,精确控制场景用sync_src/sync_dst
  • 片上存储是分级的:AIV 侧 GM→UB→Register File,AIC 侧 GM→L1→L0A/L0B→L0C,选择计算方式前先确认数据路径;
  • 多核映射有固定规则:纯 Vector/Cube 与混合 Kernel 的核索引语义不同,混合 Kernel 采用 AIC:AIV = 1:2 的执行组映射。

相关深入阅读:SIMD编程范式、Tile创建和操作、Tile计算、Reg计算、Cube计算、多核Tiling切分。

【免费下载链接】pyptoPyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。项目地址: https://gitcode.com/cann/pypto

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 6:14:58

TensorRT部署实战:YOLO转ONNX到推理加速的五大避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 6:09:20

自托管LibreChat:多模型AI对话聚合平台部署与配置指南

1. 为什么我最终选择了自托管LibreChat1.1 从“多平台来回切换”到“一个入口全搞定”的真实痛点我日常的工作流里,AI对话工具的使用频率非常高。写代码时要问技术方案,写文档时要润色措辞,查资料时要快速总结长文,偶尔还要用不同…

作者头像 李华
网站建设 2026/9/20 6:09:04

软件工程概论如何落地为DevOps自动化实践

简介:本资源是一份面向软件工程初学者与备考学生的系统性知识点梳理文档,聚焦解决软件开发中常见的概念混淆、知识碎片化与考试重点把握难等问题。文档以清晰逻辑串联软件危机成因、软件工程定义与核心目标,完整覆盖软件生命周期三时期&#…

作者头像 李华
网站建设 2026/9/20 6:07:20

LibreChat 自托管部署与多模型接入实战指南

1. 为什么我又把目光投回了 LibreChat第一次接触 LibreChat 是在一个自托管 AI 工具群里,有人丢了一张截图,界面左侧是会话列表,右侧是聊天窗口,顶部还能切换模型,底下挂着插件和文件上传按钮。当时我的第一反应是&…

作者头像 李华
网站建设 2026/9/20 6:07:04

Meteor check 包深度实战指南:轻量级参数校验与模式匹配

后端前端开发工具移动开发 【免费下载链接】meteor Meteor, the JavaScript App Platform 项目地址: https://gitcode.com/gh_mirrors/me/meteor 点击查看 免费下载 check 是 Meteor 平台内置的轻量级参数校验与通用模式匹配包,专门用于在 Meteor.publi…

作者头像 李华