openvm_continuations/circuit/inner/
trace.rs1use itertools::Itertools;
2#[cfg(feature = "cuda")]
3use openvm_circuit_primitives::hybrid_chip::cpu_proving_ctx_to_gpu;
4use openvm_cpu_backend::CpuBackend;
5#[cfg(feature = "cuda")]
6use openvm_cuda_backend::GpuBackend;
7#[cfg(feature = "cuda")]
8use openvm_cuda_common::stream::GpuDeviceCtx;
9use openvm_stark_backend::{
10 proof::Proof,
11 prover::{AirProvingContext, ProverBackend},
12};
13use openvm_stark_sdk::config::baby_bear_poseidon2::{BabyBearPoseidon2Config, F};
14use openvm_verify_stark_host::pvs::{DeferralPvs, VkCommit};
15
16use crate::circuit::{SingleAirTraceData, SubCircuitTraceData};
17
18#[derive(Copy, Clone)]
19pub enum ProofsType {
20 Vm,
21 Deferral,
22 Mix,
23 Combined,
24}
25
26pub trait InnerTraceGen<PB: ProverBackend, DC: Clone + Send + Sync> {
28 fn new(deferral_enabled: bool) -> Self;
29 fn generate_pre_verifier_subcircuit_ctxs(
30 &self,
31 proofs: &[Proof<BabyBearPoseidon2Config>],
32 proofs_type: ProofsType,
33 absent_trace_pvs: Option<(DeferralPvs<F>, bool)>,
34 child_is_app: bool,
35 child_vk_commit: VkCommit<F>,
36 device_ctx: &DC,
37 ) -> SubCircuitTraceData<PB>;
38 fn generate_post_verifier_subcircuit_ctxs(
39 &self,
40 proofs: &[Proof<BabyBearPoseidon2Config>],
41 proofs_type: ProofsType,
42 child_is_app: bool,
43 device_ctx: &DC,
44 ) -> Vec<AirProvingContext<PB>>;
45}
46
47pub struct InnerTraceGenImpl {
48 pub deferral_enabled: bool,
49}
50
51impl InnerTraceGen<CpuBackend<BabyBearPoseidon2Config>, ()> for InnerTraceGenImpl {
52 fn new(deferral_enabled: bool) -> Self {
53 Self { deferral_enabled }
54 }
55
56 fn generate_pre_verifier_subcircuit_ctxs(
57 &self,
58 proofs: &[Proof<BabyBearPoseidon2Config>],
59 proofs_type: ProofsType,
60 absent_trace_pvs: Option<(DeferralPvs<F>, bool)>,
61 child_is_app: bool,
62 child_vk_commit: VkCommit<F>,
63 _device_ctx: &(),
64 ) -> SubCircuitTraceData<CpuBackend<BabyBearPoseidon2Config>> {
65 let SingleAirTraceData {
66 air_proving_ctx: verifier_pvs_ctx,
67 mut poseidon2_compress_inputs,
68 poseidon2_permute_inputs,
69 mut range_check_inputs,
70 } = super::verifier::generate_proving_ctx(
71 proofs,
72 proofs_type,
73 child_is_app,
74 child_vk_commit,
75 self.deferral_enabled,
76 );
77 let vm_pvs_ctx = super::vm_pvs::generate_proving_ctx(
78 proofs,
79 proofs_type,
80 child_is_app,
81 self.deferral_enabled,
82 );
83
84 let idx2_ctx = if self.deferral_enabled {
85 let (def_pvs_ctx, def_poseidon2_inputs, def_range_check_inputs) =
86 super::def_pvs::generate_proving_ctx(
87 proofs,
88 proofs_type,
89 child_is_app,
90 absent_trace_pvs,
91 );
92 poseidon2_compress_inputs.extend_from_slice(&def_poseidon2_inputs);
93 range_check_inputs.extend(def_range_check_inputs);
94 def_pvs_ctx
95 } else {
96 super::unset::generate_proving_ctx(&[], child_is_app)
97 };
98
99 SubCircuitTraceData {
100 air_proving_ctxs: vec![verifier_pvs_ctx, vm_pvs_ctx, idx2_ctx],
101 poseidon2_compress_inputs,
102 poseidon2_permute_inputs,
103 range_check_inputs,
104 }
105 }
106
107 fn generate_post_verifier_subcircuit_ctxs(
108 &self,
109 proofs: &[Proof<BabyBearPoseidon2Config>],
110 proofs_type: ProofsType,
111 child_is_app: bool,
112 _device_ctx: &(),
113 ) -> Vec<AirProvingContext<CpuBackend<BabyBearPoseidon2Config>>> {
114 if !self.deferral_enabled {
115 return vec![];
116 }
117
118 let (vm_unset, def_unset) = match proofs_type {
119 ProofsType::Vm => (
120 vec![],
121 proofs.iter().enumerate().map(|(i, _)| i).collect_vec(),
122 ),
123 ProofsType::Deferral => (
124 proofs.iter().enumerate().map(|(i, _)| i).collect_vec(),
125 vec![],
126 ),
127 ProofsType::Mix => (vec![1], vec![0]),
128 ProofsType::Combined => (vec![], vec![]),
129 };
130 vec![
131 super::unset::generate_proving_ctx(&vm_unset, child_is_app),
132 super::unset::generate_proving_ctx(&def_unset, child_is_app),
133 ]
134 }
135}
136
137#[cfg(feature = "cuda")]
138impl InnerTraceGen<GpuBackend, GpuDeviceCtx> for InnerTraceGenImpl {
139 fn new(deferral_enabled: bool) -> Self {
140 Self { deferral_enabled }
141 }
142
143 fn generate_pre_verifier_subcircuit_ctxs(
144 &self,
145 proofs: &[Proof<BabyBearPoseidon2Config>],
146 proofs_type: ProofsType,
147 absent_trace_pvs: Option<(DeferralPvs<F>, bool)>,
148 child_is_app: bool,
149 child_vk_commit: VkCommit<F>,
150 device_ctx: &GpuDeviceCtx,
151 ) -> SubCircuitTraceData<GpuBackend> {
152 let data =
153 <Self as InnerTraceGen<CpuBackend<BabyBearPoseidon2Config>, ()>>::generate_pre_verifier_subcircuit_ctxs(
154 self,
155 proofs,
156 proofs_type,
157 absent_trace_pvs,
158 child_is_app,
159 child_vk_commit,
160 &(),
161 );
162 SubCircuitTraceData {
163 air_proving_ctxs: data
164 .air_proving_ctxs
165 .into_iter()
166 .map(|air_ctx| cpu_proving_ctx_to_gpu(air_ctx, device_ctx))
167 .collect_vec(),
168 poseidon2_compress_inputs: data.poseidon2_compress_inputs,
169 poseidon2_permute_inputs: data.poseidon2_permute_inputs,
170 range_check_inputs: data.range_check_inputs,
171 }
172 }
173
174 fn generate_post_verifier_subcircuit_ctxs(
175 &self,
176 proofs: &[Proof<BabyBearPoseidon2Config>],
177 proofs_type: ProofsType,
178 child_is_app: bool,
179 device_ctx: &GpuDeviceCtx,
180 ) -> Vec<AirProvingContext<GpuBackend>> {
181 let cpu_ctxs =
182 <Self as InnerTraceGen<CpuBackend<BabyBearPoseidon2Config>, ()>>::generate_post_verifier_subcircuit_ctxs(
183 self,
184 proofs,
185 proofs_type,
186 child_is_app,
187 &(),
188 );
189 cpu_ctxs
190 .into_iter()
191 .map(|air_ctx| cpu_proving_ctx_to_gpu(air_ctx, device_ctx))
192 .collect_vec()
193 }
194}