Add: [Binder] standalone three-stream kernel submission - #2187
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
43f6432 to
2db026c
Compare
2db026c to
136e971
Compare
Separate the submission protocol from pending K1 and HBG ownership APIs. Acquire a prepared owner lease, validate stream/event handles and native arguments, then enqueue AICore before the non-hidden AICPU branch and join both on caller. Pair every successful acquisition with one finish callback carrying success, clean rejection or poison-worthy failure. Keep context phase, capacity, callable and packet validation in the owner adapter. Expose no new wire layout or public C ABI. Preserve pre-AICPU cancel/retry compensation and separate submission/cleanup errors without resource creation, synchronization or capture-specific model attachment. Build the module directly on main. Cover owner lease balance, concurrency, stream switches, every enqueue/compensation failure, native HostArgs and source/dependency guards. Document the deferred owner integration.
探针实测:这个形状已被验证,但提交路径上有两处操作在 capture 下会被 CANN 拒绝环境:a2a3 onboard,CANN 9.0.0,torch_npu 2.7.1, 先说好消息:这个 PR 实现的形状,我已经在硬件上验过了,通过。下面两条问题都是条件触发的,所以naive 的 capture 冒烟测试大概率发现不了。 🔴 1.
|
| 操作 | op rc | status | CaptureEnd |
|---|---|---|---|
| wait 一个在捕获开始前 record 的 event | 107024 | ACTIVE | 0 |
107024 正是 capture 隔离错误。所以:只要 consume_prepare_tail 为真而本次 launch 正在被捕获,提交就会失败。
为什么这条特别难发现:它是条件性的(f.pending_prepare)。一次"prepare 一次、捕获 N 次 replay"的测试永远不会踩到;只有"新 prepare 之后紧接着一次被捕获的 launch"才会。
这条也正好落在设计文档 D.1 列的待确认项上——"PrepareTail 的用途或删除"。现在有硬约束了:它不能以"在 caller stream 上入队一次 wait"的形式跨越捕获边界。
🟠 2. QueryTail 用的 aclrtQueryEventStatus 在捕获中也被拒(107028)
const int rc = aclrtQueryEventStatus(event, &status);Probe C 实测:捕获期间 aclrtQueryEventStatus 与 aclrtSynchronizeEvent 都返 107028。
PR 描述里说提交路径"不 synchronize 或 query capture"——capture 查询确实没有,但 aclrtQueryEventStatus 是事件查询,是另一回事,而它同样非法。触发条件是"换了 caller",同样是条件性的。
我没有隔离清楚的一点(请自行确认):我的用例是先在捕获流上 record 该 event 再 query,所以无法区分 CANN 拒绝的原因是"这个 event 属于捕获"还是"GLOBAL 模式下捕获期间任何事件查询都不许"。若是后者,那么换 caller 分支查旧 tail 也一样会被拒。
🟡 3. "no allocation in the submission path" 没有运行期执法
PR 写了提交路径无分配——方向对,但 CANN 不会替你挡:
| 操作 | op rc | status | CaptureEnd |
|---|---|---|---|
aclrtMalloc / aclrtFree(捕获期间) |
0 | ACTIVE | 0 |
GLOBAL 与 RELAXED 模式都一样:返回 0、capture 状态仍 ACTIVE、CaptureEnd 正常出图。所以这条不变式只能靠 ⑫ST 的禁止-API 追踪 shim 守,不能指望运行期报错。
🟡 4. caller 必须每次 launch 现取,不得缓存
这条 PR 把 caller stream 作为入参接收,是对的;但对调用方的契约没有写。两个互相独立的理由:
① capture:torch_npu.npu.graph 进入时切到它自己的捕获流,outer != capture。拿捕获外那条流做 record/wait 的结果是——入队不报错、capture 不报错、replay 静默地什么都不做,只有数值不对。(Probe B′ 负对照,已复现。)
② 任务队列:TASK_QUEUE_ENABLE=1 时 torch 把 op 投给 acl_thread 后台发射。队列深 4000、每臂 40×4 轮:
| 臂 | 违例 |
|---|---|
每次现取 current_stream() |
0 / ~160 |
| 缓存 stream 指针 | 2 次 |
| 缓存 stream + data_ptr | 2 次(读到 3997、3907) |
注意"现取就没事"是观察,不是保证——0/160 不是证明,不能当契约。
✅ 正面:这个 PR 的形状已经在硬件上验过
| 探针 | 验的是 | 结果 |
|---|---|---|
| B′ | 两条侧流(AICPU 专用 + AICore hidden)只经 event 与 caller 相连,能否同时进一次 capture | 过,3/3 replay,零 ACL 错误 |
| C | 同一形状在 raw aclmdlRICapture* 下(不经 torch 包装) |
过,独立复核 |
| D | 多张图共享同一批 context 常驻 event/stream:交替 replay、背靠背不同步 replay、replay 后混 eager | 六项全过 |
计划把 Probe B 标为"最要紧""不通则整段返工,930 前返工窗口极窄"——已经通了,这个 PR 的三流形状不需要返工。D 顺带把 H7「分桶切换」的前提也验掉了。
另一条对 §12.2 三分支的正面证据:"同 caller 不查不等旧 tail"是必须的,因为跨捕获边界的 event wait 就是上面第 1 条的 107024。你们选的分支是对的。
边界
全部 限 a2a3,a5 一个没跑——按非目标 #12 不得由 a2a3 推断 a5。
Probe E(handshake 最小失效区)我没跑,它要改 simpler 源码做仪表;⑦∥K7 那边别当它已完成。
A prepared kernel invocation needs a bounded three-stream submission protocol. This draft adds a standalone binder submission module directly on main, with no unmerged K1/HBG code or prerequisite commits in the diff.
Scope
One commit, 14 files, +1,175 lines:
This is not a squash of the previous dependency stack. The K1 context/ABI/resource implementation and H1-H4 changes have been removed from this PR entirely.
Behavior
Owner boundary / deferred integration
Internal C++ types live in
simpler::kernel_launch. There is no new public C ABI, assumed invocation wire layout or duplicate context phase machine.acquiremust validate real context phase, device/callable generation, frozen capacity, packet ABI and runtime bindings, and hold the submission lease against concurrent prepare/close.finishapplies success state updates, preserves clean rejection state, or poisons partial submission, then releases the lease. Unit tests use a fake owner to exercise this contract; they do not supply a production K1/HBG adapter.The previous complete integration snapshot is retained on codex/kernel-binder-integration-backup. After prerequisite PRs merge, port its context/resource and HBG packet/slot checks into the owner adapter. No prerequisite code is imported here merely to satisfy a missing header.
Validation
Before end-to-end acceptance
These items remain separate integration work. Program-mode execution is unchanged. The design basis remains the saved September 8 v9 final-decision table; the live design site could not be refreshed from this environment.
Submission stage
Binder (pipeline step 9). This draft remains one standalone commit directly on main. The commit title now identifies its stage; the tree is unchanged. No prerequisite commits or HBG integration code have been added.