Skip to content

Fix: ACK-gate L2 swimlane rotation after moving AICore FIN early#1293

Merged
ChaoWao merged 1 commit into
hw-native-sys:mainfrom
ChaoWao:l2-swimlane-fin-early-ack-gate
Jul 8, 2026
Merged

Fix: ACK-gate L2 swimlane rotation after moving AICore FIN early#1293
ChaoWao merged 1 commit into
hw-native-sys:mainfrom
ChaoWao:l2-swimlane-fin-early-ack-gate

Conversation

@ChaoWao

@ChaoWao ChaoWao commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • AICore executor (tmr): move the FIN write ahead of the swimlane record so op order is ACK → pmu_begin → start → execute → FIN → end → pmu_end → dump → record. Completion is now signalled before the ~0.5 µs record write-back, and the three swimlane timestamps are gated on l2_swimlane_enabled (zero counter reads when profiling is off).
  • AICPU ACK-gate (fixes the race the reorder opens): because FIN now precedes the record's dcci+dsb, the completion-before-dispatch invariant no longer proves the old buffer's tail record has drained at a BUFFER_SIZE rotation. At rotation AICPU now only publishes the new buffer and stashes the just-filled one; it releases the buffer to the host only when AICore ACKs the new buffer's first task (reg_task_id == gate). By AICore's single-threaded program order that ACK is emitted only after the previous task's record + dsb, so the tail record is proven drained. New l2_swimlane_aicpu_on_aicore_ack wired into the tmr completion path; on_aicore_dispatch gains the gate reg_task_id.
  • host_build_graph writes the record before FIN, so it has no such window — it shares the rotate but relies on the next-rotation / run-end backstop (no ACK hook wired). Its dispatch caller is updated for the new signature.
  • docs/investigations: a switch-overhead decomposition (the ~0.8 µs inter-task "switch" is mostly profiling self-cost — get_sys_cnt reads + the record write-back — not a real hardware task switch; the WAIT gap p99 ~700 µs dominates decode) plus the previously-dropped head-poll micro-opt writeup.

Why

The ~1 µs inter-task overhead that only shows up on the swimlane (not in early dispatch) is the profiling instrumentation itself. Moving FIN early lets AICPU observe completion ~0.5 µs sooner (before the record write) — but that reorder makes FIN-gated buffer rotation unsafe, so the ACK-gate is required to avoid publishing an undrained tail record (which the host would otherwise discard as start_time == 0).

Testing

  • L2 swimlane ST smoke passes on a2a3 silicon (--enable-l2-swimlane 4 --enable-dep-gen)
  • qwen3_14b_decode level 4 passes on a2a3 silicon
  • Both a2a3 runtimes (tmr + host_build_graph) rebuild clean
  • Boundary path (>1024 AICore tasks/core) — not exercised by these workloads (qwen decode is ~15 tasks/core); the ACK-gate's deferral path is validated by construction, not by a boundary-crossing run

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 51768bcc-c916-4905-9cdb-ce7d591ee587

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR introduces an AICPU-side ACK gate for L2 swimlane AICore buffer rotation, deferring release of a rotated buffer until an observed ACK confirms the prior tail record's drain via a reg_task_id token threaded through dispatch and completion hooks. It also reorders AICore executor timestamp/FIN sequencing and adds two investigation documents plus an index update.

Changes

ACK-Gated Swimlane Rotation

