From 36899251cc88a44f099bfe3ece7ef0af9ad85c25 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Mon, 27 Feb 2023 16:24:30 +0100 Subject: [PATCH 1/4] chore: Speed up random poly generation As noted in https://github.com/privacy-scaling-explorations/halo2/issues/151 the generation of a random poly for degrees bigger than 20 starts to get quite slow. This PR tries to include some minimal changes in the `commit` fn so that we upstream the improvements achieved in PSE/halo2 --- halo2_proofs/Cargo.toml | 3 +- halo2_proofs/src/plonk/vanishing/prover.rs | 50 +++++++++++++++++++--- halo2_proofs/src/poly.rs | 8 ++++ halo2_proofs/src/poly/domain.rs | 2 +- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/halo2_proofs/Cargo.toml b/halo2_proofs/Cargo.toml index 86298bd255..3299dda9af 100644 --- a/halo2_proofs/Cargo.toml +++ b/halo2_proofs/Cargo.toml @@ -52,6 +52,7 @@ rand_core = { version = "0.6", default-features = false } tracing = "0.1" blake2b_simd = "1" maybe-rayon = {version = "0.1.0", default-features = false} +rand_chacha = { version = "0.3", optional = true } # Developer tooling dependencies plotters = { version = "0.3.0", default-features = false, optional = true } @@ -69,7 +70,7 @@ getrandom = { version = "0.2", features = ["js"] } [features] default = ["batch", "multicore"] -multicore = ["maybe-rayon/threads"] +multicore = ["maybe-rayon/threads", "rand_chacha"] dev-graph = ["plotters", "tabbycat"] test-dev-graph = [ "dev-graph", diff --git a/halo2_proofs/src/plonk/vanishing/prover.rs b/halo2_proofs/src/plonk/vanishing/prover.rs index 15b90f1c94..8ccfb2a99e 100644 --- a/halo2_proofs/src/plonk/vanishing/prover.rs +++ b/halo2_proofs/src/plonk/vanishing/prover.rs @@ -2,7 +2,15 @@ use std::iter; use ff::Field; use group::Curve; -use rand_core::RngCore; +#[cfg(feature = "multicore")] +use maybe_rayon::{ + current_num_threads, + prelude::{IntoParallelRefMutIterator, ParallelIterator}, +}; +#[cfg(feature = "multicore")] +use rand_chacha::ChaCha20Rng; +#[cfg(feature = "multicore")] +use rand_core::{RngCore, SeedableRng}; use super::Argument; use crate::{ @@ -42,10 +50,42 @@ impl Argument { transcript: &mut T, ) -> Result, Error> { // Sample a random polynomial of degree n - 1 - let mut random_poly = domain.empty_coeff(); - for coeff in random_poly.iter_mut() { - *coeff = C::Scalar::random(&mut rng); - } + #[cfg(feature = "multicore")] + let random_poly = { + let n_threads = current_num_threads(); + let needed_scalars = (1usize << domain.k as usize) / n_threads; + + let mut thread_seeds: Vec = (0..n_threads) + .into_iter() + .map(|_| { + let mut seed = [0u8; 32]; + rng.fill_bytes(&mut seed); + ChaCha20Rng::from_seed(seed) + }) + .collect(); + + let rand_vec: Vec = thread_seeds + .par_iter_mut() + .flat_map(|mut rng| { + (0..needed_scalars) + .into_iter() + .map(|_| C::Scalar::random(&mut rng)) + .collect::>() + }) + .collect(); + + Polynomial::::from_evals(rand_vec) + }; + + #[cfg(not(feature = "multicore"))] + let random_poly = { + let mut random_poly = domain.empty_coeff(); + for coeff in random_poly.iter_mut() { + *coeff = C::Scalar::random(&mut rng); + } + random_poly + }; + // Sample a random blinding factor let random_blind = Blind(C::Scalar::random(rng)); diff --git a/halo2_proofs/src/poly.rs b/halo2_proofs/src/poly.rs index f8f6784f32..772fd3c15d 100644 --- a/halo2_proofs/src/poly.rs +++ b/halo2_proofs/src/poly.rs @@ -130,6 +130,14 @@ impl Polynomial { pub fn num_coeffs(&self) -> usize { self.values.len() } + + /// Allows to create a Polynomial from a Vec. + pub fn from_evals(vector: Vec) -> Self { + Polynomial { + values: vector, + _marker: PhantomData, + } + } } pub(crate) fn batch_invert_assigned( diff --git a/halo2_proofs/src/poly/domain.rs b/halo2_proofs/src/poly/domain.rs index fb76af653c..4c04efceaf 100644 --- a/halo2_proofs/src/poly/domain.rs +++ b/halo2_proofs/src/poly/domain.rs @@ -19,7 +19,7 @@ use std::marker::PhantomData; #[derive(Clone, Debug)] pub struct EvaluationDomain { n: u64, - k: u32, + pub(crate) k: u32, extended_k: u32, omega: F, omega_inv: F, From e49cf60f59e3531d1f5a75863f3410685ed86337 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Mon, 27 Feb 2023 16:39:02 +0100 Subject: [PATCH 2/4] fix: Split RngCore and SeedableRng imports --- halo2_proofs/src/plonk/vanishing/prover.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/halo2_proofs/src/plonk/vanishing/prover.rs b/halo2_proofs/src/plonk/vanishing/prover.rs index 8ccfb2a99e..af36bace7b 100644 --- a/halo2_proofs/src/plonk/vanishing/prover.rs +++ b/halo2_proofs/src/plonk/vanishing/prover.rs @@ -10,7 +10,9 @@ use maybe_rayon::{ #[cfg(feature = "multicore")] use rand_chacha::ChaCha20Rng; #[cfg(feature = "multicore")] -use rand_core::{RngCore, SeedableRng}; +use rand_core::SeedableRng; + +use rand_core::RngCore; use super::Argument; use crate::{ From a4cc9f60e0b9328186783f5f29c3300605cbea92 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Tue, 28 Feb 2023 09:13:15 +0100 Subject: [PATCH 3/4] fix: Upstream concurrent poly generation fixes --- halo2_proofs/src/plonk/vanishing/prover.rs | 34 ++++++++++------------ halo2_proofs/src/poly/domain.rs | 7 ++++- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/halo2_proofs/src/plonk/vanishing/prover.rs b/halo2_proofs/src/plonk/vanishing/prover.rs index af36bace7b..e6bd0f594f 100644 --- a/halo2_proofs/src/plonk/vanishing/prover.rs +++ b/halo2_proofs/src/plonk/vanishing/prover.rs @@ -2,18 +2,15 @@ use std::iter; use ff::Field; use group::Curve; +use rand_core::RngCore; + #[cfg(feature = "multicore")] -use maybe_rayon::{ - current_num_threads, - prelude::{IntoParallelRefMutIterator, ParallelIterator}, -}; +use maybe_rayon::{current_num_threads, prelude::*}; #[cfg(feature = "multicore")] use rand_chacha::ChaCha20Rng; #[cfg(feature = "multicore")] use rand_core::SeedableRng; -use rand_core::RngCore; - use super::Argument; use crate::{ arithmetic::{eval_polynomial, CurveAffine}, @@ -55,9 +52,11 @@ impl Argument { #[cfg(feature = "multicore")] let random_poly = { let n_threads = current_num_threads(); - let needed_scalars = (1usize << domain.k as usize) / n_threads; + let n = 1usize << domain.k() as usize; + let n_chunks = n_threads + if n % n_threads != 0 { 1 } else { 0 }; + let mut rand_vec = vec![C::Scalar::ZERO; n]; - let mut thread_seeds: Vec = (0..n_threads) + let mut thread_seeds: Vec = (0..n_chunks) .into_iter() .map(|_| { let mut seed = [0u8; 32]; @@ -66,17 +65,16 @@ impl Argument { }) .collect(); - let rand_vec: Vec = thread_seeds + thread_seeds .par_iter_mut() - .flat_map(|mut rng| { - (0..needed_scalars) - .into_iter() - .map(|_| C::Scalar::random(&mut rng)) - .collect::>() - }) - .collect(); - - Polynomial::::from_evals(rand_vec) + .zip_eq(rand_vec.par_chunks_mut(n / n_threads)) + .for_each(|(mut rng, chunk)| { + chunk + .iter_mut() + .for_each(|v| *v = C::Scalar::random(&mut rng)) + }); + + domain.coeff_from_vec(rand_vec) }; #[cfg(not(feature = "multicore"))] diff --git a/halo2_proofs/src/poly/domain.rs b/halo2_proofs/src/poly/domain.rs index 4c04efceaf..ee7f302cd1 100644 --- a/halo2_proofs/src/poly/domain.rs +++ b/halo2_proofs/src/poly/domain.rs @@ -19,7 +19,7 @@ use std::marker::PhantomData; #[derive(Clone, Debug)] pub struct EvaluationDomain { n: u64, - pub(crate) k: u32, + k: u32, extended_k: u32, omega: F, omega_inv: F, @@ -142,6 +142,11 @@ impl> EvaluationDomain { } } + /// Returns the `k` or Degree associated to the domain. + pub(crate) fn k(&self) -> usize { + self.k as usize + } + /// Obtains a polynomial in Lagrange form when given a vector of Lagrange /// coefficients of size `n`; panics if the provided vector is the wrong /// length. From 580d982a642b2a9a86e531deed476feb72516388 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Tue, 28 Feb 2023 09:20:23 +0100 Subject: [PATCH 4/4] chore: Update `k` to be obtained from struct --- halo2_proofs/src/plonk/vanishing/prover.rs | 2 +- halo2_proofs/src/poly.rs | 8 -------- halo2_proofs/src/poly/domain.rs | 7 +------ 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/halo2_proofs/src/plonk/vanishing/prover.rs b/halo2_proofs/src/plonk/vanishing/prover.rs index e6bd0f594f..46b41e84db 100644 --- a/halo2_proofs/src/plonk/vanishing/prover.rs +++ b/halo2_proofs/src/plonk/vanishing/prover.rs @@ -52,7 +52,7 @@ impl Argument { #[cfg(feature = "multicore")] let random_poly = { let n_threads = current_num_threads(); - let n = 1usize << domain.k() as usize; + let n = 1usize << domain.k as usize; let n_chunks = n_threads + if n % n_threads != 0 { 1 } else { 0 }; let mut rand_vec = vec![C::Scalar::ZERO; n]; diff --git a/halo2_proofs/src/poly.rs b/halo2_proofs/src/poly.rs index 772fd3c15d..f8f6784f32 100644 --- a/halo2_proofs/src/poly.rs +++ b/halo2_proofs/src/poly.rs @@ -130,14 +130,6 @@ impl Polynomial { pub fn num_coeffs(&self) -> usize { self.values.len() } - - /// Allows to create a Polynomial from a Vec. - pub fn from_evals(vector: Vec) -> Self { - Polynomial { - values: vector, - _marker: PhantomData, - } - } } pub(crate) fn batch_invert_assigned( diff --git a/halo2_proofs/src/poly/domain.rs b/halo2_proofs/src/poly/domain.rs index ee7f302cd1..4c04efceaf 100644 --- a/halo2_proofs/src/poly/domain.rs +++ b/halo2_proofs/src/poly/domain.rs @@ -19,7 +19,7 @@ use std::marker::PhantomData; #[derive(Clone, Debug)] pub struct EvaluationDomain { n: u64, - k: u32, + pub(crate) k: u32, extended_k: u32, omega: F, omega_inv: F, @@ -142,11 +142,6 @@ impl> EvaluationDomain { } } - /// Returns the `k` or Degree associated to the domain. - pub(crate) fn k(&self) -> usize { - self.k as usize - } - /// Obtains a polynomial in Lagrange form when given a vector of Lagrange /// coefficients of size `n`; panics if the provided vector is the wrong /// length.