
CANN pyasc 多核全核同步接口 asc.language.basic.sync_all 详解硬同步与软同步的使用与约束【免费下载链接】pyasc本项目为Python用户提供算子编程接口支持在昇腾AI处理器上加速计算接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc导读asc.language.basic.sync_all是 CANN pyasc 为昇腾 AI 处理器提供的多核全核同步接口用于解决不同 AI Core计算核之间访问同一块全局内存时可能出现的读后写WAR、写后读RAW、写后写WAW等数据依赖问题。本文以该接口的官方文档为核心结合 block_sync.py、OpBlockSync.td 等仓库源码与 MLIR 测试用例系统讲解硬同步与软同步的机制差异、完整参数语义、内存申请约束以及纯 Vector / Cube-Vector 融合等场景下的正确用法。读完本文你将能够在 pyasc 算子内核中正确选择并插入全核同步语句避免多核并发访问全局内存引发的数据读写错误。一、接口概述为什么需要全核同步在昇腾 AI 处理器的多核并行执行模型中算子会被切分到多个 AI Core 上并行执行。当不同核操作同一块全局内存且存在数据依赖时各核的执行进度无法保证一致就可能出现读后写WAR一个核还未完成读取另一个核已经写入读取到被覆盖的数据写后读RAW一个核需要读取的数据另一个核尚未写入完成写后写WAW多个核同时写入同一地址最终结果不可预期。asc.language.basic.sync_all的作用正是在内核中插入同步语句强制相关核在同步点对齐从而避免上述数据读写错误。该接口属于 basic/block_sync.py 模块中的核同步Block Sync能力族与set_flag/wait_flag、ib_set/ib_wait、cross_core_set_flag/cross_core_wait_flag等接口并列可通过asc.sync_all直接调用在 python/asc/language/basic/init.py 中导出。二、两种同步机制硬同步与软同步目前多核同步分为硬同步与软同步两类硬同步利用硬件自带的全核同步指令由硬件保证多核同步。无需额外工作空间性能高。软同步使用软件算法模拟实现同步需要全局与局部工作空间保存各核状态标记性能相对较低。对应到 pyasc 的 IR 层两者分别是两个独立的算子定义见 OpBlockSync.tddef SyncAllSoftOp : APIOpsync_all_soft, SyncAll, [AscFunc] { let arguments (ins AscendC_GlobalTensor:$gmWorkspace, AscendC_LocalTensor:$ubWorkspace, AnyType:$usedCores, UnitAttr:$isAIVOnly ); let paramTypeLists [0, 0, 0]; } def SyncAllHardOp : APIOpsync_all_hard, SyncAll, [AscFunc] { let arguments (ins UnitAttr:$isAIVOnly); let paramTypeLists []; let assemblyFormat attr-dict; }从源码结构可以推断软同步算子的操作数中必须携带gmWorkspace、ubWorkspace、usedCores三个参数而硬同步算子不需要任何工作空间操作数仅通过属性isAIVOnly区分同步范围。这也与文档中“硬同步利用硬件自带指令、软同步需要缓存保存状态标记”的描述一致。2.1 Python 侧的接口分发逻辑Python 前端通过重载与可选参数实现两种同步方式的统一入口。核心实现位于 block_sync.pyoverload def sync_all(is_aiv_only: bool True) - None: ... overload def sync_all(gm_workspace: GlobalTensor, ub_workspace: LocalTensor, used_cores: int 0, is_aiv_only: bool True) - None: ... require_jit set_common_docstring(api_namesync_all) def sync_all(gm_workspace: Optional[GlobalTensor] None, ub_workspace: Optional[LocalTensor] None, used_cores: RuntimeInt 0, is_aiv_only: bool True) - None: builder global_builder.get_ir_builder() if gm_workspace is None or ub_workspace is None: if is_aiv_only: builder.create_asc_SyncAllHardOp() else: builder.create_asc_SyncAllHardOp(is_aiv_onlyTrue) else: used_cores_ir _mat(used_cores).to_ir() if is_aiv_only: builder.create_asc_SyncAllSoftOp(gm_workspace.to_ir(), ub_workspace.to_ir(), used_cores_ir) else: builder.create_asc_SyncAllSoftOp(gm_workspace.to_ir(), ub_workspace.to_ir(), used_cores_ir, is_aiv_onlyTrue)关键点当不传gm_workspace和ub_workspace时走硬同步路径创建asc_SyncAllHardOp当传入了gm_workspace与ub_workspace时走软同步路径创建asc_SyncAllSoftOp无论哪种路径is_aiv_only都会作为属性传入 IR 构建器控制同步作用范围。三、函数原型与参数说明3.1 Python 接口原型# 硬同步不传工作空间 asc.language.basic.sync_all(is_aiv_only: bool True) - None # 软同步传入工作空间与参与核数 asc.language.basic.sync_all(gm_workspace: GlobalTensor, ub_workspace: LocalTensor, used_cores: int 0, is_aiv_only: bool True) - None3.2 对应的 Ascend C 函数原型文档中给出的 C 侧对应原型如下软同步版本与硬同步版本分别对应上述两个 Python 重载// 软同步 template bool isAIVOnly true __aicore__ inline void SyncAll( const GlobalTensorint32_t gmWorkspace, const LocalTensorint32_t ubWorkspace, const int32_t usedCores 0) // 硬同步 template bool isAIVOnly true __aicore__ inline void SyncAll()3.3 参数语义详解参数类型说明gmWorkspaceGlobalTensor用户定义的全局Global空间作为所有核共用的缓存用于保存每个核的状态标记。支持的数据类型为int32_t。ubWorkspaceLocalTensor用户定义的局部Local空间每个核单独自用用于标记当前核的状态。支持的TPosition为VECIN/VECCALC/VECOUT支持的数据类型为int32_t。usedCoresint指定多少个核之间同步传入数值不能超过算子调用时指定的逻辑blockNum。此为默认参数不传时表示全核软同步默认值 0。isAIVOnlybool控制SyncAll作用于纯 Vector 算子还是融合Cube 和 Vector 融合算子。可选值见下。isAIVOnly参数取值说明true默认值纯 Vector 算子的全核同步仅执行 Vector 核的全核同步false融合算子的全核同步先分别完成 Vector 核和 Cube 核的全核同步再执行两者之间的同步软同步接口不支持此功能即false仅适用于硬同步场景。四、约束说明与内存申请要求使用该接口前必须满足以下约束否则可能出现数据竞争甚至内核“卡死”gmWorkspace 空间大小缓存申请的空间大小要求大于等于核数 × 32Bytes并且缓存的值需要初始化为 0。常见的两种初始化方式在host 侧进行初始化操作确保传入接口时gmWorkspace缓存已经初始化为 0在kernel 侧初始化时对gmWorkspace缓存进行初始化需要注意每个核上都需要初始化全部的gmWorkspace缓存空间。ubWorkspace 空间大小申请的空间大小要求大于等于核数 × 32Bytes。逻辑 blockNum 限制使用该接口进行多核控制时算子调用时指定的逻辑blockNum必须不大于实际运行该算子的 AI 处理器核数否则框架进行多轮调度时会插入异常同步导致 Kernel “卡死”现象。分离模式下的使用建议在分离模式下建议使用硬同步接口而非软同步接口。软同步接口仅适用于纯 Vector 场景且性能较低。使用硬同步接口时需根据场景设置 Kernel 类型纯 Vector / Cube 场景设置 Kernel 类型为KERNEL_TYPE_MIX_AIV_1_0或KERNEL_TYPE_MIX_AIC_1_0Vector 和 Cube 混合场景根据实际情况灵活配置 Kernel 类型。五、调用示例与源码佐证5.1 软同步调用示例软同步需要先创建全局与局部工作空间再调用sync_allgm asc.GlobalTensor() gm.set_global_buffer(x) ub asc.LocalTensor(dtypeasc.int32, posasc.TPosition.VECIN, addr0, tile_size32) asc.sync_all(gm, ub, used_cores0)其中used_cores0表示全核软同步。该写法与单元测试 test_common_api.py 中的test_sync_all_soft完全一致def test_sync_all_soft(mock_launcher_run): asc.jit def kernel_sync_all_soft(x: asc.GlobalAddress) - None: gm asc.GlobalTensor() gm.set_global_buffer(x) ub asc.LocalTensor(dtypeasc.int32, posasc.TPosition.VECIN, addr0, tile_size32) asc.sync_all(gm, ub, used_cores0) x MockTensor(asc.int32) kernel_sync_all_soft1 assert mock_launcher_run.call_count 1可以看出软同步接口通常与asc.jit装饰器配合在内核函数体内使用GlobalTensor通过set_global_buffer绑定全局内存LocalTensor显式指定dtypeasc.int32、TPosition.VECIN位置与 32 字节的tile_size。5.2 硬同步调用示例硬同步不需要任何工作空间直接调用即可asc.sync_all()单元测试 test_sync_all_hard 验证了这一用法def test_sync_all_hard(mock_launcher_run): asc.jit def kernel_sync_all_hard() - None: asc.sync_all() kernel_sync_all_hard[1]() assert mock_launcher_run.call_count 1注意硬同步接口的内核函数无需任何参数asc.sync_all()被直接插入内核体。5.3 MLIR 层面的发射验证在 test/Target/AscendC/basic/common.mlir 中可以看到两种同步方式从 MLIR 算子到 Ascend C 代码的完整发射路径// 软同步sync_all_soft 携带 gm/ub/cores 三个操作数与 isAIVOnly 属性 func.func emit_sync_all_soft( %gm: !ascendc.global_tensor*xui8, %ub: !ascendc.local_tensor*xui8, %cores: i32 ) { ascendc.sync_all_soft %gm, %ub, %cores {isAIVOnly} : !ascendc.global_tensor*xui8, !ascendc.local_tensor*xui8, i32 return } // CHECK: AscendC::SyncAll(v1, v2, v3); // 硬同步sync_all_hard 无操作数仅携带 isAIVOnly 属性 func.func emit_sync_all_hard() { ascendc.sync_all_hard {isAIVOnly} return } // CHECK: AscendC::SyncAll();这一测试同时印证了文档中的两条事实软同步发射为携带gmWorkspace、ubWorkspace、usedCores三个参数的AscendC::SyncAll(v1, v2, v3)调用硬同步发射为无参的AscendC::SyncAll()调用且isAIVOnly属性在两种同步方式中都会传递到最终代码。六、使用场景与选型建议综合文档与源码可将使用场景归纳如下场景推荐同步方式说明纯 Vector 算子多核访问同一全局内存软同步或硬同步软同步仅适用于纯 Vector 场景但性能较低硬同步性能更优分离模式 / 融合算子Cube Vector硬同步isAIVOnlyFalse软同步接口不支持 Vector/Cube 核间同步硬同步需配合设置 Kernel 类型如KERNEL_TYPE_MIX_AIV_1_0或KERNEL_TYPE_MIX_AIC_1_0指定部分核同步软同步设置used_cores传入的核数不能超过算子调用时的逻辑blockNum七、总结asc.language.basic.sync_all是 pyasc 多核编程中处理全局内存数据依赖的关键同步原语硬同步asc.sync_all()依赖硬件全核同步指令无需工作空间性能高是分离模式与融合算子的首选软同步asc.sync_all(gm, ub, used_cores0)通过gmWorkspace全局共享状态缓存与ubWorkspace每核局部状态标记以软件算法模拟同步适合纯 Vector 场景且支持通过used_cores限定参与同步的核数使用前务必满足内存约束两个工作空间均不小于核数 × 32Bytes、gmWorkspace初始化为 0与blockNum不超过实际核数的限制否则可能导致数据竞争或内核“卡死”。建议读者结合 block_sync.py 源码、OpBlockSync.td 算子定义以及 test_common_api.py 与 common.mlir 测试用例进一步理解同步接口从 Python 到 IR 再到 Ascend C 代码的完整实现链路。【免费下载链接】pyasc本项目为Python用户提供算子编程接口支持在昇腾AI处理器上加速计算接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考