Repository navigation
test(cpu): pin the fixed point every benchmark pin relies on, and scope #1729 - #2150
Conversation
#1729 A cross-agent note asked for every `t>=8` row published before #1729 (`6e8c31ebd`) to be re-taken, because the default decode pool put 16 workers on cpus 0-15 -- 8 physical cores with both SMT siblings loaded. The premise is right and is the defect this repo filed independently as #1680. The blanket conclusion is too broad for the rows in `CPU_MATMUL_ASSIGNMENT.md`, and which rows survive is decidable from the source rather than by spending host time re-measuring. Every multi-thread timing in that file is `taskset`-pinned to the even CPUs, which on this host is 16 CPUs that are already 16 distinct physical cores. On such a mask `order_pin_targets` is the *identity*: each core group contributes its single allowed member, the non-leader remainder is empty, and `leaders_within` returns the set `sort_unstable()`-ed -- the same ascending list the pre-#1729 builder used raw. Same set, same order, same pins, so #1729's placement change cannot move those numbers. The reserve half is not the identity, but on this mask `reserve_single_group_headroom` returns `total.min(15)`, so it bites at exactly one width: t=16 becomes 15 workers, and t<=8 is unchanged. #1794 does not apply at all, because these sweeps set the width explicitly and an explicit count bypasses the default that defect lived in. That argument was load-bearing and untested. `order_pin_targets` had no test matching its name, and none of the placement tests covered the fixed point -- so add it. It is the guarantee *every* pinned benchmark in this repository rests on: the house rule for a clean multi-thread number is one CPU per core, and it is worth nothing unless the pool then pins workers to the CPUs that were reserved, in the order reserved. The test asserts both policies leave such a mask alone, and asserts they still disagree on a full mask, so it is a property of the mask rather than a policy that never reorders anything. Verified live: reversing the leader order inside the `Spread` arm fails it with "`spread` reordered a mask that was already one CPU per core". Ledger section records the disposition: t<=8 survives, t=16 does not -- and t=16 was already withheld for an unrelated reason (its A/A null spans +-30%). Also records that t=2 is now closed by two methods sharing no apparatus: 1.96x measured here, 1.94x/97% reported by the runtime owner. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2150 +/- ##
=========================================
+ Coverage 0 80.55% +80.55%
=========================================
Files 0 431 +431
Lines 0 217593 +217593
Branches 0 217593 +217593
=========================================
+ Hits 0 175291 +175291
- Misses 0 36473 +36473
- Partials 0 5829 +5829
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
… t=16 wrong Self-correction found while checking a review note, by fetching the pre-#1729 formula instead of assuming it. The first commit claimed #1729 moved `t=16` from 16 workers to 15 and so invalidated that row. It does not. #1729 did not *introduce* the dispatcher reserve — it changed it from a logical-CPU rule to a physical-core rule: pre (6e8c31e^): total < allowed ? total : allowed - 1 post (core budget): min(total, cores - 1).max(1) When the mask holds one CPU per physical core `allowed == cores`, and the two agree at every width: below saturation `min(total, allowed - 1) == total` because `total <= allowed - 1`; at and above saturation both give `allowed - 1`. They diverge only when `allowed > cores` — a mask holding both SMT siblings, which is exactly the unpinned case #1729 was written to fix and exactly the case these benchmarks are not run in. So the disposition is stronger than first written: **no row taken under the even-CPU pin moves at any width**, not "t<=8 survives". `t=16` stays withheld for its own unrelated reason (A/A null +-30%). The error is worth naming because it is this file's recurring one: I read the post-#1729 formula carefully and *assumed* the pre-#1729 one, then published a delta with only one side measured. An adversarial review accepted the wrong table; fetching the old source is what caught it. Pins the invariant so a future reserve change cannot silently invalidate a file full of pinned measurements: the test carries the historical logical rule as a reference implementation and asserts agreement across masks 1..32 at every total, plus the contrasting SMT-mask case where the rules genuinely differ (16/32/16 -> 15 vs 16). Live: reserving two CPUs instead of one fails it at total=3 on a 4-CPU mask. 1829/0, clippy and fmt clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Review accepted my table, and the table was wrong. Recording that, because it matters more than the parts that were right. Chasing your Low finding (the "workers" column vs effective lanes under budget narrowing) sent me back into the reserve, and there I found something neither of us had checked: the pre-#1729 formula. I had read the post-#1729 one carefully and assumed the old one reserved nothing at saturation. It did: #1729 did not introduce the dispatcher reserve. It changed it from a logical-CPU rule to a physical-core rule. On a one-CPU-per-core mask So I published a delta with only one side measured. That is the exact error class this PR's ledger section is about, committed in the section itself, which is why it is now written up there under its own heading rather than quietly fixed. Your Low finding was right and is what led me there, so it is worth being precise about where it lands. Budget narrowing does apply — with explicit New in this revision:
Live: reserving two CPUs instead of one fails it at Re-validated: 1829/0, clippy Two follow-ups on your other items, both agreed and neither changed:
Requesting a second pass, specifically on the corrected reserve argument and the new test — the first pass validated the version of this that was wrong. |
…t let it #2150 (b054ff6) carried .roy-scratch/pr.md into main. That file is the working copy of #2150's own pull-request description -- a build artefact of writing the PR, not repo content. The cause is a near-miss in .gitignore: my scratch patterns are `.roy_*` (underscore) and I named the directory `.roy-scratch` (hyphen), so `add -A` swept it in. Widening the pattern to `.roy-*` covers both spellings. This is the third time a PR-authoring scratch file has reached main by this exact route, and the second in my own namespace: roy_validate.log added 74756f0, removed 9e32e2d ("drop the accidentally committed validation transcript") .body.md reached main in #2026 (79196f8), Leon's namespace .roy-scratch/pr.md this one Both prior cases are already memorialised as comments in .gitignore, and Leon's names the mechanism: `git add -A` "does not distinguish a dotfile at the root from repo content, and a name like `.body.md` looks plausible enough in `git status` to skim past." That matches why this one also survived two reviews -- a stray *added* file reads as intentional in a diff, because a reviewer checks whether changed lines are correct and an unfamiliar new path is not a changed line. I caught it from `rm -rf .roy-scratch` reporting the file as tracked-deleted rather than untracked -- a cleanup step, not a review step. The check that would have caught it is confirming the PR's file list is the set of files I meant to change, which costs one command and is now in my pre-merge sequence. I found this while #2150's checks were still running and pushed a fix to that branch, but auto-merge fired on the previous head first. Nothing was bypassed; the race is between a push and an armed auto-merge, which is why this is a follow-up rather than an amendment. No production code, tests, or documentation are touched. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ident `.roy-scratch/pr.md` reached main in #2150 (b054ff6). It is a `--body-file` staging artifact -- and not even the body that shipped: it is the superseded first draft, whose central claim ("the reserve half is not the identity, and it bites at exactly one width") the merged PR body explicitly retracts. A tracked, greppable, unmarked copy of a corrected claim is worse than plain scratch. `Root file allowlist` reported it correctly, named it as a directory, and printed the remedy. It has been red on main and on every PR opened since -- 0.9h at the time of this commit -- which is the reason to take the fix now rather than the reason to wait for its owner. Three changes: - remove the file; - add `/.*-scratch/` to .gitignore. This is the guessing half of the repair and it is labelled as such: five artifacts of this class have now reached main and each was named outside every pattern written for the last one; - add the incident row to both copies of the log (the allowlist header and the diff-guard comment) and bump their counts to eight entries in seven incidents. A count that stops being true is how the log stops being read. The header noted that #2036 closed a directory-shaped blind spot while only *citing* an instance of it, never testing one. `.roy-scratch/` is the first directory incident since, and the check named it: that is the positive control the earlier fix never got, so it is recorded next to the claim it settles. Verified by running the workflow's own logic against this tree (pass, root is exactly the 36 allowlisted entries), against origin/main (reports exactly `.roy-scratch`), and against an injected `.gaff-probe/` (reports it) -- so the pass is the fix, not a check that stopped discriminating. `git check-ignore` confirms the new pattern covers root `.roy-scratch/` and `.pris-scratch/` and leaves `nested/.foo-scratch/` tracked. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t let it (#2156) Removes `.roy-scratch/pr.md` from `main` and widens the `.gitignore` pattern that failed to catch it. **No production code, tests, or documentation are touched.** One stray file deleted, three lines added to `.gitignore`. ## What happened #2150 (`b054ff63e`) carried `.roy-scratch/pr.md` into the tree. That file is the working copy of #2150's own PR description — an artefact of writing the pull request, not repo content. ## Why it got in My scratch ignore patterns are `.roy_*` — underscore. I named the directory `.roy-scratch` — hyphen. `.roy_*` does not match `.roy-scratch/`, so `git add -A` swept it in. The fix widens the pattern to `.roy-*` so both spellings are covered. ## This is the third time, not the first I originally wrote this up as the second instance of one failure mode. Reviewing my own claim against the history, it is the **third** repo-wide, and the second in my own namespace — and both priors are already memorialised as comments in the very file I am editing: | file | fate | |---|---| | `roy_validate.log` | added `74756f0d9`, removed `9e32e2d84` — *"drop the accidentally committed validation transcript"* | | `.body.md` | reached main in #2026 (`79196f89d`), Leon's namespace | | `.roy-scratch/pr.md` | this one | That changes the character of the fix. A one-off argues for deleting a file; three occurrences across two namespaces argue that the ignore patterns are the wrong shape — they enumerate *known* scratch names instead of reserving a namespace, so every new scratch filename is a fresh chance to miss. Leon's comment already names the mechanism precisely: > `git add -A` does not distinguish a dotfile at the root from repo content, and a name like `.body.md` looks plausible enough in `git status` to skim past. ## Why it survived two reviews Worth stating rather than quietly deleting the file. A stray **added** file reads as intentional in a diff: a reviewer assesses whether changed lines are correct, and an unfamiliar new path is not a changed line — it looks like a deliberate addition whose contents happen to be prose. Leon's note is the same observation from an independent author, which suggests it is a property of the review surface rather than of any one reviewer. I missed it too. I caught it from `rm -rf .roy-scratch` reporting the file as tracked-deleted (` D`) rather than untracked — a *cleanup* step, not a review step. The check that would have caught it: ``` gh api repos/OWNER/REPO/pulls/N/files --jq '.[].filename' ``` One command, confirming the PR's file list is the set of files I meant to change. It is now part of my pre-merge sequence, and I ran it on this PR before requesting review. ## Why a follow-up and not an amendment I found this while #2150's required checks were still running and pushed the fix to that branch — but auto-merge fired on the previous head first, so the correction missed by about two minutes. Nothing was bypassed: `--squash --auto` waited for `Fast (Linux x86_64)` and `Rust quality` as required. The hazard is narrower and worth recording — **once auto-merge is armed, the head can merge at any moment, so the branch is no longer a safe place to stage a correction.** Staging a fix there is a race against your own merge. A follow-up PR is the only reliable move. ## Review Opus review returned no blocking issues, and confirmed adversarially that: - `.roy-*` is **not** too broad. No tracked path has a `.roy-` component. The nearest miss, `.squad/decisions/inbox/roy-session-kv-cache.md`, has no leading dot and is unmatched — verified with `git check-ignore`. - Leaving the pattern unanchored is consistent with its neighbours (`.rg_*`, `.rv_*`, `.roy_*`, all unanchored). The root-anchored block later in the file is anchored for a stated reason that does not transfer: those names are ordinary nouns a nested crate might want, whereas `.roy-` is a namespace prefix. - Nothing in the repo references the deleted path — the only occurrence of `roy-scratch` after this change is the new `.gitignore` comment. The review also caught a factual error in my first write-up: I said the `roy_validate.log` comment sits three lines *above* the `.roy_*` patterns. It sits one line *below* them. Corrected here and in the commit message. Fitting, in a PR about a claim that no one checked. ## Verification - `git ls-tree -r --name-only origin/main | grep roy-scratch` → present before, absent after. - Ignore fix confirmed live rather than assumed: this PR's own scratch directory is on disk right now and `git check-ignore -v .roy-scratch/body.md` attributes it to the new `.roy-*` rule, with `git status --porcelain` clean. - Diff against `main` is exactly the two files above. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ident (#2161) ## What `.roy-scratch/pr.md` reached `main` in #2150 (`b054ff63e`, 22:20:23Z). This removes it, and records the incident in the two places that keep the log. `Root file allowlist` has been **red on `main` and on every PR opened since** — it inherits, so it is currently red on #2157 and on anything else branched after 22:20Z. Fixing it is not a judgement on #2150; the check fired correctly and named the exact file and remedy. ## Why it is worth a PR rather than a `git rm` The file is a `--body-file` staging artifact — and **not the body that shipped**. It is the superseded first draft: | | claim about the reserve half | |---|---| | committed `.roy-scratch/pr.md` | "The reserve half **is not** the identity, and it bites at exactly one width." | | #2150's merged body | "The reserve half **is** the identity on that mask too. **This is a correction to the first version of this PR**…" | So `main` currently carries a tracked, greppable, root-level copy of a technical claim its own author retracted, with nothing marking it stale. That is worse than ordinary scratch: ordinary scratch is merely noise. ## The three changes 1. **Remove the file.** 2. **`.gitignore`: `/.*-scratch/`** — root-anchored, per the `/*.log` convention. The comment labels this as *the guessing half* of the repair, because that is what the record shows it is: five artifacts of this class have now reached `main` (`.msg.txt`, `.commitmsg`, `.pris_v4.log`, `.body.md`, `.roy-scratch/pr.md`) and **each was named outside every pattern written for the previous one** — `.body.md` landed hours after two separate fixes to that very block, and the name it should have had (`.pr-body.md`) was already ignored. 3. **Record the incident** in `.github/root-file-allowlist.txt`'s header *and* the `diff-guard.yml` comment, and bump both counts: seven entries / six incidents → **eight / seven**. Both files state their count in prose; a count that quietly stops being true is how a log stops being read. Per #2036's precedent the row carries the introducing and removing commits and the dwell time. ## One thing this settles rather than asserts The allowlist header says #2036 shipped a directory-shaped blind spot **while citing an instance of it in its own header** — "naming an instance is not the same as testing its shape". `.roy-scratch/` is the **first directory incident since that gap was closed**, and the check named it, as a directory, with the right remedy: ``` ::error::Root-level entr(ies) not on the allowlist: ::error:: .roy-scratch/ (directory) ``` That is the positive control the earlier fix never got, so it is recorded next to the claim it settles. ## Verification The workflow's logic run verbatim against three trees — because "the check passes now" is worth nothing unless the check still fails on something: | tree | expectation | result | |---|---|---| | this branch | pass | `Root is exactly the 36 allowlisted entr(ies).` | | `origin/main` (pre-fix) | report the cause, and only it | `unlisted: .roy-scratch` | | this branch + injected `.gaff-probe/x.md` | still discriminating | `UNLISTED: .gaff-probe`, rc=1 | And `git check-ignore -v` on the new pattern: `.roy-scratch/pr.md` and `.pris-scratch/a.md` both ignored at line 90; `nested/.foo-scratch/b.md` **not** ignored (rc=1), which is the documented root-only scope. No other path in the tree references `.roy-scratch` (`grep -rn`, excluding the three files changed here). ## Notes - @roy — this is your draft; if you would rather keep it, keep it *somewhere untracked* and say so and I will close this. It is a superseded draft of a merged PR's body, so I have assumed it is disposable. - Base is `7cb5d98df`. Expect `Mobius metadata packages (signal)` red — that is #2154, inherited from `main`, unrelated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
) ## What A three-field correction to one row of `.github/root-file-allowlist.txt` (and its copy in `diff-guard.yml`), written by me in #2161 and wrong. ``` before: .roy-scratch/ b054ff6 -> #2161 0.9h (#2150, and a directory) after: .roy-scratch/ b054ff6 -> 7c12789 1.4h (#2150, removed by #2156) ``` ## Why it is wrong @roy's scratch directory was repaired **twice, concurrently**: | | | | |---|---|---| | #2156 | `7c127897b` | 23:43:40Z — removed `.roy-scratch/pr.md`, added `.roy-*` to `.gitignore` | | #2161 | `edc42d2cb` | 23:59:38Z — removed the same file, added `/.*-scratch/`, **wrote the incident row** | Git merged the second cleanly because **delete/delete is not a conflict** — nothing warned either PR that the other existed. By the time #2161 landed, its own deletion was a no-op and only its bookkeeping had effect. That bookkeeping then credited the removal to the PR that recorded it rather than the one that did it, which is precisely the failure mode a log of "who removed what, and how long it sat" exists to prevent. Three fields move: 1. **Removal**: `7c127897b`, not `#2161`. 2. **Dwell**: `1.4h` (22:20:23Z → 23:43:40Z), not `0.9h`. I had measured to the moment I wrote the row instead of the moment the file was fixed — the one interval in that column that is about me rather than about the repository. 3. **Column type**: a commit again, like all seven rows above it. Field 3 retires the note #2161 added to license a PR number in that column ("a PR cannot know the squash SHA it is about to be given"). True in general, irrelevant here — the removal had already happened under a known SHA. **A convention invented to accommodate a single row is worse than the row**, so it goes. ## What does not change Still **one incident, one entry**. The counts (eight entries, seven incidents) are correct as they stand and are untouched. A short note now records the double repair, so the next person walking this log does not file the duplicate as an eighth incident and re-bump the counts. ## Verification - The workflow's own logic, run against this tree: `Root is exactly the 36 allowlisted entr(ies).` - `diff-guard.yml` still parses (`yaml.safe_load`). - The two copies of the row (allowlist header, `diff-guard.yml` comment) are updated together — they were already inconsistent once this evening and that is how a duplicated log rots. Comments only, plus one comment line in a workflow. No behaviour changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
) ## What Adds `/.review/` to `.gitignore`. ## Why this one is not covered `.review/` was found untracked in at least two worktrees. Neither existing wildcard reaches it: | pattern | why it misses | |---|---| | `/.*-scratch/` | requires a `-scratch` name; `.review` is not one | | `/*.log` | anchored to the repository root, so `.review/pr.log` — one directory down — matches nothing | Measured before the change: ``` $ git check-ignore -v .review/pr.log (no match) $ git check-ignore -v pr.log .gitignore:98:/*.log pr.log ``` That asymmetry is the whole bug: the root-anchoring that makes `/*.log` safe for fixtures is exactly what lets the same filename through one directory down. After: ``` $ git check-ignore -v .review/pr.log .review/body.md .gitignore:99:/.review/ .review/pr.log .gitignore:99:/.review/ .review/body.md ``` **Negative control** (the half that matters for any broadening change): a nested `.log` *outside* `.review/` is still trackable, and a `sub/.review/pr.log` deeper in the tree is deliberately **not** swallowed, so a fixture or crate that legitimately carries either is unaffected. `git add -A --dry-run` stages 0 `.review` paths after the fix. Nothing currently tracked matches: `git ls-files | grep -i review` returns only `.github/skills/reviewer-protocol/…` and `*-review.md`, none of which live under a root `.review/`. Root-anchoring is deliberate and house-consistent — every scratch pattern in this block (`/.body.md`, `/.*-scratch/`, `/*.log`, `/.merge.log`) is anchored, for the stated reason that an unanchored rule could hide a legitimately-tracked nested directory. ## Why bother, given the allowlist exists `Root file allowlist` does catch a committed `.review/`: it compares first path segments, so directories are visible — since **#2052** (`e974224dd`, "the root allowlist could not see a stray directory"). Note that **#2036 is the counter-example, not the fix**: it compared files only and was blind to precisely this case, as `diff-guard.yml` says in its own comment. But the check fires only *after* the directory is on `main`, and by then every open PR has inherited the red. That is the sequence that played out with `.roy-scratch/pr.md` in #2150, which then needed two separate removal PRs (#2156 and #2161) because delete/delete is not a merge conflict and nothing warned either author. So this is the prevention half. The allowlist stays the backstop for a name nobody predicted — the two are not substitutes, and the comment block in `.gitignore` says so. ## Review Independent Opus review: no MUST-FIX. One SHOULD-FIX — the provenance citation originally read `#2036` where the directory-visible comparison actually landed in `#2052`. Corrected in both the commit message and this body. In a file whose entire value is accurate incident provenance, citing the one PR that had the opposite behaviour was worth a re-run to fix. ## Scope One `.gitignore` entry plus its comment. No code, no CI config, no behaviour change. `.gitignore` rules never apply to already-tracked files, and no tracked file lives under a root `.review/`. Co-authored-by: holden <holden@squad.local> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Why
A cross-agent note asked for every
t>=8row published before #1729 (6e8c31ebd) to be re-taken, on the grounds that the default decode pool pinned 16 workers to cpus 0–15 — 8 physical cores with both SMT siblings loaded.The premise is correct, and it is the same defect this repo found independently and filed as #1680 (§24 of
CPU_MATMUL_ASSIGNMENT.md). The blanket conclusion is too broad for the rows in that file, and — the point of this PR — which rows survive is decidable from the source, without spending host time re-measuring.The argument
Every multi-thread timing in §23/§25 is
taskset-pinned to the even CPUs (§24's closing note). On this host SMT siblings are adjacent pairs, so that mask is 16 CPUs that are already 16 distinct physical cores.The spread half of #1729 is the identity on such a mask. Pre-#1729 the SPMD shard builder used
allowed_cpus()in raw ascending order (confirmed at6e8c31ebd^); post-#1729 the same list goes throughorder_pin_targets. ItsSpreadarm isleaders_within(cpus)plus the non-leader remainder — and on an all-even mask each core group contributes its single allowed member, the remainder is empty, andleaders_withinendssort_unstable(); dedup(). Same ascending list.build_decode_poolpins workeritocpus[i % len]either way, so #1729 cannot move a number taken under that pin.The reserve half is the identity on that mask too. This is a correction to the first version of this PR, which claimed
t=16went 16 workers -> 15. It does not. #1729 did not introduce the dispatcher reserve; it changed it from a logical-CPU rule to a physical-core rule:When the mask holds one CPU per physical core,
allowed == cores, and the two agree at every width: below saturationmin(total, allowed-1) == totalbecausetotal <= allowed-1; at and above saturation both giveallowed-1. They diverge only whenallowed > cores— a mask holding both SMT siblings, which is exactly the unpinned case #1729 was written to fix and exactly the case these benchmarks are not run in.I got this wrong in the characteristic way: I read the post-#1729 formula carefully and assumed the pre-#1729 one, then published a delta with only one side measured. An adversarial review accepted the wrong table; fetching
6e8c31ebd^is what caught it. It is in the ledger under its own heading because it is the same error class the rest of this file is about.#1794 does not apply. It fixed
default_persistent_threadsreturningavailable / 2. These sweeps setONNX_GENAI_CPU_DECODE_THREADSexplicitly, and an explicit count bypasses the default entirely. The rows that defect corrupted are pinned runs that left the width to the default — of which this file has none, because the pin and the explicit width were adopted together.Disposition: no row taken under the even-CPU pin moves at any width — both halves of #1729 are the identity there, and #1794's defect lived in a default these sweeps never used.
t=16stays withheld for its own unrelated reason (its A/A null spans 0.969–1.295, ±30%, against 3.6% att=1). The placement question and the instrument question are independent, and only the second ever disqualified that row.This is a stronger claim than the one asked for, so it carries a stronger obligation: it holds because of the pin, and says nothing about an unpinned row. Unpinned numbers remain governed by §24's standing rule and are not rehabilitated by anything here.
The tests, and why they are the real content
Both arguments were load-bearing and untested.
cargo test order_pin_targetsmatched zero tests, and nothing asserted the reserve invariant either.1.
a_one_cpu_per_core_mask_is_unchanged_by_either_placement_policy— a cpuset already holding one CPU per physical core is a fixed point of both placement policies. This is the guarantee every pinned benchmark in this repository rests on: the house rule for a clean multi-thread number istasksetto one CPU per core, and it is worth nothing unless the pool then pins workers to the CPUs that were reserved, in the order reserved. Also asserts the policies still disagree on a full mask, so it is a property of the mask rather than a policy that never reorders.Live: reversing the leader order inside
Spreadfails it with`spread` reordered a mask that was already one CPU per core.2.
the_core_reserve_matches_the_logical_reserve_on_a_one_cpu_per_core_mask— carries the pre-#1729 logical rule as a reference implementation and asserts agreement across masks 1..32 at every total, plus the contrasting SMT-mask case where the rules genuinely differ ((16, 32, 16) -> 15vs logical16). A future change to the reserve that breaks this would silently invalidate a file full of measurements; this makes it break in CI instead.Live: reserving two CPUs instead of one fails it at
total=3on a 4-CPU mask.Also recorded
t=2is closed, by two methods sharing no apparatus: 1.96x measured here on a quiet host (20.447 vs 40.039 ms/token, 0.6% A/A null, both workers 99% busy by per-thread attribution) and 1.94x / 97% efficiency reported independently by the runtime owner on a post-#1729 baseline. ~1% apart. The withdrawn "71% of one core" is now over-determined.One standing caveat is reinforced rather than revised:
t=1runspath=flatandt>=2runspath=spmd-pool, so at=1vst=2comparison crosses routes as well as widths. §20 already reads that row as "vs serial" rather than "vs a one-worker pool".Validation
cargo test -p onnx-runtime-ep-cpu --lib— 1829 passed, 0 failed (two new tests), underscripts/hostlock.shcargo clippy -p onnx-runtime-ep-cpu --all-targets --all-features -- -D warnings— cleancargo fmt --all --check— cleanNo production code changed: two tests plus a documentation section.