Fix: make two merged guards say what they actually guard - #1862
Conversation
Four corrections left behind by hw-native-sys#1845 and hw-native-sys#1857. No behavior changes. hw-native-sys#1857's comment on _ARM_CALLABLE_ID got the causality wrong while reaching the right conclusion. It called the L2 st_worker session-scoped; the sibling conftest overrides it to scope="class" precisely so this white-box stress gets a worker whose slot table starts empty. The collision it describes is therefore inside the class, not across the session: the framework's inherited test_run registers through Worker.register, which takes the lowest free slot (0) and caches the handle on the test class without unregistering, so id 0 stays occupied for the remaining tests. A file whose subject is what the arms prove should not misstate why they are wired the way they are. hw-native-sys#1857's diagnostics arm asserts a fallback the project intends to remove. concurrent_native_prepare_supported_impl keeps collector-bearing configurations sequential only until their state is per-epoch; when that lands and diagnostics_any() leaves allow_prepared_successor, the arm fails with the same "did not overlap" it currently requires, and the correct response is to delete it rather than restore the serialization. Nothing said so. The two negative arms differ in durability — one run in flight cannot overlap under any admission policy, so the serial arm is permanent — and that difference decides what to do when either goes red, so state it in both the test and docs/dfx/host-trace.md. hw-native-sys#1845 left set_host_log_state with no declaration anywhere: the sim AICPU backend defines it and both sim device_runner.cpp files resolve it by name, while its sibling set_log_level, resolved by the same load_sym call two lines above, is declared in aicpu/device_log.h. Declare it there too, with the state struct only forward-declared so neither <dlfcn.h> nor the state layout reaches device targets. The dlsym caller stays string-resolved, as set_log_level's does. hw-native-sys#1845's KeepsExistingInitArgumentOrder asserted that a function's address is non-null, which is a tautology; the real guard was that its helper compiled, and gcc can warn on the comparison. Express the intent directly as a static_assert on ChipWorker::init's type, which fails with a named diagnostic naming the rule it protects. Verified by reordering two parameters and confirming the build stops. Testing: ctest -LE requires_hardware --timeout 300 — 100/100 pass. Both aicpu/device_log.cpp backends syntax-check against the new declaration. pre-commit clean except clang-tidy, whose hook venv cannot import simpler and fails identically on untouched files.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe changes add a host logging state setter declaration, strengthen the ChangesHost logging API
Async pipeline contracts
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This change corrects documentation and strengthens compile-time contract checks without changing runtime behavior; no actionable merge-blocking risk remains after normal checks and review. 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 |
Summary
Four corrections left behind by #1845 and #1857. No behavior changes — one header declaration, one
static_assert, two comment blocks and one doc paragraph.Both merged PRs left a guard that does not say what it guards. That matters more than usual here: one of the files exists specifically to record what is proven, and the other holds a compile-time contract.
From #1857
The
_ARM_CALLABLE_IDcomment got the causality wrongIt reached the right conclusion from the wrong mechanism:
The sibling
conftest.pyoverridesst_workertoscope="class"— deliberately, so this white-box stress gets a worker whose slot table starts empty and does not enter_l2_worker_pool. So the collision is inside the class, not across the session.The actual chain, verified:
conftest.py:27@pytest.fixture(scope="class")test_runregisters viaWorker.registerscene_test.py:1506task_interface.py:1353_allocate_slot_lockedtype(self)._st_l2_handle; nothing unregisters itThe merged PR description also explained the original test's survival as "sorting alphabetically before
test_run". That is not how pytest collects (definition order within a class), and it does not fit the evidence either:test_serial_submission_…sorts alphabetically aftertest_runand passes.register_callable failed with code -1was a real observation; the story attached to it was not.The robustness claim in the old comment — off id 0 in any test order — is correct and is kept, since the arms bypass
_callable_registryvia_register_callable_at_slot.The diagnostics arm had no expiry condition
That arm asserts a fallback the project intends to remove.
concurrent_native_prepare_supported_implsays so itself:So when collector state becomes per-epoch and
diagnostics_any()leavesallow_prepared_successor, a diagnostic config will overlap like any other and the arm turns red with the verydid not overlapit currently demands. The correct response then is to delete the arm, not restore the serialization — and nothing in the test or the doc said so, which is how a temporary fallback gets cemented by its own test.The two negative arms are not equally durable, and that asymmetry is what decides the response:
inflight_limit=1)diagnostics_any()fallbackStated in both the arm's docstring and
docs/dfx/host-trace.md, since its value and its lifetime have the same source.From #1845
set_host_log_statehad no declaration anywhereThe sim AICPU backend defines it and both
sim/host/device_runner.cppfiles resolve it by name —grepfinds three references and zero declarations. Its siblingset_log_level, resolved by the sameload_symcall two lines above, is declared inaicpu/device_log.h. The previous revision of #1845 declared both underSIMPLER_CPU_SIM_HOST_LOG_BRIDGE; deleting that macro (correctly) took the declaration with it.Declared next to
set_log_level, with the state struct only forward-declared so neither<dlfcn.h>nor the state layout reaches device targets. Thedlsymcaller stays string-resolved, exactly asset_log_level's does — the point is that the definition now has something to disagree with.KeepsExistingInitArgumentOrderasserted a tautologyA function's address is never null. The real guard was that the helper compiled; the runtime assertion tested nothing, and gcc can warn on the comparison itself.
The intent — pin the parameter order, because the Python binding passes positionally and an inserted parameter silently changes what an existing call means — is worth keeping, so it is now expressed as what it is:
std::is_invocable_von the five leading arguments would not work — a pointer-to-member type carries no default arguments — and pinning the full type is the stricter, more useful guard anyway: any signature change becomes deliberate.Verification
ctest --test-dir tests/ut/cpp/build -LE requires_hardware -j4 --output-on-failure --timeout 300— 100/100 passaicpu/device_log.cppbackends syntax-check against the new declaration (g++ -fsyntax-only), including the onboard one that only ever sees the declaration.ruff checkandpy_compileclean.pre-commitclean on all four files exceptclang-tidy, whose hook venv cannotimport simplerand fails identically on untouched files.Not in scope
docs/dfx/host-trace.mdis now 306 lines, so this change is what pushes it pastdoc-consistency.md§6's ~300-line soft target (it already had 6 H2 sections). A split — most naturally lifting## Async pipeline proofand its negative-controls subsection intodocs/dfx/native-overlap-proof.md— is a bigger change than these corrections warrant, so it is flagged rather than bundled.CMakeLists.txtuseSIMPLER_HOST_LOG_SOURCES, butpython/bindings/CMakeLists.txt,sim_context/CMakeLists.txtandtests/ut/cpp/CMakeLists.txt(7 sites) still hardcode the two paths. A partial dedup keeps the "remember the other places" problem, so it wants its own change.🤖 Generated with Claude Code