@@ -17,7 +17,8 @@ use crate::witgen::{
17
17
18
18
use super :: {
19
19
block_machine_processor:: BlockMachineProcessor ,
20
- compiler:: { compile_effects, WitgenFunction } ,
20
+ compiler:: { compile_effects, CompiledFunction } ,
21
+ interpreter:: EffectsInterpreter ,
21
22
variable:: Variable ,
22
23
witgen_inference:: CanProcessCall ,
23
24
} ;
@@ -44,8 +45,36 @@ pub struct FunctionCache<'a, T: FieldElement> {
44
45
parts : MachineParts < ' a , T > ,
45
46
}
46
47
48
+ enum WitgenFunction < T : FieldElement > {
49
+ Compiled ( CompiledFunction < T > ) ,
50
+ Interpreted ( EffectsInterpreter < T > ) ,
51
+ }
52
+
53
+ impl < T : FieldElement > WitgenFunction < T > {
54
+ /// Call the witgen function to fill the data and "known" tables
55
+ /// given a slice of parameters.
56
+ /// The `row_offset` is the index inside `data` of the row considered to be "row zero".
57
+ /// This function always succeeds (unless it panics).
58
+ pub fn call < Q : QueryCallback < T > > (
59
+ & self ,
60
+ fixed_data : & FixedData < ' _ , T > ,
61
+ mutable_state : & MutableState < ' _ , T , Q > ,
62
+ params : & mut [ LookupCell < T > ] ,
63
+ data : CompactDataRef < ' _ , T > ,
64
+ ) {
65
+ match self {
66
+ WitgenFunction :: Compiled ( compiled_function) => {
67
+ compiled_function. call ( fixed_data, mutable_state, params, data) ;
68
+ }
69
+ WitgenFunction :: Interpreted ( interpreter) => {
70
+ interpreter. call :: < Q > ( fixed_data, mutable_state, params, data)
71
+ }
72
+ }
73
+ }
74
+ }
75
+
47
76
pub struct CacheEntry < T : FieldElement > {
48
- pub function : WitgenFunction < T > ,
77
+ function : WitgenFunction < T > ,
49
78
pub range_constraints : Vec < RangeConstraint < T > > ,
50
79
}
51
80
@@ -108,13 +137,16 @@ impl<'a, T: FieldElement> FunctionCache<'a, T> {
108
137
if !self . witgen_functions . contains_key ( cache_key) {
109
138
record_start ( "Auto-witgen code derivation" ) ;
110
139
let f = match T :: known_field ( ) {
111
- // Currently, we only support the Goldilocks fields
140
+ // TODO: Currently, code generation only supports the Goldilocks
141
+ // fields. We can't enable the interpreter for non-goldilocks
142
+ // fields due to a limitation of autowitgen.
112
143
Some ( KnownField :: GoldilocksField ) => {
113
- self . compile_witgen_function ( can_process, cache_key)
144
+ self . compile_witgen_function ( can_process, cache_key, false )
114
145
}
115
146
_ => None ,
116
147
} ;
117
148
assert ! ( self . witgen_functions. insert( cache_key. clone( ) , f) . is_none( ) ) ;
149
+
118
150
record_end ( "Auto-witgen code derivation" ) ;
119
151
}
120
152
self . witgen_functions . get ( cache_key) . unwrap ( )
@@ -124,6 +156,7 @@ impl<'a, T: FieldElement> FunctionCache<'a, T> {
124
156
& self ,
125
157
can_process : impl CanProcessCall < T > ,
126
158
cache_key : & CacheKey < T > ,
159
+ interpreted : bool ,
127
160
) -> Option < CacheEntry < T > > {
128
161
log:: debug!(
129
162
"Compiling JIT function for\n Machine: {}\n Connection: {}\n Inputs: {:?}{}" ,
@@ -187,15 +220,22 @@ impl<'a, T: FieldElement> FunctionCache<'a, T> {
187
220
. filter_map ( |( i, b) | if b { Some ( Variable :: Param ( i) ) } else { None } )
188
221
. collect :: < Vec < _ > > ( ) ;
189
222
190
- log:: trace!( "Compiling effects..." ) ;
191
- let function = compile_effects (
192
- self . fixed_data . analyzed ,
193
- self . column_layout . clone ( ) ,
194
- & known_inputs,
195
- & code,
196
- prover_functions,
197
- )
198
- . unwrap ( ) ;
223
+ let function = if interpreted {
224
+ log:: trace!( "Building effects interpreter..." ) ;
225
+ WitgenFunction :: Interpreted ( EffectsInterpreter :: try_new ( & known_inputs, & code) ?)
226
+ } else {
227
+ log:: trace!( "Compiling effects..." ) ;
228
+ WitgenFunction :: Compiled (
229
+ compile_effects (
230
+ self . fixed_data . analyzed ,
231
+ self . column_layout . clone ( ) ,
232
+ & known_inputs,
233
+ & code,
234
+ prover_functions,
235
+ )
236
+ . unwrap ( ) ,
237
+ )
238
+ } ;
199
239
log:: trace!( "Compilation done." ) ;
200
240
201
241
Some ( CacheEntry {
0 commit comments