Skip to content

Retire the Python-to-Rust parity tests and port tooling - #1492

Merged
marcinz606 merged 3 commits into
mainfrom
mz/parity
Oct 24, 2026
Merged

marcinz606 merged 3 commits into
mainfrom
mz/parity

Conversation

@marcinz606

@marcinz606 marcinz606 commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Summary

negpy_core is now the source of truth for CPU pixels (#1489). This removes what only existed to compare it with the replaced Python, and anything that no contributor can run.

  • Pins replace copies. 17 tests/test_core_*.py files rebuilt the old NumPy/cv2 pipeline to compare against. Those tests now pin the Rust output by its SHA-256 (tests/core_pin.py) on the same fixed inputs. test_core_finish.py goes: test_core_same_bits already pins the carrier.
  • Pins run on Linux x86-64 (linux_pin), where they were recorded: some pinned paths run NumPy steps whose transcendentals differ by CPU. test_core_same_bits stays the check that every release OS must match.
  • Corpus tests go (lsd, inpaint, seam, sift): they read recordings from one maintainer's disk.
  • Port tooling goes: scripts/replay.py, make replay / make bench, negpy_core/manifest.toml, scripts/core_manifest.py with its test, and negpy_core/LEDGER.md.
  • Kept: direct oracles against one cv2 or NumPy call, behaviour checks, one-line NumPy comparisons, and the GPU parity tests (the WGSL path against the CPU path).
  • Docs: CLAUDE.md and CONTRIBUTING.md describe how a kernel stays pinned (update the pin, bump the versions) instead of how a port matches Python. The native CI job drops the deleted file.

Pin inputs come from exact arithmetic (core_pin.wave, multiplies), not np.sin, np.log or **: NumPy computes those through SVML on some CPUs and libm on others. Tests whose shared RNG made inputs depend on test order (lab, altprocess, inpaint, seam) now seed their own generator, so their pins hold in any order.

Test plan

  • tests/test_core_*.py and related suites: 3213 passed, also in random order
  • make rust, make lint, make type
  • CI (after pin inputs moved to exact arithmetic: a float32 power differed between CPUs)

negpy_core is the source of truth for CPU pixels. Tests that rebuilt the
old NumPy/cv2 pipeline to compare against now pin the Rust output by its
SHA-256 (tests/core_pin.py) on the same fixed inputs. Pins run on Linux
x86-64, where they were recorded; test_core_same_bits stays the check
every release OS must match. Kernels it already pins (usm, sabattier,
lith, carrier) lose their copy-based tests outright.

Tests that read a recorded corpus from one maintainer's disk go: no
contributor can run them. Direct oracles against one cv2 or NumPy call,
behaviour checks and one-line NumPy comparisons stay.
The port is done and negpy_core is the reference, so the tools that
compared it with the old Python go: replay and bench (scripts/replay.py,
make replay/bench), the port manifest (manifest.toml, core_manifest.py,
their test) and LEDGER.md. CLAUDE.md and CONTRIBUTING.md describe how a
kernel stays pinned instead of how a port matches Python.
The cyanotype pin failed on CI's Linux runner: its input came from a
float32 power, which NumPy computes through SVML on some CPUs and libm
on others, so the input bytes differed. Pin inputs in cyanotype, zones,
inpaint, IR gammas and autocrop now come from multiplies and a
polynomial wave (core_pin.wave) instead of np.sin, np.tan, np.log and **.
@marcinz606
marcinz606 merged commit 25d47ed into main Oct 24, 2026
5 checks passed
@marcinz606
marcinz606 deleted the mz/parity branch October 24, 2026 09:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant