Skip to content

[Feature] DSL facade 跨核同步接口能力不完整 #985

Description

@bingmeiyou

Summary

背景

当前客户项目 向用户暴露了 XXX_cross_core_set_flag(mode_id, pipe, flag_id)XXX_cross_core_wait_flag(mode_id, pipe, flag_id) 两个跨核同步原语,三个参数的含义如下:

参数 类型 说明
mode_id int 同步模式,取值 0/1/2/4,控制信号传播范围(跨 block 全核同步 / AIV 间同步 / CV 广播汇聚 / CV 逐子核 1:1)
pipe str 流水线类型,如 PIPE_FIX / PIPE_MTE3 / PIPE_V / PIPE_M 等,指定信号发射或等待的流水线
flag_id int 或 PrimExpr 信号量编号,A5 平台范围 0-31(0-15 对应 AIV0,16-31 对应 AIV1)

在 AscendC codegen 中,这三个参数直接透传为 CrossCoreSetFlag<mode_id, pipe>(flag_id) / CrossCoreWaitFlag<mode_id, pipe>(flag_id),功能完整。
https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/900/API/ascendcopapi/atlasascendc_api_07_0273.html

现在我们要实现 PTO codegen,需要将 这两个接口映射到 PTO DSL 的等价接口。但当前 PTO DSL facade 暴露的跨核同步接口在能力上有缺失,无法完整覆盖这两个接口的全部功能。

接口的完整功能规格

mode_id 的四种模式

mode_id 含义 典型场景
0 跨 block 同类型核同步(所有 AIC↔AIC 或所有 AIV↔AIV) 多个 block 分担计算,需要所有同类型核到达屏障
1 block 内 AIV 子核间同步(AIV0 ↔ AIV1) 两个 AIV 子核协作处理数据,需要互相通知
2 block 内 AIC↔AIV 同步,广播+汇聚(一次 set 到达两个 AIV,一次 wait 等到两个 AIV 都完成) AIC 算完 GEMM 一次性通知两个 AIV 来搬数据
4 block 内 AIC↔AIV 同步,1:1 逐子核(AIV0 和 AIV1 可单独触发) AIC 分别通知 AIV0 和 AIV1,用不同 flag_id 区分目标子核

pipe 参数

pipe 指定信号在哪条流水线上发射(set 端)或阻塞(wait 端)。pipe 的选择必须与实际数据流经过的流水线匹配,选错会导致数据竞争。

pipe 的合法取值取决于具体场景,不应被固定为某个值。不同 mode_id 和不同操作侧(Cube/Vector)需要的 pipe 不同。例如:

  • GEMM 场景中,Cube 侧 L0C→UB 搬运走 PIPE_FIX,所以 Cube 侧 set/wait 用 PIPE_FIX
  • GEMM 场景中,Vector 侧 UB→GM 搬运走 PIPE_MTE3,所以 Vector 侧 set/wait 用 PIPE_MTE3
  • AscendC 官方文档中,mode 0 的 set 示例使用 PIPE_MTE3(不是 PIPE_FIX)
  • 其他场景中,可能还需要 PIPE_V、PIPE_M、PIPE_MTE2 等

如果 wait 端 stall 了错误的流水线,需要同步的流水线不会被阻塞,导致读到未就绪数据。

flag_id 参数

A5 平台上 flag_id 地址空间为 0-31:0-15 对应 AIV0,16-31 对应 AIV1(+16 偏移)。mode 4 场景中,AIC 需要用不同的 flag_id 分别通知两个 AIV 子核。

问题列表

问题 1:DSL facade 不支持 mode 0 和 mode 1

当前 PTO DSL facade 只提供了两组跨核同步函数:

  • set_cross_flag / wait_cross_flag(对应 mode 2 语义)
  • set_intra_flag / wait_intra_flag(对应 mode 4 语义)

mode 0(跨 block 同类型核同步)和 mode 1(AIV 子核间同步)在 DSL facade 层完全没有对应接口。TileLang 接口暴露了 mode_id 参数,用户可以使用 0/1/2/4 四种模式,我们需要 codegen 完整覆盖。

问题 2:所有跨核同步 facade 的 pipe 限制过严

当前四个 facade 函数各自只允许一个固定的 pipe 值:

facade 函数 当前允许的 pipe
set_cross_flag 仅 PIPE_FIX
wait_cross_flag 仅 PIPE_FIX
set_intra_flag 仅 PIPE_MTE3
wait_intra_flag 仅 PIPE_V

但 pipe 的合法取值应由调用方根据实际数据流决定,不同 mode_id 和不同操作侧(Cube/Vector)需要的 pipe 不同。当前的限制导致大量合法用法无法表达。

以 GEMM 场景(mode 4)为例,需要 4 种 set/wait 组合:

场景 操作 需要的 pipe 当前 facade 能否使用
Cube→Vector 通知 set PIPE_FIX set_cross_flag
Cube 等 Vector wait PIPE_FIX wait_cross_flag
Vector→Cube 通知 set PIPE_MTE3 set_intra_flag
Vector 等 Cube wait PIPE_MTE3 wait_intra_flag ❌ 只允许 PIPE_V

其中"Vector 等 Cube"无法表达:AIV 侧等待 AIC 把 GEMM 结果搬到 UB,然后在 MTE3 流水线上执行 UB→GM 搬运。wait 必须 stall MTE3 而不是 V,否则 MTE3 不会等待信号就执行搬运,产生数据竞争。

除 GEMM 外,AscendC 官方文档中 mode 0 的 set 示例使用的是 PIPE_MTE3(不是 PIPE_FIX),也无法通过 set_cross_flag 表达。其他场景中 PIPE_V、PIPE_M、PIPE_MTE2 等 pipe 也是合法选择。

这意味着当前每个 facade 的 pipe 限制都过严,不只是某个函数的问题。

问题 3:event_id 限制为 0-7,A5 平台需要 0-31

当前 DSL facade 的所有四个函数都通过 _validate_static_event_id 将静态 event_id 限制在 0-7 范围内。

A5 平台硬件支持 0-31 的 event_id 地址空间(0-15 给 AIV0,16-31 给 AIV1,通过 +16 偏移区分目标子核)。mode 4 场景中,AIC 需要用 flag_id 6 通知 AIV0、用 flag_id 22(=6+16)通知 AIV1,但 22 会被 DSL facade 拒绝。

诉求

我们希望 PTO DSL facade 能完整覆盖 用户项目中 跨核同步接口的全部功能。具体诉求:

  1. 支持 mode 0 和 mode 1:提供对应 facade 或暴露 ffts_mode 参数让调用方指定模式
  2. 移除 pipe 限制:所有跨核同步 facade 应接受任意合法 pipe 值,由调用方根据实际数据流决定,而不是在 facade 层硬编码
  3. 扩展 event_id 范围:静态 event_id 范围应支持到 0-31(A5 平台)

或者,提供一个更底层的统一 facade(如 pto.sync_flag(pipe, event_id, mode=2)),让调用方自行指定 mode、pipe、event_id,不受当前的逐函数 pipe 限制。

Motivation / use case

--

Proposed API / behavior

No response

Alternatives considered

No response

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions