Skip to content

Commit c512053

Browse files
committed
merge blake3-real-hash into mmcs-integration
Carries origin/main (cf3b1e9) onto the MMCS integration branch: the bump guest allocator default (#869), the VRAM-pressure/R2-race fix (#914), the cuda table scheduler K = num_airs default (#911), and the device-only cliff recovery at R4 DEEP / comp-tree / R3 barycentric (#935). This is the branch where the two sides genuinely interleave. M-4p2 extracted the round bodies so they take the data they use — `lde_trace`, `composition_parts`, `rap_challenges` — instead of the whole `Round1`/`Round2`, and `multi_prove_batched` reuses those same extractions. #935 works the other way: its recoveries write the resident device data back into those very buffers, which is why upstream widened the round signatures to `&mut Round1`/`&mut Round2`. Neither shape can simply win. Resolution rule, applied to all nine hunks: **keep the extraction, move the mutability onto the extracted parameter.** Each recovery then writes to exactly the buffer its caller owns, and the batched path keeps sharing one implementation with the monolithic one. - `crypto/stark/src/prover.rs` `compute_composition_parts` — `lde_trace` becomes `&mut`; the R2 host-evaluator arm takes #935's recover-then-assert (replacing the old hard abort) against that parameter rather than `round_1_result.lde_trace`. - `crypto/stark/src/prover.rs` `compute_composition_parts` — the `evaluate_dev` arm keeps the extracted `rap_challenges` and the extracted `lde_trace` in the `host_trace_empty` retain flag. - `crypto/stark/src/prover.rs` `round_2_compute_composition_polynomial` — keeps the `CompositionParts` return, and #935's fold of the R2 device parts handle into the session (`set_gpu_composition_parts`) is added after the call, where `round_1_result` is in scope. - `crypto/stark/src/prover.rs` `round_3_evaluate_polynomials_in_out_of_domain_element` — extracted `lde_trace` and `composition_parts` both become `&mut`; the R3 parts OOD arm takes #935's recovery against them. - `crypto/stark/src/prover.rs` `compute_deep_composition_poly_evaluations` — same two parameters become `&mut`; the host DEEP loop's recovery writes through `composition_parts` instead of `round_2_result.lde_composition_poly_evaluations`. - `crypto/stark/src/batched/prover.rs` — the three call sites and `deep_codeword` follow the widened signatures; the FRI combine closure captures `retained_parts` mutably. That closure is `FnOnce` and runs serially, so the capture adds no concurrency requirement. - `crypto/stark/src/prover.rs` — the two `mut` bindings the split moved: the parts the R2 commit recovery writes now live in `round_2_compute_composition_polynomial` (so `computed.parts` is bound `mut` there), and `compute_composition_parts`'s own local is no longer mutated by anything, so it loses the `mut` and the `unused_mut` cfg_attr that went with it. Only the cuda lint pass sees either. Both semantics are live afterwards: nothing is un-genericized, no recovery is dropped, and the parameter each recovery writes to is the one the caller reads next. Gates: stark release 350/0 (RESUME-MMCS-INT.md's 349/0 plus main's new `table_parallelism_stays_within_one_and_num_airs`); debug batched/mmcs 87/0, exactly the recorded baseline; crypto 71+1/0 on both round arms; `make lint` clean across all five combos; fmt clean. `lfm::` reads 345 passed / 19 failed / 9 ignored against a recorded baseline of 349/15/9, and the merge is NOT the cause. Checked out 46798a5 — this branch's own pre-merge tip — and ran the same suite there: 345/19/9, and the 19 failing test names diff byte-identical against the merged tree's. The merge delta is exactly zero; the recorded baseline is stale, drifted by the fixture/toolchain trap already documented in the lfm fixture-drift notes. Independently, every resolution in this merge is inside `#[cfg(feature = "cuda")]` or is a signature mutability change, and that suite runs without cuda, so it could not have moved those tests either way. SEMANTIC-CONFLICT NOTE. The batched path consumes its parts on the host immediately (`parts_builder.absorb`) and never reads the device parts handle, so the recoveries are inert there today — `materialize_composition_parts_host` returns true without touching anything when the evals are already populated, so the widened signatures cost the batched path nothing and cannot trip its asserts. The recovery is only reachable on the monolithic path. Flagged because that is a judgement about reachability, not something a test currently pins.
2 parents 46798a5 + 75a501e commit c512053

53 files changed

Lines changed: 2347 additions & 2575 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/benchmark-pr.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ on:
1212
- 'executor/**'
1313
- 'bin/cli/**'
1414
- 'tooling/ethrex-fixtures/**'
15+
# syscalls is linked into the guest ELF this job builds, so a change confined to
16+
# it changes the bytes proven — a guest allocator swap moves cycles on every
17+
# workload. Without it main's baseline would stay stale until some prover file
18+
# happened to change, and the comparison guard would suppress the table until
19+
# then. pr_main.yaml:99 already hashes 'syscalls/**' into the guest-ELF cache
20+
# key; the two lists must agree on what rebuilds the guest.
21+
- 'syscalls/**'
1522
# A baseline is only valid for the workload it measured, and the Makefile is
1623
# what defines that workload: it names the block and pins the URL and sha256
1724
# of the .bin this job fetches. Without it a repointed block would leave
@@ -28,6 +35,7 @@ on:
2835
# - 'crypto/**'
2936
# - 'executor/**'
3037
# - 'bin/cli/**'
38+
# - 'syscalls/**'
3139

3240
permissions:
3341
contents: read
@@ -273,7 +281,8 @@ jobs:
273281
274282
# Optional table parallelism for the HEADLINE benchmark only (the memory
275283
# growth sweep always runs at default parallelism). `/bench k=N` overrides;
276-
# otherwise default (cores/3). /bench-growth no longer forces k=1.
284+
# otherwise the build's default (num_airs on cuda, cores/3 on CPU).
285+
# /bench-growth no longer forces k=1.
277286
TABLE_K=""
278287
if [ "$EVENT_NAME" = "issue_comment" ]; then
279288
TABLE_K=$(echo "$COMMENT_BODY" | grep -o 'k=[0-9]*' | head -1 | cut -d= -f2)

.github/workflows/hyperfine.yaml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ on:
66
paths:
77
- 'executor/src/**'
88
- 'executor/Cargo.toml'
9+
# syscalls is linked into the guest ELFs this job builds and measures, so a change
10+
# confined to it moves cycles on every benchmark. The cache key below already
11+
# hashes it; both lists must agree on what rebuilds the guest, or a syscalls-only
12+
# change (a guest allocator swap, say) never gets benchmarked at all.
13+
- 'syscalls/**'
914

1015
concurrency:
1116
group: ${{ github.workflow }}-${{ github.ref }}
@@ -35,7 +40,7 @@ jobs:
3540
id: cache
3641
with:
3742
path: ${{ matrix.branch }}_programs/*.elf
38-
key: benchmarks-${{ matrix.branch }}-${{ hashFiles( 'executor/programs/bench/**', 'syscalls/src/**' ) }}
43+
key: benchmarks-${{ matrix.branch }}-${{ hashFiles( 'executor/programs/bench/**', 'syscalls/**' ) }}
3944
restore-keys: benchmarks-${{ matrix.branch }}-
4045

4146
- name: Setup Rust Environment
@@ -51,7 +56,7 @@ jobs:
5156
5257
- name: Export benchmark hashes
5358
id: export-hashes
54-
run: echo "benchmark-hashes-${{ matrix.branch }}=${{ hashFiles( 'executor/programs/bench/**', 'syscalls/src/**' ) }}" >> "$GITHUB_OUTPUT"
59+
run: echo "benchmark-hashes-${{ matrix.branch }}=${{ hashFiles( 'executor/programs/bench/**', 'syscalls/**' ) }}" >> "$GITHUB_OUTPUT"
5560

5661
build-binaries:
5762
strategy:

.github/workflows/pr_main.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,17 @@ jobs:
175175
- name: Run CLI tests
176176
run: cargo test -p cli
177177

178-
- name: Run syscalls host tests (keccak differential vs sha3)
178+
- name: Run syscalls host tests (allocator + keccak differential vs sha3)
179179
run: make test-syscalls
180180

181+
# The dlmalloc fallback is feature-selected, so nothing else in CI compiles it and it
182+
# can rot silently. Its tests run here too.
183+
- name: Test the dlmalloc guest allocator fallback
184+
run: |
185+
cd syscalls
186+
cargo test --features dlmalloc-alloc
187+
cargo test --release --features dlmalloc-alloc
188+
181189
- name: Run ethrex-crypto host tests (hint verify-then-fallback + ecrecover)
182190
run: make test-ethrex-crypto
183191

Cargo.lock

Lines changed: 14 additions & 88 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Makefile

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -514,8 +514,12 @@ check-ethrex-fixture-checksums:
514514
# differential tests (the keccak sponge vs sha3 reference). Run them explicitly
515515
# in the crate dir; wired into `test` below and run as a dedicated step
516516
# in CI's cli-test job (pr_main.yaml).
517+
# Release too: the allocator's `init` guard degrades to an early return once
518+
# `debug_assert!` is compiled out, which is the configuration guests are built in,
519+
# and the test for that path is `#[cfg(not(debug_assertions))]`.
517520
test-syscalls:
518521
cd syscalls && cargo test
522+
cd syscalls && cargo test --release
519523

520524
# ethrex-crypto is a detached workspace (excluded from the root members), so a
521525
# root `cargo test` never runs it. Run it explicitly, like test-syscalls.
@@ -561,6 +565,14 @@ test-disk-spill:
561565
cargo test --release -p stark --features disk-spill disk_spill
562566
FORCE_DISK_SPILL=1 cargo test --release -p lambda-vm-prover --features disk-spill -- disk_spill count_table_lengths
563567

568+
# Per-target wall clock for the GPU prover targets below. A panic on a device-only
569+
# cliff assert can leave the prover hung rather than aborting — the panicking thread
570+
# unwinds while its siblings stay parked in CUDA driver waits, and the process never
571+
# exits — which would hold the rented merge-queue box until the workflow timeout.
572+
# 45 min is generous against their normal runtime; the SIGKILL follows 30s later, and
573+
# timeout's 124 exit fails the target so gpu_test.sh reports the group as failed.
574+
GPU_TEST_TIMEOUT := timeout -k 30 2700
575+
564576
# math-cuda parity tests (requires NVIDIA GPU + nvcc)
565577
test-math-cuda:
566578
cargo test -p math-cuda --release
@@ -629,13 +641,13 @@ test-blake3-second-source:
629641
# --test-threads=1: these tests reset and assert on process-global GPU call
630642
# counters, so they must run serially or one test's reset races another's read.
631643
test-cuda-integration:
632-
cargo test -p lambda-vm-prover --release --features cuda \
644+
$(GPU_TEST_TIMEOUT) cargo test -p lambda-vm-prover --release --features cuda \
633645
--test cuda_path_integration -- --ignored --nocapture --test-threads=1
634646

635647
# GPU error-path coverage (requires NVIDIA GPU + nvcc).
636648
# Forces cuda dispatch errors and asserts the CPU fallback still produces a verifying proof.
637649
test-cuda-fallback:
638-
cargo test -p lambda-vm-prover --release --features test-cuda-faults \
650+
$(GPU_TEST_TIMEOUT) cargo test -p lambda-vm-prover --release --features test-cuda-faults \
639651
--test cuda_fallback_tests -- --ignored --nocapture --test-threads=1
640652

641653
# The prover/stark/crypto/ecsm test suite with the GPU (cuda) path enabled (requires NVIDIA
@@ -645,14 +657,14 @@ test-cuda-fallback:
645657
# compile-recursion-elfs: this unfiltered run executes the non-ignored recursion
646658
# smoke tests, which read prebuilt guest ELFs; scripts/gpu_test.sh otherwise never builds them.
647659
test-prover-cuda: compile-recursion-elfs
648-
cargo test --release -p lambda-vm-prover -p stark -p crypto -p ecsm \
660+
$(GPU_TEST_TIMEOUT) cargo test --release -p lambda-vm-prover -p stark -p crypto -p ecsm \
649661
--features lambda-vm-prover/cuda -- --test-threads=1
650662

651663
# The comprehensive all-instructions prove (ignored by default) on the GPU path (requires
652664
# NVIDIA GPU + nvcc). GPU counterpart of the all-instructions half of CPU CI's merge-queue-only
653665
# comprehensive job (the CPU job also runs test_recursion_execute; recursion has no GPU leg yet).
654666
test-prover-comprehensive-cuda:
655-
cargo test --release -p lambda-vm-prover --features cuda \
667+
$(GPU_TEST_TIMEOUT) cargo test --release -p lambda-vm-prover --features cuda \
656668
test_prove_elfs_all_instructions_64_full -- --ignored --test-threads=1 --nocapture
657669

658670
# math-cuda quick microbench (median of 10 runs)

0 commit comments

Comments
 (0)