news 2026/9/18 19:18:28

CANN pyasc 多核全核同步接口 asc.language.basic.sync_all 详解:硬同步与软同步的使用与约束

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN pyasc 多核全核同步接口 asc.language.basic.sync_all 详解:硬同步与软同步的使用与约束

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_flagib_set/ib_waitcross_core_set_flag/cross_core_wait_flag等接口并列,可通过asc.sync_all直接调用(在 python/asc/language/basic/init.py 中导出)。

二、两种同步机制:硬同步与软同步

目前多核同步分为硬同步软同步两类:

  • 硬同步:利用硬件自带的全核同步指令,由硬件保证多核同步。无需额外工作空间,性能高。
  • 软同步:使用软件算法模拟实现同步,需要全局与局部工作空间保存各核状态标记,性能相对较低。

对应到 pyasc 的 IR 层,两者分别是两个独立的算子定义(见 OpBlockSync.td):

def SyncAllSoftOp : APIOp<"sync_all_soft", "SyncAll", [AscFunc]> { let arguments = (ins AscendC_GlobalTensor:$gmWorkspace, AscendC_LocalTensor:$ubWorkspace, AnyType:$usedCores, UnitAttr:$isAIVOnly ); let paramTypeLists = [0, 0, 0]; } def SyncAllHardOp : APIOp<"sync_all_hard", "SyncAll", [AscFunc]> { let arguments = (ins UnitAttr:$isAIVOnly); let paramTypeLists = []; let assemblyFormat = "attr-dict"; }

从源码结构可以推断:软同步算子的操作数中必须携带gmWorkspaceubWorkspaceusedCores三个参数,而硬同步算子不需要任何工作空间操作数,仅通过属性isAIVOnly区分同步范围。这也与文档中“硬同步利用硬件自带指令、软同步需要缓存保存状态标记”的描述一致。

2.1 Python 侧的接口分发逻辑

Python 前端通过重载与可选参数实现两种同步方式的统一入口。核心实现位于 block_sync.py:

@overload 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_name="sync_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_only=True) 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_only=True)

关键点:

  • 不传gm_workspaceub_workspace时,走硬同步路径,创建asc_SyncAllHardOp
  • 传入了gm_workspaceub_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) -> None

3.2 对应的 Ascend C 函数原型

文档中给出的 C++ 侧对应原型如下,软同步版本与硬同步版本分别对应上述两个 Python 重载:

// 软同步 template <bool isAIVOnly = true> __aicore__ inline void SyncAll( const GlobalTensor<int32_t>& gmWorkspace, const LocalTensor<int32_t>& ubWorkspace, const int32_t usedCores = 0) // 硬同步 template <bool isAIVOnly = true> __aicore__ inline void SyncAll()

3.3 参数语义详解

参数类型说明
gmWorkspaceGlobalTensor用户定义的全局(Global)空间,作为所有核共用的缓存,用于保存每个核的状态标记。支持的数据类型为int32_t
ubWorkspaceLocalTensor用户定义的局部(Local)空间,每个核单独自用,用于标记当前核的状态。支持的TPositionVECIN/VECCALC/VECOUT,支持的数据类型为int32_t
usedCoresint指定多少个核之间同步,传入数值不能超过算子调用时指定的逻辑blockNum。此为默认参数,不传时表示全核软同步(默认值 0)。
isAIVOnlybool控制SyncAll作用于纯 Vector 算子还是融合(Cube 和 Vector 融合)算子。可选值见下。

isAIVOnly参数取值说明:

  • true(默认值):纯 Vector 算子的全核同步,仅执行 Vector 核的全核同步;
  • false:融合算子的全核同步,先分别完成 Vector 核和 Cube 核的全核同步,再执行两者之间的同步(软同步接口不支持此功能,即false仅适用于硬同步场景)。

四、约束说明与内存申请要求

使用该接口前必须满足以下约束,否则可能出现数据竞争甚至内核“卡死”:

  1. gmWorkspace 空间大小:缓存申请的空间大小要求大于等于核数 × 32Bytes,并且缓存的值需要初始化为 0。常见的两种初始化方式:

    • host 侧进行初始化操作,确保传入接口时gmWorkspace缓存已经初始化为 0;
    • kernel 侧初始化时对gmWorkspace缓存进行初始化,需要注意:每个核上都需要初始化全部的gmWorkspace缓存空间
  2. ubWorkspace 空间大小:申请的空间大小要求大于等于核数 × 32Bytes

  3. 逻辑 blockNum 限制:使用该接口进行多核控制时,算子调用时指定的逻辑blockNum必须不大于实际运行该算子的 AI 处理器核数,否则框架进行多轮调度时会插入异常同步,导致 Kernel “卡死”现象。

  4. 分离模式下的使用建议:在分离模式下,建议使用硬同步接口而非软同步接口。软同步接口仅适用于纯 Vector 场景,且性能较低。使用硬同步接口时,需根据场景设置 Kernel 类型:

    • 纯 Vector / Cube 场景:设置 Kernel 类型为KERNEL_TYPE_MIX_AIV_1_0KERNEL_TYPE_MIX_AIC_1_0
    • Vector 和 Cube 混合场景:根据实际情况灵活配置 Kernel 类型。

