1- use std:: { collections:: HashMap , sync:: Arc } ;
1+ use std:: {
2+ collections:: HashMap ,
3+ iter:: { once, repeat} ,
4+ sync:: Arc ,
5+ } ;
26
37use itertools:: Itertools ;
48use openvm_circuit:: {
59 arch:: { AirInventory , MatrixRecordArena } ,
610 utils:: next_power_of_two_or_zero,
711} ;
812use openvm_stark_backend:: {
9- p3_field:: FieldAlgebra ,
10- p3_matrix:: dense:: { DenseMatrix , RowMajorMatrix } ,
11- prover:: {
12- hal:: ProverBackend ,
13- types:: { AirProvingContext , AirProvingContexts } ,
14- } ,
15- Chip ,
13+ Chip , p3_field:: FieldAlgebra , p3_matrix:: dense:: { DenseMatrix , RowMajorMatrix } , prover:: {
14+ hal:: ProverBackend , types:: { AirProvingContext , AirProvingContexts , Rejected }
15+ }
1616} ;
1717use openvm_stark_sdk:: p3_baby_bear:: BabyBear ;
18- use powdr_autoprecompiles:: { trace_handler:: TraceTrait , Apc } ;
18+ use powdr_autoprecompiles:: { expression :: RowEvaluator , trace_handler:: TraceTrait , Apc } ;
1919use powdr_constraint_solver:: constraint_system:: ComputationMethod ;
2020
2121use crate :: {
@@ -62,7 +62,7 @@ impl<F> From<Arc<RowMajorMatrix<F>>> for SharedCpuTrace<F> {
6262}
6363
6464impl < R , PB : ProverBackend < Matrix = Arc < RowMajorMatrix < BabyBear > > > > Chip < R , PB > for PowdrChipCpu {
65- fn generate_proving_ctx ( & self , records : R ) -> AirProvingContext < PB > {
65+ fn generate_proving_ctx ( & self , _records : R ) -> AirProvingContext < PB > {
6666 unreachable ! ( )
6767 }
6868
@@ -73,14 +73,9 @@ impl<R, PB: ProverBackend<Matrix = Arc<RowMajorMatrix<BabyBear>>>> Chip<R, PB> f
7373 . trace_generator
7474 . generate_witness ( self . record_arena_by_air_name . take ( ) ) ;
7575
76- let rejected = rejected
77- . into_iter ( )
78- . map ( |( key, ( rows, values) ) | ( key, ( rows, AirProvingContext :: simple ( values, vec ! [ ] ) ) ) )
79- . collect ( ) ;
80-
8176 AirProvingContexts {
82- main : AirProvingContext :: simple ( Arc :: new ( trace) , vec ! [ ] ) ,
83- rejected,
77+ main : AirProvingContext :: simple ( trace, vec ! [ ] ) ,
78+ rejected
8479 }
8580 }
8681}
@@ -111,16 +106,21 @@ impl PowdrTraceGeneratorCpu {
111106 & self ,
112107 mut original_arenas : OriginalArenas < MatrixRecordArena < BabyBear > > ,
113108 ) -> (
114- DenseMatrix < BabyBear > ,
115- HashMap < String , ( Vec < usize > , Arc < DenseMatrix < BabyBear > > ) > ,
109+ Arc < DenseMatrix < BabyBear > > ,
110+ Rejected < Arc < DenseMatrix < BabyBear > > > ,
116111 ) {
112+ let mut rejected_pcs = vec ! [ ] ;
113+
117114 use powdr_autoprecompiles:: trace_handler:: { generate_trace, TraceData } ;
118115
119116 let num_apc_calls = original_arenas. number_of_calls ( ) ;
120117 if num_apc_calls == 0 {
121118 // If the APC isn't called, early return with an empty trace.
122119 let width = self . apc . machine ( ) . main_columns ( ) . count ( ) ;
123- return ( RowMajorMatrix :: new ( vec ! [ ] , width) , HashMap :: default ( ) ) ;
120+ return (
121+ Arc :: new ( RowMajorMatrix :: new ( vec ! [ ] , width) ) ,
122+ Default :: default ( )
123+ ) ;
124124 }
125125
126126 let chip_inventory = {
@@ -175,7 +175,7 @@ impl PowdrTraceGeneratorCpu {
175175 let height = next_power_of_two_or_zero ( num_apc_calls) ;
176176 let mut values = <BabyBear as FieldAlgebra >:: zero_vec ( height * width) ;
177177
178- let mut rejected : HashMap < String , Vec < usize > > = dummy_trace_by_air_name
178+ let mut rejected_rows_per_air : HashMap < String , Vec < usize > > = dummy_trace_by_air_name
179179 . keys ( )
180180 . cloned ( )
181181 . map ( |key| ( key, vec ! [ ] ) )
@@ -187,7 +187,9 @@ impl PowdrTraceGeneratorCpu {
187187 // TODO: optimize by parallelizing on chunks of rows, currently fails because `dyn AnyChip<MatrixRecordArena<Val<SC>>>` is not `Send`
188188 . chunks_mut ( width)
189189 . zip ( dummy_values)
190- . for_each ( |( row_slice, dummy_values) | {
190+ // Just for testing, reject the first call of each apc
191+ . zip ( once ( false ) . chain ( repeat ( true ) ) )
192+ . for_each ( |( ( row_slice, dummy_values) , row_is_valid) | {
191193 // map the dummy rows to the autoprecompile row
192194
193195 use powdr_autoprecompiles:: expression:: MappingRowEvaluator ;
@@ -225,7 +227,6 @@ impl PowdrTraceGeneratorCpu {
225227 let evaluator = MappingRowEvaluator :: new ( row_slice, & apc_poly_id_to_index) ;
226228
227229 // check the constraints and bus interactions
228- let row_is_valid = true ;
229230
230231 if row_is_valid {
231232 // replay the side effects of this row on the main periphery
@@ -248,12 +249,40 @@ impl PowdrTraceGeneratorCpu {
248249 ) ;
249250 } ) ;
250251 } else {
252+ // set the whole row to zero
253+ // TODO: this generates a gap in the table. Instead, reuse the row in the next iteration.
254+ for cell in row_slice {
255+ * cell = BabyBear :: ZERO ;
256+ }
257+
251258 // for each original row
252259 for original_row_reference in dummy_values {
253- // TODO replay the side effects of this row on the real periphery
260+ // replay the side effects of this row on the real periphery
261+ let original_row_data = & original_row_reference. data [ original_row_reference
262+ . start ( )
263+ ..original_row_reference. start ( ) + original_row_reference. length ] ;
264+ let evaluator = RowEvaluator :: new ( original_row_data) ;
265+ let ( machine, _) =
266+ & self . original_airs . air_name_to_machine [ original_row_reference. air_id ] ;
267+
268+ for interaction in & machine. bus_interactions {
269+ use powdr_autoprecompiles:: expression:: {
270+ AlgebraicEvaluator , ConcreteBusInteraction ,
271+ } ;
272+
273+ let ConcreteBusInteraction { id, mult, args } =
274+ evaluator. eval_bus_interaction ( interaction) ;
275+
276+ rejected_pcs. extend ( self . periphery . real . apply (
277+ id as u16 ,
278+ mult. as_canonical_u32 ( ) ,
279+ args. map ( |arg| arg. as_canonical_u32 ( ) ) ,
280+ & self . periphery . bus_ids ,
281+ ) ) ;
282+ }
254283
255284 // add the row index to the rejected set
256- rejected
285+ rejected_rows_per_air
257286 . get_mut ( original_row_reference. air_id )
258287 . unwrap ( )
259288 . push ( original_row_reference. row_index ) ;
@@ -262,19 +291,22 @@ impl PowdrTraceGeneratorCpu {
262291 } ) ;
263292
264293 // merge the rejected indices with the traces
265- let rejected = rejected
266- . into_iter ( )
267- . map ( | ( name , indices ) | {
268- (
269- name . clone ( ) ,
294+ let rejected = Rejected {
295+ pcs : rejected_pcs ,
296+ rows_per_air : rejected_rows_per_air
297+ . into_iter ( )
298+ . map ( | ( name , indices ) | {
270299 (
271- indices,
272- dummy_trace_by_air_name. remove ( & name) . unwrap ( ) . matrix ,
273- ) ,
274- )
275- } )
276- . collect ( ) ;
277-
278- ( RowMajorMatrix :: new ( values, width) , rejected)
300+ name. clone ( ) ,
301+ (
302+ dummy_trace_by_air_name. remove ( & name) . unwrap ( ) . matrix ,
303+ indices,
304+ ) ,
305+ )
306+ } )
307+ . collect ( ) ,
308+ } ;
309+
310+ ( Arc :: new ( RowMajorMatrix :: new ( values, width) ) , rejected)
279311 }
280312}
0 commit comments