Skip to content

Commit a6be3df

Browse files
feat: use cached max trace heights in leaf/internal aggregation (#1839)
1 parent a7d1125 commit a6be3df

File tree

9 files changed

+124
-39
lines changed

9 files changed

+124
-39
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benchmarks/prove/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ license.workspace = true
1010
[dependencies]
1111
openvm-benchmarks-utils.workspace = true
1212
openvm-circuit.workspace = true
13+
openvm-continuations.workspace = true
1314
openvm-sdk.workspace = true
1415
openvm-stark-backend.workspace = true
1516
openvm-stark-sdk.workspace = true

benchmarks/prove/src/bin/kitchen_sink.rs

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,85 @@ use eyre::Result;
55
use num_bigint::BigUint;
66
use openvm_algebra_circuit::{Fp2Extension, ModularExtension};
77
use openvm_benchmarks_prove::util::BenchmarkCli;
8-
use openvm_circuit::arch::{instructions::exe::VmExe, SystemConfig};
8+
use openvm_circuit::arch::{instructions::exe::VmExe, SingleSegmentVmExecutor, SystemConfig};
9+
use openvm_continuations::verifier::leaf::types::LeafVmVerifierInput;
910
use openvm_ecc_circuit::{WeierstrassExtension, P256_CONFIG, SECP256K1_CONFIG};
11+
use openvm_native_circuit::{NativeConfig, NATIVE_MAX_TRACE_HEIGHTS};
1012
use openvm_native_recursion::halo2::utils::{CacheHalo2ParamsReader, DEFAULT_PARAMS_DIR};
1113
use openvm_pairing_circuit::{PairingCurve, PairingExtension};
1214
use openvm_pairing_guest::{
1315
bls12_381::BLS12_381_COMPLEX_STRUCT_NAME, bn254::BN254_COMPLEX_STRUCT_NAME,
1416
};
1517
use openvm_sdk::{
16-
commit::commit_app_exe, config::SdkVmConfig, prover::EvmHalo2Prover,
17-
DefaultStaticVerifierPvHandler, Sdk, StdIn,
18+
commit::commit_app_exe,
19+
config::SdkVmConfig,
20+
keygen::AppProvingKey,
21+
prover::{vm::types::VmProvingKey, EvmHalo2Prover},
22+
DefaultStaticVerifierPvHandler, NonRootCommittedExe, Sdk, StdIn, SC,
1823
};
1924
use openvm_stark_sdk::{
2025
bench::run_with_metric_collection, config::baby_bear_poseidon2::BabyBearPoseidon2Engine,
2126
};
2227
use openvm_transpiler::FromElf;
2328

29+
fn verify_native_max_trace_heights(
30+
sdk: &Sdk,
31+
app_pk: Arc<AppProvingKey<SdkVmConfig>>,
32+
app_committed_exe: Arc<NonRootCommittedExe>,
33+
leaf_vm_pk: Arc<VmProvingKey<SC, NativeConfig>>,
34+
num_children_leaf: usize,
35+
) -> Result<()> {
36+
let app_proof =
37+
sdk.generate_app_proof(app_pk.clone(), app_committed_exe.clone(), StdIn::default())?;
38+
let leaf_inputs =
39+
LeafVmVerifierInput::chunk_continuation_vm_proof(&app_proof, num_children_leaf);
40+
let vm_vk = leaf_vm_pk.vm_pk.get_vk();
41+
42+
leaf_inputs.iter().for_each(|leaf_input| {
43+
let executor = {
44+
let mut executor = SingleSegmentVmExecutor::new(leaf_vm_pk.vm_config.clone());
45+
executor
46+
.set_trace_height_constraints(leaf_vm_pk.vm_pk.trace_height_constraints.clone());
47+
executor
48+
};
49+
let max_trace_heights = executor
50+
.execute_metered(
51+
app_pk.leaf_committed_exe.exe.clone(),
52+
leaf_input.write_to_stream(),
53+
&vm_vk.total_widths(),
54+
&vm_vk.num_interactions(),
55+
)
56+
.expect("execute_metered failed");
57+
println!("max_trace_heights: {:?}", max_trace_heights);
58+
59+
let actual_trace_heights = executor
60+
.execute_and_generate(
61+
app_pk.leaf_committed_exe.clone(),
62+
leaf_input.write_to_stream(),
63+
&max_trace_heights,
64+
)
65+
.expect("execute_and_generate failed")
66+
.per_air
67+
.iter()
68+
.map(|(_, air)| air.raw.height())
69+
.collect::<Vec<usize>>();
70+
println!("actual_trace_heights: {:?}", actual_trace_heights);
71+
72+
actual_trace_heights
73+
.iter()
74+
.zip(NATIVE_MAX_TRACE_HEIGHTS)
75+
.for_each(|(&actual, &expected)| {
76+
assert!(
77+
actual <= (expected as usize),
78+
"Actual trace height {} exceeds expected height {}",
79+
actual,
80+
expected
81+
);
82+
});
83+
});
84+
Ok(())
85+
}
86+
2487
fn main() -> Result<()> {
2588
let args = BenchmarkCli::parse();
2689

@@ -88,6 +151,15 @@ fn main() -> Result<()> {
88151
&DefaultStaticVerifierPvHandler,
89152
)?;
90153

154+
// Verify that NATIVE_MAX_TRACE_HEIGHTS remains valid
155+
verify_native_max_trace_heights(
156+
&sdk,
157+
app_pk.clone(),
158+
app_committed_exe.clone(),
159+
full_agg_pk.agg_stark_pk.leaf_vm_pk.clone(),
160+
args.agg_tree_config.num_children_leaf,
161+
)?;
162+
91163
run_with_metric_collection("OUTPUT_PATH", || -> Result<()> {
92164
let mut prover = EvmHalo2Prover::<_, BabyBearPoseidon2Engine>::new(
93165
&halo2_params_reader,

crates/sdk/src/keygen/dummy.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,12 +207,8 @@ where
207207
vm_heights
208208
};
209209
// For the dummy proof, we must override the trace heights.
210-
let app_prover =
211-
VmLocalProver::<SC, VC, BabyBearPoseidon2Engine>::new_with_overridden_trace_heights(
212-
app_vm_pk,
213-
dummy_exe,
214-
Some(overridden_heights),
215-
);
210+
let app_prover = VmLocalProver::<SC, VC, BabyBearPoseidon2Engine>::new(app_vm_pk, dummy_exe)
211+
.with_overridden_continuation_trace_heights(overridden_heights);
216212
ContinuationVmProver::prove(&app_prover, vec![])
217213
}
218214

crates/sdk/src/prover/agg.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use openvm_continuations::verifier::{
66
leaf::types::LeafVmVerifierInput,
77
root::types::RootVmVerifierInput,
88
};
9-
use openvm_native_circuit::NativeConfig;
9+
use openvm_native_circuit::{NativeConfig, NATIVE_MAX_TRACE_HEIGHTS};
1010
use openvm_native_compiler::ir::DIGEST_SIZE;
1111
use openvm_native_recursion::hints::Hintable;
1212
use openvm_stark_sdk::{engine::StarkFriEngine, openvm_stark_backend::proof::Proof};
@@ -45,14 +45,16 @@ impl<E: StarkFriEngine<SC>> AggStarkProver<E> {
4545
tree_config: AggregationTreeConfig,
4646
) -> Self {
4747
let leaf_prover =
48-
VmLocalProver::<SC, NativeConfig, E>::new(agg_stark_pk.leaf_vm_pk, leaf_committed_exe);
48+
VmLocalProver::<SC, NativeConfig, E>::new(agg_stark_pk.leaf_vm_pk, leaf_committed_exe)
49+
.with_overridden_single_segment_trace_heights(NATIVE_MAX_TRACE_HEIGHTS.to_vec());
4950
let leaf_controller = LeafProvingController {
5051
num_children: tree_config.num_children_leaf,
5152
};
5253
let internal_prover = VmLocalProver::<SC, NativeConfig, E>::new(
5354
agg_stark_pk.internal_vm_pk,
5455
agg_stark_pk.internal_committed_exe,
55-
);
56+
)
57+
.with_overridden_single_segment_trace_heights(NATIVE_MAX_TRACE_HEIGHTS.to_vec());
5658
let root_prover = RootVerifierLocalProver::new(agg_stark_pk.root_verifier_pk);
5759
Self {
5860
leaf_prover,

crates/sdk/src/prover/vm/local.rs

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ use crate::prover::vm::{
2727
pub struct VmLocalProver<SC: StarkGenericConfig, VC, E: StarkFriEngine<SC>> {
2828
pub pk: Arc<VmProvingKey<SC, VC>>,
2929
pub committed_exe: Arc<VmCommittedExe<SC>>,
30-
overridden_heights: Option<VmComplexTraceHeights>,
30+
continuation_heights: Option<VmComplexTraceHeights>,
31+
single_segment_heights: Option<Vec<u32>>,
3132
_marker: PhantomData<E>,
3233
}
3334

@@ -36,26 +37,26 @@ impl<SC: StarkGenericConfig, VC, E: StarkFriEngine<SC>> VmLocalProver<SC, VC, E>
3637
Self {
3738
pk,
3839
committed_exe,
39-
overridden_heights: None,
40+
continuation_heights: None,
41+
single_segment_heights: None,
4042
_marker: PhantomData,
4143
}
4244
}
4345

44-
pub fn new_with_overridden_trace_heights(
45-
pk: Arc<VmProvingKey<SC, VC>>,
46-
committed_exe: Arc<VmCommittedExe<SC>>,
47-
overridden_heights: Option<VmComplexTraceHeights>,
46+
pub fn with_overridden_continuation_trace_heights(
47+
mut self,
48+
overridden_heights: VmComplexTraceHeights,
4849
) -> Self {
49-
Self {
50-
pk,
51-
committed_exe,
52-
overridden_heights,
53-
_marker: PhantomData,
54-
}
50+
self.continuation_heights = Some(overridden_heights);
51+
self
5552
}
5653

57-
pub fn set_override_trace_heights(&mut self, overridden_heights: VmComplexTraceHeights) {
58-
self.overridden_heights = Some(overridden_heights);
54+
pub fn with_overridden_single_segment_trace_heights(
55+
mut self,
56+
overridden_heights: Vec<u32>,
57+
) -> Self {
58+
self.single_segment_heights = Some(overridden_heights);
59+
self
5960
}
6061

6162
pub fn vm_config(&self) -> &VC {
@@ -81,7 +82,7 @@ where
8182
let mut vm = VirtualMachine::new_with_overridden_trace_heights(
8283
e,
8384
self.pk.vm_config.clone(),
84-
self.overridden_heights.clone(),
85+
self.continuation_heights.clone(),
8586
);
8687
vm.set_trace_height_constraints(trace_height_constraints.clone());
8788
let VmCommittedExe {
@@ -179,16 +180,20 @@ where
179180

180181
let vm_vk = self.pk.vm_pk.get_vk();
181182
let input = input.into();
182-
let max_trace_heights = executor
183-
.execute_metered(
184-
self.committed_exe.exe.clone(),
185-
input.clone(),
186-
&vm_vk.total_widths(),
187-
&vm_vk.num_interactions(),
188-
)
189-
.expect("execute_metered failed");
183+
let max_trace_heights = if let Some(overridden_heights) = &self.single_segment_heights {
184+
overridden_heights
185+
} else {
186+
&executor
187+
.execute_metered(
188+
self.committed_exe.exe.clone(),
189+
input.clone(),
190+
&vm_vk.total_widths(),
191+
&vm_vk.num_interactions(),
192+
)
193+
.expect("execute_metered failed")
194+
};
190195
let proof_input = executor
191-
.execute_and_generate(self.committed_exe.clone(), input, &max_trace_heights)
196+
.execute_and_generate(self.committed_exe.clone(), input, max_trace_heights)
192197
.unwrap();
193198

194199
let vm = VirtualMachine::new(e, executor.config);

crates/vm/src/system/phantom/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,10 @@ where
175175
&self,
176176
state: &mut VmStateMut<F, GuestMemory, MeteredCtx>,
177177
instruction: &Instruction<F>,
178-
_chip_index: usize,
178+
chip_index: usize,
179179
) -> Result<(), ExecutionError> {
180180
self.execute_e1(state, instruction)?;
181+
state.ctx.trace_heights[chip_index] += 1;
181182

182183
Ok(())
183184
}

crates/vm/src/system/public_values/core.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,9 @@ where
264264
&self,
265265
state: &mut VmStateMut<F, GuestMemory, MeteredCtx>,
266266
instruction: &Instruction<F>,
267-
chip_index: usize,
267+
_chip_index: usize,
268268
) -> Result<()> {
269269
self.execute_e1(state, instruction)?;
270-
state.ctx.trace_heights[chip_index] += 1;
271270

272271
Ok(())
273272
}

extensions/native/circuit/src/extension.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,3 +471,11 @@ impl Default for Rv32WithKernelsConfig {
471471

472472
// Default implementation uses no init file
473473
impl InitFileGenerator for Rv32WithKernelsConfig {}
474+
475+
// Pre-computed maximum trace heights for NativeConfig. Found by doubling
476+
// the actual trace heights of kitchen-sink leaf verification (except for
477+
// VariableRangeChecker, which has a fixed height).
478+
pub const NATIVE_MAX_TRACE_HEIGHTS: &[u32] = &[
479+
4194304, 4, 128, 2097152, 8388608, 4194304, 262144, 2097152, 16777216, 2097152, 8388608,
480+
262144, 2097152, 1048576, 4194304, 65536, 262144,
481+
];

0 commit comments

Comments
 (0)