Repository navigation
style: rustfmt device_argmax.rs (unblocks Fast CI after #1119) - #1120
Merged
Merged
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Aug 17, 2026
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1120 +/- ##
==========================================
+ Coverage 79.84% 79.94% +0.09%
==========================================
Files 367 369 +2
Lines 157368 160348 +2980
Branches 157368 160348 +2980
==========================================
+ Hits 125656 128186 +2530
- Misses 26991 27424 +433
- Partials 4721 4738 +17
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
🔴 Benchmark Regression DetectedComparison of criterion micro-benchmarks: PR head vs merge-base, measured on the same runner in the same job (base first → PR second).
Visual flags: Host infoWhat this cannot catch
|
justinchuby
added a commit
that referenced
this pull request
Aug 17, 2026
…ild shipped (#1115) ## The published wheel shipped the slow build ORT's own CPU execution provider **is** MLAS. This repository vendors MLAS (`crates/mlas-sys`, 833 files) and `onnx-runtime-ep-cpu` has an opt-in `mlas` feature for it — but nothing in the packaging ever turned it on. `python/nxrt-ep-cpu/setup.py` ran `cargo build --release -p onnx-runtime-ep-cpu-plugin` with `CARGO_FEATURES: list[str] = []`, so **every published `nxrt-ep-cpu` wheel contained the pure-Rust fallback paths**. That is not a small difference. Measured end-to-end through the plugin path (the harness added in #1110), same host, same ORT, interleaved A/B: | case | ours/ORT p50, no MLAS | ours/ORT p50, MLAS | ours p50 (ms) no MLAS → MLAS | |---|---|---|---| | `MatMulNBits` int4 M=128 | **81.1x** | 7.3x | 115.9 → 8.80 | | `MatMulNBits` int4 M=1 | 14.8x | 5.2x | 1.850 → 0.400 | | `MatMulNBits` int4 f16-act M=1 | 20.1x | 4.7x | 1.418 → 0.437 | | `MatMulNBits` int8 M=256 | 7.1x | 1.5x | 46.38 → 13.86 | | `QLinearMatMul` u8 M=128 | **54.9x** | 9.3x | 47.62 → 10.36 | | `QLinearMatMul` u8 M=1 | 122.8x | 2.1x | 6.414 → 0.092 | | `QLinearMatMul` i8 M=1 | 10.1x | **0.038x** | 5.457 → 0.092 | | `MatMul` f32 M=128 | 1.58x | **0.82x** | 12.56 → 3.82 | | `MatMul` f32 M=1 | 30.9x | 1.32x | 5.246 → 0.118 | | `MatMul` f16 M=1 | 0.58x | 0.85x | 2.321 → 2.084 | | `MatMul` f16 M=128 | 2.73x | 4.08x | 24.76 → 20.36 | Host: AMD EPYC 9V74 (32 vCPU / 16 physical cores, AVX2+FMA+F16C, no AVX-512), ORT 1.27.0, release build, K=N=2048, 3 warmups + 41 interleaved iterations, p50. Ratios are **ours/ORT**, so below 1.0 means we are faster. Cold session-creation time is reported separately by the same harness and is not folded into these numbers. The two f16 rows move in opposite directions because that path does not go through MLAS at all — they are the control, and they bracket the host noise for this table (±0.3x at p50 on a shared machine). ## What this PR changes 1. **`python/nxrt-ep-cpu/setup.py` enables the feature** on every `(system, machine)` pair in `MLAS_TARGETS`. `NXRT_EP_CPU_NO_MLAS=1` builds the pure-Rust cdylib anyway, for a toolchain with no C++ compiler. 2. **`onnx-runtime-ep-cpu-plugin` gets its own `mlas` feature** that forwards to `onnx-runtime-ep-cpu/mlas`, so the cdylib crate can `cfg` on it. 3. **The cdylib now exports `nxrt_ep_build_features()`.** A compiled library says nothing about how it was built, and here that difference is 81x. `setup.py` refuses to bundle a cdylib whose report disagrees with what it asked cargo for (`target/release` is shared with every other build in the checkout, so the file that exists after `cargo build` is not necessarily the file that build produced), and the wheel's cibuildwheel smoke test re-checks the installed artifact against `nxrt_ep_cpu._build.EXPECTED_FEATURES`, which `setup.py` generates. `nxrt_ep_cpu.build_features()` exposes the same fact to users. 4. **A test-harness bug that made feature-specific testing meaningless.** `onnx_runtime_ort_testkit::find_plugin_cdylib` rebuilds the cdylib with `cargo build -p <pkg>` — *no features*. So `cargo test -p onnx-runtime-ep-cpu-plugin --features mlas` compiled the test binary with MLAS and then **overwrote the MLAS cdylib with a default-feature build**, asserting against the wrong library, silently, in the direction that hides problems. `find_plugin_cdylib_with_features` fixes it and `cdylib_resolve.rs` passes the features it was compiled with. Consequence worth stating: the ORT conformance suite has now run against the MLAS cdylib for the first time, and passes on both feature sets. 5. **CI builds the MLAS cdylib on each lane that matches a wheel target** — `Fast (Linux x86_64)`, `Rust coverage (Windows x86_64)`, `Rust coverage (macOS arm64)`, `Rust (Windows ARM64)`. A target is only listed in `MLAS_TARGETS` if a lane compiles it; if these lanes go red on some platform I will remove that platform from the set rather than ship a wheel that fails to build at release time. ## Tests - `l1_build_features_match_the_compiled_feature_set` (new, `plugin_export_abi`) — dlopens the cdylib the harness resolved and asserts its reported features equal `cfg!(feature = "mlas")`. **This is the falsifier for item 4:** with the testkit fix reverted it fails with `the cdylib at …/libonnx_runtime_ep_cpu_plugin.so reports features "" but this test binary was built with "mlas"`. - `check_wheel.py` (new) replaces the wheel's one-line `test-command`. Falsified by hand: editing the installed `_build.py` to claim `"avx9000"` fails with `bundled cdylib reports build features 'mlas', but this wheel was built asking for 'avx9000'`. - `plugin_export_abi::l1_no_symbol_leakage` — the new export is added to the allow-list; `nm -D` on the MLAS cdylib shows the same 8 exported symbols as before plus this one, i.e. the vendored C++ does not leak symbols. - Local wheel build + install + smoke test on Linux x86_64: `OK …/libonnx_runtime_ep_cpu_plugin.so features='mlas'`. ## Verification - `cargo test -p onnx-runtime-ep-cpu-plugin` — 50 + 9 + 7 + 1 passed (default features) - `cargo test -p onnx-runtime-ep-cpu-plugin --features mlas` — same counts, all passed (first time this actually tested the MLAS build) - `cargo clippy --all-targets` clean for `onnx-runtime-ep-cpu-plugin` and `onnx-runtime-ort-testkit`, with and without `--features mlas` - `cargo fmt --all -- --check` clean - `python -m build --wheel` + install + `check_wheel.py` green locally ## Still losing after this change With MLAS, on this host: `MatMul` f16 M=128 4.08x, `MatMulNBits` int4 M=128 7.3x and M=1 5.2x, `QLinearMatMul` u8 M=128 9.3x. Those are kernel gaps and stay open on my task list — this PR only stops us from shipping the *much* slower build. Nothing here reduces precision or hides setup cost. --- ## Post-review fix (commit 2): the smoke test pointed at the wrong path Independent review found a release-blocking bug, and it was right. `test-command = 'python {project}/check_wheel.py'` — but cibuildwheel is invoked as `cibuildwheel python/nxrt-ep-cpu` **from the repository root** (`publish-ep-plugins.yml:122`), so `{project}` is the repository root and `{package}` is this directory. All four wheel lanes would have failed with `python: can't open file '/project/check_wheel.py'`, and only on an `nxrt-ep-v*` tag — the release-time failure this PR exists to prevent. Fixed to `{package}`, and pinned by a new test binary that runs in ordinary CI: - `wheel_test_command_names_a_file_that_exists` — rejects `{project}` and asserts the referenced script exists. Falsified by restoring `{project}`: *"test-command uses {project} (the repository root)"*. - `every_mlas_wheel_target_is_built_by_a_ci_lane` — asserts each operating system in `MLAS_TARGETS` has a lane in `ci.yml` that compiles the MLAS cdylib. Falsified by adding `("freebsd", "x86_64")`: *"enables MLAS for the operating systems {"darwin", "freebsd", "linux", "windows"} but ci.yml builds the MLAS cdylib on only 3 lanes"*. It counts operating systems rather than targets because one coverage-matrix step covers both `windows/amd64` and `darwin/arm64`. Also from the review: the `comma-separated` wording in the `nxrt_ep_build_features` doc (only one token is ever emitted), the undocumented `AttributeError` in `build_features()`, the stale `_mlas_features()` reference in the pyproject comment, and a note on the testkit cache key (feature sets share one `target/<profile>` path; no caller resolves two in one process, and the key stops the two answers being conflated). Rebased onto `main` after #1110; the export allow-list now carries both that PR's counters and this PR's build-identity symbol. ### Verification (re-run after rebase) - `cargo test -p onnx-runtime-ep-cpu-plugin --features mlas` — 52 e2e (1 ignored) + 9 + 7 + 2 + 1 passed - `cargo test -p onnx-runtime-ep-cpu-plugin` — same counts on default features - `cargo fmt --all -- --check` clean **for this branch**; note `main` is currently fmt-broken at `crates/onnx-runtime-ep-cuda/src/kernels/device_argmax.rs`, repaired by #1118 - `cargo clippy --all-targets` clean for both crates, with and without `--features mlas` --- ## Second review round (commit 3): the CI guard could pass while broken Review returned APPROVE with two MINORs that were both real, and both are fixed. **1. `every_mlas_wheel_target_is_built_by_a_ci_lane` was vacuous under the exact failure it guards.** It counted text occurrences of the MLAS build command in `ci.yml` and compared against the number of operating systems. darwin/arm64's only MLAS build is the `if: runner.os != 'Linux'` step on the coverage matrix, so **deleting the `macos-latest` matrix row removes that build while the count stays at 3** and the test stays green. It is now structural: it parses `ci.yml`, resolves each job's runner operating systems (expanding `runs-on: ${{ matrix.os }}` over `matrix.include[].os` and plain `matrix.os`), applies each step's `runner.os` condition, and asserts the union covers every operating system in `MLAS_TARGETS`. Both falsifiers fire: - delete the `macos-latest` row → *"setup.py enables MLAS for {"darwin", "linux", "windows"} but no ci.yml lane compiles the MLAS cdylib on ["darwin"] … (lanes cover {"linux", "windows"})"* - add `("freebsd", "x86_64")` → the same, for freebsd. **2. CI built the MLAS cdylib but never tested it.** With default features the build-identity assertion is trivially satisfied (`"" == ""`), the vendored C++ is not linked so the leakage check has nothing to leak, and the testkit rebuild defect this PR fixes is only observable when features are requested — so reverting that fix would have left CI green. The ORT-gate lane (the only one with a real ONNX Runtime) now runs the plugin suite a **second time** with `--features mlas`, which is where the conformance and build-identity claims are actually enforced. **NIT:** both ctypes identity reads now release the handle in a `finally` (on Windows a retained handle locks the DLL for the life of the process). **NIT — thread counts, which the tables omitted.** Every measurement below and above uses **default `SessionOptions`** on both sides: the harness never sets `intra_op_num_threads`, so ORT uses its own default (physical cores — 16 on this host) and our EP uses its own pools (sized from available parallelism — 32 vCPUs). Both sides therefore run multi-threaded, and neither is throttled. Ratios are ours/ORT p50, so >1 means we are slower. ### Verification (re-run after rebase onto `main` @ b7fa5e1) - `NXRT_REQUIRE_ORT_TESTS=1 cargo test -p onnx-runtime-ep-cpu-plugin --features mlas` — 52 e2e (1 ignored) + 9 + 7 + 2 + 1 passed - `NXRT_REQUIRE_ORT_TESTS=1 cargo test -p onnx-runtime-ep-cpu-plugin` — identical counts on default features - `cargo clippy --all-targets` clean for both crates, with and without `--features mlas` - `cargo fmt --all -- --check` clean (`main`'s unrelated fmt breakage was repaired by #1120; my #1118 was closed as superseded) --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Pure
rustfmt-only repair of test blocks incrates/onnx-runtime-ep-cuda/src/kernels/device_argmax.rsthat #1119 left unformatted.Details
cargo fmt --all --checkwas failing onorigin/mainafter Reconcile on-GPU argmax tie-break to lowest-index (ONNX/ORT canonical); byte-identical incl. ties #1119 landed new test blocks without running the formatter.cargo fmt --alland commits only the resulting whitespace/line-wrap changes — zero logic change.cargo fmt --all --checknow exits 0.Files changed
References #1119.