Skip to content

recursion-v2: add PCS aggregation checks#1378

Merged
hero78119 merged 15 commits into
feat/recursion_batch_main_constraintsfrom
feat/recursion_pcs
Jul 8, 2026
Merged

recursion-v2: add PCS aggregation checks#1378
hero78119 merged 15 commits into
feat/recursion_batch_main_constraintsfrom
feat/recursion_pcs

Conversation

@hero78119

@hero78119 hero78119 commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Problem

Recursion v2 aggregation needs to verify the child proof PCS opening path, not only the VM public values, main claims, and tower checks inherited from the base branch.

Design Rationale

This PR maps the native PCS verifier flow into explicit recursion-v2 preflight records, AIRs, and lookup/permutation buses. The design keeps transcript order and proof-shape data owned by preflight replay, then constrains each PCS phase with row-local checks plus cross-module bus bindings. This keeps the verifier logic auditable while avoiding a broad backend fork.

Change Highlights

  • ceno_recursion_v2: add PCS preflight records, buses, AIR modules, and circuit wiring for base input openings, Merkle paths, basefold queries, sumcheck claims, jagged helpers, and final claims.
  • ceno_recursion_v2: bind PCS transcript values and commitment heights into the existing aggregation flow.
  • ceno_zkvm: update test-only field constructors for the upgraded Plonky3/field trait surface.

Benchmark / Performance Impact

Not a performance optimization PR. The new PCS AIRs add prover work; release shard runs remain the relevant sanity check.

Operation

Operation master (s) this PR (s) Improve (master -> this PR)
N/A N/A N/A N/A

Layer

Layer master (s) this PR (s) Improve (master -> this PR)
N/A N/A N/A N/A

Benchmark command(s):

# No benchmark comparison in this PR body.

Environment (CPU/GPU, core count, rust toolchain, commit hash):

raw data:

  • master: N/A
  • this PR: N/A

Testing

cargo fmt --all --check
RUSTFLAGS="-Dwarnings" cargo check --workspace --all-targets
RUSTFLAGS="-Dwarnings" cargo check --workspace --all-targets --release
RUSTFLAGS="-Dwarnings" cargo make clippy
RUSTFLAGS="-Dwarnings" cargo clippy --workspace --all-targets --release
RUSTFLAGS="" cargo make tests
RUSTFLAGS="" cargo make tests_goldilock
taplo fmt --check --diff
git diff --exit-code Cargo.lock

Risks and Rollout

The main risk is verifier soundness from mismatched transcript or PCS phase ordering. Rollout should keep the current shard aggregation tests as the gate and treat new PCS AIR changes as verifier-path changes requiring focused proof fixtures.

Follow-ups (optional)

  • TODO: reduce PCS trace size and prove-time cost after correctness lands.
  • TODO: add narrower PCS phase regression tests so failures localize before full aggregation prove.

Copilot Reviewer Directive (keep this section)

When Copilot reviews this PR, apply .github/copilot-instructions.md strictly.

hero78119 added 13 commits July 7, 2026 11:44
Update the hardcoded child VK digest for the generated keccak_syscall fixture so local aggregation tests no longer need CENO_REC_V2_REAL_VK_DIGEST.\n\nFix multi-shard recursion constraints across verifier PVS, VM PVS aggregation, selector point transcript routing, and ECC RT accounting so agg_prover_two_shards proves and verifies with the current AIR settings.
@hero78119

hero78119 commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator Author

Recursion-v2 aggregation timing update from the local Keccak fixture.

Environment:

  • Fixture regenerated as a real 2-shard keccak_syscall proof with --max-cycle-per-shard=1600; the earlier 2-shard failure was caused by cycling a 1-shard fixture, which duplicated a final shard and violated VmPvsAir continuation adjacency.

Verification:

  • agg_prover_single_shard: passed, elapsed=100.12s
  • agg_prover_two_shards: passed, elapsed=155.29s
  • CENO_REC_V2_DEBUG_CONSTRAINTS=1 agg_prover_two_shards: passed

Single-shard timing split:

  • generate_proving_ctx: 2.17s
  • prove: 97.59s
  • verify: 0.36s
  • total trace cells: 30,778,586

Bottleneck by trace cells:

AIR cells share
MainFrontloadTermAir 12,320,768 ~40%
Poseidon2Air 9,863,168 ~32%
PcsJaggedAssistQAir 3,276,800 ~11%
PcsCommitPhaseMerkleAir 1,638,400 ~5%
PcsEqProductAir 950,272 ~3%
ForkedTranscriptAir 770,048 ~2.5%
PcsSuffixProductAir 688,128 ~2%

Conclusion: the ~100s single-shard runtime is dominated by the prove phase, not generate_proving_ctx. The largest trace surfaces are MainFrontloadTermAir, Poseidon2Air, and jagged PCS tables. The ECC/selector AIRs are not the main cell-count bottleneck in this run (MainEccRtEquationAir: 13,632 cells; MainSelectorFormulaAir: 80,896 cells).

