Skip to content

fix(bench): resolve the #361 harness's source SHA from soup_cli's tree, not the checkout's HEAD - #1382

Merged
MakazhanAlpamys merged 1 commit into
MakazhanAlpamys:mainfrom
drakeo338:claude/1327-fix
Sep 28, 2026
Merged

MakazhanAlpamys merged 1 commit into
MakazhanAlpamys:mainfrom
drakeo338:claude/1327-fix

Conversation

@drakeo338

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes #1327.

The #361 NF4 harness stamped every row with the harness checkout's own HEAD, not the tree soup_cli actually imported from, and never marked a dirty tree. A shadow soup_cli install elsewhere on sys.path, or local edits, got a row naming a commit whose code did not run. _source_sha() now resolves the git root from soup_cli.__file__, appends -dirty on uncommitted changes, and returns unknown when the imported package isn't in a git checkout, matching variant2_gate._source_sha's existing fix for #1085.

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation
  • Tests

Checklist

  • ruff check src/soup_cli/ scripts/ tests/ passes
  • pytest tests/ -v passes
  • Updated relevant docs (README.md and the matching page under docs/) if needed
  • Added a changelog fragment, or this change has no user-visible impact

Left unticked: ruff check fails on pre-existing, unrelated errors in another test file, and pytest tests/ -v fails to collect here on a pre-existing missing numpy dependency. pytest tests/test_issue361_nf4_throughput.py -v (the changed file) passes: 31 passed, 2 skipped.