五、调用示例与源码佐证

5.1 软同步调用示例

软同步需要先创建全局与局部工作空间,再调用sync_all

gm = asc.GlobalTensor() gm.set_global_buffer(x) ub = asc.LocalTensor(dtype=asc.int32, pos=asc.TPosition.VECIN, addr=0, tile_size=32) asc.sync_all(gm, ub, used_cores=0)

其中used_cores=0表示全核软同步。该写法与单元测试 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(dtype=asc.int32, pos=asc.TPosition.VECIN, addr=0, tile_size=32) asc.sync_all(gm, ub, used_cores=0) x = MockTensor(asc.int32) kernel_sync_all_soft1 assert mock_launcher_run.call_count == 1

可以看出:软同步接口通常与asc.jit装饰器配合,在内核函数体内使用,GlobalTensor通过set_global_buffer绑定全局内存,LocalTensor显式指定dtype=asc.int32TPosition.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();

这一测试同时印证了文档中的两条事实:软同步发射为携带gmWorkspaceubWorkspaceusedCores三个参数的AscendC::SyncAll(v1, v2, v3)调用;硬同步发射为无参的AscendC::SyncAll()调用;且isAIVOnly属性在两种同步方式中都会传递到最终代码。

六、使用场景与选型建议

综合文档与源码,可将使用场景归纳如下:

场景推荐同步方式说明
纯 Vector 算子,多核访问同一全局内存软同步或硬同步软同步仅适用于纯 Vector 场景,但性能较低;硬同步性能更优
分离模式 / 融合算子(Cube + Vector)硬同步isAIVOnly=False软同步接口不支持 Vector/Cube 核间同步;硬同步需配合设置 Kernel 类型(如KERNEL_TYPE_MIX_AIV_1_0KERNEL_TYPE_MIX_AIC_1_0
指定部分核同步软同步(设置used_cores传入的核数不能超过算子调用时的逻辑blockNum

七、总结

asc.language.basic.sync_all是 pyasc 多核编程中处理全局内存数据依赖的关键同步原语:

  • 硬同步asc.sync_all())依赖硬件全核同步指令,无需工作空间,性能高,是分离模式与融合算子的首选;
  • 软同步asc.sync_all(gm, ub, used_cores=0))通过gmWorkspace(全局共享状态缓存)与ubWorkspace(每核局部状态标记)以软件算法模拟同步,适合纯 Vector 场景,且支持通过used_cores限定参与同步的核数;
  • 使用前务必满足内存约束(两个工作空间均不小于核数 × 32BytesgmWorkspace初始化为 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),仅供参考

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

室内定位实战:Arduino+BLE4.0实现RSSI测距与三边定位

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

作者头像 李华
网站建设 2026/9/18 19:16:35

工业无人机电力巡检Word方案自动化:POI-TL模板引擎实战指南

简介&#xff1a;这是一份Word格式的工业级无人机电力行业应用通用方案&#xff0c;共36页&#xff0c;面向电力行业项目决策者、无人机应用方案工程师及低空经济研究人员&#xff0c;针对传统人工巡检效率低、高危环境作业风险大、电网规模扩张后运维压力上升等现实痛点&#…

作者头像 李华
网站建设 2026/9/18 19:14:41

远程桌面0x204报错修复:CredSSP加密Oracle修正完整指南

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

作者头像 李华
网站建设 2026/9/18 19:14:39

SQL Server 2019安装深度指南:避坑、配置与生产就绪

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

作者头像 李华
网站建设 2026/9/18 19:13:38

卷积核不是滤镜:从视觉细胞到工程实践的深度解析

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

作者头像 李华
网站建设 2026/9/18 19:13:23

Java List去重8种方法:整体去重与按属性去重全解析

简介&#xff1a;Java中List集合的去重及按属性去重是编程中的常见需求&#xff0c;这份资料以PDF文档形式整理了8种实现方法&#xff0c;覆盖HashSet、LinkedHashSet、Stream distinct、TreeSet、自定义Comparator、Map与Lambda表达式等写法&#xff0c;既包含对象整体去重&am…

作者头像 李华