Repository navigation
v0.2.4
GrayNFS v0.2.4
0.x carries no compatibility promise.
Highlights
- Operation cancellation that actually works:
factor_with_progresscallback returningFalsecancels (previously ignored) surfacingGrayNFSError(category=cancelled); new public RustCancellationTokenwithfactor_with_cancellation/factor_with_timings_cancelled; CLI Ctrl+C interrupts long GNFS runs instead of hanging them. - CLI batch mode:
graynfs batch --input numbers.txt [--jsonl] [--continue-on-error]streams one integer per line with per-input JSON Lines records (input/factors/status/method/elapsed_ms/error); a bad line no longer aborts the run under the continue flag. - Per-factor primality confidence:
factor_reportand CLI JSON now carryfactor_confidence(proven_prime | probable_prime | composite) per factor; CLI JSON also emits the previously missingpolynomial/root. Proven means deterministic-u64-Miller-Rabin (rigorous below 2^64), never AKS on the hot path. - GNFS relation product-merge filter + excess/target retune 1.5x+16 to 1.33x+16: deg3skip-deg3 wall down 21% (2015.9 to 1590.0 ms), b70-deg3 wall down 36% (13456.0 to 8566.0 ms), RSS down ~28 MiB each, identical factors throughout (A/B 5/5 product-verified).
- SIQS static-buffer buckets: hostile-105
sieve_markworker-sum down 25.65% at identical call counts (interleaved arms, fully non-overlapping); bit100 guard +2.60% (limit +5%). - ECM cheap-tier per-tier calibration: collection fill up 8.0x/4.1x on ECM wins (measured 0.53/1.03 ms per curve vs the old unmeasured 64).
Breaking changes
- Progress-callback contract: a falsy callback return now requests cancellation (was ignored); truthy/
Nonecontinue as before. Any existing callback returningFalsewill now cancel runs. - Ctrl+C now interrupts the CLI run with a clean
Cancelled/cancelledterminal instead of the default handler. FactorReport, Pythonfactor_reportdicts, and CLI JSON gain additive-only keys (factor_confidence, pluspolynomial/rootin CLI JSON); parsers matching exact key sets should allow the new keys.- Standing pins moved by the measured retune (same factors, fewer relations): deg3skip-deg3 3677/2419 to 3023/2160, observed b70-deg3 5981/3966 to 5062/3698 (both predecessors kept as historical).
What's changed
- Cancellation plumbing:
CancellationToken(Arc<AtomicBool>, clone-shares-state) threaded throughfactor_collected; progress closures check the token at every event; join-fallback precedent kept (no new panics). - Batch CLI: subcommand with streaming reader, additive-only 6-key JSONL schema with golden + abort + parse tests; cancelled/error lines exit non-zero (Ctrl+C mid-batch exits FAILURE).
- Confidence: deterministic-u64-MR-first classifier (AKS off the hot path after it hung a 30-bit factor past 180 s); M11 base set untouched;
aks_calls()==0tripwire on the factor path. - Cost model split: collect-only pilot rate with select added exactly once (
T_GNFS = T_select+T_base+T_collect+T_LA+T_sqrt); GNFS rates kept out of SIQS projections; winning pilots now emit rated need; skip/escalation select asymmetry replayed NO-FLIP (standing adjudicator kept). - Pin system:
bench/pins.jsonis the single spec (standing/observed/historical split); perf_smoke extended to 4 cells with deg3skip-deg2 240/145 (5/5, med 10.0 ms vs 45.0 limit); hostile105-deg2 1177/926 enforced (med 657.0 vs 4290.0 limit); README historical/current split, filtering row corrected for the landed merge. - Front-end instrumentation: additive-only trial/rho/siqs_multiplier timing rows (envelope schema additive-only verified).
- Correctness fixes: drain path no longer drops just-appended filter squares (hoisted post-drain, unit-pinned); batch Ctrl+C exit code; stale
stage_timingsempty-list test pin updated for the new trial row. - CI clippy denies fixed (test-only
retain/[T; N]/iterator forms + one same-branch mapping collapse, behavior-neutral). - KILL ledger (no production change, exact reverts with grep-zero proofs): P-1 stage-2 BSGS (broke the bit100-default standing gate: pm1 745/633 ms vs ecm 144 ms — re-proposable with B2 cap + cost gate), duplicate/freerel removal (dup=0/free=0 on corpus).
- CLOSE ledger (measurement-only, standing adjudicators kept): usable-decay projector (K<=2 pilots cannot separate decaying/saturating cells), select-symmetry replay (12/12 NO-FLIP), component/clique analysis (single components, zero duplicate masks on recorded matrices), 25-digit deg3 finality (double-LP inflates singles bank 9.7x and trips the memory gate at 10.1 s — 18/19/21 stay sealed, no auto-reopen).
Benchmarks
- CI smoke gate (release, 16 threads, medians of 5, binary
e8fb3e42, 2026-11-01 + full-gate rebuild191928ce): OVERALL PASS 4/4, all 5/5 product-verified — bit100-deg2 siqs 1878/945 med 189.0 (limit 322.5), bit100-default ecm med 89.0 (limit 197.5, method pin restored post-KILL), hostile105-deg2 siqs 1177/926 med 657.0 (limit 4290.0), deg3skip-deg2 siqs 240/145 med 10.0 (limit 45.0). - Retuned GNFS cells (A/B -n 5, STOP/load-gated, release pair): deg3skip-deg3 3023/2160 (was 3677/2419) wall 2015.9 to 1590.0 ms, RSS -28.30 MiB; b70-deg3 5062/3698 (was 5981/3966) wall 13456.0 to 8566.0 ms, RSS -28.26 MiB; factors byte-identical both arms.
- Full gates on the tagged tree: fmt clean, clippy -D warnings clean,
cargo test --workspace383 passed / 0 failed, pytest 52 passed on the attached wheel. - Standing pins held exact: 1878/945, 240/145; hostile105 1177/926 with identical factors to the historical 3269/907.
Full Changelog: v0.2.3...v0.2.4