@kunxian-xia kunxian-xia mentioned this pull request Jul 8, 2026
@hero78119 hero78119 changed the title WIP Feat/recursion pcs recursion-v2: add PCS aggregation checks Jul 8, 2026
@hero78119 hero78119 merged commit 70a9ede into feat/recursion_batch_main_constraints Jul 8, 2026
6 checks passed
@hero78119 hero78119 deleted the feat/recursion_pcs branch July 8, 2026 04:41
kunxian-xia added a commit that referenced this pull request Jul 9, 2026
## Problem

Stacked on #1378.

Recursion v2 had CPU-side trace generation and proof wiring, but the
CUDA path was not usable end to end for inner recursion proving. That
left GPU proving unable to exercise the verifier, PCS, transcript,
proof-shape, and public-value traces in the same path used by
aggregation.

## Design Rationale

The main design is to keep recursion proving backend selection behind
the existing generic engine/backend type and enable the CUDA
specialization under the `cuda` feature. CUDA tracegen receives
explicit, typed inputs for proof shape, public values, PCS, transcript,
and verifier data instead of duplicating host-side layout assumptions.

For the OpenVM CUDA prover path, `PcsJaggedAssistQAir` is kept within
degree 4 by materializing the high-degree factor in the trace. This
avoids the logup zerocheck round0 5-coset CUDA limit while preserving
the AIR relation through explicit constraints.

## Change Highlights

- `ceno_recursion_v2`: add CUDA tracegen ABI, build wiring, fixtures,
and test harness.
- `ceno_recursion_v2`: wire CUDA inner tracegen/proving into
`e2e_aggregate`.
- `ceno_recursion_v2`: add CUDA layouts for proof shape, public values,
transcript, verifier, PCS, and main recursion traces.
- `ceno_recursion_v2`: reduce `PcsJaggedAssistQAir` max constraint
degree for CUDA proving compatibility.

## Benchmark / Performance Impact

This PR enables GPU recursion proving. There is no direct `master`
baseline for the CUDA recursion path because the path was not functional
before this PR.

### Operation

| Operation | master (s) | this PR (s) | Improve (master -> this PR) |
|-----------|------------|-------------|-----------------------------|
| recursion aggregation prove, fibonacci | N/A | 0.235 | enables CUDA
path |
| recursion aggregation verify, fibonacci | N/A | 0.037 | enables CUDA
path |
| recursion aggregation prove, keccak_syscall | N/A | 0.185 | enables
CUDA path |
| recursion aggregation verify, keccak_syscall | N/A | 0.033 | enables
CUDA path |

### Layer

| Layer | master (s) | this PR (s) | Improve (master -> this PR) |
|-------|------------|-------------|-----------------------------|
| CUDA inner recursion proving | N/A | 0.185-0.235 | new working path |

Benchmark command(s):

```sh
RUST_LOG=openvm_cuda_backend::logup_zerocheck=debug,ceno_recursion_v2::continuation::prover::inner=info RUST_MIN_STACK=67108864 cargo run --release --features cuda --bin e2e_aggregate -- /home/zbx/blockchain/ceno/examples/target/riscv32im-ceno-zkvm-elf/release/examples/fibonacci --platform ceno --max-cycle-per-shard 16000 --hints 10 --public-io 4191

RUST_LOG=openvm_cuda_backend::logup_zerocheck=debug,ceno_recursion_v2::continuation::prover::inner=info RUST_MIN_STACK=67108864 cargo run --release --features cuda --bin e2e_aggregate -- /home/zbx/blockchain/ceno/examples/target/riscv32im-ceno-zkvm-elf/release/examples/keccak_syscall --platform ceno --max-cycle-per-shard 16000
```

Environment (CPU/GPU, core count, rust toolchain, commit hash):

- local CUDA dev machine
- commit: `25d8ec89`

raw data:

- master: CUDA recursion proving path not available
- this PR:
- fibonacci: proved recursion aggregation in 0.235s, verified in 0.037s;
final exit is the known internal aggregation tree-reduction gap for 4
leaf proofs
- keccak_syscall: proved recursion aggregation in 0.185s, verified in
0.033s; exit code 0

## Testing

```sh
cargo fmt --check
git diff --check -- src/pcs/mod.rs src/bin/e2e_aggregate.rs
RUST_MIN_STACK=67108864 cargo run --release --features cuda --bin e2e_aggregate -- /home/zbx/blockchain/ceno/examples/target/riscv32im-ceno-zkvm-elf/release/examples/keccak_syscall --platform ceno --max-cycle-per-shard 16000
RUST_MIN_STACK=67108864 cargo run --release --features cuda --bin e2e_aggregate -- /home/zbx/blockchain/ceno/examples/target/riscv32im-ceno-zkvm-elf/release/examples/fibonacci --platform ceno --max-cycle-per-shard 16000 --hints 10 --public-io 4191
```

## Risks and Rollout

The main risk is CUDA/host layout drift. The PR mitigates this with
typed ABI structs, generated fixtures, and CUDA tracegen tests. Rollout
is feature-gated behind `cuda`, so CPU proving remains the fallback
path.

## Follow-ups (optional)

- Implement internal aggregation tree reduction for multiple leaf
proofs.
- Remove temporary CUDA diagnostic prints from the local OpenVM checkout
or rebuild clean CUDA objects before collecting final benchmark logs.

## Copilot Reviewer Directive (keep this section)

When Copilot reviews this PR, apply `.github/copilot-instructions.md`
strictly.
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.

1 participant