fix: graceful AVX2 CPU check with clear error message instead of crash#2083
Open
Gosha250311 wants to merge 3 commits intonexus-xyz:mainfrom
Open
fix: graceful AVX2 CPU check with clear error message instead of crash#2083Gosha250311 wants to merge 3 commits intonexus-xyz:mainfrom
Gosha250311 wants to merge 3 commits intonexus-xyz:mainfrom
Conversation
…y clamp Two bugs prevented --max-threads from taking effect: 1. Memory clamping fired automatically whenever --max-threads was set (condition was `max_threads.is_some() || check_mem`). On machines with ≤8 GB RAM the formula `floor(RAM * 0.75 / 4 GB)` evaluates to 1, silently overriding the user's value and causing the dashboard to always show "Threads: 1". The guard is now gated on --check-memory only. 2. The Rayon thread pool (used by nexus-sdk's Stwo prover inside each proving subprocess) was never configured from num_workers. Added a --num-threads flag to the hidden prove-fib-subprocess subcommand; prove_and_validate forwards the value when spawning the subprocess, and prove_fib_subprocess calls rayon::ThreadPoolBuilder::build_global at startup so the prover uses exactly the requested thread count. Also adds unit tests for the num_workers computation logic and integration tests confirming both --max-threads and --num-threads are accepted by clap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On older CPUs that lack AVX2 instructions, the prover crashes with a floating point exception (SIGILL) deep in the proving stack with no useful message. This check runs at the very start of main(), before any other initialization, and exits with a clear human-readable error explaining which CPU generations are supported. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Problem
-------
The Nexus CLI is compiled with `-C target-cpu=native` (.cargo/config.toml),
which bakes AVX2 instructions into the binary at compile time via the
stwo-prover SIMD backend. When the resulting binary is run on a CPU that
lacks AVX2 (pre-2013 Intel / pre-2017 AMD), the OS delivers SIGILL, which
Rust surfaces as a "floating point exception" with no actionable guidance.
Solution
--------
Check for AVX2 at the very start of `main()`, before the panic hook and
before any other initialisation, so we can exit with a clear message instead
of crashing.
Implementation details
----------------------
The check is factored into three small, composable functions to keep the
logic fully testable without needing hardware that lacks AVX2:
avx2_missing_message() — the human-readable error text (static str)
cpu_feature_error(avx2: bool) — maps a bool to Option<&'static str>;
accepts an injected value so unit tests
can exercise both branches on any machine
check_cpu_features() — calls is_x86_feature_detected!("avx2")
on x86_64; returns None on all other arches
Both helper functions are gated with #[cfg(any(target_arch = "x86_64", test))]
so they compile on non-x86_64 during `cargo test` (for unit tests) but are
absent in non-test non-x86_64 release builds.
Other CPU features investigated
--------------------------------
stwo-prover also has an avx512f code path, but that is an optional
enhancement selected at compile time via target_feature; AVX2 is the
mandatory baseline on x86_64. No other ISA extensions (SSE4, BMI, …) are
required independently because they are all implied by AVX2.
Tests added (src/main.rs — cpu_check_tests)
--------------------------------------------
avx2_error_message_names_avx2
avx2_error_message_names_intel_and_amd
avx2_error_message_names_specific_cpu_generations (Haswell/2013, Ryzen/Zen/2017)
avx2_error_message_explains_the_cpu_is_too_old
cpu_feature_error_returns_none_when_avx2_present (injectable: avx2=true)
cpu_feature_error_returns_message_when_avx2_absent (injectable: avx2=false)
cpu_check_passes_on_avx2_capable_x86_64 (#[cfg(target_arch="x86_64")])
cpu_check_is_skipped_on_non_x86_64 (#[cfg(not(target_arch="x86_64"))])
Tests added (tests/cli.rs — integration)
-----------------------------------------
avx2_check_does_not_trigger_on_supported_x86_64_hardware
avx2_check_absent_on_non_x86_64
cli_exits_zero_for_help_on_supported_hardware
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.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.
Problem
Closes #2060
On CPUs that do not support AVX2 instructions (Intel pre-Haswell,
AMD pre-Ryzen), the CLI crashes immediately with a cryptic
Floating point exception (core dumped)instead of a helpful error.This happens because the CLI is compiled with
-C target-cpu=nativewhich bakes in AVX2 instructions at compile time. When these
instructions execute on unsupported hardware, the OS sends SIGILL
which appears as a floating point exception.
Fix
Added a CPU feature check at the very start of main() before any
prover code runs. If AVX2 is not available, the CLI exits gracefully
with a clear, actionable error message.
The check is skipped entirely on non-x86_64 platforms (ARM, etc.)
since they use NEON/scalar paths with no AVX2 dependency.
Error message shown to users
Architecture
Refactored into 3 composable functions for testability:
avx2_missing_message()- error text, testable independentlycpu_feature_error(bool)- logic, injectable for unit testscheck_cpu_features()- real hardware detectionTesting
79 tests pass, 0 failures, 0 warnings
11 new tests added covering message content, logic injection,
and platform-specific behaviour