diff --git a/.cargo/config-v3.toml b/.cargo/config-v3.toml new file mode 100644 index 000000000..a71aebe5a --- /dev/null +++ b/.cargo/config-v3.toml @@ -0,0 +1,6 @@ +# Portable distribution baseline: x86-64-v3 (AVX2), every x86_64 since +# Haswell. REQUIRED for anything shipped from this tree, now that the default +# `.cargo/config.toml` is `native`. Mirrors ndarray/.cargo/config-v3.toml. +# cargo build --config .cargo/config-v3.toml ... +[target.'cfg(target_arch = "x86_64")'] +rustflags = ["-Ctarget-cpu=x86-64-v3"] diff --git a/.cargo/config.toml b/.cargo/config.toml index 6dd5d98a7..8fdd89a22 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -16,14 +16,35 @@ # scalar, because the polyfill's scalar arm is emulating eight lanes through # arrays. A build with no target-cpu is a regression, not a no-op. # -# Default here is v3 (AVX2) for the same reason ndarray chose it: portable -# across all x86_64 since Haswell, and what CI runs (`.github/workflows/*.yml` -# set `-C target-cpu=x86-64-v3` explicitly). Anything below v3 SIGILLs on the -# `simd_avx2` intrinsics. +# ⊘ SUPERSEDED 2026-10-12: the default here WAS v3 (AVX2), "for the same +# reason ndarray chose it". ndarray itself flipped its default to `native` on +# 2026-09-16 (see its `.cargo/config.toml`): a default that names a tier the +# host is not makes every faster-tier measurement need an incantation, and a +# forgotten one does not fail, it grades the wrong tier. Measured here the +# same way: a cost probe under this file reported AVX2 timings on an AVX-512 +# host with nothing in the output saying so. # -# AVX-512 (v4): cargo build --config .cargo/config-avx512.toml ... -# or CARGO_BUILD_RUSTFLAGS='-Ctarget-cpu=x86-64-v4' -# Build machine: cargo build --config .cargo/config-native.toml ... +# Default is now `native`: rustc resolves the host CPUID, so the polyfill +# compiles to the arm this machine can run and can never SIGILL here. A +# measurement is labelled by the arm the program reports +# (`cfg!(target_feature = "avx512f")`), never by "it was the default". +# +# A default build is therefore tuned to the BUILD HOST and is NOT portable. +# Anything shipped pins its tier explicitly: +# +# portable baseline (AVX2): cargo build --config .cargo/config-v3.toml ... +# AVX-512 (v4): cargo build --config .cargo/config-avx512.toml ... +# +# CI is unaffected: every workflow sets `RUSTFLAGS` with an explicit +# `-C target-cpu=x86-64-v3`, and a RUSTFLAGS env REPLACES every cargo-config +# rustflags entry. Everything else that ships pins x86_64 to v3 without +# touching other architectures: the Dockerfiles that copy this tree replace +# this file with config-v3.toml (x86_64-only), the thinking-engine images set +# CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS, and `make publish` in +# python/ sets RUSTFLAGS only on an x86_64 host. Note that the per-target +# variable is JOINED with this file's entry, with `native` last (measured), so +# it cannot pin a build that sees this file. Anything below v3 still SIGILLs on the +# `simd_avx2` intrinsics, so never build with no target-cpu at all. # # The two crypto cfgs ndarray's config also carries (`curve25519_dalek_backend`, # `poly1305_force_soft`) are deliberately NOT repeated: neither crate is in @@ -31,4 +52,16 @@ # AVX2 crypto surface here to compile out. Re-check if `encryption` or # `ed25519-dalek` ever enters the tree. [target.'cfg(target_arch = "x86_64")'] -rustflags = ["-Ctarget-cpu=x86-64-v3"] +rustflags = ["-Ctarget-cpu=native"] + +# Debug info off for every dev/test build under this tree, including the +# crates that are their own workspace (19 of them: they never see the root +# Cargo.toml's `[profile.dev] debug = 0`). Debug info is what fills the disk, +# not the code. A config-file profile overrides a manifest profile; an +# explicit CARGO_PROFILE_* env var still overrides this. Release profiles are +# left to each crate. +[profile.dev] +debug = 0 + +[profile.test] +debug = 0 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 15fb96a47..90da7f3a0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ concurrency: env: CARGO_TERM_COLOR: always - RUSTFLAGS: "-C debuginfo=1 -C target-cpu=x86-64-v3" + RUSTFLAGS: "-C debuginfo=0 -C target-cpu=x86-64-v3" RUST_BACKTRACE: "1" CARGO_INCREMENTAL: "0" @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 30 env: - # Override the workflow-level debuginfo=1 for this job (parity with the + # Pin debuginfo=0 here too (the workflow level is also 0 since 2026-10-12) for this job (parity with the # `test` + `test-with-coverage` jobs in rust-test.yml, TD-CI-TEST-JOB-DEBUGINFO0 # / TD-CI-COVERAGE-MOLD-1). This job links the SAME full lance+datafusion # test-binary set at the SAME disk/RSS cliff and was the one job still diff --git a/.github/workflows/rust-publish.yml b/.github/workflows/rust-publish.yml index f1b82d608..5e08b003f 100644 --- a/.github/workflows/rust-publish.yml +++ b/.github/workflows/rust-publish.yml @@ -20,7 +20,7 @@ on: env: CARGO_TERM_COLOR: always - RUSTFLAGS: "-C debuginfo=1 -C target-cpu=x86-64-v3" + RUSTFLAGS: "-C debuginfo=0 -C target-cpu=x86-64-v3" RUST_BACKTRACE: "1" CARGO_INCREMENTAL: "0" CARGO_BUILD_JOBS: "1" diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index 66de0a480..0818360b4 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -16,7 +16,7 @@ concurrency: env: CARGO_TERM_COLOR: always - RUSTFLAGS: "-C debuginfo=1 -C target-cpu=x86-64-v3" + RUSTFLAGS: "-C debuginfo=0 -C target-cpu=x86-64-v3" RUST_BACKTRACE: "1" CARGO_INCREMENTAL: "0" @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 30 env: - # Override the workflow-level debuginfo=1 for this job too (parity with + # Pin debuginfo=0 here too (the workflow level is also 0 since 2026-10-12) for this job too (parity with # test-with-coverage, TD-CI-COVERAGE-MOLD-1). The `test` job links the # full lance+datafusion integration-test set at the SAME disk/RSS cliff # the coverage job hit — and #507 (+4055 lines across causal-edge + @@ -506,7 +506,7 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 30 env: - # Override the workflow-level debuginfo=1 for this job only. llvm-cov + # Pin debuginfo=0 here too (the workflow level is also 0 since 2026-10-12) for this job only. llvm-cov # coverage lives in __llvm_covmap/__llvm_prf_* ELF sections, NOT in # DWARF (verified locally: 600/600 contract tests pass under # `-C instrument-coverage -C debuginfo=0`, covmap sections present, diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 4837ca08d..5bfc9e46e 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -16,7 +16,7 @@ concurrency: env: CARGO_TERM_COLOR: always - RUSTFLAGS: "-C debuginfo=1 -C target-cpu=x86-64-v3" + RUSTFLAGS: "-C debuginfo=0 -C target-cpu=x86-64-v3" # Least-privilege: these jobs only read the repo (checkout + build + lint). permissions: diff --git a/Dockerfile.hhtld b/Dockerfile.hhtld index 47ea52e59..7927a30ea 100644 --- a/Dockerfile.hhtld +++ b/Dockerfile.hhtld @@ -48,6 +48,12 @@ RUN if [ ! -d /build/ndarray ]; then \ fi WORKDIR /build/lance-graph +# Portable baseline. The repo's .cargo/config.toml defaults to `native` +# (tuned to the build host); an image must run on any x86_64 since Haswell. +# The copied tree's config is replaced by config-v3.toml, which only applies +# to x86_64 targets, so an arm64 build keeps its own aarch64 baseline (a +# global RUSTFLAGS would hand the aarch64 compiler an x86 CPU name). +RUN cp .cargo/config-v3.toml .cargo/config.toml # Build the decode example (the inference binary) RUN cargo build --release --example tts_17b_hhtld_decode \ diff --git a/crates/cognitive-stack/Dockerfile b/crates/cognitive-stack/Dockerfile index 49db32ea0..acdbfffeb 100644 --- a/crates/cognitive-stack/Dockerfile +++ b/crates/cognitive-stack/Dockerfile @@ -35,6 +35,12 @@ WORKDIR /build # The lance-graph repo (this build context). cognitive-stack path-deps the # in-repo crates (lance-graph, the four template crates, lance-graph-ogar). COPY . /build/lance-graph +# Portable baseline. The repo's .cargo/config.toml defaults to `native` +# (tuned to the build host); an image must run on any x86_64 since Haswell. +# The copied tree's config is replaced by config-v3.toml, which only applies +# to x86_64 targets, so an arm64 build keeps its own aarch64 baseline (a +# global RUSTFLAGS would hand the aarch64 compiler an x86 CPU name). +RUN cp /build/lance-graph/.cargo/config-v3.toml /build/lance-graph/.cargo/config.toml # lance-graph path-deps the ndarray fork as a SIBLING (`../../../ndarray`). # Clone it next to the repo so that path resolves. diff --git a/crates/symbiont/Dockerfile b/crates/symbiont/Dockerfile index 0bf5d9900..c54144a36 100644 --- a/crates/symbiont/Dockerfile +++ b/crates/symbiont/Dockerfile @@ -35,6 +35,12 @@ WORKDIR /build # The lance-graph repo (this build context). symbiont path-deps lance-graph + # perturbation-sim from inside it. COPY . /build/lance-graph +# Portable baseline. The repo's .cargo/config.toml defaults to `native` +# (tuned to the build host); an image must run on any x86_64 since Haswell. +# The copied tree's config is replaced by config-v3.toml, which only applies +# to x86_64 targets, so an arm64 build keeps its own aarch64 baseline (a +# global RUSTFLAGS would hand the aarch64 compiler an x86 CPU name). +RUN cp /build/lance-graph/.cargo/config-v3.toml /build/lance-graph/.cargo/config.toml # lance-graph's own Cargo.toml path-deps the ndarray fork as a SIBLING # (`../../../ndarray`). Clone it next to the repo so that path resolves. diff --git a/crates/thinking-engine/Dockerfile b/crates/thinking-engine/Dockerfile index 4dcf38986..125a69359 100644 --- a/crates/thinking-engine/Dockerfile +++ b/crates/thinking-engine/Dockerfile @@ -1,4 +1,8 @@ FROM rust:1.98.1-bookworm AS builder +# Portable baseline for x86_64 only: this image does not copy .cargo, so the +# per-target variable is the only flag source, and it does not apply when +# building for another architecture. +ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C target-cpu=x86-64-v3" WORKDIR /app # Dependencies first (cached layer) diff --git a/crates/thinking-engine/Dockerfile.railway b/crates/thinking-engine/Dockerfile.railway index e6bcd18f4..d54e5489a 100644 --- a/crates/thinking-engine/Dockerfile.railway +++ b/crates/thinking-engine/Dockerfile.railway @@ -7,6 +7,10 @@ # The codebooks run standalone for reasoning at 5,676 queries/sec FROM rust:1.98.1-bookworm AS builder +# Portable baseline for x86_64 only: this image does not copy .cargo, so the +# per-target variable is the only flag source, and it does not apply when +# building for another architecture. +ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C target-cpu=x86-64-v3" WORKDIR /app # Copy workspace diff --git a/python/Makefile b/python/Makefile index aa0f18c56..eb8b886b0 100644 --- a/python/Makefile +++ b/python/Makefile @@ -24,5 +24,11 @@ clean: rm -rf .venv rm -rf ../target +# The repo's .cargo/config.toml defaults to `native`, which would tune the +# wheel to the build host; a published x86_64 wheel must run on any x86_64 +# since Haswell. RUSTFLAGS replaces the config's flags; it is set only on an +# x86_64 host so an arm64 build keeps its own baseline. +PORTABLE_RUSTFLAGS := $(if $(filter x86_64,$(shell uname -m)),RUSTFLAGS="-C target-cpu=x86-64-v3",) + publish: - maturin build --release --out dist --sdist + $(PORTABLE_RUSTFLAGS) maturin build --release --out dist --sdist