FEATURED · 精选文章

PTO-ISA 集群 ID(CVID)映射深度解析:TPUSH/TPOP 环形缓冲在 A5 与 A2A3 平台的同步基石

发布时间 / 2026/9/19 23:39:43
来源 / 创域科博编辑部
栏目 / 资讯中心
PTO-ISA 集群 ID(CVID)映射深度解析:TPUSH/TPOP 环形缓冲在 A5 与 A2A3 平台的同步基石 PTO-ISA 集群 IDCVID映射深度解析TPUSH/TPOP 环形缓冲在 A5 与 A2A3 平台的同步基石【免费下载链接】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导读本文围绕 CANN pto-isa 中 docs/reference/pto-cvid-cluster-id-mapping.md 记载的集群 IDCluster IDCVID映射假设展开系统讲解 A5 与 A2A3 平台如何在 CubeAIC与 VectorAIV核心之间建立一致的集群标识为 TPUSH/TPOP 环形缓冲通信提供跨核同步基础。读完本文你将掌握何时应直接使用逻辑block_idx作为集群 ID、FFTS 信号量的分配与 mode2 广播/归约语义、硬件/AICPU 的集群绑定流程以及block_dim 核心数场景下基于物理核心 ID 的通用 CVID 计算与工作缓冲区预留方案并能在 include/pto/npu/a5/custom/TSyncCVID.hpp、include/pto/npu/a2a3/custom/TSyncCVID.hpp 等源码中找到一一对应的实现证据。概述为什么 TPUSH/TPOP 需要 CVIDTPUSH/TPOP 是 PTO-ISA 提供的跨核心Cross-Core生产者-消费者环形缓冲通信原语生产者把 Tile 推入环形缓冲区FIFO消费者从中弹出二者通过信号量完成数据就绪与槽位空闲的握手指令语义可参考 docs/isa/TPUSH.md 与 docs/isa/TPOP.md。要让这套机制在异构的 Cube Vector 集群上正确工作首先必须回答一个基础问题当前核心属于哪个逻辑集群这个集群标识即CVIDCluster ID。只有 Cube 与 Vector 核心对我是哪个集群达成一致双方才能访问同一段 GM 环形缓冲槽位、使用同一组 FFTS 信号量完成同步。本文档描述的正是这一映射假设A5 与 A2A3 平台各自如何确定 CVID推荐路径block_dim 核心数与通用备选路径block_dim 核心数SIMD 超额订阅的区别跨核同步FFTS 信号量与集群绑定硬件分配 / AICPU 握手的完整流程。推荐方法直接使用逻辑 Block ID 作为集群 ID当block_dim 核心数时最简单且推荐的做法是直接使用逻辑 block ID 作为集群 ID// 推荐使用逻辑 block_idx 作为 cluster_id int cluster_id get_block_idx(); // GM_SLOT_BUFFER 访问 my_gm_slot_buffer GM_SLOT_BUFFER_BASE cluster_id * PER_CLUSTER_SLOT_BUFFER_SIZE;为什么这种方法可行文档给出了四条理由背后各有明确的硬件/软件依据硬件分配 block_idxFFTS 块调度器在启动任务时分配block_idx值这是硬件提供的逻辑标识符软件无需自行生成1:1 映射当block_dim num_cores时每个逻辑块恰好映射到一个物理集群不存在超额订阅over-subscription因此逻辑 ID 与物理集群天然一一对应无需 GM 通信Cube 和 Vector 核心都可以直接使用get_block_idx()无需运行时协商也就消除了额外的全局内存往返与缓存一致性开销无需工作缓冲区预留不需要为 CVID 交换预留 12.5KB 的cv_comm_buf区域该区域仅在附录 A/B 描述的通用实现中需要。内核标识如何确定集群归属内核使用硬件提供的 ID 来识别自身集群归属与集群内的角色// 在 Cube (AIC) 上 int my_cluster get_block_idx(); // 在 Vector (AIV) 上 int my_cluster get_block_idx(); int my_aiv_idx get_subblockid(); // 0 或 1其中get_subblockid()返回当前 Vector 核心在集群内的 subblock 编号0 或 1用于区分同一个集群中的 AIV0 / AIV1。这一模式在 TPUSH/TPOP 的消费端源码中同样可见——例如 include/pto/npu/a5/TPop.hpp 的TPOP_IMPL在Split ! TILE_NO_SPLIT时使用get_subblockid()计算子块偏移include/pto/npu/a5/TPush.hpp 的TPUSH_IMPL也在分裂模式下将get_subblockid()传给 push 流程用于决定数据写入环形缓冲的哪个子区域。平台架构对比A5 与 A2A3CVID 映射策略的差异源于两大平台的架构差异方面A5A2A3架构紧耦合解耦集群绑定硬件固定 1:2 映射任务调度器绑定同步机制SET 块内同步通过 FFTS 的 SET 跨核同步本地数据通路L0C↔UB, UB↔L1 直连通过 GM 中转A51:2 的 Cube-Vector 集群关系由硬件固定L0C↔UB、UB↔L1 存在本地直连数据通路集群内同步开销低A2A3集群由任务调度器绑定核心间本地数据通路有限跨核数据通常需要经 GM 中转同步依赖 FFTS。这一差异直接决定了两种 CVID 计算路径A5 可从物理核心 ID 纯函数推导见附录 A而 A2A3 在通用场景需要借助 GM 交换。跨核同步机制FFTS 信号量 ID每个集群拥有16 个信号量 IDID 0-15可通过set_cross_core与wait_flag_dev完成跨核同步集群信号量资源 --------------------------------------------------------------- | 每集群 16 个信号量 IDID 0-15 | | | | 每个 ID 有一个 4 位信号量值0-15 | | 每个信号量可控制 0-15 个 FIFO 槽位 | | | ---------------------------------------------------------------从源码看PTO 还从这 16 个 ID 中为 Cube-Vector 通信预留了系统保留事件号两份 TSyncCVID.hpp 中定义了enum CVCommFftsEvent其中CV_COMM_CTRL 12CV_COMM_RSVD_13/14/15为保留位即 12-15 四个 ID 专用于 CV 通信控制。TPUSH/TPOP 信号量分配TPUSH/TPOP 使用4 个信号量 ID完成双向 Cube-Vector 通信ID方向用途0C→VCube 通知 Vector 数据就绪1C→VVector 通知 Cube 槽位空闲2V→CVector 通知 Cube 数据就绪3V→CCube 通知 Vector 槽位空闲在 include/pto/npu/a5/TPush.hpp 的TPipe模板中可以看到这一分配的实现模板参数FlagID是生产者使用的信号量起始 ID其内部通过FlagIDPlusOne FlagID 1、FlagIDPlusTwo FlagID 2、FlagIDPlusThree FlagID 3推导出消费者确认/释放用的其余三个信号量并且用static_assert(FlagIDPlusOne MAX_SYC_ID, ...)与FlagIDPlusThree MAX_SYC_ID强约束双向通信时 FlagID3 必须小于 15硬件上限与文档每集群 16 个信号量 ID完全对应。信号量操作// 生产者通知数据就绪信号量加 1 // pipe: VEC, MTE, CUBE, 或 FIX避免 SU 屏障 // 使用 mode2 用于 1:2 集群配置 set_cross_core(pipe, semaphore_id); // 消费者等待数据信号量减 1若为 0 则阻塞 wait_flag_dev(semaphore_id);约束增量始终为1不可配置必须指定pipeVEC/MTE/CUBE/FIX以避免 SUScalar Unit屏障停顿使用mode2用于 1:2 集群配置。源码中可以看到更细粒度的体现TPipe 的 Producer 与 Consumer 内部使用set_intra_block/wait_intra_block如 include/pto/npu/a5/TPush.hpp 的record()并根据方向选择不同的 pipe——C2V 场景在 Cube 侧走PIPE_FIXV2C 场景在 Vector 侧走PIPE_MTE3GM 方向或PIPE_S控制方向消费端wait()则按方向分别走PIPE_V、PIPE_MTE1、PIPE_MTE2等include/pto/npu/a5/TPush.hpp。这正是文档所述必须指定 pipe 以避免 SU 屏障停顿的落地实现。Mode2 语义1:2 配置在 1:2 集群配置下set_cross_core与wait_flag_dev具有特殊的广播/归约语义方向操作语义C→Vset_cross_core广播Block 为两个 subblockAIV0 AIV1设置信号量C→Vwait_flag_dev每个 Vector 核心独立等待V→Cset_cross_core每个 Vector 核心设置自己的信号量V→Cwait_flag_dev归约Cube 等待两个Vector subblock 都设置完成C→V 广播Cube 发出 set_cross_core AIC ──set──┬── AIV0 信号量 └── AIV1 信号量 V→C 归约Cube 上的 wait_flag_dev AIV0 ──set──┐ ├── AIC 等待两者完成 AIV1 ──set──┘这确保了 1:2 Cube-Vector 集群拓扑的正确同步无需向每个 Vector 核心单独发信号。在 include/pto/npu/a5/TPush.hpp 中可以看到对应实现setIntraBlockBySplit/waitIntraBlockBySplit在Split ! TILE_NO_SPLIT时会额外对flagId VEC_CORE_ID_OFFSET其中VEC_CORE_ID_OFFSET 16再执行一次 set/wait即 Cube 侧需要同时看到 AIV0flagId与 AIV1flagId16两个子块的信号——这正是 V→C 归约语义、以及 16 个信号量 ID 之上用偏移扩展子块编号的硬件约定。4 位信号量范围每个信号量 ID 有一个4 位计数器值 0-15限制了最大未完成的 FIFO 槽位数信号量值范围0-15 - 值 0无可用槽位消费者在 wait_flag_dev 上阻塞 - 值 1-15有 N 个槽位可用 - 最大未完成槽位数每个方向 15 个这与环形缓冲设计相匹配每个方向最多可有8 个槽位远在 15 槽位信号量限制之内因此在满负荷流水下也不会出现信号量计数溢出。集群绑定流程硬件 Block/Subblock 分配block_idx与subblock_id由硬件FFTS 块调度器分配而非软件。当 FFTS 启动混合内核mixed kernel时它创建具有 1:2 block-subblock 关系的逻辑集群FFTS 混合内核启动 --------------------------------------------------------------------- | FFTS 块调度器硬件 | | | | 分配每核心的 block_idx、subblock_id | | 创建每集群 1 个 block 2 个 subblock1:2 比例 | | | | ------------------- ------------------- | | | 集群 0 | | 集群 1 | ... | | | block_idx0 | | block_idx1 | | | | AIC (block) | | AIC (block) | | | | AIV0 (subblk 0) | | AIV0 (subblk 0) | | | | AIV1 (subblk 1) | | AIV1 (subblk 1) | | | ------------------- ------------------- | | | ---------------------------------------------------------------------AICPU 握手进行核心映射当 AICPU 需要在集群上启动运行时它必须通过与硬件调度器的握手来获取核心到 block/subblock 的映射而不是自行分配这些 IDAICPU 运行时启动 --------------------------------------------------------------------- | AICPU | | | | 1. 向硬件调度器请求集群分配 | | 2. 接收映射physical_core_id - (block_idx, subblock_id) | | 3. 为跨核同步初始化 ffts_addr | | 4. 在分配的核心上启动运行时使用一致的 block_idx | | | --------------------------------------------------------------------- | | 握手 v --------------------------------------------------------------------- | FFTS / 硬件调度器 | | | | 提供物理核心的 block_idx、subblock_id 分配 | | 确保与内核启动相同的 1:2 集群结构 | | | ---------------------------------------------------------------------这确保 TPUSH/TPOP 环形缓冲操作无论通过 FFTS 直接启动还是通过 AICPU 运行时启动都能在一致的集群视图下正确工作。A3 ffts_addr 初始化在 A3 上必须在 AICPU 握手过程中初始化ffts_addr以启用通过set_cross_core与wait_flag_dev的跨核同步ffts_addrFFTS 信号量寄存器的基地址初始化时机必须在任何跨核同步操作之前完成作用域每集群一个由集群中所有核心AIC AIV0 AIV1共享。此初始化是 AICPU 握手上述步骤 3的一部分确保信号量 ID0-15正确映射到所分配集群的硬件寄存器。A3 FFTS 调度器与逻辑集群设置当前 TPUSH/TPOP 实现依赖A3 的 TPUSH/TPOP 实现依赖FFTS 跨核同步能力。在混合内核启动mixed kernel kickstart期间FFTS 硬件通过块调度器建立逻辑集群。逻辑到物理核心映射FFTS 硬件在任务启动时建立逻辑到物理核心的映射Block ID → 物理 Cube 核心块调度器为每个逻辑块分配一个物理 AIC 核心Subblock ID → 物理 Vector 核心每个 subblock0, 1映射到一个物理 AIV 核心该 AIV 成为已分配 Cube 的伙伴buddy核心集群内同步解析FFTS 硬件根据此映射解析所有集群内同步与通信路径。从源码结构看TPUSH/TPOP 的测试覆盖了与该映射相关的多种拓扑例如 tests/npu/a5/src/st/testcase/tpushpop_subblock_dispatch/tpushpop_subblock_dispatch_kernel.cpp 专门验证 subblock 分发路径tests/npu/a5/src/st/testcase/tpushpop_cv/tpushpop_cv_kernel.cpp 与 tests/npu/a2a3/src/st/testcase/tpushpop_cv/tpushpop_cv_kernel.cpp 分别在 A5 与 A2A3 上验证 Cube→Vector 双向通信可作为理解集群映射行为的参考用例。附录 A基于通用核心 ID 的 CVID 计算注意本附录描述用于block_dim num_coresSIMD 模式的通用实现。不推荐用于带有 MPMD AICPU 运行时的 PyPTO——请使用主文档中描述的逻辑block_idx方法。常量参考常量A5 值A2A3 值描述CORE_PER_DIE1825每 die 的集群数AIV_RATIO22每 Cube 的 Vector 核心数AIC_AIV_PER_DIE5475每 die 的总核心数AIC AIVSEMAPHORE_IDS1616每集群的信号量 ID 数TPUSH_TPOP_SEMA_IDS44用于 CV 双向通信的 ID 数SEMA_BITS44每信号量的位数0-15 槽位CV_MAX_CORES3625支持的最大集群数上述常量可在源码中逐一印证两份 TSyncCVID.hpp 中kCvCommSlotBytes 512、kCvMaxCores 25A5 侧#define CORE_PER_DIE 18、#define AIV_RATIO 2、#define AIC_AIV_PER_DIE (CORE_PER_DIE * (AIV_RATIO 1))即 54与文档表格一致而TSYNC_CVID本身是模板函数template int CV_COMM_SLOT_BYTES kCvCommSlotBytes, int CV_MAX_CORES kCvMaxCores允许按需覆盖槽位大小与最大集群数这也解释了为什么 A5 在表格中CV_MAX_CORES记为 36 而源码默认值为 25——模板参数可由调用方按平台规模调整。本节记录从物理核心 ID 计算集群 ID 的通用实现作为block_dim num_coresSIMD 超额订阅场景或直接 block_idx 映射不可用时的备选方案。通用实现代码对应仓库文件A5include/pto/npu/a5/custom/TSyncCVID.hppA2A3include/pto/npu/a2a3/custom/TSyncCVID.hppA5直接核心 ID 计算在 A5 上每个 die 包含18 个核心集群具有固定的 1:2 架构。集群 ID 直接从物理核心 ID 计算// A5 TSYNC_CVID 实现通用 #ifdef PTO_COMPILE_CUBE int die_id get_coreid() / AIC_AIV_PER_DIE; // AIC_AIV_PER_DIE 54 comm_slot die_id * CORE_PER_DIE get_coreid() % AIC_AIV_PER_DIE; #elif defined(PTO_COMPILE_VEC) int die_id get_coreid() / AIC_AIV_PER_DIE; comm_slot die_id * CORE_PER_DIE (((get_coreid() % AIC_AIV_PER_DIE) - CORE_PER_DIE - get_subblockid()) / AIV_RATIO); #endif注源码实际宏名为PTO_COMPILE_CUBE/PTO_COMPILE_VEC含义与文档中的__DAV_CUBE__/__DAV_VEC__一致见 include/pto/npu/a5/custom/TSyncCVID.hpp。关键特性无需运行时通信CVID 完全由核心 ID 推导确定性映射核心 ID → 集群 ID 是纯函数硬件强制 1:2 关系每个集群内存在 L0C↔UB 和 UB↔L1 本地数据通路。该文件还包含一个便于调试的_DEBUG分支Cube 侧打印Core %d Cube Block %d, comm_slot %dVector 侧打印Core %d Vec Block %d, SubBlock %d, comm_slot %d可用于核对不同核心上推导出的comm_slot是否一致。A2A3通过 GM 交换核心 ID通用在 A2A3 上使用通用实现时集群 ID 通过 GM 在 Cube 与 Vector 核心之间交换// A2A3 TSYNC_CVID 实现通用 #ifdef PTO_COMPILE_CUBE // Cube 核心将其核心 ID 写入 GM 槽位 comm_slot static_castint(get_coreid() 0x7f); comm_slot % CV_MAX_CORES; // 写入 GM 槽位并刷新缓存 __gm__ volatile uint32_t *comm_slot_ptr reinterpret_cast__gm__ volatile uint32_t *( cv_comm_buf static_caststd::size_t(block_idx) * CV_COMM_SLOT_BYTES); comm_slot_ptr[0] static_castuint32_t(comm_slot); dcci(comm_slot_ptr, cache_line_t::SINGLE_CACHE_LINE); dsb(DSB_DDR); // 通过 FFTS 向 Vector 核心发信号 ffts_cross_core_sync(PIPE_MTE2, _getFFTSMsg(CV_CORE_SYNC, CV_COMM_CTRL)); #elif defined(PTO_COMPILE_VEC) // Vector 核心等待 Cube 的信号然后从 GM 读取集群 ID __gm__ volatile uint32_t *comm_slot_ptr reinterpret_cast__gm__ volatile uint32_t *( cv_comm_buf static_caststd::size_t(block_idx) * CV_COMM_SLOT_BYTES); dcci(comm_slot_ptr, cache_line_t::SINGLE_CACHE_LINE); wait_flag_dev(CV_COMM_CTRL); comm_slot static_castint(comm_slot_ptr[0]); #endif源码include/pto/npu/a2a3/custom/TSyncCVID.hpp还给出了两点文档之外的关键细节Cube 侧先PTO_ASSERT(cv_comm_buf ! nullptr, ...)明确启用 CV 通信时 Cube 核心上cv_comm_buf必须非空防止未预留工作缓冲区时越界访问Vector 侧带static_assert(CV_MAX_CORES 0, ...)在编译期保证取模运算安全。通信流程为Cube 写核心 ID →dcci使缓存行失效 →dsb(DSB_DDR)刷写 DDR →ffts_cross_core_sync通过 FFTS 通知 Vector → Vectorwait_flag_dev等待 → 读取 GM 槽位拿到 CVID。这一GM 写 FFTS 通知的组合正是附录 B 需要预留工作缓冲区的原因。附录 BA2A3 工作缓冲区预留通用实现使用基于通用核心 ID 的 CVID 计算附录 A时A2A3 需要在工作缓冲区底部预留一个区域用于cv_comm_buf槽位。这是block_dim num_coresSIMD 超额订阅场景所需的。预留空间计算CV_COMM_SLOT_BYTES 512 字节每 block512B 对齐 CV_MAX_CORES 25最大 block_dim 预留空间 CV_COMM_SLOT_BYTES * CV_MAX_CORES 512 * 25 12,800 字节 12.5 KB向上取整到 16KB 以对齐注意使用推荐的block_idx作为集群 ID 方法当block_dim num_cores时不需要此预留。这与推荐方法一节中无需工作缓冲区预留的理由相互印证。内存布局仅通用实现A2A3 工作缓冲区 (GM) - 仅通用实现 ------------------------------------------------------------------ | 底部 12.5KB为 cv_comm_buf 预留CVID 协商 | | | | ----------------------------------------------------- | | | block_idx0| block_idx1| block_idx2| ... | block_idx24| | | | 512B | 512B | 512B | | 512B | | | ----------------------------------------------------- | | | ------------------------------------------------------------------ | 剩余空间可用于 GM_SLOT_BUFFER、任务数据等 | ------------------------------------------------------------------每个block_idx占用 512 字节槽位共支持 25 个 blockCV_MAX_CORES 25与附录 A 中 A2A3 的最大集群数一致。A5无需工作缓冲区预留在 A5 上CVID 直接从get_coreid()计算无需任何 GM 通信。因此无论block_dim如何A5都不需要工作缓冲区预留这是 A5 紧耦合架构带来的显著优势。常量仅通用实现常量A5 值A2A3 值描述CV_COMM_SLOT_BYTES512512每 block 通信槽位字节数CV_COMM_RESERVED012.5KB工作缓冲区预留总结CVID集群 ID映射是 TPUSH/TPOP 跨核环形缓冲通信的基石。本文完整梳理了 pto-isa 在该问题上的分层设计推荐路径block_dim 核心数时直接用硬件分配的get_block_idx()作为集群 ID零通信开销、无需预留缓冲区同步机制每集群 16 个 4 位信号量 IDTPUSH/TPOP 使用其中 4 个完成双向握手mode2 语义下 C→V 广播、V→C 归约配合 pipe 参数避免 SU 屏障停顿绑定流程block/subblock 由 FFTS 硬件分配AICPU 运行时通过握手获取映射并初始化ffts_addr通用备选block_dim 核心数SIMD 超额订阅时A5 从核心 ID 纯函数推导 CVIDA2A3 则需经 GM 交换并在工作缓冲区底部预留 12.5KBcv_comm_buf。相关实现与测试均可直接在仓库中查阅include/pto/npu/a5/custom/TSyncCVID.hpp、include/pto/npu/a2a3/custom/TSyncCVID.hpp、include/pto/npu/a5/TPush.hpp、include/pto/npu/a5/TPop.hpp以及 A5/A2A3 下的tpushpop_cv、tpushpop_subblock_dispatch等测试用例。【免费下载链接】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),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