Skip to content

a5 host_build_graph: shrink ready-queue capacity 65536 -> 8192 + graph_ready safe-fail - #1773

Merged
ChaoZheng109 merged 1 commit into
hw-native-sys:mainfrom
ChaoZheng109:hbg-ready-queue-8192-a5
Aug 11, 2026
Merged

a5 host_build_graph: shrink ready-queue capacity 65536 -> 8192 + graph_ready safe-fail#1773
ChaoZheng109 merged 1 commit into
hw-native-sys:mainfrom
ChaoZheng109:hbg-ready-queue-8192-a5

Conversation

@ChaoZheng109

Copy link
Copy Markdown
Collaborator

a5 host_build_graph: ready-queue capacity 65536 -> 8192 + graph_ready safe-fail

a5 mirror of #1762 (which was a2a3-only). a5's Graph execution landed in #1733,
which copied a2a3's pre-#1762 push_ready_routed — including the graph_ready
push that ignored its return value. This PR applies the same two changes #1762
landed for a2a3.

Changes

a5's push_ready_routed was byte-identical to a2a3 pre-#1762; this is a 1:1
mirror and the two changed regions are now identical across a2a3 and a5.
PTO2_ERROR_READY_QUEUE_OVERFLOW 104 was already added to a5's error enum by
#1733, so no enum change is needed.

Verification

  • Builds clean: a5 HBG host + aicpu (sim).
  • a5sim golden: graph_execution (3) + paged_attention (1) — 4 passed.
  • a2a3/a5 byte-parity of both changed regions confirmed.

Caveat

a5 has no independent peak-occupancy measurement — the same gap #1762 noted
when it deferred a5. The safe-fail now covers graph_ready too, so an undersized
cap surfaces as READY_QUEUE_OVERFLOW (named emergency_shutdown) rather than
silent corruption or a hang. a5 onboard occupancy measurement remains a
separate follow-up, matching how #1762 treated a5.

…h_ready safe-fail

Mirror of hw-native-sys#1762 for a5. a5 gained Graph execution in hw-native-sys#1733, which also copied
a2a3's pre-hw-native-sys#1762 push_ready_routed — including the graph_ready push that
ignored its return value, so a full graph_ready_queue would silently drop a
task and stall. Apply the same two changes hw-native-sys#1762 landed for a2a3:

  - PTO2_READY_QUEUE_SIZE 65536 -> 8192. The Vyukov ring bounds peak concurrent
    occupancy (enqueue_pos - dequeue_pos), not total task count, so capacity
    need only exceed the worst-case ready burst with margin.
  - push_ready_routed: route the GRAPH task through the same checked push as
    ready/sync/dummy so a full graph_ready_queue latches
    PTO2_ERROR_READY_QUEUE_OVERFLOW (named emergency_shutdown) instead of a
    silent drop.

a5 push_ready_routed was byte-identical to a2a3 pre-hw-native-sys#1762, so this is a 1:1
mirror; both regions are now identical across the two arches. The
PTO2_ERROR_READY_QUEUE_OVERFLOW 104 code was already added to a5's error enum
by hw-native-sys#1733, so no enum change is needed here.

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR reduces PTO2_READY_QUEUE_SIZE from 65536 to 8192 and documents occupancy-based sizing. It also checks graph-task queue pushes and latches PTO2_ERROR_READY_QUEUE_OVERFLOW when enqueue operations fail.

Changes

Ready Queue Overflow Handling

Layer / File(s) Summary
Ready queue capacity contract
src/a5/runtime/host_build_graph/runtime/pto_runtime2_types.h
The ready queue capacity is reduced to 8192. Documentation defines power-of-two sizing and overflow behavior.
Graph-task enqueue handling
src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h
Graph-task routing now checks graph_ready_queue.push and uses the shared overflow-reporting path.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Possibly related PRs

Poem

A queue once wide now holds its line,
Eight thousand slots in powers align.
Graph tasks knock; pushes now reply,
Overflow errors no longer fly.
The rabbit hops through safer time.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description directly explains the ready-queue reduction, graph queue overflow handling, parity goal, and verification results.
Title check ✅ Passed The title clearly summarizes both primary changes: reducing ready-queue capacity and adding safe failure for graph-ready enqueue.
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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/a5/runtime/host_build_graph/runtime/pto_runtime2_types.h`:
- Around line 96-102: Update the PTO2_READY_QUEUE_SIZE comment to explicitly
include graph_ready_queue and graph_prepare_queue alongside the ready, sync, and
dummy queues. Document that overflow from insertion into all named ready, sync,
dummy, and graph queue paths latches PTO2_ERROR_READY_QUEUE_OVERFLOW.
- Around line 96-102: Synchronize the a5 and a2a3 mirror headers byte-for-byte,
including include guards, comments, and the trailing `#endif`; update the affected
header to exactly match its counterpart while preserving the shared queue
definition and scheduler content.

In `@src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h`:
- Around line 493-505: Update both graph_prepare_queue enqueue paths to detect
push_tagged failure, latch PTO2_ERROR_READY_QUEUE_OVERFLOW, and stop retrying
instead of spinning indefinitely. Match the overflow handling used by
push_ready_routed while preserving the existing successful enqueue behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a43bfa95-0809-41e2-8684-687a4f854f90

