From 73507a2301dd443ad70a8ca347ee1c23089890de Mon Sep 17 00:00:00 2001 From: Alexander Camuto Date: Tue, 17 Oct 2023 12:35:52 +0100 Subject: [PATCH 1/8] feat: allow for lookup overflow in calibration --- benches/accum_matmul_relu_overflow.rs | 2 +- src/graph/mod.rs | 21 ++------------------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/benches/accum_matmul_relu_overflow.rs b/benches/accum_matmul_relu_overflow.rs index 8d6d10f35..3c7675837 100644 --- a/benches/accum_matmul_relu_overflow.rs +++ b/benches/accum_matmul_relu_overflow.rs @@ -92,7 +92,7 @@ impl Circuit for MyCircuit { fn runmatmul(c: &mut Criterion) { let mut group = c.benchmark_group("accum_matmul"); - for &k in [8, 10, 12, 14].iter() { + for &k in [8, 10, 11, 12, 13, 14].iter() { let len = unsafe { LEN }; unsafe { K = k; diff --git a/src/graph/mod.rs b/src/graph/mod.rs index 34161f2f3..f9faaadde 100644 --- a/src/graph/mod.rs +++ b/src/graph/mod.rs @@ -23,7 +23,7 @@ use self::modules::{ }; use crate::circuit::lookup::LookupOp; use crate::circuit::modules::ModulePlanner; -use crate::circuit::table::{Table, RANGE_MULTIPLIER, RESERVED_BLINDING_ROWS_PAD}; +use crate::circuit::table::{RANGE_MULTIPLIER, RESERVED_BLINDING_ROWS_PAD}; use crate::circuit::{CheckMode, InputType}; use crate::tensor::{Tensor, ValTensor}; use crate::RunArgs; @@ -703,12 +703,7 @@ impl GraphCircuit { let (_, client) = setup_eth_backend(Some(&source.rpc), None).await?; let inputs = read_on_chain_inputs(client.clone(), client.address(), &source.calls).await?; // quantize the supplied data using the provided scale + QuantizeData.sol - let quantized_evm_inputs = evm_quantize( - client, - scales, - &inputs, - ) - .await?; + let quantized_evm_inputs = evm_quantize(client, scales, &inputs).await?; // on-chain data has already been quantized at this point. Just need to reshape it and push into tensor vector let mut inputs: Vec> = vec![]; for (input, shape) in [quantized_evm_inputs].iter().zip(shapes) { @@ -784,18 +779,6 @@ impl GraphCircuit { let reserved_blinding_rows = Self::reserved_blinding_rows(); let safe_range = Self::calc_safe_range(res); - let max_col_size = - Table::::cal_col_size(MAX_PUBLIC_SRS as usize, reserved_blinding_rows as usize); - let num_cols = Table::::num_cols_required(safe_range, max_col_size); - - if num_cols > 1 { - let err_string = format!( - "No possible lookup range can accomodate max value min and max value ({}, {})", - safe_range.0, safe_range.1 - ); - return Err(err_string.into()); - } - let min_bits = ((safe_range.1 - safe_range.0) as f64 + reserved_blinding_rows + 1.) .log2() .ceil() as usize; From d993171055c5542bfa53905344a0f4561eac6f01 Mon Sep 17 00:00:00 2001 From: Alexander Camuto Date: Tue, 17 Oct 2023 12:57:51 +0100 Subject: [PATCH 2/8] Update mod.rs --- src/graph/mod.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/graph/mod.rs b/src/graph/mod.rs index f9faaadde..7876d758c 100644 --- a/src/graph/mod.rs +++ b/src/graph/mod.rs @@ -23,7 +23,7 @@ use self::modules::{ }; use crate::circuit::lookup::LookupOp; use crate::circuit::modules::ModulePlanner; -use crate::circuit::table::{RANGE_MULTIPLIER, RESERVED_BLINDING_ROWS_PAD}; +use crate::circuit::table::{Table, RANGE_MULTIPLIER, RESERVED_BLINDING_ROWS_PAD}; use crate::circuit::{CheckMode, InputType}; use crate::tensor::{Tensor, ValTensor}; use crate::RunArgs; @@ -779,6 +779,19 @@ impl GraphCircuit { let reserved_blinding_rows = Self::reserved_blinding_rows(); let safe_range = Self::calc_safe_range(res); + let max_col_size = + Table::::cal_col_size(MAX_PUBLIC_SRS as usize, reserved_blinding_rows as usize); + let num_cols = Table::::num_cols_required(safe_range, max_col_size); + + // empirically determined that this is when performance starts to degrade + if num_cols > 4 { + let err_string = format!( + "No possible lookup range can accomodate max value min and max value ({}, {})", + safe_range.0, safe_range.1 + ); + return Err(err_string.into()); + } + let min_bits = ((safe_range.1 - safe_range.0) as f64 + reserved_blinding_rows + 1.) .log2() .ceil() as usize; From ed769b004652ded2322ca7241e8a6508cd3d7d28 Mon Sep 17 00:00:00 2001 From: Alexander Camuto Date: Tue, 17 Oct 2023 12:58:08 +0100 Subject: [PATCH 3/8] Update mod.rs --- src/graph/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graph/mod.rs b/src/graph/mod.rs index 7876d758c..a9e41572e 100644 --- a/src/graph/mod.rs +++ b/src/graph/mod.rs @@ -784,7 +784,7 @@ impl GraphCircuit { let num_cols = Table::::num_cols_required(safe_range, max_col_size); // empirically determined that this is when performance starts to degrade - if num_cols > 4 { + if num_cols > 5 { let err_string = format!( "No possible lookup range can accomodate max value min and max value ({}, {})", safe_range.0, safe_range.1 From b3f11a5a0b746aabc9cd008fb86a321f2a0c58fc Mon Sep 17 00:00:00 2001 From: Alexander Camuto Date: Tue, 17 Oct 2023 13:16:00 +0100 Subject: [PATCH 4/8] bump amount --- src/circuit/ops/mod.rs | 8 ++++++++ src/execute.rs | 14 +++++++++++++- src/graph/mod.rs | 4 ++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/circuit/ops/mod.rs b/src/circuit/ops/mod.rs index c91429cd7..f072b438b 100644 --- a/src/circuit/ops/mod.rs +++ b/src/circuit/ops/mod.rs @@ -125,6 +125,14 @@ pub enum InputType { } impl InputType { + /// + pub fn is_integer(&self) -> bool { + match self { + InputType::Bool | InputType::Int | InputType::TDim => true, + _ => false, + } + } + /// pub fn roundtrip(&self, input: &mut T) { match self { diff --git a/src/execute.rs b/src/execute.rs index a916e7a2b..4bdf11aec 100644 --- a/src/execute.rs +++ b/src/execute.rs @@ -597,11 +597,23 @@ pub(crate) async fn calibrate( .collect::>(); // remove all entries where input_scale > param_scale - let range_grid = range_grid + let mut range_grid = range_grid .into_iter() .filter(|(a, b)| a <= b) .collect::>(); + // if all integers + let all_scale_0 = model.graph.get_input_types().iter().all(|t| t.is_integer()); + if all_scale_0 { + // set all a values to 0 then dedup + range_grid = range_grid + .iter() + .map(|(_, b)| (0, *b)) + .sorted() + .dedup() + .collect::>(); + } + let range_grid = range_grid .iter() .cartesian_product(scale_rebase_multiplier.iter()) diff --git a/src/graph/mod.rs b/src/graph/mod.rs index a9e41572e..9afded75e 100644 --- a/src/graph/mod.rs +++ b/src/graph/mod.rs @@ -783,8 +783,8 @@ impl GraphCircuit { Table::::cal_col_size(MAX_PUBLIC_SRS as usize, reserved_blinding_rows as usize); let num_cols = Table::::num_cols_required(safe_range, max_col_size); - // empirically determined that this is when performance starts to degrade - if num_cols > 5 { + // empirically determined that this is when performance starts to degrade significantly + if num_cols > 7 { let err_string = format!( "No possible lookup range can accomodate max value min and max value ({}, {})", safe_range.0, safe_range.1 From a8b689380d43c549cd179239556b3cbaaa9a914d Mon Sep 17 00:00:00 2001 From: Alexander Camuto Date: Tue, 17 Oct 2023 13:25:15 +0100 Subject: [PATCH 5/8] Update chip.rs --- src/circuit/ops/chip.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/circuit/ops/chip.rs b/src/circuit/ops/chip.rs index 307d2422b..525521379 100644 --- a/src/circuit/ops/chip.rs +++ b/src/circuit/ops/chip.rs @@ -366,12 +366,12 @@ impl BaseConfig { let (default_x, default_y) = table.get_first_element(col_idx); - log::debug!("---------------- col {:?} ------------------", col_idx,); - log::debug!("expr: {:?}", col_expr,); - log::debug!("multiplier: {:?}", multiplier); - log::debug!("not_expr: {:?}", not_expr); - log::debug!("default x: {:?}", default_x); - log::debug!("default y: {:?}", default_y); + log::trace!("---------------- col {:?} ------------------", col_idx,); + log::trace!("expr: {:?}", col_expr,); + log::trace!("multiplier: {:?}", multiplier); + log::trace!("not_expr: {:?}", not_expr); + log::trace!("default x: {:?}", default_x); + log::trace!("default y: {:?}", default_y); res.extend([ ( From ea2b6cdb019881fa733fae8e98e1a85bd0a893a3 Mon Sep 17 00:00:00 2001 From: Alexander Camuto Date: Tue, 17 Oct 2023 13:33:11 +0100 Subject: [PATCH 6/8] add logrow cap --- src/commands.rs | 3 +++ src/execute.rs | 6 ++++-- src/graph/mod.rs | 28 ++++++++++++++++++++-------- src/python.rs | 6 ++++++ 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index a987239fa..6ba90cfea 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -246,6 +246,9 @@ pub enum Commands { /// Optional scales to specifically try for calibration. #[arg(long, value_delimiter = ',')] scales: Option>, + /// max logrows to use for calibration, 26 is the max public SRS size + #[arg(long)] + max_logrows: Option, }, /// Generates a dummy SRS diff --git a/src/execute.rs b/src/execute.rs index 4bdf11aec..fdfbb82f9 100644 --- a/src/execute.rs +++ b/src/execute.rs @@ -147,7 +147,8 @@ pub async fn run(cli: Cli) -> Result<(), Box> { data, target, scales, - } => calibrate(model, data, settings_path, target, scales).await, + max_logrows, + } => calibrate(model, data, settings_path, target, scales, max_logrows).await, Commands::GenWitness { data, compiled_circuit, @@ -561,6 +562,7 @@ pub(crate) async fn calibrate( settings_path: PathBuf, target: CalibrationTarget, scales: Option>, + max_logrows: Option, ) -> Result<(), Box> { let data = GraphData::from_path(data)?; // load the pre-generated settings @@ -669,7 +671,7 @@ pub(crate) async fn calibrate( .map_err(|e| format!("failed to load circuit inputs: {}", e))?; circuit - .calibrate(&data) + .calibrate(&data, max_logrows) .map_err(|e| format!("failed to calibrate: {}", e))?; let settings = circuit.settings().clone(); diff --git a/src/graph/mod.rs b/src/graph/mod.rs index 9afded75e..1122a0b75 100644 --- a/src/graph/mod.rs +++ b/src/graph/mod.rs @@ -105,7 +105,7 @@ const ASSUMED_BLINDING_FACTORS: usize = 5; pub const MIN_LOGROWS: u32 = 4; /// 26 -const MAX_PUBLIC_SRS: u32 = bn256::Fr::S - 2; +pub const MAX_PUBLIC_SRS: u32 = bn256::Fr::S - 2; use std::cell::RefCell; @@ -775,12 +775,21 @@ impl GraphCircuit { ) } - fn calc_min_logrows(&mut self, res: &GraphWitness) -> Result<(), Box> { + fn calc_min_logrows( + &mut self, + res: &GraphWitness, + max_logrows: Option, + ) -> Result<(), Box> { + // load the max logrows + let max_logrows = max_logrows.unwrap_or(MAX_PUBLIC_SRS); + let max_logrows = std::cmp::min(max_logrows, MAX_PUBLIC_SRS); + let max_logrows = std::cmp::max(max_logrows, MIN_LOGROWS); + let reserved_blinding_rows = Self::reserved_blinding_rows(); let safe_range = Self::calc_safe_range(res); let max_col_size = - Table::::cal_col_size(MAX_PUBLIC_SRS as usize, reserved_blinding_rows as usize); + Table::::cal_col_size(max_logrows as usize, reserved_blinding_rows as usize); let num_cols = Table::::num_cols_required(safe_range, max_col_size); // empirically determined that this is when performance starts to degrade significantly @@ -830,7 +839,7 @@ impl GraphCircuit { // ensure logrows is at least 4 logrows = std::cmp::max(logrows, MIN_LOGROWS as usize); - logrows = std::cmp::min(logrows, MAX_PUBLIC_SRS as usize); + logrows = std::cmp::min(logrows, max_logrows as usize); let model = self.model().clone(); let settings_mut = self.settings_mut(); settings_mut.run_args.lookup_range = safe_range; @@ -853,8 +862,7 @@ impl GraphCircuit { settings_mut.run_args.logrows = std::cmp::max(settings_mut.run_args.logrows, min_rows_from_constraints); - settings_mut.run_args.logrows = - std::cmp::min(MAX_PUBLIC_SRS, settings_mut.run_args.logrows); + settings_mut.run_args.logrows = std::cmp::min(max_logrows, settings_mut.run_args.logrows); info!( "setting lookup_range to: {:?}, setting logrows to: {}", @@ -866,10 +874,14 @@ impl GraphCircuit { } /// Calibrate the circuit to the supplied data. - pub fn calibrate(&mut self, input: &[Tensor]) -> Result<(), Box> { + pub fn calibrate( + &mut self, + input: &[Tensor], + max_logrows: Option, + ) -> Result<(), Box> { let res = self.forward(&mut input.to_vec())?; - self.calc_min_logrows(&res) + self.calc_min_logrows(&res, max_logrows) } /// Runs the forward pass of the model / graph of computations and any associated hashing. diff --git a/src/python.rs b/src/python.rs index f752cfac7..fa5b1c045 100644 --- a/src/python.rs +++ b/src/python.rs @@ -8,6 +8,7 @@ use crate::circuit::{CheckMode, Tolerance}; use crate::commands::CalibrationTarget; use crate::fieldutils::{felt_to_i128, i128_to_felt}; use crate::graph::modules::POSEIDON_LEN_GRAPH; +use crate::graph::MAX_PUBLIC_SRS; use crate::graph::{ quantize_float, scale_to_multiplier, GraphCircuit, GraphSettings, Model, Visibility, }; @@ -624,6 +625,7 @@ fn gen_settings( settings, target, scales = None, + max_logrows = None, ))] fn calibrate_settings( py: Python, @@ -632,10 +634,14 @@ fn calibrate_settings( settings: PathBuf, target: Option, scales: Option>, + max_logrows: Option, ) -> PyResult<&pyo3::PyAny> { let target = target.unwrap_or(CalibrationTarget::Resources { col_overflow: false, }); + + let max_logrows = max_logrows.unwrap_or(MAX_PUBLIC_SRS); + pyo3_asyncio::tokio::future_into_py(py, async move { crate::execute::calibrate(model, data, settings, target, scales) .await From 07206dd5fddbe981def56b5018a6806215d2c929 Mon Sep 17 00:00:00 2001 From: Alexander Camuto Date: Tue, 17 Oct 2023 13:38:01 +0100 Subject: [PATCH 7/8] Update python.rs --- src/python.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/python.rs b/src/python.rs index fa5b1c045..6b3ea81fc 100644 --- a/src/python.rs +++ b/src/python.rs @@ -8,7 +8,6 @@ use crate::circuit::{CheckMode, Tolerance}; use crate::commands::CalibrationTarget; use crate::fieldutils::{felt_to_i128, i128_to_felt}; use crate::graph::modules::POSEIDON_LEN_GRAPH; -use crate::graph::MAX_PUBLIC_SRS; use crate::graph::{ quantize_float, scale_to_multiplier, GraphCircuit, GraphSettings, Model, Visibility, }; @@ -640,10 +639,8 @@ fn calibrate_settings( col_overflow: false, }); - let max_logrows = max_logrows.unwrap_or(MAX_PUBLIC_SRS); - pyo3_asyncio::tokio::future_into_py(py, async move { - crate::execute::calibrate(model, data, settings, target, scales) + crate::execute::calibrate(model, data, settings, target, scales, max_logrows) .await .map_err(|e| { let err_str = format!("Failed to calibrate settings: {}", e); From 89c05de945dec17b4e97952d6b375cf00e887ecb Mon Sep 17 00:00:00 2001 From: Alexander Camuto Date: Tue, 17 Oct 2023 14:15:38 +0100 Subject: [PATCH 8/8] reduce by 1 --- src/graph/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graph/mod.rs b/src/graph/mod.rs index 1122a0b75..871c50008 100644 --- a/src/graph/mod.rs +++ b/src/graph/mod.rs @@ -793,7 +793,7 @@ impl GraphCircuit { let num_cols = Table::::num_cols_required(safe_range, max_col_size); // empirically determined that this is when performance starts to degrade significantly - if num_cols > 7 { + if num_cols > 3 { let err_string = format!( "No possible lookup range can accomodate max value min and max value ({}, {})", safe_range.0, safe_range.1