From 17a3f072160c5a40397d4dac3448b89389cc50a4 Mon Sep 17 00:00:00 2001 From: guorong009 Date: Tue, 6 Aug 2024 10:34:41 +0800 Subject: [PATCH] refactor: move unit tests to own files --- halo2_frontend/src/dev.rs | 182 +------------------------------- halo2_frontend/src/dev/gates.rs | 77 ++++++++++++++ halo2_frontend/src/dev/tfp.rs | 127 ++++++++++++++++++++++ 3 files changed, 205 insertions(+), 181 deletions(-) diff --git a/halo2_frontend/src/dev.rs b/halo2_frontend/src/dev.rs index 31c9248dc4..2958a32021 100644 --- a/halo2_frontend/src/dev.rs +++ b/halo2_frontend/src/dev.rs @@ -1258,7 +1258,7 @@ mod tests { use super::{FailureLocation, MockProver, VerifyFailure}; use crate::circuit::{Layouter, SimpleFloorPlanner, Value}; - use crate::dev::{CellValue, CircuitGates, InstanceValue, TracingFloorPlanner}; + use crate::dev::{CellValue, InstanceValue}; use crate::plonk::{ Advice, Circuit, Column, ConstraintSystem, Error, Expression, Fixed, Instance, Selector, TableColumn, @@ -2256,184 +2256,4 @@ mod tests { // if this verifies correctly -> we have an issue and we are missing a range check assert_eq!(prover.verify(), Ok(())); } - - #[test] - fn test_tracing_floor_planner() { - use tracing_capture::{CaptureLayer, SharedStorage}; - use tracing_subscriber::layer::SubscriberExt; - - const K: u32 = 4; - - #[derive(Clone)] - struct TestCircuitConfig { - a: Column, - b: Column, - c: Column, - d: Column, - q: Selector, - } - - struct TestCircuit {} - - impl Circuit for TestCircuit { - type Config = TestCircuitConfig; - type FloorPlanner = TracingFloorPlanner; - #[cfg(feature = "circuit-params")] - type Params = (); - - fn configure(meta: &mut ConstraintSystem) -> Self::Config { - let a = meta.advice_column(); - let b = meta.advice_column(); - let c = meta.advice_column(); - let d = meta.fixed_column(); - let q = meta.selector(); - - meta.create_gate("Equality check", |cells| { - let a = cells.query_advice(a, Rotation::cur()); - let b = cells.query_advice(b, Rotation::cur()); - let c = cells.query_advice(c, Rotation::cur()); - let d = cells.query_fixed(d, Rotation::cur()); - let q = cells.query_selector(q); - - // If q is enabled, a and b must be assigned to. - vec![q * (a - b) * (c - d)] - }); - - TestCircuitConfig { a, b, c, d, q } - } - - fn without_witnesses(&self) -> Self { - Self {} - } - - fn synthesize( - &self, - config: Self::Config, - mut layouter: impl Layouter, - ) -> Result<(), Error> { - layouter.assign_region( - || "Correct synthesis", - |mut region| { - // Enable the equality gate. - config.q.enable(&mut region, 0)?; - - // Assign a = 1. - region.assign_advice(|| "a", config.a, 0, || Value::known(Fp::one()))?; - - // Assign b = 1. - region.assign_advice(|| "b", config.b, 0, || Value::known(Fp::one()))?; - - // Assign c = 5. - region.assign_advice( - || "c", - config.c, - 0, - || Value::known(Fp::from(5u64)), - )?; - // Assign d = 7. - region.assign_fixed( - || "d", - config.d, - 0, - || Value::known(Fp::from(7u64)), - )?; - Ok(()) - }, - )?; - - Ok(()) - } - } - - // // At the start of your test, enable tracing. - // tracing_subscriber::fmt() - // .with_max_level(tracing::Level::DEBUG) - // .with_ansi(false) - // .without_time() - // .init(); - - let subscriber = tracing_subscriber::fmt() - .with_max_level(tracing::Level::DEBUG) - .with_ansi(false) - .without_time() - .finish(); - let storage = SharedStorage::default(); - let subscriber = subscriber.with(CaptureLayer::new(&storage)); - tracing::subscriber::set_global_default(subscriber).unwrap(); - - // run the prover to check if every step is traced. - let prover = MockProver::run(K, &TestCircuit {}, vec![]).unwrap(); - assert_eq!(prover.verify(), Ok(())); - - // check if all tracing logs are captured - let storage = storage.lock(); - assert_eq!(storage.all_spans().len(), 12); - for span in storage.all_spans() { - let metadata = span.metadata(); - assert_eq!(*metadata.level(), tracing::Level::DEBUG); - } - } - - #[test] - fn test_gates() { - #[derive(Clone)] - struct TestCircuitConfig { - a: Column, - b: Column, - c: Column, - d: Column, - q: Selector, - } - - struct TestCircuit {} - - impl Circuit for TestCircuit { - type Config = TestCircuitConfig; - type FloorPlanner = SimpleFloorPlanner; - #[cfg(feature = "circuit-params")] - type Params = (); - - fn configure(meta: &mut ConstraintSystem) -> Self::Config { - let a = meta.advice_column(); - let b = meta.advice_column(); - let c = meta.advice_column(); - let d = meta.fixed_column(); - let q = meta.selector(); - - meta.create_gate("Equality check", |cells| { - let a = cells.query_advice(a, Rotation::cur()); - let b = cells.query_advice(b, Rotation::cur()); - let c = cells.query_advice(c, Rotation::cur()); - let d = cells.query_fixed(d, Rotation::cur()); - let q = cells.query_selector(q); - - // If q is enabled, a and b must be assigned to. - vec![q * (a - b) * (c - d)] - }); - - TestCircuitConfig { a, b, c, d, q } - } - - fn without_witnesses(&self) -> Self { - Self {} - } - - fn synthesize(&self, _: Self::Config, _: impl Layouter) -> Result<(), Error> { - unreachable!(); - } - } - - let gates = CircuitGates::collect::(); - assert_eq!( - format!("{}", gates), - r#####"Equality check: -- (S0 * (A0@0 - A1@0)) * (A2@0 - F0@0) -Total gates: 1 -Total custom constraint polynomials: 1 -Total negations: 2 -Total additions: 2 -Total multiplications: 2 -"##### - ) - } } diff --git a/halo2_frontend/src/dev/gates.rs b/halo2_frontend/src/dev/gates.rs index 5c48bbed4c..b2682c1115 100644 --- a/halo2_frontend/src/dev/gates.rs +++ b/halo2_frontend/src/dev/gates.rs @@ -308,3 +308,80 @@ impl fmt::Display for CircuitGates { writeln!(f, "Total multiplications: {}", self.total_multiplications) } } + +#[cfg(test)] +mod tests { + use halo2_middleware::poly::Rotation; + use halo2curves::pasta::Fp; + + use crate::{ + circuit::{Layouter, SimpleFloorPlanner}, + plonk::{Advice, Column, Error, Fixed, Selector}, + }; + + use super::*; + + #[test] + fn test_circuit_gates() { + #[allow(unused)] + #[derive(Clone)] + struct TestCircuitConfig { + a: Column, + b: Column, + c: Column, + d: Column, + q: Selector, + } + + struct TestCircuit {} + + impl Circuit for TestCircuit { + type Config = TestCircuitConfig; + type FloorPlanner = SimpleFloorPlanner; + #[cfg(feature = "circuit-params")] + type Params = (); + + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let a = meta.advice_column(); + let b = meta.advice_column(); + let c = meta.advice_column(); + let d = meta.fixed_column(); + let q = meta.selector(); + + meta.create_gate("Equality check", |cells| { + let a = cells.query_advice(a, Rotation::cur()); + let b = cells.query_advice(b, Rotation::cur()); + let c = cells.query_advice(c, Rotation::cur()); + let d = cells.query_fixed(d, Rotation::cur()); + let q = cells.query_selector(q); + + // If q is enabled, a and b must be assigned to. + vec![q * (a - b) * (c - d)] + }); + + TestCircuitConfig { a, b, c, d, q } + } + + fn without_witnesses(&self) -> Self { + Self {} + } + + fn synthesize(&self, _: Self::Config, _: impl Layouter) -> Result<(), Error> { + unreachable!(); + } + } + + let gates = CircuitGates::collect::(); + assert_eq!( + format!("{}", gates), + r#####"Equality check: +- (S0 * (A0@0 - A1@0)) * (A2@0 - F0@0) +Total gates: 1 +Total custom constraint polynomials: 1 +Total negations: 2 +Total additions: 2 +Total multiplications: 2 +"##### + ) + } +} diff --git a/halo2_frontend/src/dev/tfp.rs b/halo2_frontend/src/dev/tfp.rs index 0d02d1d2bd..fa492f52e3 100644 --- a/halo2_frontend/src/dev/tfp.rs +++ b/halo2_frontend/src/dev/tfp.rs @@ -509,3 +509,130 @@ impl<'cs, F: Field, CS: Assignment> Assignment for TracingAssignment<'cs, // We exit namespace spans in TracingLayouter. } } + +#[cfg(test)] +mod tests { + use halo2_middleware::poly::Rotation; + use halo2curves::pasta::Fp; + + use crate::{circuit::SimpleFloorPlanner, dev::MockProver}; + + use super::*; + + #[test] + fn test_tracing_floor_planner() { + use tracing_capture::{CaptureLayer, SharedStorage}; + use tracing_subscriber::layer::SubscriberExt; + + const K: u32 = 4; + + #[derive(Clone)] + struct TestCircuitConfig { + a: Column, + b: Column, + c: Column, + d: Column, + q: Selector, + } + + struct TestCircuit {} + + impl Circuit for TestCircuit { + type Config = TestCircuitConfig; + type FloorPlanner = TracingFloorPlanner; + #[cfg(feature = "circuit-params")] + type Params = (); + + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let a = meta.advice_column(); + let b = meta.advice_column(); + let c = meta.advice_column(); + let d = meta.fixed_column(); + let q = meta.selector(); + + meta.create_gate("Equality check", |cells| { + let a = cells.query_advice(a, Rotation::cur()); + let b = cells.query_advice(b, Rotation::cur()); + let c = cells.query_advice(c, Rotation::cur()); + let d = cells.query_fixed(d, Rotation::cur()); + let q = cells.query_selector(q); + + // If q is enabled, a and b must be assigned to. + vec![q * (a - b) * (c - d)] + }); + + TestCircuitConfig { a, b, c, d, q } + } + + fn without_witnesses(&self) -> Self { + Self {} + } + + fn synthesize( + &self, + config: Self::Config, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + layouter.assign_region( + || "Correct synthesis", + |mut region| { + // Enable the equality gate. + config.q.enable(&mut region, 0)?; + + // Assign a = 1. + region.assign_advice(|| "a", config.a, 0, || Value::known(Fp::one()))?; + + // Assign b = 1. + region.assign_advice(|| "b", config.b, 0, || Value::known(Fp::one()))?; + + // Assign c = 5. + region.assign_advice( + || "c", + config.c, + 0, + || Value::known(Fp::from(5u64)), + )?; + // Assign d = 7. + region.assign_fixed( + || "d", + config.d, + 0, + || Value::known(Fp::from(7u64)), + )?; + Ok(()) + }, + )?; + + Ok(()) + } + } + + // // At the start of your test, enable tracing. + // tracing_subscriber::fmt() + // .with_max_level(tracing::Level::DEBUG) + // .with_ansi(false) + // .without_time() + // .init(); + + let subscriber = tracing_subscriber::fmt() + .with_max_level(tracing::Level::DEBUG) + .with_ansi(false) + .without_time() + .finish(); + let storage = SharedStorage::default(); + let subscriber = subscriber.with(CaptureLayer::new(&storage)); + tracing::subscriber::set_global_default(subscriber).unwrap(); + + // run the prover to check if every step is traced. + let prover = MockProver::run(K, &TestCircuit {}, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + + // check if all tracing logs are captured + let storage = storage.lock(); + assert_eq!(storage.all_spans().len(), 12); + for span in storage.all_spans() { + let metadata = span.metadata(); + assert_eq!(*metadata.level(), tracing::Level::DEBUG); + } + } +}