WASM compatibility
Extracted all logs and timers calls to a separate file Added WASM specific logging and profiling
This commit is contained in:
parent
9819e9e08b
commit
4ed859e151
@ -27,6 +27,7 @@ num_cpus = {version = "1", optional = true}
|
||||
crossbeam = {version = "0.7.1", optional = true}
|
||||
|
||||
tiny-keccak = {version = "1.4.2", optional = true}
|
||||
web-sys = {version = "0.3.17", optional = true, features = ["console", "Performance", "Window"]}
|
||||
|
||||
[dependencies.blake2-rfc]
|
||||
git = "https://github.com/gtank/blake2-rfc"
|
||||
@ -35,8 +36,8 @@ rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9"
|
||||
[features]
|
||||
default = ["multicore"]
|
||||
#default = ["multicore", "gm17", "sonic"]
|
||||
#default = ["singlecore"]
|
||||
#default = ["wasm"]
|
||||
multicore = ["futures-cpupool", "num_cpus", "crossbeam"]
|
||||
sonic = ["tiny-keccak"]
|
||||
gm17 = []
|
||||
singlecore = []
|
||||
wasm = ["web-sys"]
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::super::verbose_flag;
|
||||
use crate::log::Stopwatch;
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
@ -187,8 +187,6 @@ pub fn generate_parameters<E, C>(
|
||||
) -> Result<Parameters<E>, SynthesisError>
|
||||
where E: Engine, C: Circuit<E>
|
||||
{
|
||||
let verbose = verbose_flag();
|
||||
|
||||
let mut assembly = KeypairAssembly {
|
||||
num_inputs: 0,
|
||||
num_aux: 0,
|
||||
@ -217,7 +215,7 @@ pub fn generate_parameters<E, C>(
|
||||
);
|
||||
}
|
||||
|
||||
if verbose {eprintln!("Making {} powers of tau", assembly.num_constraints)};
|
||||
elog_verbose!("Making {} powers of tau", assembly.num_constraints);
|
||||
// Create bases for blind evaluation of polynomials at tau
|
||||
let powers_of_tau = vec![Scalar::<E>(E::Fr::zero()); assembly.num_constraints];
|
||||
let mut powers_of_tau = EvaluationDomain::from_coeffs(powers_of_tau)?;
|
||||
@ -250,9 +248,9 @@ pub fn generate_parameters<E, C>(
|
||||
let mut h = vec![E::G1::zero(); powers_of_tau.as_ref().len() - 1];
|
||||
{
|
||||
// Compute powers of tau
|
||||
if verbose {eprintln!("computing powers of tau...")};
|
||||
elog_verbose!("computing powers of tau...");
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
{
|
||||
let powers_of_tau = powers_of_tau.as_mut();
|
||||
@ -270,15 +268,15 @@ pub fn generate_parameters<E, C>(
|
||||
}
|
||||
});
|
||||
}
|
||||
if verbose {eprintln!("powers of tau stage 1 done in {} s", start.elapsed().as_millis() as f64 / 1000.0);};
|
||||
elog_verbose!("powers of tau stage 1 done in {} s", stopwatch.elapsed());
|
||||
|
||||
// coeff = t(x) / delta
|
||||
let mut coeff = powers_of_tau.z(&tau);
|
||||
coeff.mul_assign(&delta_inverse);
|
||||
|
||||
if verbose {eprintln!("computing the H query with multiple threads...")};
|
||||
elog_verbose!("computing the H query with multiple threads...");
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
// Compute the H query with multiple threads
|
||||
worker.scope(h.len(), |scope, chunk| {
|
||||
@ -302,27 +300,26 @@ pub fn generate_parameters<E, C>(
|
||||
});
|
||||
}
|
||||
});
|
||||
if verbose {eprintln!("computing the H query done in {} s", start.elapsed().as_millis() as f64 / 1000.0);};
|
||||
elog_verbose!("computing the H query done in {} s", stopwatch.elapsed());
|
||||
}
|
||||
|
||||
if verbose {eprintln!("using inverse FFT to convert powers of tau to Lagrange coefficients...")};
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
elog_verbose!("using inverse FFT to convert powers of tau to Lagrange coefficients...");
|
||||
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
// Use inverse FFT to convert powers of tau to Lagrange coefficients
|
||||
powers_of_tau.ifft(&worker);
|
||||
let powers_of_tau = powers_of_tau.into_coeffs();
|
||||
|
||||
if verbose {eprintln!("powers of tau stage 2 done in {} s", start.elapsed().as_millis() as f64 / 1000.0)};
|
||||
|
||||
elog_verbose!("powers of tau stage 2 done in {} s", stopwatch.elapsed());
|
||||
let mut a = vec![E::G1::zero(); assembly.num_inputs + assembly.num_aux];
|
||||
let mut b_g1 = vec![E::G1::zero(); assembly.num_inputs + assembly.num_aux];
|
||||
let mut b_g2 = vec![E::G2::zero(); assembly.num_inputs + assembly.num_aux];
|
||||
let mut ic = vec![E::G1::zero(); assembly.num_inputs];
|
||||
let mut l = vec![E::G1::zero(); assembly.num_aux];
|
||||
|
||||
if verbose {eprintln!("evaluating polynomials...")};
|
||||
let start = std::time::Instant::now();
|
||||
elog_verbose!("evaluating polynomials...");
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
fn eval<E: Engine>(
|
||||
// wNAF window tables
|
||||
@ -475,7 +472,7 @@ pub fn generate_parameters<E, C>(
|
||||
&worker
|
||||
);
|
||||
|
||||
if verbose {eprintln!("evaluating polynomials done in {} s", start.elapsed().as_millis() as f64 / 1000.0);};
|
||||
elog_verbose!("evaluating polynomials done in {} s", stopwatch.elapsed());
|
||||
|
||||
// Don't allow any elements be unconstrained, so that
|
||||
// the L query is always fully dense.
|
||||
@ -498,7 +495,7 @@ pub fn generate_parameters<E, C>(
|
||||
ic: ic.into_iter().map(|e| e.into_affine()).collect()
|
||||
};
|
||||
|
||||
println!("Has generated {} points", a.len());
|
||||
log!("Has generated {} points", a.len());
|
||||
|
||||
Ok(Parameters {
|
||||
vk: vk,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::super::verbose_flag;
|
||||
use crate::log::Stopwatch;
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
@ -164,20 +164,18 @@ impl<E:Engine> PreparedProver<E> {
|
||||
s: E::Fr
|
||||
) -> Result<Proof<E>, SynthesisError>
|
||||
{
|
||||
let verbose = verbose_flag();
|
||||
|
||||
let prover = self.assignment.clone();
|
||||
let worker = Worker::new();
|
||||
|
||||
let vk = params.get_vk(self.assignment.input_assignment.len())?;
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
let h = {
|
||||
let mut a = EvaluationDomain::from_coeffs(prover.a)?;
|
||||
let mut b = EvaluationDomain::from_coeffs(prover.b)?;
|
||||
let mut c = EvaluationDomain::from_coeffs(prover.c)?;
|
||||
if verbose {eprintln!("H query domain size is {}", a.as_ref().len())};
|
||||
elog_verbose!("H query domain size is {}", a.as_ref().len());
|
||||
|
||||
// here a coset is a domain where denominator (z) does not vanish
|
||||
// inverse FFT is an interpolation
|
||||
@ -209,9 +207,9 @@ impl<E:Engine> PreparedProver<E> {
|
||||
multiexp(&worker, params.get_h(a.len())?, FullDensity, a)
|
||||
};
|
||||
|
||||
if verbose {eprintln!("{} seconds for prover for H evaluation (mostly FFT)", start.elapsed().as_millis() as f64 / 1000.0)};
|
||||
elog_verbose!("{} seconds for prover for H evaluation (mostly FFT)", stopwatch.elapsed());
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
// TODO: Check that difference in operations for different chunks is small
|
||||
|
||||
@ -222,9 +220,8 @@ impl<E:Engine> PreparedProver<E> {
|
||||
|
||||
let input_len = input_assignment.len();
|
||||
let aux_len = aux_assignment.len();
|
||||
if verbose {eprintln!("H query is dense in G1,\nOther queries are {} elements in G1 and {} elements in G2",
|
||||
2*(input_len + aux_len) + aux_len, input_len + aux_len)
|
||||
};
|
||||
elog_verbose!("H query is dense in G1,\nOther queries are {} elements in G1 and {} elements in G2",
|
||||
2*(input_len + aux_len) + aux_len, input_len + aux_len);
|
||||
|
||||
// Run a dedicated process for dense vector
|
||||
let l = multiexp(&worker, params.get_l(aux_assignment.len())?, FullDensity, aux_assignment.clone());
|
||||
@ -287,7 +284,7 @@ impl<E:Engine> PreparedProver<E> {
|
||||
g_c.add_assign(&h.wait()?);
|
||||
g_c.add_assign(&l.wait()?);
|
||||
|
||||
if verbose {eprintln!("{} seconds for prover for point multiplication", start.elapsed().as_millis() as f64 / 1000.0)};
|
||||
elog_verbose!("{} seconds for prover for point multiplication", stopwatch.elapsed());
|
||||
|
||||
Ok(Proof {
|
||||
a: g_a.into_affine(),
|
||||
@ -411,8 +408,6 @@ pub fn create_proof<E, C, P: ParameterSource<E>>(
|
||||
) -> Result<Proof<E>, SynthesisError>
|
||||
where E: Engine, C: Circuit<E>
|
||||
{
|
||||
let verbose = verbose_flag();
|
||||
|
||||
let mut prover = ProvingAssignment {
|
||||
a_aux_density: DensityTracker::new(),
|
||||
b_input_density: DensityTracker::new(),
|
||||
@ -440,13 +435,13 @@ pub fn create_proof<E, C, P: ParameterSource<E>>(
|
||||
|
||||
let vk = params.get_vk(prover.input_assignment.len())?;
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
let h = {
|
||||
let mut a = EvaluationDomain::from_coeffs(prover.a)?;
|
||||
let mut b = EvaluationDomain::from_coeffs(prover.b)?;
|
||||
let mut c = EvaluationDomain::from_coeffs(prover.c)?;
|
||||
if verbose {eprintln!("H query domain size is {}", a.as_ref().len())};
|
||||
elog_verbose!("H query domain size is {}", a.as_ref().len());
|
||||
// here a coset is a domain where denominator (z) does not vanish
|
||||
// inverse FFT is an interpolation
|
||||
a.ifft(&worker);
|
||||
@ -477,9 +472,9 @@ pub fn create_proof<E, C, P: ParameterSource<E>>(
|
||||
multiexp(&worker, params.get_h(a.len())?, FullDensity, a)
|
||||
};
|
||||
|
||||
if verbose {eprintln!("{} seconds for prover for H evaluation (mostly FFT)", start.elapsed().as_millis() as f64 / 1000.0)};
|
||||
elog_verbose!("{} seconds for prover for H evaluation (mostly FFT)", stopwatch.elapsed());
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
// TODO: Check that difference in operations for different chunks is small
|
||||
|
||||
@ -549,7 +544,7 @@ pub fn create_proof<E, C, P: ParameterSource<E>>(
|
||||
g_c.add_assign(&h.wait()?);
|
||||
g_c.add_assign(&l.wait()?);
|
||||
|
||||
if verbose {eprintln!("{} seconds for prover for point multiplication", start.elapsed().as_millis() as f64 / 1000.0)};
|
||||
elog_verbose!("{} seconds for prover for point multiplication", stopwatch.elapsed());
|
||||
|
||||
Ok(Proof {
|
||||
a: g_a.into_affine(),
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![allow(unused_imports)]
|
||||
#![allow(unused_macros)]
|
||||
#[macro_use]
|
||||
|
||||
extern crate cfg_if;
|
||||
@ -7,6 +8,9 @@ extern crate rand;
|
||||
extern crate bit_vec;
|
||||
extern crate byteorder;
|
||||
|
||||
#[macro_use]
|
||||
mod log;
|
||||
|
||||
pub mod domain;
|
||||
pub mod groth16;
|
||||
|
||||
@ -43,6 +47,7 @@ pub mod pairing {
|
||||
mod cs;
|
||||
pub use self::cs::*;
|
||||
|
||||
// todo move to log module after removing all references
|
||||
static mut VERBOSE_SWITCH: i8 = -1;
|
||||
|
||||
use std::str::FromStr;
|
||||
|
70
src/log.rs
Normal file
70
src/log.rs
Normal file
@ -0,0 +1,70 @@
|
||||
#[allow(unused_macros)]
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "wasm")] {
|
||||
use web_sys;
|
||||
use web_sys::Performance;
|
||||
|
||||
macro_rules! log {
|
||||
($($t:tt)*) => (web_sys::console::log_1(&format_args!($($t)*).to_string().into()))
|
||||
}
|
||||
|
||||
macro_rules! elog {
|
||||
($($t:tt)*) => (web_sys::console::log_1(&format_args!($($t)*).to_string().into()))
|
||||
}
|
||||
|
||||
macro_rules! log_verbose {
|
||||
($($t:tt)*) => (if $crate::verbose_flag() { web_sys::console::log_1(&format_args!($($t)*).to_string().into()) })
|
||||
}
|
||||
|
||||
macro_rules! elog_verbose {
|
||||
($($t:tt)*) => (if $crate::verbose_flag() { web_sys::console::log_1(&format_args!($($t)*).to_string().into()) })
|
||||
}
|
||||
|
||||
pub struct Stopwatch {
|
||||
start: f64,
|
||||
perf: Performance
|
||||
}
|
||||
|
||||
impl Stopwatch {
|
||||
pub fn new() -> Stopwatch {
|
||||
let perf = web_sys::window().unwrap().performance().unwrap();
|
||||
Stopwatch { start: perf.now(), perf }
|
||||
}
|
||||
|
||||
pub fn elapsed(&self) -> f64 {
|
||||
(self.perf.now() - self.start) / 1000.0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
macro_rules! log {
|
||||
($($t:tt)*) => (println!("{}", &format_args!($($t)*).to_string()))
|
||||
}
|
||||
|
||||
macro_rules! elog {
|
||||
($($t:tt)*) => (println!("{}", &format_args!($($t)*).to_string()))
|
||||
}
|
||||
|
||||
macro_rules! log_verbose {
|
||||
($($t:tt)*) => (if $crate::verbose_flag() { println!("{}", &format_args!($($t)*).to_string()) })
|
||||
}
|
||||
|
||||
macro_rules! elog_verbose {
|
||||
($($t:tt)*) => (if $crate::verbose_flag() { println!("{}", &format_args!($($t)*).to_string()) })
|
||||
}
|
||||
|
||||
pub struct Stopwatch {
|
||||
start: std::time::Instant
|
||||
}
|
||||
|
||||
impl Stopwatch {
|
||||
pub fn new() -> Stopwatch {
|
||||
Stopwatch { start: std::time::Instant::now() }
|
||||
}
|
||||
|
||||
pub fn elapsed(&self) -> f64 {
|
||||
self.start.elapsed().as_millis() as f64 / 1000.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user