Skip to content

merge: main (post-#826) into feat/logup-acc-current-row — compose deep-composition fuse+hoist with g·z pruning#840

Merged
MauroToscano merged 3 commits into
feat/logup-acc-current-rowfrom
merge/main-826-into-logup-acc
Jul 16, 2026
Merged

merge: main (post-#826) into feat/logup-acc-current-row — compose deep-composition fuse+hoist with g·z pruning#840
MauroToscano merged 3 commits into
feat/logup-acc-current-rowfrom
merge/main-826-into-logup-acc

Conversation

@MauroToscano

Copy link
Copy Markdown
Contributor

Why a textual merge was impossible

Main (via #826) and this branch both rewrote reconstruct_deep_composition_poly_evaluations_for_all_queries and reconstruct_deep_composition_poly_evaluation in crypto/stark/src/verifier.rs. The conflict is semantic, not just textual: #826's new compute_query_invariant_deep_terms hoist reads proof.trace_ood_evaluations() as the full OOD grid, but after this branch's g·z pruning that field carries only the current-row block — taking either side verbatim would either drop the fuse+hoist or compute the DEEP trace term over a truncated grid.

Union resolution

  • compute_query_invariant_deep_terms now takes the reconstructed full grid ood_full (from crate::ood::reconstruct_ood_full, zeros at pruned next-row positions) plus next_row_cols/step_size; the hoisted ood_row_sum sums all columns for current rows and only the transition-window columns for next rows. The grid width is stored in QueryInvariantDeepTerms so the pair function no longer reads the proof.
  • The fused reconstruct_deep_composition_poly_evaluation_pair (regular + symmetric together, shared z·gᵏ walk, single batch inverse per pair, F×E base-field multiplications) keeps perf(stark): fuse and hoist deep-composition reconstruction for both FRI points #826's per-row column loop for rows below step_size and iterates only next_row_cols (one column in production) for rows at or above it — this branch's per-query pruning saving landed inside perf(stark): fuse and hoist deep-composition reconstruction for both FRI points #826's structure, replacing the old branch-per-cell skip. next_row_cols: &[usize] replaces next_row_flags: &[bool] end to end in verifier.rs; ood.rs's public API is unchanged.
  • Every rejection path from both sides survives: perf(stark): fuse and hoist deep-composition reconstruction for both FRI points #826's coefficient-grid product-shape guard, gammas-length guard, num_base != num_base_sym and OOD-width checks, number_of_parts equality for both openings, and both batch-inverse rejections. No new panic paths reachable from a malformed proof, and no allocations beyond what the two PRs individually did.

Exactness: pruned next-row positions have a zero DEEP coefficient (build_pruned_trace_term_coeffs) and a zero value in the reconstructed grid, so restricting both the hoisted coeff·ood sum and the per-query coeff·base sum to the window columns is bit-exact with the unpruned computation.

This composes #826's measured −20.3% verifier win with this branch's per-query g·z pruning saving — neither is lost.

Validation

MauroToscano and others added 3 commits July 16, 2026 15:30
…T) (#800)

* fix(math-cuda): robust CUDA version handling for cuda builds

Two driver-independence fixes so `--features cuda` builds AND runs on the
team's GPU hardware without CUDARC_CUDA_VERSION env or a hand-picked toolkit.

1. cudarc symbol floor. Pin cudarc's CUDA version to `cuda-12080` in
   crypto/math-cuda/Cargo.toml (was `cuda-version-from-build-system` +
   `fallback-latest`). Auto-detect bound the newest symbol set the build
   toolkit knew (e.g. CUDA 13.1 -> cuDevSmResourceSplit, gated behind
   cuda-13010/13020), which cudarc eagerly resolves at init and panics on a
   driver that predates it (580.x = CUDA 13.0 max). Our cudarc surface is all
   CUDA-11-era, so the 12.8 symbol set (a strict subset every >=12.8 driver
   exports) resolves cleanly everywhere. Replaces the per-script sed pin;
   drops it from scripts/gpu_test.sh and adjusts the compat shim in
   scripts/bench_abba.sh (still rewrites pre-pin baseline shas).

2. PTX ISA version. AOT-compile kernels to native cubin (SASS) via
   `nvcc --cubin -arch=sm_XX` instead of `--ptx`, loaded through
   `Ptx::from_binary` (cuModuleLoadData). A cubin carries pre-compiled SASS
   for a real arch, so the driver loads it regardless of the toolkit's PTX
   ISA version -- no CUDA_ERROR_UNSUPPORTED_PTX_VERSION and no silent
   CPU fallback when the toolkit is newer than the driver. Build+run are
   co-located and the arch is detected from nvidia-smi, so the arch always
   matches; a too-old toolkit now fails loudly at nvcc build time.

CPU-only and nvcc-less stub builds unaffected (empty cubin stub). README
"GPU Tests" updated.

* fix(math-cuda): review fixes — warn on cubin load failure + bench pin no-op

- backend(): warn once when GPU init fails, so a cubin arch mismatch (AOT cubins
  are arch-specific) doesn't silently disable the GPU with no signal. Stale
  ptx->cubin comment fixed.
- bench_abba.sh: warn when CUDARC_PIN can't apply (post-pin sha, anchor gone)
  instead of silently no-opping.

* fix(math-cuda,scripts): review fixes — warn on sm_89 arch fallback + bench_abba_gpu pin guard/restore + cubin comment

* refactor(scripts): shared ABBA bench lib + README GPU driver floor

bench_abba.sh and bench_abba_gpu.sh carried near-verbatim copies of the
prove-time parsing, the CUDARC_PIN compat sed, and the paired-stats python —
a stats fix applied to one would silently leave the other reporting different
numbers for the same pairs. scripts/lib/bench_abba_common.sh now holds all
three; the GPU bench gains the full analysis (exact Wilcoxon, stability
diagnostics, verdicts) it previously lacked.

README: state the cuda-12080 pin's driver floor (CUDA >= 12.8 / 570+) and
that older drivers abort at CUDA init rather than CPU-fallback.

* chore(scripts): drop unused bench_abba_gpu.sh

No automation calls it (the GPU bench CI runs bench_abba.sh), and its whole
premise — the rigorous ABBA paired-t + Wilcoxon method — is overkill for the
question it wrapped: a GPU-on-vs-off delta is 10-40%, which two runs and your
eyes resolve. The ABBA machinery earns its keep only for the ~1% effects
(bench_abba.sh's PR-vs-baseline deltas), so one bench script is enough.

* fix(math-cuda): hard-fail arch detection instead of guessing sm_89

A cubin is arch-locked, so when nvcc is present but no GPU arch can be
detected there is no safe default — the old sm_89 fallback produced a binary
that loads on exactly one GPU model (Ada) and silently CPU-falls-back on every
other, including lower-arch cards like the 3090 (sm_86, which an sm_89 cubin
can't even run — cubins aren't backward-compatible). Panic with an actionable
message (set CUDARC_NVCC_ARCH or build on the target host) instead. Only
reachable with nvcc present + no visible GPU + no override; nvcc-absent hosts
take the empty-stub path and never hit this, so CPU-only CI is unaffected.

* chore(scripts): move ABBA bench cleanup to its own PR (#812)

The bench-tooling dedup + bench_abba_gpu.sh removal are split into #812 so this
PR is purely the cuda build-robustness changes (which want a GPU test run),
leaving the trivial script cleanup free to merge independently.
…FRI points (#826)

* perf(stark): fuse and hoist deep-composition reconstruction for both FRI points

reconstruct_deep_composition_poly_evaluation walked the OOD table and
trace-term coefficients, and inverted denominators, independently for the
regular and symmetric evaluation points, then recomputed the point-invariant
OOD/gamma sums from scratch on every one of the ~80 FRI queries per proof.

Rewriting coeff*(base-ood)*denom as denom*(coeff*base - coeff*ood) isolates
the point-independent coeff*ood term (identical between the two points) from
coeff*base, so both points can share the OOD walk and a single batch-inverse.
The point-invariant ood_row_sum/z_pow/h_sum_zpow sums are now computed once
per proof in compute_query_invariant_deep_terms instead of once per query.

Multi-query recursion profile: 1,325,335,927 -> 916,824,543 cycles (-30.8%);
step 3 (FRI) 635,418,644 -> 233,869,693 cycles (-63.2%).

* fmt

---------

Co-authored-by: Diego K <43053772+diegokingston@users.noreply.github.com>
Composes #826's deep-composition fuse+hoist with this branch's g·z OOD
pruning in crypto/stark/src/verifier.rs (union resolution, replayed via
rerere from the pre-merge dry run): the QueryInvariantDeepTerms hoist
reads the reconstructed full OOD grid, and next rows iterate only the
transition-window columns in both the hoisted and per-query sums.
Exact because pruned positions have zero coefficient and zero grid
value. All guards from both sides preserved; no new panic paths.
Everything else from main merged clean.
@MauroToscano
MauroToscano merged commit 43351e1 into feat/logup-acc-current-row Jul 16, 2026
13 checks passed
@MauroToscano
MauroToscano deleted the merge/main-826-into-logup-acc branch July 16, 2026 17:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants