From f1e749163b34b95a47e8c8ce2d8005dfd9d1590b Mon Sep 17 00:00:00 2001 From: Steve Wang Date: Thu, 2 Nov 2023 21:42:10 -0400 Subject: [PATCH] Python frontend lookup fix (#173) Two issues fixed: 1. Serde deserializer failed to store the parsed Lookup in Rust AST. 2. Python frontend uses the single circuit compile function rather than the by phase compile functions for super circuits. --- Cargo.toml | 2 +- src/ast/mod.rs | 3 ++- src/frontend/python/chiquito/dsl.py | 5 +++-- src/frontend/python/mod.rs | 30 +++++++++++++++++++++++++++-- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c15cf949..c0427401 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chiquito" -version = "0.1.2023101100" +version = "0.1.2023110200" edition = "2021" license = "MIT OR Apache-2.0" authors = ["Leo Lara "] diff --git a/src/ast/mod.rs b/src/ast/mod.rs index ef9d10ef..b28eb50b 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -217,6 +217,7 @@ impl Debug for StepType { .field("signals", &self.signals) .field("constraints", &self.constraints) .field("transition_constraints", &self.transition_constraints) + .field("lookups", &self.lookups) .finish() } } @@ -292,7 +293,7 @@ pub struct TransitionConstraint { pub expr: ASTExpr, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Lookup { pub annotation: String, pub exprs: Vec<(Constraint, ASTExpr)>, diff --git a/src/frontend/python/chiquito/dsl.py b/src/frontend/python/chiquito/dsl.py index 60b45686..2cb79e5d 100644 --- a/src/frontend/python/chiquito/dsl.py +++ b/src/frontend/python/chiquito/dsl.py @@ -42,7 +42,7 @@ def sub_circuit(self: SuperCircuit, sub_circuit: Circuit) -> Circuit: "SuperCircuit: sub_circuit() cannot be called twice on the same circuit." ) ast_json: str = sub_circuit.get_ast_json() - sub_circuit.rust_id: int = rust_chiquito.ast_to_halo2(ast_json) + sub_circuit.rust_id: int = rust_chiquito.ast_map_store(ast_json) self.ast.sub_circuits[sub_circuit.rust_id] = sub_circuit.ast return sub_circuit @@ -277,7 +277,8 @@ def assign(self: StepType, lhs: Queriable, rhs: F): self.step_instance.assign(lhs, F(rhs)) def add_lookup(self: StepType, lookup_builder: LookupBuilder): - self.step_type.lookups.append(lookup_builder.build()) + lookup = lookup_builder.build() + self.step_type.lookups.append(lookup) LookupBuilder = LookupTableBuilder | InPlaceLookupBuilder diff --git a/src/frontend/python/mod.rs b/src/frontend/python/mod.rs index dcc80985..030477b3 100644 --- a/src/frontend/python/mod.rs +++ b/src/frontend/python/mod.rs @@ -60,7 +60,23 @@ pub fn chiquito_ast_to_halo2(ast_json: &str) -> UUID { .insert(uuid, (circuit, chiquito_halo2, assignment_generator)); }); - println!("{:?}", uuid); + uuid +} + +// Internal function called by `sub_circuit` function in Python frontend. Used in conjunction with +// the super circuit only. Parses AST JSON and stores AST in `CIRCUIT_MAP` without compiling it. +// Compilation is done by `chiquito_super_circuit_halo2_mock_prover`. +pub fn chiquito_ast_map_store(ast_json: &str) -> UUID { + let circuit: Circuit = + serde_json::from_str(ast_json).expect("Json deserialization to Circuit failed."); + + let uuid = uuid(); + + CIRCUIT_MAP.with(|circuit_map| { + circuit_map + .borrow_mut() + .insert(uuid, (circuit, ChiquitoHalo2::default(), None)); + }); uuid } @@ -412,13 +428,14 @@ impl<'de> Visitor<'de> for StepTypeVisitor { let constraints = constraints.ok_or_else(|| de::Error::missing_field("constraints"))?; let transition_constraints = transition_constraints .ok_or_else(|| de::Error::missing_field("transition_constraints"))?; + let lookups = lookups.ok_or_else(|| de::Error::missing_field("lookups"))?; let annotations = annotations.ok_or_else(|| de::Error::missing_field("annotations"))?; let mut step_type = StepType::::new(id, name); step_type.signals = signals; step_type.constraints = constraints; step_type.transition_constraints = transition_constraints; - step_type.lookups = Default::default(); + step_type.lookups = lookups; step_type.annotations = annotations; Ok(step_type) @@ -1631,6 +1648,7 @@ mod tests { } } ], + "lookups":[], "annotations":{ "5":"a", "6":"b", @@ -1827,6 +1845,13 @@ fn ast_to_halo2(json: &PyString) -> u128 { uuid } +#[pyfunction] +fn ast_map_store(json: &PyString) -> u128 { + let uuid = chiquito_ast_map_store(json.to_str().expect("PyString convertion failed.")); + + uuid +} + #[pyfunction] fn halo2_mock_prover(witness_json: &PyString, rust_id: &PyLong, k: &PyLong) { chiquito_halo2_mock_prover( @@ -1878,6 +1903,7 @@ fn rust_chiquito(_py: Python, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(convert_and_print_ast, m)?)?; m.add_function(wrap_pyfunction!(convert_and_print_trace_witness, m)?)?; m.add_function(wrap_pyfunction!(ast_to_halo2, m)?)?; + m.add_function(wrap_pyfunction!(ast_map_store, m)?)?; m.add_function(wrap_pyfunction!(halo2_mock_prover, m)?)?; m.add_function(wrap_pyfunction!(super_circuit_halo2_mock_prover, m)?)?; Ok(())