📥 Commits

Reviewing files that changed from the base of the PR and between 89f15eb and d015c41.

📒 Files selected for processing (2)
  • src/a5/runtime/host_build_graph/runtime/pto_runtime2_types.h
  • src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h

Comment on lines +96 to +102
// Per-shape ready-queue capacity (power of two). This is a ring buffer that
// bounds peak CONCURRENT occupancy (enqueue_pos - dequeue_pos), not total task
// count: slots recycle, so capacity need only exceed the most tasks ever
// simultaneously ready in any one queue. Overflow on the ready/sync/dummy queues
// latches PTO2_ERROR_READY_QUEUE_OVERFLOW (safe-fail), so it must exceed the
// worst-case ready burst with margin.
#define PTO2_READY_QUEUE_SIZE 8192

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Document the graph queues in the capacity contract.

PTO2_READY_QUEUE_SIZE also sizes graph_ready_queue and graph_prepare_queue in src/a5/runtime/host_build_graph/runtime/shared/pto_runtime2_init.cpp:104-124. Lines 99-100 list only ready, sync, and dummy queues. The “per-shape” description also omits graph queues. Name all queues that use this capacity and state which insertion paths latch PTO2_ERROR_READY_QUEUE_OVERFLOW.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/a5/runtime/host_build_graph/runtime/pto_runtime2_types.h` around lines 96
- 102, Update the PTO2_READY_QUEUE_SIZE comment to explicitly include
graph_ready_queue and graph_prepare_queue alongside the ready, sync, and dummy
queues. Document that overflow from insertion into all named ready, sync, dummy,
and graph queue paths latches PTO2_ERROR_READY_QUEUE_OVERFLOW.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

diff -u \
  <(sed -n '96,102p' src/a5/runtime/host_build_graph/runtime/pto_runtime2_types.h) \
  <(sed -n '96,102p' src/a2a3/runtime/host_build_graph/runtime/pto_runtime2_types.h)

diff -u \
  <(sed -n '491,518p' src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h) \
  <(sed -n '491,518p' src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h)

Repository: hw-native-sys/simpler

Length of output: 247


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for file in \
  src/a5/runtime/host_build_graph/runtime/pto_runtime2_types.h \
  src/a2a3/runtime/host_build_graph/runtime/pto_runtime2_types.h \
  src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h \
  src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h
do
  if [ -f "$file" ]; then
    echo "FOUND $file"
    wc -l "$file"
  else
    echo "MISSING $file"
  fi
done

tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT

if [ -f src/a5/runtime/host_build_graph/runtime/pto_runtime2_types.h ] &&
   [ -f src/a2a3/runtime/host_build_graph/runtime/pto_runtime2_types.h ]; then
  sed -n '96,102p' src/a5/runtime/host_build_graph/runtime/pto_runtime2_types.h > "$tmpdir/a5-types"
  sed -n '96,102p' src/a2a3/runtime/host_build_graph/runtime/pto_runtime2_types.h > "$tmpdir/a2a3-types"
  diff -u "$tmpdir/a5-types" "$tmpdir/a2a3-types" || true
fi

if [ -f src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h ] &&
   [ -f src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h ]; then
  sed -n '491,518p' src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h > "$tmpdir/a5-scheduler"
  sed -n '491,518p' src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h > "$tmpdir/a2a3-scheduler"
  diff -u "$tmpdir/a5-scheduler" "$tmpdir/a2a3-scheduler" || true
fi

Repository: hw-native-sys/simpler

Length of output: 1347


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- a5 types ---'
sed -n '90,110p' src/a5/runtime/host_build_graph/runtime/pto_runtime2_types.h

echo '--- a2a3 types ---'
sed -n '90,115p' src/a2a3/runtime/host_build_graph/runtime/pto_runtime2_types.h

echo '--- a5 scheduler ---'
sed -n '485,525p' src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h

echo '--- a2a3 scheduler ---'
sed -n '485,525p' src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h

echo '--- exact scheduler-region comparison ---'
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT
sed -n '491,518p' src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h > "$tmpdir/a5"
sed -n '491,518p' src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h > "$tmpdir/a2a3"
cmp -s "$tmpdir/a5" "$tmpdir/a2a3" && echo IDENTICAL || echo DIFFERENT

Repository: hw-native-sys/simpler

Length of output: 7266


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
from difflib import unified_diff

a5 = Path("src/a5/runtime/host_build_graph/runtime/pto_runtime2_types.h").read_text()
a2a3 = Path("src/a2a3/runtime/host_build_graph/runtime/pto_runtime2_types.h").read_text()

print("--- header diff ---")
for line in unified_diff(
    a2a3.splitlines(True),
    a5.splitlines(True),
    fromfile="a2a3",
    tofile="a5",
):
    print(line, end="")

print("--- queue definitions ---")
for name, text in [("a5", a5), ("a2a3", a2a3)]:
    lines = text.splitlines()
    matches = [f"{i+1}: {line}" for i, line in enumerate(lines)
               if "PTO2_READY_QUEUE_SIZE" in line]
    print(name)
    print("\n".join(matches))

s5 = Path("src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h").read_bytes()
s2 = Path("src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h").read_bytes()
print("--- scheduler equality ---")
print("full files identical:", s5 == s2)
print("region 491-518 identical:",
      Path("src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h").read_text().splitlines()[490:518] ==
      Path("src/a2a3/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h").read_text().splitlines()[490:518])
PY

echo '--- queue-capacity usages ---'
rg -n -C 3 'PTO2_READY_QUEUE_SIZE|ready_sync_queues|dummy_ready_queue|graph_ready_queue|READY_QUEUE_OVERFLOW' \
  src/a5/runtime/host_build_graph/runtime \
  src/a2a3/runtime/host_build_graph/runtime

Repository: hw-native-sys/simpler

Length of output: 50377


Keep the a5 and a2a3 mirror headers byte-for-byte identical.

The queue definition and scheduler region match. The headers still differ in include guards, comments, and trailing #endif; these files are not documented exceptions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/a5/runtime/host_build_graph/runtime/pto_runtime2_types.h` around lines 96
- 102, Synchronize the a5 and a2a3 mirror headers byte-for-byte, including
include guards, comments, and the trailing `#endif`; update the affected header to
exactly match its counterpart while preserving the shared queue definition and
scheduler content.

