Fix: guard tensor producer resolution on the returned slot pointer - #1686
Conversation
wait_for_tensor_ready's resolve_producer returns nullptr for a rejected producer, and both call sites dereference the result immediately. They branched on the `failed` flag instead of the pointer, so the null check was correct only because every rejection path happens to latch `failed` first — a coupling invisible at the call site. Branch on the pointer. submit_task aborted via always_assert on an empty MixedKernels active mask, while the adjacent block_num check reports INVALID_ARGS. Both are caller input errors; report the mask one the same way. submit_dummy_task keeps its empty mask: it calls submit_task_common directly and an empty mask is what routes it to the DUMMY bucket. Document ThreadCompletionGate's contract: the release/acquire pair that makes the finalizer's writes visible to the cleanup claimant, that thread_count is a per-round constant, and that reset() is unsynchronized and may only run outside a round. Correct the wide-dispatch scene test's docstring. It sizes cohorts from rt_available_cluster_count(), which is SIM_AUTO_BLOCKDIM (8) on the sim platforms it is marked for — 24 core-state bits, so it cannot reach a cluster offset above bit 63. test_hbg_core_tracker.cpp carries that coverage by driving CoreTracker at MAX_CLUSTERS. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe PR replaces assertion-based failures with runtime fatal error reporting for invalid kernel masks. It also uses null producer slots for immediate failure handling and adds documentation for thread completion and wide-dispatch behavior. ChangesOrchestrator error handling
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/common/utils/thread_completion_gate.h`:
- Around line 32-34: Update the reset() precondition documentation and
enforcement so reset occurs only after the previous round’s cleanup claim has
completed, not merely after the finalizer returns; alternatively synchronize
reset() with any pending claim_cleanup() calls. Ensure cleanup_ready_ cannot be
cleared before claim_cleanup() finishes.
🪄 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: ef00c447-e6de-4828-90be-c0b44d0d2333
📒 Files selected for processing (6)
src/a2a3/runtime/host_build_graph/runtime/orchestrator_core/pto_orchestrator.cppsrc/a2a3/runtime/host_build_graph/runtime/orchestrator_core/pto_runtime2.cppsrc/a5/runtime/host_build_graph/runtime/orchestrator_core/pto_orchestrator.cppsrc/a5/runtime/host_build_graph/runtime/orchestrator_core/pto_runtime2.cppsrc/common/utils/thread_completion_gate.htests/st/host_build_graph_wide_dispatch/test_host_build_graph_wide_dispatch.py
CI triage:
|
Update: card-7 fault confirmed on an unrelated branch — re-run would be pointless
Same runner, same refusal, unrelated code. Combined with the three I am not re-running it: Everything else on this PR is green, including all four checks that actually exercise the
|
✅ All checks green —
|
Summary
Follow-ups from the review of #1674, which merged as e041083. No behavior change
on any path that was already correct; each item removes a latent hazard or a
claim the code does not support.
wait_for_tensor_ready'sresolve_producerreturnsnullptrfor a rejectedproducer and both call sites dereference the result immediately, but they
branched on the
failedflag rather than the pointer. That is safe onlybecause every rejection path happens to latch
failedfirst — a couplinginvisible at the call site, and one early-return without the flag turns it
into a null deref inside the fatal-error path. Branch on the pointer.
submit_taskaborted viaalways_asserton an emptyMixedKernelsactivemask while the adjacent
block_numcheck reportsINVALID_ARGS. Both arecaller input errors; report them the same way.
submit_dummy_taskisdeliberately untouched — it calls
submit_task_commondirectly and an emptymask is exactly what routes it to the DUMMY bucket.
ThreadCompletionGate's contract: the release/acquire pair thatmakes the finalizer's writes visible to the cleanup claimant, that
thread_countis a per-round constant rather than a property of one arrival,and that
reset()is unsynchronized and may only run outside a round."across the high half of the 128-bit core mask". It sizes cohorts from
rt_available_cluster_count(), which isSIM_AUTO_BLOCKDIM(8) on the simplatforms it is marked for — 24 core-state bits, so it cannot reach a cluster
offset above bit 63.
test_hbg_core_tracker.cppcarries that coverage bydriving
CoreTrackerdirectly atMAX_CLUSTERS.Both arch trees stay byte-identical for the two
.cppfiles touched.Testing
thread_completion_gate.hcompiled standalone with-Wall -Wextraandexercised with the blocked-finalizer and reset-reuse cases from the existing
UT: passes, and passes again under
-fsanitize=thread..cppfiles:clang++ -std=c++17 -fsyntax-onlyclean with theUT target's include paths.
format, pyright, and the repo header/English/platform-literal hooks all pass.
Not run, and why: this host has neither the scikit-build-core/nanobind build
environment nor an NPU (
npu-smiabsent), so I could not do an editable rebuildor run the C++ UTs, the sim sweeps, or any onboard test. The three C++ edits are
a branch-condition swap, an assert-to-error-return conversion, and comments; the
Python edit is docstring and comment only. CI is the first real build of this
branch.
One unrelated environment defect found: the
clang-tidypre-commit hook abortswith
FileNotFoundErroron a stale worktree path inPYTHONPATH(
tests/lint/clang_tidy.py:33). It reproduces on a clean tree with all localchanges stashed, so it is not caused by this branch, and CI is unaffected since
it builds a fresh environment.
🤖 Generated with Claude Code