@@ -3,8 +3,11 @@ use metrics_tracing_context::{MetricsLayer, TracingContextLayer};
33use metrics_util:: { debugging:: DebuggingRecorder , layers:: Layer } ;
44use openvm_sdk:: StdIn ;
55use openvm_stark_sdk:: bench:: serialize_metric_snapshot;
6+ use powdr_autoprecompiles:: empirical_constraints:: EmpiricalConstraintsJson ;
67use powdr_autoprecompiles:: pgo:: { pgo_config, PgoType } ;
8+ use powdr_autoprecompiles:: PowdrConfig ;
79use powdr_openvm:: { compile_openvm, default_powdr_openvm_config, CompiledProgram , GuestOptions } ;
10+ use powdr_openvm:: { detect_empirical_constraints, OriginalCompiledProgram } ;
811
912#[ cfg( feature = "metrics" ) ]
1013use openvm_stark_sdk:: metrics_tracing:: TimingMetricsLayer ;
@@ -46,6 +49,12 @@ enum Commands {
4649 /// When `--pgo-mode cell`, the directory to persist all APC candidates + a metrics summary
4750 #[ arg( long) ]
4851 apc_candidates_dir : Option < PathBuf > ,
52+
53+ /// If active, generates "optimistic" precompiles. Optimistic precompiles are smaller in size
54+ /// but may fail at runtime if the assumptions they make are violated.
55+ #[ arg( long) ]
56+ #[ arg( default_value_t = false ) ]
57+ optimistic_precompiles : bool ,
4958 } ,
5059
5160 Execute {
@@ -73,6 +82,12 @@ enum Commands {
7382 /// When `--pgo-mode cell`, the directory to persist all APC candidates + a metrics summary
7483 #[ arg( long) ]
7584 apc_candidates_dir : Option < PathBuf > ,
85+
86+ /// If active, generates "optimistic" precompiles. Optimistic precompiles are smaller in size
87+ /// but may fail at runtime if the assumptions they make are violated.
88+ #[ arg( long) ]
89+ #[ arg( default_value_t = false ) ]
90+ optimistic_precompiles : bool ,
7691 } ,
7792
7893 Prove {
@@ -108,6 +123,12 @@ enum Commands {
108123 /// When `--pgo-mode cell`, the directory to persist all APC candidates + a metrics summary
109124 #[ arg( long) ]
110125 apc_candidates_dir : Option < PathBuf > ,
126+
127+ /// If active, generates "optimistic" precompiles. Optimistic precompiles are smaller in size
128+ /// but may fail at runtime if the assumptions they make are violated.
129+ #[ arg( long) ]
130+ #[ arg( default_value_t = false ) ]
131+ optimistic_precompiles : bool ,
111132 } ,
112133}
113134
@@ -135,15 +156,20 @@ fn run_command(command: Commands) {
135156 max_columns,
136157 input,
137158 apc_candidates_dir,
159+ optimistic_precompiles,
138160 } => {
139161 let mut powdr_config = default_powdr_openvm_config ( autoprecompiles as u64 , skip as u64 ) ;
140162 if let Some ( apc_candidates_dir) = apc_candidates_dir {
141163 powdr_config = powdr_config. with_apc_candidates_dir ( apc_candidates_dir) ;
142164 }
165+ if optimistic_precompiles {
166+ powdr_config = powdr_config. with_optimistic_precompiles ( true ) ;
167+ }
143168 let guest_program = compile_openvm ( & guest, guest_opts. clone ( ) ) . unwrap ( ) ;
144169 let execution_profile =
145170 powdr_openvm:: execution_profile_from_guest ( & guest_program, stdin_from ( input) ) ;
146171
172+ maybe_compute_empirical_constraints ( & guest_program, & powdr_config, stdin_from ( input) ) ;
147173 let pgo_config = pgo_config ( pgo, max_columns, execution_profile) ;
148174 let program =
149175 powdr_openvm:: compile_exe ( guest_program, powdr_config, pgo_config) . unwrap ( ) ;
@@ -159,12 +185,17 @@ fn run_command(command: Commands) {
159185 input,
160186 metrics,
161187 apc_candidates_dir,
188+ optimistic_precompiles,
162189 } => {
163190 let mut powdr_config = default_powdr_openvm_config ( autoprecompiles as u64 , skip as u64 ) ;
164191 if let Some ( apc_candidates_dir) = apc_candidates_dir {
165192 powdr_config = powdr_config. with_apc_candidates_dir ( apc_candidates_dir) ;
166193 }
194+ if optimistic_precompiles {
195+ powdr_config = powdr_config. with_optimistic_precompiles ( true ) ;
196+ }
167197 let guest_program = compile_openvm ( & guest, guest_opts. clone ( ) ) . unwrap ( ) ;
198+ maybe_compute_empirical_constraints ( & guest_program, & powdr_config, stdin_from ( input) ) ;
168199 let execution_profile =
169200 powdr_openvm:: execution_profile_from_guest ( & guest_program, stdin_from ( input) ) ;
170201 let pgo_config = pgo_config ( pgo, max_columns, execution_profile) ;
@@ -194,12 +225,17 @@ fn run_command(command: Commands) {
194225 input,
195226 metrics,
196227 apc_candidates_dir,
228+ optimistic_precompiles,
197229 } => {
198230 let mut powdr_config = default_powdr_openvm_config ( autoprecompiles as u64 , skip as u64 ) ;
199231 if let Some ( apc_candidates_dir) = apc_candidates_dir {
200232 powdr_config = powdr_config. with_apc_candidates_dir ( apc_candidates_dir) ;
201233 }
234+ if optimistic_precompiles {
235+ powdr_config = powdr_config. with_optimistic_precompiles ( true ) ;
236+ }
202237 let guest_program = compile_openvm ( & guest, guest_opts) . unwrap ( ) ;
238+ maybe_compute_empirical_constraints ( & guest_program, & powdr_config, stdin_from ( input) ) ;
203239
204240 let execution_profile =
205241 powdr_openvm:: execution_profile_from_guest ( & guest_program, stdin_from ( input) ) ;
@@ -261,3 +297,33 @@ pub fn run_with_metric_collection_to_file<R>(file: std::fs::File, f: impl FnOnce
261297 . unwrap ( ) ;
262298 res
263299}
300+
301+ fn maybe_compute_empirical_constraints (
302+ guest_program : & OriginalCompiledProgram ,
303+ powdr_config : & PowdrConfig ,
304+ stdin : StdIn ,
305+ ) {
306+ if !powdr_config. optimistic_precompiles {
307+ return ;
308+ }
309+
310+ tracing:: warn!(
311+ "Optimistic precompiles are not implemented yet. Computing empirical constraints..."
312+ ) ;
313+
314+ let ( empirical_constraints, debug_info) =
315+ detect_empirical_constraints ( & guest_program, powdr_config. degree_bound , stdin) ;
316+
317+ if let Some ( path) = & powdr_config. apc_candidates_dir_path {
318+ tracing:: info!(
319+ "Saving empirical constraints debug info to {}/empirical_constraints.json" ,
320+ path. display( )
321+ ) ;
322+ let export = EmpiricalConstraintsJson {
323+ empirical_constraints : empirical_constraints. clone ( ) ,
324+ debug_info,
325+ } ;
326+ let json = serde_json:: to_string_pretty ( & export) . unwrap ( ) ;
327+ std:: fs:: write ( path. join ( "empirical_constraints.json" ) , json) . unwrap ( ) ;
328+ }
329+ }
0 commit comments