Source: Learnings

Comment on lines +493 to 505
if (slot_state->task_kind == TaskKind::GRAPH) {
pushed = graph_ready_queue.push(slot_state);
} else {
pushed = ready_queues[static_cast<int32_t>(shape)].push(slot_state);
PTO2ResourceShape shape = slot_state->active_mask.to_shape();
if (shape == PTO2ResourceShape::DUMMY ||
(slot_state->task_attrs.has_predicate() && !slot_state->payload->predicate.pass())) {
pushed = dummy_ready_queue.push(slot_state);
} else if (slot_state->task_attrs.requires_sync_start()) {
pushed = ready_sync_queues[static_cast<int32_t>(shape)].push(slot_state);
} else {
pushed = ready_queues[static_cast<int32_t>(shape)].push(slot_state);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -u

rg -n -C 8 -P '\bgraph_prepare_queue\b' src/a5/runtime/host_build_graph

Repository: hw-native-sys/simpler

Length of output: 16999


🏁 Script executed:

#!/bin/bash
set -u

printf '%s\n' '--- queue implementation and error constants ---'
rg -n -C 10 'struct PTO2ReadyQueue|class PTO2ReadyQueue|bool push|push_tagged|PTO2_ERROR_READY_QUEUE_OVERFLOW|ready_queue_capacity' \
  src/a5/runtime/host_build_graph/runtime

printf '%s\n' '--- graph preparation call sites ---'
rg -n -C 14 'graph_prepare_queue\.(push|push_tagged)|while \(!sched_->graph_prepare_queue' \
  src/a5/runtime/host_build_graph/runtime

printf '%s\n' '--- scheduler error consumption and queue sizing ---'
rg -n -C 8 'sched_error_code|PTO2_READY_QUEUE_SIZE|off_graph_prepare_queue_slots|ready_queue_capacity' \
  src/a5/runtime/host_build_graph/runtime/scheduler \
  src/a5/runtime/host_build_graph/runtime/shared

Repository: hw-native-sys/simpler

Length of output: 50377


🏁 Script executed:

#!/bin/bash
set -u

printf '%s\n' '--- PTO2ReadyQueue push semantics ---'
sed -n '63,152p' src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h

printf '%s\n' '--- graph preparation control flow ---'
sed -n '1118,1160p' src/a5/runtime/host_build_graph/runtime/scheduler/scheduler_cold_path.cpp
sed -n '1288,1365p' src/a5/runtime/host_build_graph/runtime/scheduler/scheduler_dispatch.cpp

printf '%s\n' '--- queue consumers and scheduler stop behavior ---'
rg -n -C 6 'graph_prepare_queue\.pop|sched_error_code\.load|completed_\.load|PTO2_ERROR_READY_QUEUE_OVERFLOW' \
  src/a5/runtime/host_build_graph/runtime/scheduler

Repository: hw-native-sys/simpler

Length of output: 26385


Retain the overflow-handling concern for graph_prepare_queue.

Both graph_prepare_queue enqueue paths retry until push_tagged succeeds, but neither path latches PTO2_ERROR_READY_QUEUE_OVERFLOW. A full queue therefore causes an unbounded spin rather than the error handling used by push_ready_routed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h` around
lines 493 - 505, Update both graph_prepare_queue enqueue paths to detect
push_tagged failure, latch PTO2_ERROR_READY_QUEUE_OVERFLOW, and stop retrying
instead of spinning indefinitely. Match the overflow handling used by
push_ready_routed while preserving the existing successful enqueue behavior.

@ChaoZheng109
ChaoZheng109 merged commit 5d141a5 into hw-native-sys:main Aug 11, 2026
18 checks passed
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