Skip to content

Commit e451be1

Browse files
authored
Do now follow intermediate columns. (#2599)
Fixes #2597
1 parent c00a424 commit e451be1

File tree

4 files changed

+48
-96
lines changed

4 files changed

+48
-96
lines changed

executor/src/witgen/jit/block_machine_processor.rs

-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ impl<'a, T: FieldElement> BlockMachineProcessor<'a, T> {
167167
.filter_map(|(i, is_input)| (!is_input).then_some(Variable::Param(i)))
168168
.collect_vec();
169169
let mut result = Processor::new(
170-
self.fixed_data,
171170
identities,
172171
queue_items,
173172
requested_known.iter().cloned(),

executor/src/witgen/jit/identity_queue.rs

+47-89
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ use std::{
66
use itertools::Itertools;
77
use powdr_ast::{
88
analyzed::{
9-
AlgebraicExpression as Expression, AlgebraicReferenceThin, PolynomialIdentity,
10-
PolynomialType,
9+
AlgebraicExpression as Expression, AlgebraicReference, PolynomialIdentity, PolynomialType,
1110
},
1211
parsed::visitor::{AllChildren, Children},
1312
};
1413
use powdr_number::FieldElement;
1514

16-
use crate::witgen::{
17-
data_structures::identity::Identity, jit::variable::MachineCallVariable, FixedData,
18-
};
15+
use crate::witgen::{data_structures::identity::Identity, jit::variable::MachineCallVariable};
1916

2017
use super::{prover_function_heuristics::ProverFunction, variable::Variable};
2118

@@ -29,12 +26,9 @@ pub struct IdentityQueue<'a, T: FieldElement> {
2926
}
3027

3128
impl<'a, T: FieldElement> IdentityQueue<'a, T> {
32-
pub fn new(
33-
fixed_data: &'a FixedData<'a, T>,
34-
items: impl IntoIterator<Item = QueueItem<'a, T>>,
35-
) -> Self {
29+
pub fn new(items: impl IntoIterator<Item = QueueItem<'a, T>>) -> Self {
3630
let queue: BTreeSet<_> = items.into_iter().collect();
37-
let mut references = ReferencesComputer::new(fixed_data);
31+
let mut references = ReferencesComputer::default();
3832
let occurrences = Rc::new(
3933
queue
4034
.iter()
@@ -154,33 +148,24 @@ pub struct ConstantAssignment<'a, T: FieldElement> {
154148
}
155149

156150
/// Utility to compute the variables that occur in a queue item.
157-
/// Follows intermediate column references and employs caches.
158-
struct ReferencesComputer<'a, T: FieldElement> {
159-
fixed_data: &'a FixedData<'a, T>,
160-
intermediate_cache: HashMap<AlgebraicReferenceThin, Vec<AlgebraicReferenceThin>>,
151+
#[derive(Default)]
152+
struct ReferencesComputer<'a> {
161153
/// A cache to store algebraic references in a polynomial identity, so that it
162154
/// can be re-used on all rows.
163-
references_per_identity: HashMap<u64, Vec<AlgebraicReferenceThin>>,
155+
references_per_identity: HashMap<u64, Vec<&'a AlgebraicReference>>,
164156
}
165157

166-
impl<'a, T: FieldElement> ReferencesComputer<'a, T> {
167-
pub fn new(fixed_data: &'a FixedData<'a, T>) -> Self {
168-
Self {
169-
fixed_data,
170-
intermediate_cache: HashMap::new(),
171-
references_per_identity: HashMap::new(),
172-
}
173-
}
174-
pub fn references(&mut self, item: &QueueItem<'a, T>) -> Vec<Variable> {
158+
impl<'a> ReferencesComputer<'a> {
159+
pub fn references<T: FieldElement>(&mut self, item: &QueueItem<'a, T>) -> Vec<Variable> {
175160
let vars: Box<dyn Iterator<Item = _>> = match item {
176161
QueueItem::Identity(id, row) => match id {
177162
Identity::Polynomial(poly_id) => Box::new(
178163
self.references_in_polynomial_identity(poly_id)
179164
.into_iter()
180-
.map(|r| self.reference_to_variable(&r, *row)),
165+
.map(|r| Variable::from_reference(r, *row)),
181166
),
182167
Identity::BusSend(bus_send) => Box::new(
183-
self.variables_in_expression(&bus_send.selected_payload.selector, *row)
168+
variables_in_expression(&bus_send.selected_payload.selector, *row)
184169
.into_iter()
185170
.chain(
186171
(0..bus_send.selected_payload.expressions.len()).map(|index| {
@@ -194,18 +179,16 @@ impl<'a, T: FieldElement> ReferencesComputer<'a, T> {
194179
),
195180
Identity::Connect(..) => Box::new(std::iter::empty()),
196181
},
197-
QueueItem::ConstantAssignment(a) => Box::new(
198-
self.variables_in_expression(a.lhs, a.row_offset)
199-
.into_iter(),
200-
),
182+
QueueItem::ConstantAssignment(a) => {
183+
Box::new(variables_in_expression(a.lhs, a.row_offset).into_iter())
184+
}
201185
QueueItem::VariableAssignment(a) => Box::new(
202-
std::iter::once(a.rhs.clone())
203-
.chain(self.variables_in_expression(a.lhs, a.row_offset)),
186+
std::iter::once(a.rhs.clone()).chain(variables_in_expression(a.lhs, a.row_offset)),
204187
),
205188
QueueItem::ProverFunction(p, row) => Box::new(
206189
p.condition
207190
.iter()
208-
.flat_map(|c| self.variables_in_expression(c, *row))
191+
.flat_map(|c| variables_in_expression(c, *row))
209192
.chain(
210193
p.input_columns
211194
.iter()
@@ -216,79 +199,54 @@ impl<'a, T: FieldElement> ReferencesComputer<'a, T> {
216199
vars.unique().collect_vec()
217200
}
218201

219-
fn variables_in_expression(&mut self, expression: &Expression<T>, row: i32) -> Vec<Variable> {
220-
self.references_in_expression(expression)
221-
.iter()
222-
.map(|r| {
223-
let name = self.fixed_data.column_name(&r.poly_id).to_string();
224-
Variable::from_reference(&r.with_name(name), row)
225-
})
226-
.collect()
227-
}
228-
229-
/// Turns AlgebraicReferenceThin to Variable, by including the row offset.
230-
fn reference_to_variable(&self, reference: &AlgebraicReferenceThin, row: i32) -> Variable {
231-
let name = self.fixed_data.column_name(&reference.poly_id).to_string();
232-
Variable::from_reference(&reference.with_name(name), row)
233-
}
234-
235-
fn references_in_polynomial_identity(
202+
fn references_in_polynomial_identity<T: FieldElement>(
236203
&mut self,
237-
identity: &PolynomialIdentity<T>,
238-
) -> Vec<AlgebraicReferenceThin> {
204+
identity: &'a PolynomialIdentity<T>,
205+
) -> Vec<&'a AlgebraicReference> {
239206
// Clippy suggests to use `entry()...or_insert_with()`,
240207
// but the code does not work, since we need `&mut self` in
241208
// self.references_in_expression.
242209
#[allow(clippy::map_entry)]
243210
if !self.references_per_identity.contains_key(&identity.id) {
244211
let mut result = BTreeSet::new();
245212
for e in identity.children() {
246-
result.extend(self.references_in_expression(e));
213+
result.extend(references_in_expression(e));
247214
}
248215
self.references_per_identity
249216
.insert(identity.id, result.into_iter().collect_vec());
250217
}
251218
self.references_per_identity[&identity.id].clone()
252219
}
220+
}
253221

254-
/// Returns all references to witness column in the expression, including indirect
255-
/// references through intermediate columns.
256-
fn references_in_expression(
257-
&mut self,
258-
expression: &Expression<T>,
259-
) -> Vec<AlgebraicReferenceThin> {
260-
let mut references = BTreeSet::new();
261-
for e in expression.all_children() {
262-
match e {
263-
Expression::Reference(r) => match r.poly_id.ptype {
264-
PolynomialType::Constant => {}
265-
PolynomialType::Committed => {
266-
references.insert(r.into());
267-
}
268-
PolynomialType::Intermediate => references
269-
.extend(self.references_in_intermediate(&r.into()).iter().cloned()),
270-
},
271-
Expression::PublicReference(_) | Expression::Challenge(_) => {
272-
// TODO we need to introduce a variable type for those.
222+
fn variables_in_expression<T: FieldElement>(expression: &Expression<T>, row: i32) -> Vec<Variable> {
223+
references_in_expression(expression)
224+
.iter()
225+
.map(|r| Variable::from_reference(r, row))
226+
.collect()
227+
}
228+
229+
/// Returns all references to witness column in the expression, including indirect
230+
/// references through intermediate columns.
231+
fn references_in_expression<T: FieldElement>(
232+
expression: &Expression<T>,
233+
) -> Vec<&AlgebraicReference> {
234+
let mut references = BTreeSet::new();
235+
for e in expression.all_children() {
236+
match e {
237+
Expression::Reference(r) => match r.poly_id.ptype {
238+
PolynomialType::Constant => {}
239+
PolynomialType::Committed | PolynomialType::Intermediate => {
240+
references.insert(r);
273241
}
274-
Expression::Number(_)
275-
| Expression::BinaryOperation(..)
276-
| Expression::UnaryOperation(..) => {}
242+
},
243+
Expression::PublicReference(_) | Expression::Challenge(_) => {
244+
// TODO we need to introduce a variable type for those.
277245
}
246+
Expression::Number(_)
247+
| Expression::BinaryOperation(..)
248+
| Expression::UnaryOperation(..) => {}
278249
}
279-
references.into_iter().collect()
280-
}
281-
282-
fn references_in_intermediate(
283-
&mut self,
284-
intermediate: &AlgebraicReferenceThin,
285-
) -> &Vec<AlgebraicReferenceThin> {
286-
if !self.intermediate_cache.contains_key(intermediate) {
287-
let definition = &self.fixed_data.intermediate_definitions[intermediate];
288-
let references = self.references_in_expression(definition);
289-
self.intermediate_cache
290-
.insert(intermediate.clone(), references.clone());
291-
}
292-
&self.intermediate_cache[intermediate]
293250
}
251+
references.into_iter().collect()
294252
}

executor/src/witgen/jit/processor.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use crate::witgen::{
88
data_structures::identity::{BusSend, Identity},
99
jit::debug_formatter::format_polynomial_identities,
1010
range_constraints::RangeConstraint,
11-
FixedData,
1211
};
1312

1413
use super::{
@@ -22,7 +21,6 @@ use super::{
2221

2322
/// A generic processor for generating JIT code.
2423
pub struct Processor<'a, T: FieldElement> {
25-
fixed_data: &'a FixedData<'a, T>,
2624
/// List of identities and row offsets to process them on.
2725
identities: Vec<(&'a Identity<T>, i32)>,
2826
/// List of assignments (or other queue items) provided from outside.
@@ -48,15 +46,13 @@ pub struct ProcessorResult<T: FieldElement> {
4846

4947
impl<'a, T: FieldElement> Processor<'a, T> {
5048
pub fn new(
51-
fixed_data: &'a FixedData<'a, T>,
5249
identities: impl IntoIterator<Item = (&'a Identity<T>, i32)>,
5350
initial_queue: Vec<QueueItem<'a, T>>,
5451
requested_known_vars: impl IntoIterator<Item = Variable>,
5552
max_branch_depth: usize,
5653
) -> Self {
5754
let identities = identities.into_iter().collect_vec();
5855
Self {
59-
fixed_data,
6056
identities,
6157
initial_queue,
6258
block_size: 1,
@@ -103,7 +99,7 @@ impl<'a, T: FieldElement> Processor<'a, T> {
10399
}
104100
}));
105101
let branch_depth = 0;
106-
let identity_queue = IdentityQueue::new(self.fixed_data, queue_items);
102+
let identity_queue = IdentityQueue::new(queue_items);
107103
self.generate_code_for_branch(can_process, witgen, identity_queue, branch_depth)
108104
}
109105

executor/src/witgen/jit/single_step_processor.rs

-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ impl<'a, T: FieldElement> SingleStepProcessor<'a, T> {
102102
}
103103

104104
Processor::new(
105-
self.fixed_data,
106105
identities,
107106
queue_items,
108107
requested_known,

0 commit comments

Comments
 (0)