… soup_cli's tree, not the checkout's HEAD (MakazhanAlpamys#1327)

_source_sha() ran `git rev-parse HEAD` two directories above the harness
file, so a dirty tree recorded the same SHA as a clean one and a shadow
soup_cli install elsewhere on sys.path had its row stamped with the
harness checkout's commit instead of the tree that actually ran.

Resolve the git root from soup_cli.__file__ instead, append -dirty when
`git status --porcelain --untracked-files=normal` is non-empty in that
tree, and return unknown when the imported package isn't in a git
checkout or the SHA doesn't match [0-9a-f]{40} — the same fix MakazhanAlpamys#1085's
variant2_gate._source_sha already carries, now shared in structure with
this harness's copy.

@MakazhanAlpamys MakazhanAlpamys left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@drakeo338, thank you. This does what #1327 asked, and it does it the way the repository already does it elsewhere. Three things stand out:

  • Both harnesses now answer "which tree ran?" the same way. Your _source_sha() is the #1085 function from variant2_gate.py, and the row format stays <sha>, <sha>-dirty or unknown, so rows that are already published stay comparable.
  • The test pins the part that matters. It answers --show-toplevel with a directory that belongs neither to the package nor to the harness, and it asserts the cwd of every git call. Any way of reading the commit from the wrong tree therefore fails it. Against main's harness both cases fail on the value itself (2 failed, 31 passed).
  • You widened the shape check instead of dropping it. [0-9a-f]{40}(-dirty)? at tests/test_issue361_nf4_throughput.py:178 keeps the real-git test meaningful on a dirty CI checkout.

From my side this is ready. Nothing below holds the merge. It now waits only on the 13 required checks, which are queued on 5d86dcc1.

What I ran

Everything ran on CPU with the GPU hidden, on 5d86dcc1, which already sits on today's main (1e8a0ae5).

Tests. tests/test_issue361_nf4_throughput.py: 33 passed. Your two skips are the tests that importorskip("torch"), and they run here. Adding tests/test_issue379_variant2_gate.py and the Qwen4 benchmarks-index test gives 67 passed. ruff check src/soup_cli/ tests/ scripts/ benchmarks/ passes on this head (ruff 0.16.6).

_source_sha() with real git, with the harness loaded through importlib:

case result
clean checkout its commit
one appended line in src/soup_cli/utils/block_expansion.py <sha>-dirty
a git archive extract (no .git) unknown
harness from one checkout, soup_cli from another the imported checkout's commit (main's harness reports its own checkout's commit)
no PYTHONPATH, so import soup_cli finds the installed 0.75.1 wheel unknown (main's harness stamps its checkout's commit, the issue's run 3)
no git on PATH unknown

Ten mutations of _source_sha() in benchmarks/harness/issue361_nf4_throughput.py, each run against the #361 test file:

mutation result
repository resolved from the harness file again (:118) 2 failed
-dirty dropped (:153) 1 failed
--untracked-files=no (:142) 2 failed
HEAD read in the package directory instead of the toplevel (:132) 2 failed
git status run in the harness checkout (:143) 2 failed
except narrowed to OSError (:149) 0 failed
except narrowed to subprocess.SubprocessError (:149) 0 failed
40-hex check deleted (:151-152) 0 failed
empty-toplevel guard deleted (:127-128) 0 failed
__file__ is None guard deleted (:115-116) 0 failed

Every mutation that moves the commit to the wrong tree or drops -dirty fails a test. I would not test the last two guards. Git 2.55 exits 128 rather than printing an empty toplevel, even in a bare repository, and a regular package always has a __file__.

Optional follow-ups (none of them holds the merge)

1. Three error branches have no test. Narrowing the except to either half, or deleting the 40-hex check, passes all 33 tests. The git archive case is the one that happens in practice: git rev-parse --show-toplevel exits 128 there, and with check=True that is a CalledProcessError.

These three methods fit into TestTheRowNamesItsTree as they are, because the file already imports subprocess, SimpleNamespace, Any, Path and pytest. They pass on 5d86dcc1, and each one fails exactly one of those three mutations (36 passed unmutated; 1 failed under each):

    def test_source_sha_is_unknown_outside_a_git_checkout(
        self, monkeypatch: pytest.MonkeyPatch
    ) -> None:
        """A ``git archive`` extract has no ``.git``, so ``git rev-parse
        --show-toplevel`` exits 128, which ``check=True`` raises as
        ``CalledProcessError``."""

        def fake_run(command: list[str], *, cwd: Path, **kwargs: object) -> Any:
            raise subprocess.CalledProcessError(128, command)

        monkeypatch.setattr(subprocess, "run", fake_run)
        assert _harness._source_sha() == "unknown"

    def test_source_sha_is_unknown_without_a_git_binary(
        self, monkeypatch: pytest.MonkeyPatch
    ) -> None:
        def fake_run(command: list[str], *, cwd: Path, **kwargs: object) -> Any:
            raise FileNotFoundError(2, "No such file or directory", command[0])

        monkeypatch.setattr(subprocess, "run", fake_run)
        assert _harness._source_sha() == "unknown"

    def test_source_sha_does_not_record_a_head_that_is_not_a_commit(
        self, monkeypatch: pytest.MonkeyPatch, tmp_path: Path
    ) -> None:
        def fake_run(command: list[str], *, cwd: Path, **kwargs: object) -> Any:
            if command == ["git", "rev-parse", "--show-toplevel"]:
                return SimpleNamespace(stdout=f"{tmp_path}\n")
            if command == ["git", "rev-parse", "HEAD"]:
                return SimpleNamespace(stdout="not-a-commit\n")
            return SimpleNamespace(stdout="")

        monkeypatch.setattr(subprocess, "run", fake_run)
        assert _harness._source_sha() == "unknown"

2. -dirty also fires on this harness's own outputs. git status --untracked-files=normal counts untracked files anywhere in the checkout. The docstring's example (:33-36) writes --shards ./shards-llama8b-nf4 and --json ./rows/issue361-post-repair.json into the current directory, and neither path is ignored. Run from the repository root, the first run is still clean, because _versions() (:391) runs before sharding (:429) and before the first JSON write (:522). Every re-run that reuses the shards, though, is stamped -dirty. I checked both paths with real git. This errs in the safe direction, variant2_gate.py behaves the same way, and #1327 asked for exactly this status call, so no change is needed. If you want to avoid it, point the example's paths outside the checkout, or scope the call with -- src benchmarks/harness, which still catches a local edit to soup_cli or to the harness itself.

3. One case the #1085 function does not cover. This PR inherits it; it did not introduce it. The case is a wheel installed into a gitignored .venv/ inside the checkout. I copied the installed 0.75.1 wheel into <checkout>/.venv/Lib/site-packages and imported it from there. --show-toplevel finds the checkout, .venv/ is ignored so git status is empty, and the row gets the checkout's clean commit (5d86dcc1…) for code that differs from src/ in 187 files. variant2_gate.py reports the same commit. Running git ls-files --error-unmatch -- <soup_cli/__init__.py> in that root tells the two apart: it exits 1 for the wheel's copy and 0 for src/soup_cli/__init__.py. The fix belongs in every copy of the function, so it fits better with item 4 than in this PR.

4. One shared helper. #1327's fix path also offered a small helper that both harnesses import, like bitexact.py, with a test that both use the same function object. This PR's _source_sha() is byte-identical to variant2_gate.py:213-255, and #1258 adds a third copy that is already scoped differently (-- src), so the copies have started to drift. Recording soup_cli.__file__ in the versions blob, the other optional item in #1327, would also make a case like item 3 visible in the row itself. cuda_graph_decode_bench.py already records it as soup_import_path.

@MakazhanAlpamys MakazhanAlpamys added the ci:full Run the full CI matrix on this PR (a maintainer adds it at approval) label Sep 28, 2026
@MakazhanAlpamys
MakazhanAlpamys merged commit dccc868 into MakazhanAlpamys:main Sep 28, 2026
18 checks passed
@MakazhanAlpamys

Copy link
Copy Markdown
Owner

Merged as dccc8680. Thank you, @drakeo338: your test answers --show-toplevel with a directory that belongs neither to the package nor to the harness, and it pins the cwd of every git call, so any way of reading the commit from the wrong tree fails it. On CPU, the #361 test file gave 33 passed, and 67 with the variant2 gate file and the benchmarks-index test. Against main's harness the new test fails 2 of 2. 5 of 10 mutations of _source_sha() fail a test, including all five that move the commit to the wrong tree or drop -dirty.

MakazhanAlpamys added a commit that referenced this pull request Sep 28, 2026
Display names from `gh api users/<login>`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:full Run the full CI matrix on this PR (a maintainer adds it at approval)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The #361 NF4 throughput harness records git rev-parse HEAD of its own checkout: no -dirty marker, and not the soup_cli tree it actually imported

2 participants