
PTO-ISA 跨核同步屏障 SYNCALL 实战指南Hard/Soft 双路径原理、接口详解与使用约束【免费下载链接】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导读SYNCALL是 CANN PTO-ISAParallel Tile Operation Instruction Set Architecture并行 Tile 操作虚拟指令集中的跨核控制面同步原语用于让多个计算核AIV/AIC在指定汇合点完成 barrier 后再继续执行。它不描述任何单 Tile 上的数据变换而是解决多核协同计算中谁先到、谁等谁、何时放行的核心同步问题。读完本文你将掌握SYNCALL的数学语义、两个模板参数SyncCoreType/SyncAllMode的组合用法、HardFFTS 硬件旗标与 SoftGM 共享原子计数器两条实现路径的底层原理、参数gmWorkspace与usedCores的正确配置以及从官方文档与源码实现中提炼出的全部使用约束可直接指导你在 A2/A3、A5 等平台上的多核 kernel 开发与排障。一、指令定位跨核控制面原语在 PTO 指令体系中绝大多数指令如TADD、TMATMUL、TSTORE等描述的是单个 Tile 上的数据变换或搬运属于数据面原语。SYNCALL则属于控制面原语——它不在任何 Tile 上产生数据变换其语义是全体参与者在同一点汇合后再前进rendezvous barrier。这一点在文档中有明确说明仓库也未提供SYNCALL.svg指令示意图因为跨核同步描述的是核间时序关系而非数据流。从实现文件布局上也能印证这一控制面定位include/pto/npu/a5/SyncAll.hpp、include/pto/npu/a2a3/SyncAll.hpp、include/pto/npu/a6/SyncAll.hpp与TSync.hpp、syncall_soft.hpp等同步基础设施放在一起而不与数据运算指令同文件CPU 仿真侧则提供了兼容性存根实现见include/pto/common/cpu_stub.hpp。两条实现路径总览路径机制是否需要 workspace适用平台Hard硬件模式FFTS 跨核硬件旗标ffts_cross_core_syncwait_flag_dev否无参重载A2/A3、A5、A6Soft软件模式GM 共享原子计数器arrive poll是gmWorkspaceA2/A3、A5两者的 barrier 语义完全相同仅实现路径不同。文档给出的流程图如下二、数学语义barrier 到达关系SYNCALL不适用逐元素算术语义它表达的是barrier 到达arrival关系属于当前参与者集合的每个 core 都执行过该SYNCALL之后任一 core 方可继续。Hard 与 Soft 的语义完全相同区别仅在于实现路径。需要特别强调这是一个到达计数语义不隐含任何数据可见性保证——屏障前后的跨核读写可见性需要调用方自行通过缓存维护指令dcci/dsb保证详见下文约束一节。三、C 内建接口与模板参数SYNCALL是 PTO 的 C 内建指令公共头文件为pto/pto-inst.hpp声明位于include/pto/common/pto_instr.hpp// 硬件模式所有 CoreType 通用 template SyncCoreType CoreType SyncCoreType::AIVOnly PTO_INST void SYNCALL(); // 软件模式 — GM 共享原子计数器 template SyncAllMode Mode, SyncCoreType CoreType SyncCoreType::AIVOnly, typename GlobalData, std::enable_if_tis_global_data_vGlobalData, int 0 PTO_INST void SYNCALL(GlobalData gmWorkspace, int32_t usedCores 0);两个模板参数各自独立共同决定同步行为3.1SyncCoreType选择参与者集合枚举定义见include/pto/common/type.hpp取值参与者集合说明SyncCoreType::AIVOnly默认仅 AIV向量核最常见的用法SyncCoreType::AICOnly仅 AICCube/矩阵核用于纯矩阵计算核同步SyncCoreType::MixAIC AIVAIC 与其配对的 AIV 核共同汇合3.2SyncAllMode选择实现路径取值实现路径携带的重载SyncAllMode::HardFFTS 硬件旗标无 workspace 重载SyncAllMode::SoftGM 共享原子计数器带 workspace 重载当Mode为Hard时gmWorkspace与usedCores会被忽略行为等同无参SYNCALL()。这在pto_instr.hpp的实现中可以看到if constexpr (Mode SyncAllMode::Hard)分支直接将两个参数(void)掉并转发到SYNCALL_IMPLCoreType()。3.3 后端可用性从pto_instr.hpp的源码可以看出SYNCALL目前仅对PTO_NPU_ARCH_A2A3、PTO_NPU_ARCH_A5以及__CPU_SIM三种构建后端开放其他后端会触发PTO_STATIC_ASSERT(CoreType ! CoreType, SYNCALL is not supported on this backend.)的编译期断言。A6 平台同样提供了SyncAll.hpp实现。因此在使用前需要确认目标 kernel 的编译宏属于上述架构之一。四、参数详解4.1gmWorkspaceSoft 模式类型GlobalTensorint32_t, pto::Shape, pto::Stride即一块 GMGlobal Memory缓冲。用途指令只用它的首个 int32作为全体参与者共享的到达计数器。分配建议分配一条 cache line64 字节16 个 int32即可且该 line 不得与任何业务数据共享。这一约束在源码中有明确量化——include/pto/common/type.hpp中定义了SYNCALL_SOFT_WORKSPACE_INT32 16注释解释了原因Soft 计数器通过dcci发布dcci会整行写回 64 字节 cache line因此 workspace 必须独占整条 line。测试代码tests/npu/a5/src/st/testcase/syncall/syncall_soft_kernel.cpp中的kInt32PerCacheLine 8也体现了按 cache line 划分旗标槽位的惯例。初始化首次使用前必须清零每个参与者到达时加一若残留旧值会导致计数错乱。4.2usedCores参与同步的核数为 0 时默认由指令自动推算AIV-only 与 AIC-only取本次 launch 的核数对应实现中的get_block_num()MIX取全部 AIC 核与其配对 AIV 核之和。显式指定时可以小于 launch 核数即只让部分核参与同步此时未参与的核不得调用SYNCALL否则会造成计数错乱或死锁。在实现层面usedCores为 0 时的自动推算逻辑体现在include/pto/common/syncall_soft.hppconst int32_t totalBlocks (usedCores ! 0) ? usedCores : SYNCALL_GET_MIX_PARTICIPANT_COUNT();对于 MIX 场景参与者数量通过 AIC 核数乘以(1 AIV 配比)计算PTO_INTERNAL int32_t SYNCALL_GET_MIX_PARTICIPANT_COUNT() { return static_castint32_t(SYNCALL_GET_MIX_AIC_BLOCKS() * (1 SYNCALL_GET_MIX_AIV_RATIO())); }其中 AIV 配比优先取编译期宏__MIX_CORE_AIV_RATIO__它声明的正是 launch 实际使用的配比cube 侧无法通过get_subblockdim()获知其次在 vec 编译路径下回退到get_subblockdim()最后回退为 1见syncall_soft.hpp。五、实现原理从源码看 Hard 与 Soft 的底层路径5.1 Hard 模式FFTS 跨核硬件旗标Hard 模式的实现位于各架构的SyncAll.hpp中核心是ffts_cross_core_sync发起跨核同步、wait_flag_dev等待旗标置位。以include/pto/npu/a5/SyncAll.hpp为例template SyncCoreType CoreType SyncCoreType::AIVOnly PTO_INTERNAL void SYNCALL_IMPL() { pipe_barrier(PIPE_ALL); if constexpr (CoreType SyncCoreType::AIVOnly) { ffts_cross_core_sync(PIPE_MTE3, getFFTSMsg(0x0, SYNC_AIV_ONLY_ALL)); wait_flag_dev(PIPE_S, SYNC_AIV_ONLY_ALL); } else if constexpr (CoreType SyncCoreType::AICOnly) { ffts_cross_core_sync(PIPE_FIX, getFFTSMsg(0x0, SYNC_AIC_FLAG)); wait_flag_dev(PIPE_S, SYNC_AIC_FLAG); } // Mix 分支AIC 侧 wait_intra_block 等待 AIV 旗标后发起 FFTS再 set_intra_block 放行配对 AIV ... }关键点每次SYNCALL都先执行pipe_barrier(PIPE_ALL)确保本核前序流水含数据搬运在发起同步前已完成本核内的执行getFFTSMsg将 mode 与 eventId 打包成 FFTS 消息字flag ID 定义在include/pto/common/type.hppSYNC_AIC_FLAG 11、SYNC_AIV_FLAG 12、SYNC_AIC_AIV_FLAG 13、SYNC_AIV_ONLY_ALL 14MIX 模式下 AIC 与 AIV 通过wait_intra_block/set_intra_block完成块内配对同步再借助 FFTS 完成跨核汇聚A2/A3 与 A5/A6 在具体 flag 收发细节上略有差异但整体模式一致。5.2 Soft 模式GM 共享原子计数器epoch barrierSoft 模式是纯软件实现的轮次屏障epoch barrier核心代码在include/pto/common/syncall_soft.hppPTO_INTERNAL void SYNCALL_SOFT_ATOMIC_BARRIER(__gm__ int32_t* gmWorkspace, int32_t totalBlocks) { dsb(DSB_DDR); const int32_t before SYNCALL_SOFT_ARRIVE(gmWorkspace); // 到达原子加一返回旧值 const int32_t target (before / totalBlocks 1) * totalBlocks; // 由旧值推算本轮放行目标 SYNCALL_SOFT_POLL(gmWorkspace, target); // 轮询等待计数达到目标 dsb(DSB_DDR); }算法要点到达arrive每个参与者对共享计数器做一次原子加一并取回加一前的旧值before推算本轮放行条件target (before / totalBlocks 1) * totalBlocks即本组轮内最后一个参与者到达后的总计数。这正是文档所说指令按到达次数推算当前是第几轮的实现轮询poll循环读取计数器直到 target。轮询带超时保护——SYNCALL_SOFT_MAX_POLL_ITERATIONS 1000000超时后触发PTO_CPU_ASSERT(false, SYNCALL soft barrier timeout - possible deadlock)方便在死锁时快速定位见syncall_soft.hpp。原子操作的原语因架构而异见syncall_soft.hpp的注释与实现A5直接用atomicAdd(counter, 1)到达、atomicAdd(counter, 0)轮询读取A2/A3硬件标量原子加路径通过set_st_atomic_cfg(ATOMIC_S32, ATOMIC_SUM)配置、st_atomicint32_t(1, counter)执行原子加并围绕原子操作做dcci写回/失效 cache line与dsb(DSB_DDR)内存屏障以dcci写回作为原子发布点。usedCores为 0 时的自动推算、以及 MIX 配比宏的优先级同样在本文件中实现见 4.2 节。而__PTO_AUTO__auto 构建路径下Soft 实现整体被#ifndef __PTO_AUTO__屏蔽SYNCALL成为 no-op见pto_instr.hpp。六、使用约束必须逐条遵守以下约束来自官方文档并可在源码中得到印证是多核 kernel 使用SYNCALL时最容易踩坑、也最需要重视的部分6.1 只保证到达不保证数据可见性SYNCALL只保证 barrier到达这一件事业务数据的顺序与可见性都要调用方自己负责它不参与 PTO 的 Event 自动依赖编排——不接受WaitEvents也不返回RecordEvent。对比TADD、TSTORE等数据面指令见pto_instr.hpp这些指令都会先detail::PtoWaitEvents(events...)再执行并返回RecordEvent而SYNCALL的签名中没有任何 Event 参数它不会等待本核前序数据指令如TSTORE落地Hard 与 Soft都不刷业务数据的 cache因此 barrier 前后的跨核 GM 读写需要自行执行dcci数据 cache 失效/写回与dsb数据同步屏障。这一点在测试用例中有直接体现tests/npu/a5/src/st/testcase/syncall/syncall_soft_kernel.cpp中参与者写入 GM 旗标后、跨核读取对方旗标前都显式调用了InvalidateInt32Lines内含dccidsb以此验证barrier 之外必须靠缓存维护指令保证可见性的语义。该测试还覆盖了多轮 barrier连续 3 次SYNCALLSyncAllMode::Soft下各核按轮次推进的正确性。6.2 Soft 模式相同顺序、相同次数进入同一组 barrierSoft 模式要求所有参与的核以相同顺序、相同次数进入同一组 barrier。因为指令按到达次数推算轮次target (before / totalBlocks 1) * totalBlocks某个核多进或少进一次就会与其他核错轮进而卡死最终触发 6.1 节提到的超时断言。6.3 参与者集合由编译与启动方式决定参与者集合由 kernel 的编译与启动方式决定不由SYNCALL决定。模板参数只是声明本次要同步哪一类核实际拉起多少核、AIC 与 AIV 如何配对取决于 kernel 编译成哪种 arch、以什么方式启动。两者对不上就会一直有核在等待hang。6.4 A2/A3 的 Hard AIC-only 编译限制A2/A3的 Hard AIC-only不能编译成纯 cube kernel纯dav-c220-cube建立不起 AIC-only 硬同步所需的 FFTS 上下文实测会 hang。须按 MIX 编译dav-c220AIC 侧调用SYNCALLSyncCoreType::AICOnly()AIV 侧留空A5用dav-c310-cube即可。6.5 手工编译时必须声明 kernel meta手工编译 kernel不走 chevron 自动拆分时必须自行声明 kernel meta否则 runtime 会按错误的核型调度硬同步拿不到 FFTS 上下文而 hang。meta 用include/pto/common/kernel_meta.hpp中的宏声明PTO_SYNCALL_AIV_KERNEL_META(kernelName)声明为 MIX AIV 主核PTO_META_K_TYPE_MIX_AIV_MAIN配比 0:1PTO_SYNCALL_AIC_KERNEL_META(kernelName)声明为 AIC-onlyPTO_META_K_TYPE_AIC_ONLY配比 1:0PTO_SYNCALL_MIX_AIC_KERNEL_META(kernelName, aicRatio, aivRatio)声明为 MIX AIC 主核并显式给出 AIC/AIV 配比。宏参必须与__global__入口符号完全一致宏通过__attribute__((used, section(.ascend.meta. #kernelName)))把 meta 挂到以 kernel 名命名的 section 上。当前仅 A2/A3 的Hard AIV-only与Soft AIC-only需要手写 meta其余场景由编译器生成。6.6 auto 构建路径下为 no-op在 auto 构建路径__PTO_AUTO__下SYNCALL为no-opHard 与 Soft 均被#ifndef __PTO_AUTO__屏蔽真实同步只在 manual kernel 中发生。这意味着依赖SYNCALL保证正确性的代码不能期望 auto 模式提供同步。6.7 CPU_SIM 下为兼容性空操作在 CPU 仿真__CPU_SIM中所有SYNCALL重载当前都是兼容性空操作包括 Soft 模式不会同步由LaunchKernelMultiCore启动的工作线程。多核同步行为需要在真实 NPU 环境验证。七、代码示例7.1 硬件模式#include pto/pto-inst.hpp using namespace pto; void example_hard_aiv() { SYNCALL(); } // 全 AIV 核 void example_hard_aic() { SYNCALLSyncCoreType::AICOnly(); } // 全 AIC 核 void example_hard_mix() { SYNCALLSyncCoreType::Mix(); } // AIC AIV编译与启动方面的要求见上文约束一节尤其 6.4、6.5。7.2 软件模式#include pto/pto-inst.hpp using namespace pto; // AIV-onlyusedCores0 自动取 get_block_num() void example_soft_aiv(__gm__ int32_t *gmPtr) { GlobalTensorint32_t, pto::Shape, pto::Stride gmWs(gmPtr); SYNCALLSyncAllMode::Soft, SyncCoreType::AIVOnly(gmWs, 0); } // MIXAIC 与 AIV 参与者到达同一计数器 void example_soft_mix(__gm__ int32_t *gmPtr) { GlobalTensorint32_t, pto::Shape, pto::Stride gmWs(gmPtr); SYNCALLSyncAllMode::Soft, SyncCoreType::Mix(gmWs, 0); } // 部分核参与launch 全部核仅前 syncBlocks 个核同步其余核不得调用 SYNCALL void example_soft_partial(__gm__ int32_t *gmPtr, int32_t syncBlocks) { if (static_castint32_t(get_block_idx()) syncBlocks) { return; } GlobalTensorint32_t, pto::Shape, pto::Stride gmWs(gmPtr); SYNCALLSyncAllMode::Soft, SyncCoreType::AIVOnly(gmWs, syncBlocks); }注意事项gmWs指向的 GM 缓冲在首次使用前必须清零且独占一条 cache line见 4.1 节部分核参与场景example_soft_partial中未参与同步的核直接return绝不能调用SYNCALL使用前先确认构建后端属于 A2A3 / A5 / CPU_SIM见 3.3 节否则编译期即报错。八、测试验证与排障参考仓库为SYNCALL提供了完整的多平台 ST 测试是学习用法与排查问题的第一手资料A5 平台tests/npu/a5/src/st/testcase/syncall/目录包含syncall_hard_kernel.cppHard AIV-only、syncall_aic_hard_kernel.cppHard AIC-only、syncall_aic_soft_kernel.cppSoft AIC-only、syncall_soft_kernel.cppSoft 多轮 barrier dcci/dsb 可见性验证、syncall_mix_1_1_kernel.cpp、syncall_hard_mix_1_2_kernel.cpp等覆盖了 AIV-only / AIC-only / Mix1:1、1:2 配比与 Hard/Soft 的多种组合以及部分核参与idle core 标记kIdleCoreMark 2用于区分跑了但跳过 barrier与根本没跑的场景A2/A3 平台tests/npu/a2a3/src/st/testcase/syncall/目录同样覆盖 Hard/Soft、AIC/AIV/Mix 各类组合syncall_aic_hard_kernel.cpp、syncall_aic_kernel.cpp、syncall_soft_kernel.cpp、syncall_mix_1_1_soft_kernel.cpp、syncall_mix_1_2_kernel.cpp等测试配置与数据生成脚本为CMakeLists.txt与gen_data.py。排障速查现象可能原因对应约束死锁 hangSoft 模式触发SYNCALL soft barrier timeout - possible deadlock断言各核进入 barrier 的顺序/次数不一致或参与者集合与 launch 方式不匹配6.2、6.3Hard 模式 hang拿不到 FFTS 上下文编译 arch 错误如 A2/A3 的 AIC-only 编译成纯dav-c220-cube或手工编译未声明 kernel meta6.4、6.5跨核读到的业务数据是旧值未在 barrier 前后自行dcci/dsb6.1计数器计数错乱gmWorkspace未清零或与业务数据共享了 cache line4.1结语SYNCALL是 PTO-ISA 中为数不多的控制面跨核原语其Hard 硬件旗标 / Soft 共享计数器的双路径设计让开发者可以在追求极致硬件效率与实现灵活支持部分核参与、任意配比之间按需选择。理解它的 barrier 到达语义、两个模板参数的组合规则以及只保证到达、不保证数据可见性这条最容易被忽视的约束是写出正确、可维护的多核 PTO kernel 的前提。结合本文给出的源码路径接口声明、Soft 实现、各架构 Hard 实现与测试用例你可以进一步深入验证每条行为边界。【免费下载链接】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),仅供参考