1
1
#![ allow( dead_code) ]
2
- use std:: {
3
- collections:: BTreeSet ,
4
- fmt:: { self , Display , Formatter , Write } ,
5
- } ;
2
+ use std:: fmt:: { self , Display , Formatter , Write } ;
6
3
7
4
use itertools:: Itertools ;
8
- use powdr_ast:: analyzed:: {
9
- AlgebraicExpression as Expression , PolyID , PolynomialIdentity , PolynomialType ,
10
- } ;
5
+ use powdr_ast:: analyzed:: PolynomialIdentity ;
11
6
use powdr_number:: FieldElement ;
12
7
13
8
use crate :: witgen:: {
@@ -21,8 +16,8 @@ use super::{
21
16
affine_symbolic_expression,
22
17
effect:: { format_code, Effect } ,
23
18
identity_queue:: { IdentityQueue , QueueItem } ,
24
- variable:: { Cell , MachineCallVariable , Variable } ,
25
- witgen_inference:: { BranchResult , CanProcessCall , FixedEvaluator , Value , WitgenInference } ,
19
+ variable:: { MachineCallVariable , Variable } ,
20
+ witgen_inference:: { BranchResult , CanProcessCall , FixedEvaluator , WitgenInference } ,
26
21
} ;
27
22
28
23
/// A generic processor for generating JIT code.
@@ -36,8 +31,6 @@ pub struct Processor<'a, T: FieldElement, FixedEval> {
36
31
initial_queue : Vec < QueueItem < ' a , T > > ,
37
32
/// The size of a block.
38
33
block_size : usize ,
39
- /// If the processor should check for correctly stackable block shapes.
40
- check_block_shape : bool ,
41
34
/// List of variables we want to be known at the end. One of them not being known
42
35
/// is a failure.
43
36
requested_known_vars : Vec < Variable > ,
@@ -71,7 +64,6 @@ impl<'a, T: FieldElement, FixedEval: FixedEvaluator<T>> Processor<'a, T, FixedEv
71
64
identities,
72
65
initial_queue,
73
66
block_size : 1 ,
74
- check_block_shape : false ,
75
67
requested_known_vars : requested_known_vars. into_iter ( ) . collect ( ) ,
76
68
requested_range_constraints : vec ! [ ] ,
77
69
max_branch_depth,
@@ -93,13 +85,6 @@ impl<'a, T: FieldElement, FixedEval: FixedEvaluator<T>> Processor<'a, T, FixedEv
93
85
self
94
86
}
95
87
96
- /// Activates the check to see if the code for two subsequently generated
97
- /// blocks conflicts.
98
- pub fn with_block_shape_check ( mut self ) -> Self {
99
- self . check_block_shape = true ;
100
- self
101
- }
102
-
103
88
pub fn generate_code (
104
89
self ,
105
90
can_process : impl CanProcessCall < T > ,
@@ -143,16 +128,6 @@ impl<'a, T: FieldElement, FixedEval: FixedEvaluator<T>> Processor<'a, T, FixedEv
143
128
) ) ;
144
129
}
145
130
146
- if self . check_block_shape {
147
- // Check that the "spill" into the previous block is compatible
148
- // with the "missing pieces" in the next block.
149
- // If this is not the case, this is a hard error
150
- // (i.e. cannot be fixed by runtime witgen) and thus we panic inside.
151
- // We could do this only at the end of each branch, but it's a bit
152
- // more convenient to do it here.
153
- self . check_block_shape ( & witgen) ;
154
- }
155
-
156
131
// Check that we could derive all requested variables.
157
132
let missing_variables = self
158
133
. requested_known_vars
@@ -347,27 +322,23 @@ impl<'a, T: FieldElement, FixedEval: FixedEvaluator<T>> Processor<'a, T, FixedEv
347
322
. unique ( )
348
323
. flat_map ( |& call| {
349
324
let rows = self . rows_for_identity ( call) ;
350
- let complete_rows = rows
325
+ if rows
351
326
. iter ( )
352
327
. filter ( |& & row| witgen. is_complete_call ( call, row) )
353
- . collect :: < Vec < _ > > ( ) ;
354
- // We might process more rows than ` self.block_size`, so we check
355
- // that the complete calls are on consecutive rows.
356
- if complete_rows . len ( ) >= self . block_size {
357
- let ( min , max ) = complete_rows . iter ( ) . minmax ( ) . into_option ( ) . unwrap ( ) ;
358
- // TODO instead of checking for consecutive rows, we could also check
359
- // that they "fit" the next block .
360
- // TODO actually I think that we should not allow more than block size
361
- // completed calls.
362
- let is_consecutive = * max - * min == complete_rows . len ( ) as i32 - 1 ;
363
- if is_consecutive {
364
- return vec ! [ ] ;
365
- }
328
+ . count ( )
329
+ >= self . block_size
330
+ {
331
+ // We might process more rows than ` self.block_size`, so we check
332
+ // that we have the reqired amount of calls.
333
+ // The block shape check done by block_machine_processor will do a more
334
+ // thorough check later on .
335
+ vec ! [ ]
336
+ } else {
337
+ rows . iter ( )
338
+ . filter ( | & row| !witgen . is_complete_call ( call , * row ) )
339
+ . map ( |row| ( call , * row ) )
340
+ . collect_vec ( )
366
341
}
367
- rows. iter ( )
368
- . filter ( |& row| !witgen. is_complete_call ( call, * row) )
369
- . map ( |row| ( call, * row) )
370
- . collect :: < Vec < _ > > ( )
371
342
} )
372
343
. collect :: < Vec < _ > > ( )
373
344
}
@@ -386,77 +357,6 @@ impl<'a, T: FieldElement, FixedEval: FixedEvaluator<T>> Processor<'a, T, FixedEv
386
357
. collect ( )
387
358
}
388
359
389
- /// After solving, the known cells should be such that we can stack different blocks.
390
- /// If this is not the case, this function panics.
391
- /// TODO the same is actually true for machine calls.
392
- fn check_block_shape ( & self , witgen : & WitgenInference < ' a , T , FixedEval > ) {
393
- let known_columns: BTreeSet < _ > = witgen
394
- . known_variables ( )
395
- . iter ( )
396
- . filter_map ( |var| match var {
397
- Variable :: WitnessCell ( cell) => Some ( cell. id ) ,
398
- _ => None ,
399
- } )
400
- . collect ( ) ;
401
- for column_id in known_columns {
402
- let known_rows = witgen
403
- . known_variables ( )
404
- . iter ( )
405
- . filter_map ( |var| match var {
406
- Variable :: WitnessCell ( cell) if cell. id == column_id => Some ( cell. row_offset ) ,
407
- _ => None ,
408
- } )
409
- . collect :: < BTreeSet < _ > > ( ) ;
410
-
411
- // Two values that refer to the same row (modulo block size) are compatible if:
412
- // - One of them is unknown, or
413
- // - Both are concrete and equal
414
- let is_compatible = |v1 : Value < T > , v2 : Value < T > | match ( v1, v2) {
415
- ( Value :: Unknown , _) | ( _, Value :: Unknown ) => true ,
416
- ( Value :: Concrete ( a) , Value :: Concrete ( b) ) => a == b,
417
- _ => false ,
418
- } ;
419
- let cell_var = |row_offset| {
420
- Variable :: WitnessCell ( Cell {
421
- // Column name does not matter.
422
- column_name : "" . to_string ( ) ,
423
- id : column_id,
424
- row_offset,
425
- } )
426
- } ;
427
-
428
- // A column is stackable if all rows equal to each other modulo
429
- // the block size are compatible.
430
- for row in & known_rows {
431
- let this_val = witgen. value ( & cell_var ( * row) ) ;
432
- let next_block_val = witgen. value ( & cell_var ( row + self . block_size as i32 ) ) ;
433
- if !is_compatible ( this_val, next_block_val) {
434
- let column_name = self . fixed_data . column_name ( & PolyID {
435
- id : column_id,
436
- ptype : PolynomialType :: Committed ,
437
- } ) ;
438
- let row_vals = known_rows
439
- . iter ( )
440
- . map ( |& r| format ! ( " row {r}: {}\n " , witgen. value( & cell_var( r) ) ) )
441
- . format ( "" ) ;
442
- log:: debug!(
443
- "Code generated so far:\n {}\n \
444
- Column {column_name} is not stackable in a {}-row block, \
445
- conflict in rows {row} and {}.\n {row_vals}",
446
- format_code( witgen. code( ) ) ,
447
- self . block_size,
448
- row + self . block_size as i32
449
- ) ;
450
- panic ! (
451
- "Column {column_name} is not stackable in a {}-row block, conflict in rows {row} and {}.\n {row_vals}" ,
452
- self . block_size,
453
- row + self . block_size as i32
454
- ) ;
455
- }
456
- }
457
- }
458
- }
459
-
460
360
/// If the only missing sends all only have a single argument, try to set those arguments
461
361
/// to zero.
462
362
fn try_fix_simple_sends (
@@ -494,7 +394,7 @@ impl<'a, T: FieldElement, FixedEval: FixedEvaluator<T>> Processor<'a, T, FixedEv
494
394
} ;
495
395
assert ! ( !witgen. is_known( param) ) ;
496
396
match modified_witgen. process_equation_on_row (
497
- & Expression :: Number ( T :: from ( 0 ) ) ,
397
+ & T :: from ( 0 ) . into ( ) ,
498
398
Some ( param. clone ( ) ) ,
499
399
0 . into ( ) ,
500
400
row,
0 commit comments