Repository navigation
chore: upgrade to Rust 1.99 and audit numerical/codegen impact #251
Description
Summary
Upgrade la-stack to Rust 1.99 for v0.5.0 and perform a thorough correctness, codegen, and performance audit before evaluating algebraic floating-point changes in #250.
This is not just an MSRV/toolchain bump. Rust 1.99 changes the compiler/backend environment, including LLVM 23, so existing numerical performance conclusions established under Rust 1.98 / LLVM 22 must be revalidated before making further floating-point optimization decisions.
#250 depends on this issue: establish and document the final Rust 1.99 strict-f64 baseline first, then evaluate algebraic floating point against that baseline.
Goals
- Move the crate's toolchain/MSRV and CI/release configuration to Rust 1.99.
- Identify all Rust 1.99 language/library/Cargo/lint changes relevant to la-stack.
- Characterize any numerical-behavior, code-generation, or performance changes caused by Rust 1.99 / LLVM 23 alone.
- Preserve scientific/numerical correctness and existing exact/certified guarantees.
- Produce a stable Rust 1.99 baseline for perf: evaluate algebraic floating point for selected f64 functions #250 and the rest of v0.5.0.
Rust 1.99 feature and compatibility audit
Review the final Rust 1.99 release notes and relevant merged compiler/library changes rather than relying only on headline stabilizations.
At minimum:
- Review language/compiler/library/Cargo/rustdoc compatibility notes for source, lint, CI, documentation, and release effects.
- Check for new warnings/errors under the repository's configured lint policy, including macro-expression semicolon diagnostics and other newly enabled/strengthened lints.
- Search for deprecated legacy floating-point module constants such as
std::f64::EPSILON/std::f64::MAXand use associated constants where applicable. - Evaluate new stable APIs only where they simplify existing code or improve correctness/performance; do not churn code merely to adopt new APIs.
- Ignore low-level allocation/raw-pointer APIs that conflict with the repository's no-unsafe policy unless they affect dependencies/tooling indirectly.
- Confirm all supported targets/features continue to build and test as intended.
LLVM 23 / codegen audit
Because Rust 1.99 uses LLVM 23, inspect numerical hot paths for materially changed code generation even when Rust source is unchanged.
Compare Rust 1.98 / LLVM 22 and Rust 1.99 / LLVM 23 for representative strict implementations, especially:
- dot products and reduction-heavy vector functions
norm/norm_squaredand scale-aware norm paths- matrix-vector multiplication
- matrix-matrix multiplication
- small fixed-size matrix operations
- LDLT / solve / decomposition loops used by the f64 path
- interval arithmetic hot paths from perf: reduce interval arithmetic overhead before downstream adoption #247
- certified dot/linear-form paths from perf: reduce certified linear-form overhead before downstream adoption #248
- stable vector-angle work from feat: add a stable vector-angle primitive for downstream spherical metrics #249 where applicable
- exact/Bareiss/rational paths from perf: avoid unnecessary exact elimination for triangular rational systems #246 as a control for compiler effects outside f64
Where performance changes materially, inspect generated assembly/LLVM remarks or other appropriate codegen evidence to determine whether vectorization, unrolling, branching, inlining, FMA formation, or another backend change explains the difference.
Do not optimize for a particular assembly shape unless it is justified by measured performance and preserves the numerical contract.
Correctness audit
The 1.99 migration must preserve behavior before any algebraic-floating-point experiment is considered.
Run the repository's normal validation plus focused numerical regression/property coverage for:
- finite ordinary inputs
- cancellation and ill-conditioned cases
- mixed and extreme magnitudes
- signed zero
- subnormals
- underflow and overflow boundaries
- NaN and infinities wherever public contracts permit or reject them
- exact/certified/interval containment and sign guarantees
- singularity and typed range/error behavior
- deterministic fixtures used by downstream Delaunay
Where practical, compare strict f64 outputs against independent exact/rational/analytical references rather than merely comparing 1.98 and 1.99 outputs.
A changed result is not automatically a bug, but any change affecting a documented contract, exact/certified guarantee, predicate-relevant downstream behavior, or known scientific fixture must be understood and resolved before release.
Performance methodology
Establish a reproducible before/after comparison between the final Rust 1.98 baseline and Rust 1.99.
- Use the same machine, target, profile, feature set, benchmark fixtures, and Criterion settings for paired comparisons.
- Record exact
rustc -Vvinformation including LLVM version. - Keep fixture construction and correctness assertions outside timed regions except in explicitly named construction benchmarks.
- Avoid overlapping benchmark/validation jobs that distort results.
- Report absolute central estimates and relative changes; retain statistical significance/noise information where Criterion provides it.
- Re-run suspicious regressions to distinguish persistent changes from noise.
- Treat performance regressions in correctness-critical code as optimization candidates, not justification for weakening correctness.
Primary development evidence should include aarch64-apple-darwin; retain cross-target CI/build coverage as appropriate.
PERFORMANCE.md
Record the Rust 1.99 migration results in PERFORMANCE.md, including:
- Rust 1.98 and 1.99 compiler versions and LLVM versions
- machine/target/profile/features and benchmark methodology
- a before/after table for representative numerical functions and current hot paths
- material codegen observations where they explain measured differences
- correctness-relevant behavioral changes, if any
- regressions investigated and their resolution/status
- optimizations adopted specifically because of 1.99/LLVM 23
- negative results where 1.99 produces no meaningful change
- the final strict-f64 baseline that perf: evaluate algebraic floating point for selected f64 functions #250 must use
The record should be sufficient to avoid repeating the migration experiment without new compiler/hardware evidence.
Acceptance criteria
- Update the pinned toolchain/MSRV and repository configuration to stable Rust 1.99 for v0.5.0.
- Review the final Rust 1.99 release notes and relevant merged compiler/backend changes for la-stack-specific impact; document findings that require action or deliberate non-action.
- Resolve new compiler/clippy/rustdoc/lint diagnostics without broad suppression unless suppression is specifically justified.
- Audit deprecated/changed floating-point APIs and compatibility issues; avoid gratuitous API churn.
- Run the full repository validation required for release plus focused adversarial numerical tests; preserve exact, interval, certified, typed-error, signed-zero, subnormal, overflow/underflow, and non-finite contracts.
- Establish paired Rust 1.98/LLVM 22 versus Rust 1.99/LLVM 23 Criterion baselines for representative vector, matrix, norm, solve/decomposition, interval, certified, and exact-control workloads.
- Investigate every material regression and every unexpectedly large improvement; use codegen/assembly evidence where useful to explain the change.
- Apply only evidence-backed 1.99-specific optimizations that preserve or improve numerical correctness; do not introduce relaxed floating-point semantics in this issue.
- Re-run affected downstream Delaunay correctness/performance fixtures where la-stack behavior or performance materially changes.
- Record methodology, before/after results, codegen findings, accepted optimizations, regressions, and the final strict-f64 1.99 baseline in
PERFORMANCE.md. - Complete this issue before perf: evaluate algebraic floating point for selected f64 functions #250. Algebraic floating-point evaluation must use the resulting Rust 1.99 / LLVM 23 baseline, not a Rust 1.98 baseline.
Non-goals
- Do not evaluate or adopt algebraic floating-point operations here; that remains perf: evaluate algebraic floating point for selected f64 functions #250 after this baseline is complete.
- Do not weaken strict IEEE-754-oriented behavior, exact arithmetic, interval soundness, certified bounds, or downstream scientific correctness to recover performance.
- Do not introduce unsafe code.
- Do not add compiler-specific source tricks without a demonstrated, durable benefit and clear documentation.
- Do not assume LLVM 23 is faster or slower; measure it.
Activity