-
Notifications
You must be signed in to change notification settings - Fork 79
feat(vpto): add sdma_gm_gm with session-template expansion #1324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kerwinair
wants to merge
7
commits into
hw-native-sys:main
Choose a base branch
from
kerwinair:feat/vpto-sdma-gm-gm-expand
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
7bbe31b
feat(vpto): add sdma_gm_gm with session-template expansion
84a5104
feat(ptodsl): let @pto.jit link host C++ into the kernel library
4e061f7
test(vpto): move async-comm ST cases onto the PTODSL framework
2aeba06
fix(ptodsl): keep native_options tests importable without ptoas.mlir
47b92c9
fix(test): keep engine-spike jit annotations as live objects
afbe5ae
fix(ptodsl): link libstdc++ when host C++ is part of the kernel library
1a66b02
feat(ptodsl): expose session_init and sdma_gm_gm on the Python surface
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,168 @@ | ||
| # VPTO 通信模型 | ||
|
|
||
| 本文描述跨 rank 通信的编程模型:对称共享内存、单边访问、完成与可见性约定, | ||
| 以及 `comm_scope` 边界。 | ||
|
|
||
| 非目标:集合通信算法、Runtime HCCL 绑定细节、Tile 层 DSL、CCU。 | ||
|
|
||
| 当前 IR 已落地的只有 `pto.session_init` 与 `pto.sdma_gm_gm`,写法见 | ||
| [19. Async Communication](../isa/micro-isa/19-async-comm.md)。下文仍是模型约定。 | ||
| 下列条目尚未进入当前 IR,不要当成可编写语法: | ||
|
|
||
| - `!pto.async_session`、`pto.session_config` | ||
| - `#pto.remote` / `#pto.mr<rma>` 指针属性 | ||
| - `pto.comm_scope` | ||
| - `pto.urma_gm_gm`、`pto.rdma_gm_gm`、`pto.sdma_gm_l2c` | ||
| - 融合 `*_signal` / `*_counter` | ||
| - kick 返回 CQ 完成记录 | ||
|
|
||
| 对端地址目前就是普通 `!pto.ptr<T, gm>`,由 host 按 `windowsIn` 同偏移算好后 | ||
| 作为 kernel 参数传入。A5 远端写需要 `{soft_put}`,该形态在 op 返回前完成拷贝。 | ||
|
|
||
| ## 1. 范式 | ||
|
|
||
| 采用 **PGAS / SHMEM** 式对称共享内存 + 单边访问:各 rank 共享段布局一致, | ||
| 设备侧以「本端指针 + 目标 rank」读写对端同偏移数据,无需对端参与。 | ||
|
|
||
| 跨卡交换收敛为三件事:**寻址、搬运、显式同步**。Scale-up(节点内)与 | ||
| Scale-out(跨节点)只更换引擎与通路,不改变编程面。 | ||
|
|
||
|  | ||
|
|
||
| 一次通信分两阶段: | ||
|
|
||
| - **Host 准备期**:建通信域、协商对称共享段、按需注册鉴权 MR、初始化异步引擎; | ||
| 随 launch 下发寻址上下文(只读)与引擎会话(有状态)。二者职责分离即可, | ||
| 字段级 ABI 不在本文展开。 | ||
| - **NPU 运行期**:kernel 内算址、发起搬运、用同步量或融合形态约定跨卡可见性。 | ||
|
|
||
| ```mermaid | ||
| flowchart LR | ||
| A["① Bootstrap<br/>带外交换 root info"] --> B["② BuildComm<br/>HCCL 建通信域"] | ||
| B --> C["③ 注册对称内存<br/>Window / 鉴权 RMA MR<br/>交换基址表 + token"] | ||
| B --> D["④ 逐引擎建 workspace<br/>SDMA · URMA · RDMA<br/>持久化于 device HBM"] | ||
| C --> E["CommDeviceContext<br/>寻址上下文 · 只读"] | ||
| D --> F["引擎 workspace"] | ||
| F --> G["AsyncSession<br/>有状态 · 引用 workspace"] | ||
| E --> K["launch 入参"] | ||
| G --> K | ||
| HC["CommContext<br/>host only · 不下设备"] -.->|"X"| K | ||
| ``` | ||
|
|
||
| ## 2. 共享内存与指针属性 | ||
|
|
||
| 跨卡地址空间一律 `gm`。远近与鉴权不另开地址空间,由可组合指针属性表达: | ||
|
|
||
| | 形态 | 含义 | | ||
| |------|------| | ||
| | `!pto.ptr<T, gm>` | 本端、普通共享内存 | | ||
| | `!pto.ptr<T, gm, #pto.mr<rma>>` | 本端、已注册鉴权 RMA MR | | ||
| | `!pto.ptr<T, gm, #pto.remote>` | 远端、普通共享内存 | | ||
| | `!pto.ptr<T, gm, #pto.mr<rma>, #pto.remote>` | 远端且已注册 | | ||
|
|
||
| `#pto.remote` 管远近,`#pto.mr<rma>` 管鉴权;缺省分别为本端、未注册。 | ||
| 同偏移算址由调用方用 `CommDeviceContext.windowsIn[]` 自行完成: | ||
|
|
||
| ```text | ||
| remote = windowsIn[peer] + (local − windowsIn[myRank]) | ||
| ``` | ||
|
|
||
| 结果以 `pto.castptr` 等既有手段成型为 `!pto.ptr<T, gm, #pto.remote>`(可与 | ||
| `#pto.mr<rma>` 组合)。不设专用 remap op。 | ||
|
|
||
|  | ||
|
|
||
| ## 3. 完成与可见性(E2 / E3) | ||
|
|
||
| | 事件 | 保证 | 观测 | | ||
| |------|------|------| | ||
| | **E2** | 本端 source 可复用 | 异步:轮询搬运返回的 CQ 完成记录;同步 MTE:指令/pipe 完成即成立 | | ||
| | **E3** | 对端可见本次 payload | 写远端同步量,或使用融合 `*_signal` / `*_counter` | | ||
|
|
||
| E2 与 E3 相互独立:等到 E2 **不**代表对端可见。分离写法必须先到 E2 再发同步量; | ||
| 融合形态同事务保证,对端观测到同步量即可读 payload。 | ||
|
|
||
| ```mermaid | ||
| sequenceDiagram | ||
| participant H as Host | ||
| participant D as rank i Kernel | ||
| participant Li as rank i 对称共享内存 | ||
| participant Rj as rank j 对称共享内存 | ||
| participant P as rank j Kernel | ||
|
|
||
| H->>D: launch(寻址上下文, AsyncSession, 数据 buffer) | ||
| H->>P: launch(寻址上下文, AsyncSession, 数据 buffer) | ||
| D->>Li: 取得本端 payload / 同步量地址 | ||
| D->>D: windowsIn 同偏移算址 → #pto.remote 指针 | ||
|
|
||
| alt 同步通路(MTE) | ||
| D->>Rj: 单边写 payload | ||
| Note over D,Rj: 返回即本端完成 | ||
| else 异步通路(DMA 引擎) | ||
| D->>Rj: kick 单边写 payload(不阻塞标量流) | ||
| D->>D: wait event → E2:本端源可复用 | ||
| end | ||
|
|
||
| D->>Rj: 写 signal / atomic add counter → 发布 E3 | ||
| loop 同步量未满足 | ||
| P->>Rj: wait / test 本端 signal / counter | ||
| Rj-->>P: 未满足则继续轮询 | ||
| end | ||
| P->>Rj: 读取本端 payload | ||
| Rj-->>P: payload(已保证可见) | ||
| ``` | ||
|
|
||
| 跨 rank E3 **不**复用 `cmo.cacheinvalid` / `fence.barrier_all`(核间粗栅栏)。 | ||
|
|
||
| ## 4. 同步量(内存约定,无新 op) | ||
|
|
||
| 跨 rank 同步量是对称段内用户自划的 `i32` 位置,不是专用指令族: | ||
|
|
||
| | 用法 | 写者 | 发布 | | ||
| |------|------|------| | ||
| | **signal** | 单写者 | `stg` / `store` / 远端 `mte_ub_gm` | | ||
| | **counter** | 多写者汇合 | `atomic_add` | | ||
|
|
||
| 观测:本端 `dcci` + `ldg`;等待写成 IR 轮询。与片上 SC 信号量 | ||
| (`set_intra_core` 等)互不合并:核间用 SC,跨 rank 用 GM 同步量。 | ||
|
|
||
| ## 5. 融合搬运+同步 | ||
|
|
||
| 异步通路可将 E3 发布并进同一搬运事务:`*_gm_gm_signal` / `*_gm_gm_counter`。 | ||
| 这是跨 rank 同步唯一新增的 mnemonic 族;独立发布仍用 §4 的普通访存。 | ||
| MTE 同步通路无融合形态。 | ||
|
|
||
| ## 6. `comm_scope` | ||
|
|
||
| `comm_scope` 是 `section.vector` / `section.cube` 内的词法区域,给通信资源 | ||
| (session / 完成记录等)划寿命边界,并作为 sync 分析锚点。应对齐 | ||
| `pto.vecscope` 写在 `docs/vpto-spec.md` 的层级;本节暂存约定,后续迁入该处。 | ||
|
|
||
| ```mlir | ||
| pto.section.vector { | ||
| pto.vecscope { /* 计算 */ } | ||
| pto.comm_scope { | ||
| %dst = pto.castptr %remote_i64 : i64 -> !pto.ptr<f16, gm, #pto.remote> | ||
| %cq = pto.sdma_gm_gm %dst, %src, %nbytes session(%sess) | ||
| -> !pto.ptr<i64, gm> | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| | 项 | 约定 | | ||
| |----|------| | ||
| | 位置 | `section.vector` / `section.cube`;**不**进入 `vecscope` | | ||
| | 职责 | 资源寿命边界 + Sync 分析锚点 | | ||
| | vs `vecscope` | 通信 kick、同步量读写、session、远端指针构造落在 `comm_scope` | | ||
| | 推断 | session/event 流可按 SSA 穿线推断;纯同步量流需显式书写 | | ||
| | cube | AIC 只发 GM↔GM kick 时 PlanMemory 锚点弱化;资源/Sync 锚点仍成立 | | ||
|
|
||
| 开放问题:出口是否默认强制 E2(与正确性正交,影响跨窗 overlap)。 | ||
|
|
||
| ## 7. 通路总览 | ||
|
|
||
| | 通路 | 承载 | | ||
| |------|------| | ||
| | 同步远端 | 核内 MTE:`mte_gm_ub` / `mte_ub_gm` + `#pto.remote` | | ||
| | 异步 GM↔GM | SDMA / URMA / RDMA + session | | ||
| | 融合 notify | `*_gm_gm_signal` / `*_gm_gm_counter` | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,200 @@ | ||
| # 19. Async Communication | ||
|
|
||
| > **Category:** Asynchronous GM↔GM engine transfers | ||
| > **Pipelines:** SDMA engine kick from an ordinary AICore scalar stream | ||
|
|
||
| This group copies a contiguous GM range through the SDMA engine. The kick does | ||
| not wait for the engine except where `{soft_put}` is documented below. The op | ||
| does not publish a completion record; local drain and cross-rank visibility are | ||
| arranged by the caller. | ||
|
|
||
| This document describes: | ||
|
|
||
| - `pto.session_init` | ||
| - `pto.sdma_gm_gm` | ||
|
|
||
| There is no `mte_gm_gm`. Synchronous GM↔UB copies remain in | ||
| [2. DMA Copy Programming](02-dma-copy.md). | ||
|
|
||
| These ops must sit in an ordinary AICore entry function. They are illegal | ||
| inside `pto.simt_entry` functions and `pto.section.simt`. | ||
|
|
||
| --- | ||
|
|
||
| ## Session | ||
|
|
||
| A session cannot be a kernel argument: only `pto.declare_struct` may produce a | ||
| `!pto.struct`. The host therefore writes a GM template, and the kernel declares | ||
| its own struct and fills it with `pto.session_init`. | ||
|
|
||
| The session type is fixed: | ||
|
|
||
| ```mlir | ||
| !pto.struct<i64, i64, i32, i32, i32, i32, i64, i64, i32, i32, i32, i32, i32> | ||
| ``` | ||
|
|
||
| The template uses one 8-byte slot per field, in the same order. Narrow fields | ||
| occupy the low half of their slot. Each core fills its own copy, so a session | ||
| is per-core even when the template is shared and read-only. | ||
|
|
||
| After the fill, a kernel may retune individual fields with `pto.struct_set`. | ||
| The channel group is field 4, which is how a multi-core launch gives each core | ||
| its own queue without the host naming the core. | ||
|
|
||
| --- | ||
|
|
||
| ## Operation Summary | ||
|
|
||
| | Operation | Purpose | | ||
| |-----------|---------| | ||
| | `pto.session_init` | Copy the host template into a stack-local session struct | | ||
| | `pto.sdma_gm_gm` | Kick a contiguous GM→GM copy through the session | | ||
|
|
||
| --- | ||
|
|
||
| ### `pto.session_init` | ||
|
|
||
| - **Purpose:** Fill `session` in place from the host-written GM template. | ||
| - **Syntax:** | ||
|
|
||
| ```mlir | ||
| pto.session_init %sess, %sess_gm | ||
| : !pto.struct<i64, i64, i32, i32, i32, i32, i64, i64, i32, i32, i32, i32, i32>, | ||
| !pto.ptr<i8, gm> | ||
| ``` | ||
|
|
||
| - **Operands:** | ||
|
|
||
| | Operand | Type | Description | | ||
| |---------|------|-------------| | ||
| | `%sess` | the 13-field session struct | Destination; written in place, no result | | ||
| | `%sess_gm` | `!pto.ptr<T, gm>` | Base of the host template | | ||
|
|
||
| - **Results:** None. | ||
| - **Constraints:** | ||
| - `%sess` must use the session struct type above. | ||
| - `%sess_gm` must be a GM pointer. | ||
| - Must be outside SIMT entry functions and `pto.section.simt`. | ||
| - Must be inside an ordinary AICore `pto.kernel` function. | ||
| - **Semantics:** Copy each template slot into the corresponding struct field. | ||
| The caller keeps using the value `pto.declare_struct` produced. | ||
|
|
||
| ```text | ||
| for i in 0 .. 13: | ||
| session[i] = template_slot[i] | ||
| ``` | ||
|
|
||
| - **Example:** | ||
|
|
||
| ```mlir | ||
| %sess = pto.declare_struct | ||
| -> !pto.struct<i64, i64, i32, i32, i32, i32, i64, i64, i32, i32, i32, i32, i32> | ||
| pto.session_init %sess, %sess_gm | ||
| : !pto.struct<i64, i64, i32, i32, i32, i32, i64, i64, i32, i32, i32, i32, i32>, | ||
| !pto.ptr<i8, gm> | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### `pto.sdma_gm_gm` | ||
|
|
||
| - **Purpose:** Copy `%nbytes` contiguous bytes from `%src` to `%dst` through | ||
| the SDMA engine attached to `%sess`. | ||
| - **Syntax:** | ||
|
|
||
| ```mlir | ||
| pto.sdma_gm_gm %dst, %src, %nbytes session(%sess) | ||
| {block_bytes = $block}? {channel_idx = $ch}? {soft_put}? | ||
| : !pto.ptr<T, gm>, !pto.ptr<U, gm>, i64, | ||
| !pto.struct<i64, i64, i32, i32, i32, i32, i64, i64, i32, i32, i32, i32, i32> | ||
| ``` | ||
|
|
||
| - **Operands and attributes:** | ||
|
|
||
| | Name | Type | Description | | ||
| |------|------|-------------| | ||
| | `%dst` | `!pto.ptr<T, gm>` | Destination range; may name peer memory by address | | ||
| | `%src` | `!pto.ptr<U, gm>` | Source range; may name peer memory by address | | ||
| | `%nbytes` | `i64` | Contiguous byte count | | ||
| | `session(%sess)` | the 13-field session struct | Required session | | ||
| | `block_bytes` | optional `i64` attr | Split size in bytes; omitted uses the session value | | ||
| | `channel_idx` | optional `i64` attr | Channel group for this kick; omitted uses the session value | | ||
| | `soft_put` | optional unit attr | A5 remote-write completion path; ignored on A2/A3 | | ||
|
|
||
| - **Results:** None. | ||
| - **Constraints:** | ||
| - `%dst` and `%src` must be GM pointers. Element types need not match; the | ||
| transfer is counted in bytes. | ||
| - `%sess` must use the session struct type above. | ||
| - There is no stride or burst model. | ||
| - `block_bytes`, when present, must be positive and a multiple of 64. | ||
| - `channel_idx`, when present, must be less than 40. | ||
| - Must be outside SIMT entry functions and `pto.section.simt`. | ||
| - Must be inside an ordinary AICore `pto.kernel` function. | ||
| - **Semantics:** Post a copy of `%nbytes` bytes from `%src` to `%dst`. The | ||
| session supplies the engine connection, the default split, the channel group, | ||
| and the service class. Either pointer may address peer memory; peer-ness is | ||
| the numeric address, not a pointer attribute. | ||
|
|
||
| Without `{soft_put}` the kick does not wait for the engine. Returning from | ||
| the kernel does not mean the destination is visible. The caller observes | ||
| completion by an agreed host-side check or a later sync object. | ||
|
|
||
| `{soft_put}` is for a remote write on A5. That generation's engine does not | ||
| perform a remote write, so this attr makes the copy complete before the op | ||
| returns. A2/A3 ignore it and still post to the engine. | ||
|
|
||
| ```text | ||
| if soft_put and target is A5: | ||
| copy nbytes bytes from src to dst # finished when the op returns | ||
| else: | ||
| post the copy to the session's engine | ||
| return without waiting | ||
| ``` | ||
|
|
||
| - **Example (local copy):** | ||
|
|
||
| ```mlir | ||
| %sess = pto.declare_struct | ||
| -> !pto.struct<i64, i64, i32, i32, i32, i32, i64, i64, i32, i32, i32, i32, i32> | ||
| pto.session_init %sess, %sess_gm | ||
| : !pto.struct<i64, i64, i32, i32, i32, i32, i64, i64, i32, i32, i32, i32, i32>, | ||
| !pto.ptr<i8, gm> | ||
| pto.sdma_gm_gm %dst, %src, %nbytes session(%sess) | ||
| : !pto.ptr<i8, gm>, !pto.ptr<i8, gm>, i64, | ||
| !pto.struct<i64, i64, i32, i32, i32, i32, i64, i64, i32, i32, i32, i32, i32> | ||
| ``` | ||
|
|
||
| - **Example (A5 remote write):** | ||
|
|
||
| ```mlir | ||
| pto.sdma_gm_gm %dst, %src, %nbytes session(%sess) {soft_put} | ||
| : !pto.ptr<i8, gm>, !pto.ptr<i8, gm>, i64, | ||
| !pto.struct<i64, i64, i32, i32, i32, i32, i64, i64, i32, i32, i32, i32, i32> | ||
| ``` | ||
|
|
||
| - **Example (per-core channel after init):** | ||
|
|
||
| ```mlir | ||
| %bid = pto.get_block_idx | ||
| %bid32 = arith.trunci %bid : i64 to i32 | ||
| pto.session_init %sess, %sess_gm | ||
| : !pto.struct<i64, i64, i32, i32, i32, i32, i64, i64, i32, i32, i32, i32, i32>, | ||
| !pto.ptr<i8, gm> | ||
| pto.struct_set %sess[4], %bid32 | ||
| : !pto.struct<i64, i64, i32, i32, i32, i32, i64, i64, i32, i32, i32, i32, i32>, i32 | ||
| pto.sdma_gm_gm %dst, %src, %nbytes session(%sess) | ||
| : !pto.ptr<i8, gm>, !pto.ptr<i8, gm>, i64, | ||
| !pto.struct<i64, i64, i32, i32, i32, i32, i64, i64, i32, i32, i32, i32, i32> | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## PTODSL | ||
|
|
||
| PTODSL explicit mode exposes the same two operations as `pto.session_init` and | ||
| `pto.sdma_gm_gm`. The session type is `pto.async_session_type()`. A session still | ||
| cannot be a kernel argument: the host writes the GM template, and the kernel | ||
| declares its own struct then fills it. See | ||
| [7.7 GM↔GM SDMA](../../../ptodsl/docs/user_guide/07-data-movement-ops.md#77-gmgm-sdma-ptosession_init-and-ptosdma_gm_gm) | ||
| in the PTODSL user guide. | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PTODSL接口和文档也需要补充