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 能完整覆盖 用户项目中 跨核同步接口的全部功能。具体诉求:
- 支持 mode 0 和 mode 1:提供对应 facade 或暴露
ffts_mode 参数让调用方指定模式
- 移除 pipe 限制:所有跨核同步 facade 应接受任意合法 pipe 值,由调用方根据实际数据流决定,而不是在 facade 层硬编码
- 扩展 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
Summary
背景
当前客户项目 向用户暴露了
XXX_cross_core_set_flag(mode_id, pipe, flag_id)和XXX_cross_core_wait_flag(mode_id, pipe, flag_id)两个跨核同步原语,三个参数的含义如下:mode_idpipeflag_id在 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 的四种模式
pipe 参数
pipe 指定信号在哪条流水线上发射(set 端)或阻塞(wait 端)。pipe 的选择必须与实际数据流经过的流水线匹配,选错会导致数据竞争。
pipe 的合法取值取决于具体场景,不应被固定为某个值。不同 mode_id 和不同操作侧(Cube/Vector)需要的 pipe 不同。例如:
如果 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 值:
set_cross_flagwait_cross_flagset_intra_flagwait_intra_flag但 pipe 的合法取值应由调用方根据实际数据流决定,不同 mode_id 和不同操作侧(Cube/Vector)需要的 pipe 不同。当前的限制导致大量合法用法无法表达。
以 GEMM 场景(mode 4)为例,需要 4 种 set/wait 组合:
set_cross_flagwait_cross_flagset_intra_flagwait_intra_flag其中"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 能完整覆盖 用户项目中 跨核同步接口的全部功能。具体诉求:
ffts_mode参数让调用方指定模式或者,提供一个更底层的统一 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