Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/a5/runtime/host_build_graph/runtime/pto_runtime2_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,13 @@
// buffer (which would be UB on the arena's malloc'd backing).
#define PTO2_SCOPE_TASKS_CAP (PTO2_TASK_WINDOW_SIZE * PTO2_MAX_RING_DEPTH)

// Ready queue
#define PTO2_READY_QUEUE_SIZE 65536 // Per-shape queue size
// 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
Comment on lines +96 to +102

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


// Cross-thread early-dispatch work queue (power of two)
#define PTO2_EARLY_DISPATCH_QUEUE_SIZE 64
Expand Down
35 changes: 18 additions & 17 deletions src/a5/runtime/host_build_graph/runtime/scheduler/pto_scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,26 +489,27 @@ struct PTO2SchedulerState {
// the per-shape ready_sync_queues[] (drained as Tier-0); everything else to
// ready_queues[].
void push_ready_routed(PTO2TaskSlotState *slot_state) {
if (slot_state->task_kind == TaskKind::GRAPH) {
graph_ready_queue.push(slot_state);
return;
}
PTO2ResourceShape shape = slot_state->active_mask.to_shape();
bool pushed;
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);
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);
}
}
Comment on lines +493 to 505

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.

// A queue is sized for the whole task window and each task is routed to one
// queue exactly once, so push cannot legitimately fail. A false return means
// the target slot fell outside the shipped prefix, or the window genuinely
// exceeds queue capacity — either way the task is dropped and the run would
// otherwise stall. Latch a named error so it surfaces as READY_QUEUE_OVERFLOW
// rather than an anonymous forward-progress timeout.
// Every ready / sync / dummy / graph task routes to exactly one queue. A
// false push means that queue's peak concurrent occupancy exceeded
// PTO2_READY_QUEUE_SIZE — a capacity mis-sizing, not a normal condition.
// Silently dropping the task would stall the run, so latch a named error
// (surfaces as READY_QUEUE_OVERFLOW rather than an anonymous
// forward-progress timeout). The graph_ready push is checked identically
// so a graph task cannot be dropped either.
if (!pushed) {
int32_t expected = PTO2_ERROR_NONE;
sm_header->sched_error_code.compare_exchange_strong(
Expand Down
Loading