11use itertools:: Itertools ;
22use openvm_circuit:: arch:: VmCircuitConfig ;
33use openvm_sdk:: StdIn ;
4+ use openvm_stark_backend:: p3_maybe_rayon:: prelude:: IntoParallelIterator ;
5+ use openvm_stark_backend:: p3_maybe_rayon:: prelude:: ParallelIterator ;
46use openvm_stark_sdk:: openvm_stark_backend:: p3_field:: PrimeField32 ;
57use powdr_autoprecompiles:: empirical_constraints:: {
68 intersect_partitions, DebugInfo , EmpiricalConstraints ,
@@ -91,26 +93,29 @@ fn collect_trace(program: &CompiledProgram, inputs: StdIn) -> (Trace, DebugInfo)
9193 . collect :: < HashMap < _ , _ > > ( ) ;
9294
9395 for ( air_id, proving_context) in & ctx. per_air {
94- if !proving_context. cached_mains . is_empty ( ) {
95- // Not the case for instruction circuits
96- continue ;
97- }
98- let main = proving_context. common_main . as_ref ( ) . unwrap ( ) ;
99-
10096 let air = & global_airs[ air_id] ;
10197 let Some ( column_names) = air. columns ( ) else {
98+ // Instruction chips always have column names.
10299 continue ;
103100 } ;
101+
102+ if !proving_context. cached_mains . is_empty ( ) {
103+ // Instruction chips always have a cached main.
104+ continue ;
105+ }
106+ let main = proving_context. common_main . as_ref ( ) . unwrap ( ) ;
104107 assert_eq ! ( main. width, column_names. len( ) ) ;
105108
106- // This is the case for all instruction circuits
107- let Some ( pc_index) = column_names
108- . iter ( )
109- . position ( |name| name == "from_state__pc" )
110- else {
109+ // Instruction chips have a PC and time stamp
110+ let find_col = |name : & str | -> Option < usize > {
111+ column_names. iter ( ) . position ( |col_name| {
112+ col_name == name || col_name == & format ! ( "inner__{}" , name)
113+ } )
114+ } ;
115+ let Some ( pc_index) = find_col ( "from_state__pc" ) else {
111116 continue ;
112117 } ;
113- let ts_index = 1 ;
118+ let ts_index = find_col ( "from_state__timestamp" ) . unwrap ( ) ;
114119
115120 for row in main. row_slices ( ) {
116121 let row = row. iter ( ) . map ( |v| v. as_canonical_u32 ( ) ) . collect :: < Vec < _ > > ( ) ;
@@ -222,8 +227,11 @@ impl ConstraintDetector {
222227 & self ,
223228 trace : & Trace ,
224229 ) -> BTreeMap < u64 , BTreeSet < BTreeSet < ( usize , usize ) > > > {
225- self . get_blocks ( trace)
226- . into_iter ( )
230+ tracing:: info!( " Segmenting trace into blocks..." ) ;
231+ let blocks = self . get_blocks ( trace) ;
232+ tracing:: info!( " Finding equivalence classes..." ) ;
233+ blocks
234+ . into_par_iter ( )
227235 . map ( |( block_id, block_instances) | {
228236 // Segment each block instance into equivalence classes
229237 let classes = block_instances
@@ -252,36 +260,15 @@ impl ConstraintDetector {
252260 let mut row_index = 0 ;
253261 let rows_by_time = trace. rows_by_time ( ) ;
254262
255- // Maps Block ID -> (successful instances, unsuccessful instances) for reporting
256- let mut block_stats = BTreeMap :: new ( ) ;
257-
258263 while row_index < rows_by_time. len ( ) {
259264 let first_row = rows_by_time[ row_index] ;
260265 let block_id = first_row. pc as u64 ;
261266
262267 if let Some ( instruction_count) = self . instruction_counts . get ( & block_id) {
263268 let block_row_slice = & rows_by_time[ row_index..row_index + instruction_count] ;
264269
265- // Check that we do indeed have all instructions of the block
266- // TODO: I'm not sure in which cases don't have them. In practice, this seems to
267- // happen rarely.
268- let has_all_instructions = block_row_slice
269- . iter ( )
270- . tuple_windows ( )
271- . all ( |( row1, row2) | row2. pc == row1. pc + 4 ) ;
272- if !has_all_instructions {
273- // Incomplete block instance, skip.
274- row_index += 1 ;
275- block_stats
276- . entry ( block_id)
277- . and_modify ( |( _successful, unsuccessful) | * unsuccessful += 1 )
278- . or_insert ( ( 0 , 1 ) ) ;
279- continue ;
280- } else {
281- block_stats
282- . entry ( block_id)
283- . and_modify ( |( successful, _unsuccessful) | * successful += 1 )
284- . or_insert ( ( 1 , 0 ) ) ;
270+ for ( row1, row2) in block_row_slice. iter ( ) . tuple_windows ( ) {
271+ assert_eq ! ( row2. pc, row1. pc + 4 ) ;
285272 }
286273
287274 block_rows
@@ -295,17 +282,6 @@ impl ConstraintDetector {
295282 }
296283 }
297284
298- for ( block_id, ( successful, unsuccessful) ) in block_stats {
299- if unsuccessful > 0 {
300- tracing:: warn!(
301- " Block {:#x}: {} / {} instances skipped due to incomplete execution" ,
302- block_id,
303- unsuccessful,
304- unsuccessful + successful
305- ) ;
306- }
307- }
308-
309285 block_rows
310286 }
311287
0 commit comments