Skip to content

Commit 0710333

Browse files
feat: add debug to StarkEngineV2 (#211)
Slightly roundabout because we fix `SC` in some places, but for openvm compatibility we need it to be generic.
1 parent e24f5a8 commit 0710333

File tree

5 files changed

+155
-4
lines changed

5 files changed

+155
-4
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// Merge into debug/mod.rs in v1:
2+
// - debug_constraints
3+
// - debug_constraints_and_interactions
4+
use std::sync::Arc;
5+
6+
use itertools::{izip, Itertools};
7+
use openvm_stark_backend::{
8+
air_builders::{
9+
debug::{check_constraints, check_logup, USE_DEBUG_BUILDER},
10+
symbolic::SymbolicConstraints,
11+
},
12+
prover::types::AirProofRawInput,
13+
AirRef,
14+
};
15+
16+
use crate::{
17+
keygen::{types::StarkProvingKeyV2, MultiStarkKeygenBuilderV2},
18+
prover::{
19+
ColMajorMatrix, DeviceDataTransporterV2, ProverBackendV2, ProvingContextV2,
20+
StridedColMajorMatrixView,
21+
},
22+
SystemParams, SC,
23+
};
24+
25+
// TODO[jpw]: move into StarkEngineV2::debug default implementation after `SC` is made generic.
26+
/// `airs` should be the full list of all AIRs, not just used AIRs.
27+
pub fn debug_impl<PB: ProverBackendV2<Val = crate::F>, PD: DeviceDataTransporterV2<PB>>(
28+
config: SystemParams,
29+
device: &PD,
30+
airs: &[AirRef<SC>],
31+
ctx: &ProvingContextV2<PB>,
32+
) {
33+
let mut keygen_builder = MultiStarkKeygenBuilderV2::new(config);
34+
for air in airs {
35+
keygen_builder.add_air(air.clone());
36+
}
37+
let pk = keygen_builder.generate_pk().unwrap();
38+
39+
let transpose = |mat: ColMajorMatrix<crate::F>| {
40+
let row_major = StridedColMajorMatrixView::from(mat.as_view()).to_row_major_matrix();
41+
Arc::new(row_major)
42+
};
43+
let (inputs, used_airs, used_pks): (Vec<_>, Vec<_>, Vec<_>) = ctx
44+
.per_trace
45+
.iter()
46+
.map(|(air_id, air_ctx)| {
47+
// Transfer from device **back** to host so the debugger can read the data.
48+
let common_main = device.transport_matrix_from_device_to_host(&air_ctx.common_main);
49+
let cached_mains = air_ctx
50+
.cached_mains
51+
.iter()
52+
.map(|cd| transpose(device.transport_matrix_from_device_to_host(&cd.trace)))
53+
.collect_vec();
54+
let common_main = Some(transpose(common_main));
55+
let public_values = air_ctx.public_values.clone();
56+
(
57+
AirProofRawInput {
58+
cached_mains,
59+
common_main,
60+
public_values,
61+
},
62+
airs[*air_id].clone(),
63+
&pk.per_air[*air_id],
64+
)
65+
})
66+
.multiunzip();
67+
68+
debug_constraints_and_interactions(&used_airs, &used_pks, &inputs);
69+
}
70+
71+
/// The debugging will check the main AIR constraints and then separately check LogUp constraints by
72+
/// checking the actual multiset equalities. Currently it will not debug check any after challenge
73+
/// phase constraints for implementation simplicity.
74+
#[allow(dead_code)]
75+
#[allow(clippy::too_many_arguments)]
76+
pub fn debug_constraints_and_interactions(
77+
airs: &[AirRef<SC>],
78+
pk: &[&StarkProvingKeyV2],
79+
inputs: &[AirProofRawInput<crate::F>],
80+
) {
81+
USE_DEBUG_BUILDER.with(|debug| {
82+
if *debug.lock().unwrap() {
83+
let (main_parts_per_air, pvs_per_air): (Vec<_>, Vec<_>) = inputs
84+
.iter()
85+
.map(|input| {
86+
let mut main_parts = input
87+
.cached_mains
88+
.iter()
89+
.map(|trace| trace.as_view())
90+
.collect_vec();
91+
if let Some(trace) = input.common_main.as_ref() {
92+
main_parts.push(trace.as_view());
93+
}
94+
(main_parts, input.public_values.clone())
95+
})
96+
.unzip();
97+
let preprocessed = izip!(airs, pk, &main_parts_per_air, &pvs_per_air)
98+
.map(|(air, pk, main_parts, pvs)| {
99+
let preprocessed_trace = pk
100+
.preprocessed_data
101+
.as_ref()
102+
.map(|data| data.mat_view(0).to_row_major_matrix());
103+
tracing::debug!("Checking constraints for {}", air.name());
104+
check_constraints(
105+
air.as_ref(),
106+
&air.name(),
107+
&preprocessed_trace.as_ref().map(|t| t.as_view()),
108+
main_parts,
109+
pvs,
110+
);
111+
preprocessed_trace
112+
})
113+
.collect_vec();
114+
115+
let (air_names, interactions): (Vec<_>, Vec<_>) = pk
116+
.iter()
117+
.map(|pk| {
118+
let sym_constraints = SymbolicConstraints::from(&pk.vk.symbolic_constraints);
119+
(pk.air_name.clone(), sym_constraints.interactions)
120+
})
121+
.unzip();
122+
let preprocessed_views = preprocessed
123+
.iter()
124+
.map(|t| t.as_ref().map(|t| t.as_view()))
125+
.collect_vec();
126+
check_logup(
127+
&air_names,
128+
&interactions,
129+
&preprocessed_views,
130+
&main_parts_per_air,
131+
&pvs_per_air,
132+
);
133+
}
134+
});
135+
}

crates/stark-backend-v2/src/engine.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use openvm_stark_backend::{config::StarkGenericConfig, prover::Prover, AirRef};
99
use openvm_stark_sdk::config::baby_bear_poseidon2::BabyBearPoseidon2Config;
1010

1111
use crate::{
12+
debug::debug_impl,
1213
keygen::{
1314
types::{MultiStarkProvingKeyV2, MultiStarkVerifyingKeyV2},
1415
MultiStarkKeygenBuilderV2,
@@ -96,6 +97,11 @@ where
9697
verify(vk, proof, &mut transcript)
9798
}
9899

100+
/// The indexing of AIR ID in `ctx` should be consistent with the order of `airs`. In
101+
/// particular, `airs` should correspond to the global proving key with all AIRs, including ones
102+
/// not present in the `ctx`.
103+
fn debug(&self, airs: &[AirRef<Self::SC>], ctx: &ProvingContextV2<Self::PB>);
104+
99105
/// Runs a single end-to-end test for a given set of chips and traces partitions.
100106
/// This includes proving/verifying key generation, creating a proof, and verifying the proof.
101107
fn run_test(
@@ -139,12 +145,17 @@ where
139145
fn device(&self) -> &Self::PD {
140146
&self.device
141147
}
148+
142149
fn prover_from_transcript(
143150
&self,
144151
transcript: TS,
145152
) -> CoordinatorV2<Self::PB, Self::PD, Self::TS> {
146153
CoordinatorV2::new(CpuBackendV2, self.device.clone(), transcript)
147154
}
155+
156+
fn debug(&self, airs: &[AirRef<Self::SC>], ctx: &ProvingContextV2<Self::PB>) {
157+
debug_impl::<Self::PB, Self::PD>(self.config().clone(), self.device(), airs, ctx);
158+
}
148159
}
149160

150161
// TODO[jpw]: move to stark-sdk

crates/stark-backend-v2/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use p3_util::log2_ceil_u64;
88
mod chip;
99
pub mod codec;
1010
mod config;
11+
pub mod debug;
1112
pub mod dft;
1213
mod engine;
1314
pub mod keygen;

crates/stark-backend-v2/src/test_utils.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -482,21 +482,25 @@ impl SystemParams {
482482
/// **These parameters should not be used in production!**
483483
pub fn new_for_testing(log_trace_height: usize) -> Self {
484484
let l_skip = 4;
485-
test_system_params_small(4, log_trace_height - l_skip, 4)
485+
let k_whir = 4;
486+
let mut params = test_system_params_small(l_skip, log_trace_height - l_skip, k_whir);
487+
params.max_constraint_degree = 4;
488+
params
486489
}
487490
}
488491

489492
/// Trace heights cannot exceed 2^{l_skip + n_stack} when using these system params.
490493
pub fn test_system_params_small(l_skip: usize, n_stack: usize, k_whir: usize) -> SystemParams {
491494
let log_final_poly_len = (n_stack + l_skip) % k_whir;
492-
test_system_params_small_with_poly_len(l_skip, n_stack, k_whir, log_final_poly_len)
495+
test_system_params_small_with_poly_len(l_skip, n_stack, k_whir, log_final_poly_len, 3)
493496
}
494497

495498
pub fn test_system_params_small_with_poly_len(
496499
l_skip: usize,
497500
n_stack: usize,
498501
k_whir: usize,
499502
log_final_poly_len: usize,
503+
max_constraint_degree: usize,
500504
) -> SystemParams {
501505
assert!(log_final_poly_len < l_skip + n_stack);
502506
let log_blowup = 1;
@@ -507,7 +511,7 @@ pub fn test_system_params_small_with_poly_len(
507511
log_blowup,
508512
whir: test_whir_config_small(log_blowup, l_skip + n_stack, k_whir, log_final_poly_len),
509513
logup: log_up_security_params_baby_bear_100_bits(),
510-
max_constraint_degree: 3,
514+
max_constraint_degree,
511515
}
512516
}
513517

crates/stark-backend/src/air_builders/debug/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{
1717

1818
mod check_constraints;
1919

20-
use check_constraints::*;
20+
pub use check_constraints::*;
2121

2222
use crate::interaction::BusIndex;
2323

0 commit comments

Comments
 (0)