Layer / File(s) Summary
Header contracts for ACK-gated dispatch and release hooks
src/a2a3/platform/include/aicore/l2_swimlane_collector_aicore.h, src/a2a3/platform/include/aicpu/l2_swimlane_collector_aicpu.h
Adds reg_task_id parameter to the dispatch hook, declares new l2_swimlane_aicpu_on_aicore_ack hook, and rewrites rotation invariant documentation.
AICPU pending-enqueue and ACK-gate implementation
src/common/platform/shared/aicpu/l2_swimlane_collector_aicpu.cpp
Introduces AicorePendingEnqueue, flush_aicore_pending_enqueue, reworks aicore_rotate to stash rather than immediately enqueue buffers, implements the new ACK hook, and updates end-of-run flush.
Executor timestamp reorder and dispatch/completion wiring
src/a2a3/runtime/tensormap_and_ringbuffer/aicore/aicore_executor.cpp, src/a2a3/runtime/host_build_graph/aicpu/aicpu_executor.cpp, src/a2a3/runtime/tensormap_and_ringbuffer/runtime/scheduler/scheduler_dispatch.cpp, src/a2a3/runtime/tensormap_and_ringbuffer/runtime/scheduler/scheduler_completion.cpp
Reorders FIN/timestamp capture, gates timing on l2_swimlane_enabled, and threads reg_task_id/task_id through dispatch and completion call sites to trigger the ACK gate.
Investigation write-ups and index
docs/investigations/2026-07-aicore-swimlane-switch-overhead-and-ack-gate.md, docs/investigations/2026-07-aicore-swimlane-head-dcci-boundary-poll.md, docs/investigations/README.md
Adds two investigation documents (shipped ACK-gate change, dropped head-poll optimization) and indexes them.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Poem

A buffer rotates, waits, and stalls,
Till ACK confirms the tail record falls.
No poll too eager, no gate too late—
Just reg_task_id deciding fate. 🐇
Two docs recorded what we learned,
One shipped, one dropped, both hard-earned. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: ACK-gating L2 swimlane rotation after moving AICore FIN earlier.
Description check ✅ Passed The description is detailed and directly describes the implemented ACK-gate fix, profiling changes, docs, and testing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements an AICPU-side ACK-gate on buffer rotation and reorders operations in the AICore executor to sample end_time after an early FIN write, which decouples the record write from the completion-signal path. It also adds detailed investigation documents explaining these design choices and why other micro-optimizations were dropped. The reviewer identified a critical issue in l2_swimlane_collector_aicpu.cpp where the static global array s_aicore_pending_enqueue is not reset during initialization, which can lead to state leakage and memory corruption across runs on the AICPU platform.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/common/platform/shared/aicpu/l2_swimlane_collector_aicpu.cpp
@ChaoWao ChaoWao force-pushed the l2-swimlane-fin-early-ack-gate branch 4 times, most recently from dae7f24 to fb6eb0c Compare July 8, 2026 09:10
Move the tensormap_and_ringbuffer AICore FIN write ahead of the swimlane
record (order: ACK -> pmu_begin -> start -> execute -> FIN -> end ->
pmu_end -> dump -> record) so completion is signalled before the ~0.5us
record write-back, and gate the three swimlane timestamps on
l2_swimlane_enabled.

FIN now precedes the record's dcci+dsb, so the completion-before-dispatch
invariant no longer proves the old buffer's tail record has drained at a
BUFFER_SIZE rotation. AICPU therefore stops enqueueing the just-filled
buffer at rotation: it stashes the buffer and releases it to the host
only when AICore ACKs the new buffer's first task (that ACK is emitted
after the previous task's record dcci+dsb, proving it drained).
host_build_graph writes the record before FIN and has no such window; it
shares the rotate but relies on the next-rotation / run-end backstop.

- reorder + timestamp gating: a2a3 tmr aicore_executor.cpp
- ACK-gate: shared l2_swimlane_collector_aicpu.{cpp,h}, new
  l2_swimlane_aicpu_on_aicore_ack wired into the a2a3 tmr
  scheduler_completion path; the deferred-enqueue stash is reset in
  l2_swimlane_aicpu_init so it cannot leak a dangling buffer across launches
- on_aicore_dispatch gains the gate reg_task_id; all callers updated
  (a2a3 + a5, tmr scheduler_dispatch + hbg aicpu_executor) and the a5
  aicpu collector header brought in line with the shared signature
- docs/investigations: switch-overhead decomposition (the gap is mostly
  profiling self-cost - get_sys_cnt reads + record write-back)

Verified: a2a3 L2 swimlane ST smoke + qwen3_14b_decode level 4 pass on
silicon; a2a3sim + a5 sim/plain swimlane smokes pass; a2a3/a5 runtimes
and sims rebuild clean. The boundary path (>1024 tasks/core) is not
exercised by these workloads.
@ChaoWao ChaoWao merged commit bd1025f into hw-native-sys:main Jul 8, 2026
16 checks passed
@ChaoWao ChaoWao deleted the l2-swimlane-fin-early-ack-gate branch July 8, 2026 09:26
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.

1 participant