diff --git a/CLAUDE.md b/CLAUDE.md index 62ae0a2c..bb4c8f6f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -141,8 +141,19 @@ src/ `env -u RUSTFLAGS` is load-bearing: a RUSTFLAGS env var REPLACES every cargo-config rustflags entry, so it silently drops `-Ctarget-cpu=x86-64-v4` - and the arm measures v3 while claiming v4 (the trap `scripts/masking-parity.sh` - documents). + and the arm does NOT measure v4 while claiming to (the trap + `scripts/masking-parity.sh` documents). + + > ⊘ **CORRECTED 2026-09-16 (coderabbit, #313).** This read "*and the arm + > measures v3*". Wrong, and this session's own measurement is what disproves + > it: RUSTFLAGS replaces **every** config rustflags entry, so it drops the + > DEFAULT config's target-cpu too, not just the overlay's. Measured on one + > unit — `RUSTFLAGS="-D warnings"` produced **zero** `-Ctarget-cpu` flags, + > against 65 with the env unset. What you actually get is rustc's own default + > for the target, i.e. the `x86-64` baseline (SSE2), which is LOWER than v3 + > and is the tier `simd_avx2.rs`'s intrinsics SIGILL on. The sentence was + > wrong before the native flip as well; the flip only changed which config + > gets discarded. **That same mechanism had silently disabled the whole config in CI, and it is the more serious half (found 2026-09-16).** `.github/workflows/ci.yaml` sets a diff --git a/Dockerfile b/Dockerfile index 08e979aa..b8bd2bd4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -72,6 +72,15 @@ COPY ndarray-rand/benches/ ndarray-rand/benches/ # detects AVX-512 at runtime via LazyLock even when compiled for v3; # compile-time v3 just means the scalar/AVX2 fallback paths are used when the # runtime check fails. Both paths produce identical results. +# The cargo CONFIG DIRECTORY, required by the `--config` flags below and easy to +# forget: this Dockerfile COPYs selectively by design (see the note above), so a +# file that is not named here does not exist in the image. Adding `--config +# .cargo/config-v3.toml` without this line makes cargo fail on a missing +# configuration file BEFORE it compiles anything — which is exactly what +# happened on #313 and was caught in review after merge, not by a build (there +# is no Docker daemon in the dev container, so neither image is built here). +COPY .cargo/ .cargo/ + # The tier is passed as a CONFIG, not as `ENV RUSTFLAGS` (changed 2026-09-16). # A RUSTFLAGS env REPLACES every cargo-config `rustflags` entry rather than # joining it, so `ENV RUSTFLAGS="-C target-cpu=x86-64-v3"` did set the tier — diff --git a/Dockerfile.avx512 b/Dockerfile.avx512 index 21d2e1e9..f53f1802 100644 --- a/Dockerfile.avx512 +++ b/Dockerfile.avx512 @@ -50,6 +50,11 @@ COPY examples/ examples/ COPY benches/ benches/ COPY ndarray-rand/benches/ ndarray-rand/benches/ +# The cargo CONFIG DIRECTORY, required by the `--config` flags below. This +# Dockerfile COPYs selectively, so a file not named here is absent from the +# image and cargo fails on a missing configuration file before compiling. +COPY .cargo/ .cargo/ + # AVX-512 pinned: compile-time dispatch, everything inlined. # # Passed as a CONFIG, not `ENV RUSTFLAGS` (changed 2026-09-16): a RUSTFLAGS env diff --git a/scripts/masking-parity.sh b/scripts/masking-parity.sh index 4dff97cb..787c652b 100755 --- a/scripts/masking-parity.sh +++ b/scripts/masking-parity.sh @@ -26,8 +26,21 @@ case "$ARM" in # `env -u RUSTFLAGS`: a workflow-global RUSTFLAGS (CI sets "-D warnings") # REPLACES every cargo-config rustflags entry, so a `--config # .cargo/config-v4.toml` passed through CARGO_ARGS would silently lose its - # `-Ctarget-cpu=x86-64-v4` and this arm would measure v3 while claiming - # v4 — the exact trap the tier4 CI job hit. Clearing it lets the config win. + # `-Ctarget-cpu=x86-64-v4` — the exact trap the tier4 CI job hit. Clearing + # it lets the config win. + # + # What you get INSTEAD is not v3 (corrected 2026-09-16, coderabbit on #314; + # this comment said "would measure v3"). RUSTFLAGS replaces EVERY entry, + # including the DEFAULT `.cargo/config.toml`'s own `-Ctarget-cpu`, so no + # target-cpu reaches rustc at all and the build lands on rustc's generic + # `x86-64` baseline — SSE2, BELOW v3, and the tier `simd_avx2.rs`'s + # intrinsics SIGILL on. Measured on one unit: `RUSTFLAGS="-D warnings"` + # emitted ZERO `-Ctarget-cpu` flags against 65 with the env unset. + # + # This arm NAMES NO TIER by design: it builds with whatever config wins, + # which by default is `target-cpu=native` (the host). Read the program's + # own `avx512f=` header line for the tier; pin `.cargo/config-v3.toml` + # through CARGO_ARGS when you specifically want AVX2. env -u RUSTFLAGS cargo ${CARGO_ARGS:-} build --release --manifest-path "$MANIFEST" --bin simd-masking-parity "$TD/release/simd-masking-parity" ;;