Skip to content

Add: [Binder] standalone three-stream kernel submission - #2187

Draft
TaoZQY wants to merge 1 commit into
hw-native-sys:mainfrom
TaoZQY:codex/kernel-launch-binder
Draft

Add: [Binder] standalone three-stream kernel submission#2187
TaoZQY wants to merge 1 commit into
hw-native-sys:mainfrom
TaoZQY:codex/kernel-launch-binder

Conversation

@TaoZQY

@TaoZQY TaoZQY commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

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:

Area Lines
Core C++ submission interfaces/implementation 434
Unit tests and test fixtures 605
Build entries and docs navigation 35
Documentation 101

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

  • Acquire a prepared owner lease; validate distinct caller/AICPU/AICore streams and five event handles. The native adapter checks argument buffers, placeholder agreement/bounds and prepared clear/cancel regions inside that lease.
  • Consume the owner's pending PrepareTail, clear launch/handshake/report state, record Start, submit hidden AICore first, submit dedicated non-hidden AICPU with HostArgs, join both Done events on caller and record SerialTail.
  • Same-caller submission skips old-tail query/wait. A caller change queries the previous tail before enqueue and rejects not-ready/error cleanly.
  • Pair every successful acquire with exactly one finish, including native preflight, tail-query and partial-enqueue failures. Return the original error and compensation error separately. The owner applies poison after enqueue failure; no Host cancel follows successful AICPU submission.
  • Use pre-existing registered handles, HostArgs and cancel storage; no allocation, synchronization, capture query or model attachment in the submission path.

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.

acquire must validate real context phase, device/callable generation, frozen capacity, packet ABI and runtime bindings, and hold the submission lease against concurrent prepare/close. finish applies 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

  • Direct main-based runtime rebuild passed, including the real CANN adapter sources.
  • All 141 no-hardware C++ executables passed. Final namespace/lease-assertion changes were additionally rebuilt and all seven binder cases passed.
  • Three native-adapter cases passed against installed CANN declarations with fake ACL symbols.
  • 20 source/dependency guard cases passed, including the earlier raw RTS/ACL lifecycle guard fix.
  • Binder ASan with leak detection passed.
  • Full a2a3sim and a5sim regression sweeps passed (all runtimes, exclude level 4).
  • All applicable pre-commit checks and strict docs build passed.
  • No hardware tests: the read-only device query showed nonzero HBM on all devices. No native capture/replay, accuracy or performance claim.

Before end-to-end acceptance

  • Connect production context/callable/resource ownership and HBG packet/slot validation through the owner interface.
  • Connect native HBG device restore/retirement and the public kernel entry.
  • Verify ACL_EVENT_SYNC creation, wrong-event-flag rejection and three-stream event Probe B on device.
  • Verify mixed-operator capture/replay, pristine restore, numerical accuracy and performance.

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.

@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@TaoZQY
TaoZQY force-pushed the codex/kernel-launch-binder branch from 43f6432 to 2db026c Compare September 10, 2026 08:38
@TaoZQY TaoZQY changed the title Add: bind prepared kernel invocations to three-stream launch Add: standalone binder for three-stream kernel submission Sep 10, 2026
@TaoZQY
TaoZQY force-pushed the codex/kernel-launch-binder branch from 2db026c to 136e971 Compare September 10, 2026 08:48
@TaoZQY TaoZQY changed the title Add: standalone binder for three-stream kernel submission Add: [Binder] standalone three-stream kernel submission Sep 10, 2026
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.
@ChaoWao

ChaoWao commented Sep 12, 2026

Copy link
Copy Markdown
Collaborator

探针实测:这个形状已被验证,但提交路径上有两处操作在 capture 下会被 CANN 拒绝

环境:a2a3 onboard,CANN 9.0.0,torch_npu 2.7.1,task-submit --device auto
代码与完整结果在 docs-kernel-mode/probes/(每条含复跑命令与观测边界)。

先说好消息:这个 PR 实现的形状,我已经在硬件上验过了,通过。下面两条问题都是条件触发的,所以naive 的 capture 冒烟测试大概率发现不了。


🔴 1. PrepareWait 在 capture 下必被拒(107024)

if (h.consume_prepare_tail &&
    !step(KernelLaunchStep::PrepareWait, ops.wait_event(ops.context, h.caller, h.prepare_tail)))

文档里写 "Preparation records PrepareTail after initialization and slot registration"——也就是 PrepareTail 是在 prepare 期 record 的,而 prepare 在捕获之外(kernel 模式的 prepare_callable 本就定义为"capture 外 staging")。

Probe C 实测aclrtStreamWaitEvent 等一个在捕获开始之前 record 的 event107024,当场拒绝

操作 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 实测:捕获期间 aclrtQueryEventStatusaclrtSynchronizeEvent 都返 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 作为入参接收,是对的;但对调用方的契约没有写。两个互相独立的理由:

① capturetorch_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 那边别当它已完成。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants