diff --git a/prover/Cargo.lock b/prover/Cargo.lock index b4d25a191ff0..cdada054703e 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -2914,6 +2914,18 @@ dependencies = [ "hashbrown 0.14.3", ] +[[package]] +name = "indicatif" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b" +dependencies = [ + "console", + "lazy_static", + "number_prefix", + "regex", +] + [[package]] name = "ipnet" version = "2.9.0" @@ -3886,6 +3898,12 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "object" version = "0.32.2" @@ -7069,6 +7087,7 @@ dependencies = [ "circuit_definitions 1.5.0", "clap 4.4.6", "hex", + "indicatif", "itertools 0.10.5", "md5", "once_cell", diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 138e4c0523f2..963282e3f62e 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -41,6 +41,7 @@ dialoguer = "0.11" futures = "0.3" hex = "0.4" itertools = "0.10.5" +indicatif = "0.16" jemallocator = "0.5" local-ip-address = "0.5.0" log = "0.4.20" @@ -52,7 +53,7 @@ proptest = "1.2.0" prover_dal = { path = "prover_dal" } queues = "1.1.0" rand = "0.8" -regex = "1.7.2" +regex = "1.10.4" reqwest = "0.11" serde = "1.0" serde_derive = "1.0" diff --git a/prover/vk_setup_data_generator_server_fri/Cargo.toml b/prover/vk_setup_data_generator_server_fri/Cargo.toml index bda9dafe3de6..c1d72cf6ba24 100644 --- a/prover/vk_setup_data_generator_server_fri/Cargo.toml +++ b/prover/vk_setup_data_generator_server_fri/Cargo.toml @@ -45,6 +45,7 @@ toml_edit.workspace = true md5.workspace = true sha3.workspace = true hex.workspace = true +indicatif.workspace = true [dev-dependencies] proptest.workspace = true diff --git a/prover/vk_setup_data_generator_server_fri/README.md b/prover/vk_setup_data_generator_server_fri/README.md index 6cdea0b87f33..d33323dd20bf 100644 --- a/prover/vk_setup_data_generator_server_fri/README.md +++ b/prover/vk_setup_data_generator_server_fri/README.md @@ -15,6 +15,9 @@ circuit changes), first please make sure that you have a CRS file (used for SNAR CRS_FILE=yyy ZKSYNC_HOME=xxx cargo run --release --bin key_generator generate-vk ``` +You can also generate multiple keys in parallel (to speed things up), with `--jobs` flag, but you need at least 30 GB of +ram for each job. + ### CRS FILE The SNARK VK generation requires the `CRS_FILE` environment variable to be present and point to the correct file. The diff --git a/prover/vk_setup_data_generator_server_fri/src/main.rs b/prover/vk_setup_data_generator_server_fri/src/main.rs index 4cf7aa1abb30..da86f931b1c2 100644 --- a/prover/vk_setup_data_generator_server_fri/src/main.rs +++ b/prover/vk_setup_data_generator_server_fri/src/main.rs @@ -6,9 +6,13 @@ use std::collections::HashMap; use anyhow::Context as _; use clap::{Parser, Subcommand}; use commitment_generator::read_and_update_contract_toml; +use indicatif::{ProgressBar, ProgressStyle}; use tracing::level_filters::LevelFilter; use zkevm_test_harness::{ - compute_setups::{generate_base_layer_vks_and_proofs, generate_recursive_layer_vks_and_proofs}, + compute_setups::{ + basic_vk_count, generate_base_layer_vks, generate_recursive_layer_vks, + recursive_layer_vk_count, + }, data_source::{in_memory_data_source::InMemoryDataSource, SetupDataSource}, proof_wrapper_utils::{ check_trusted_setup_file_existace, get_wrapper_setup_and_vk_from_scheduler_vk, @@ -30,20 +34,45 @@ mod commitment_generator; #[cfg(test)] mod tests; -fn generate_vks(keystore: &Keystore) -> anyhow::Result<()> { +/// Generates new verification keys, and stores them in `keystore`. +/// Jobs describe how many generators can run in parallel (each one is around 30 GB). +/// If quiet is true, it doesn't display any progress bar. +fn generate_vks(keystore: &Keystore, jobs: usize, quiet: bool) -> anyhow::Result<()> { // Start by checking the trusted setup existence. // This is used at the last step, but we want to fail early if user didn't configure everything // correctly. check_trusted_setup_file_existace(); + let progress_bar = if quiet { + None + } else { + let count = basic_vk_count() + recursive_layer_vk_count() + 1; + let progress_bar = ProgressBar::new(count as u64); + progress_bar.set_style(ProgressStyle::default_bar() + .template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {pos:>7}/{len:7} ({eta})") + .progress_chars("#>-")); + Some(progress_bar) + }; + + let pb = std::sync::Arc::new(std::sync::Mutex::new(progress_bar)); + let mut in_memory_source = InMemoryDataSource::new(); tracing::info!("Generating verification keys for Base layer."); - generate_base_layer_vks_and_proofs(&mut in_memory_source) - .map_err(|err| anyhow::anyhow!("Failed generating base vk's: {err}"))?; + + generate_base_layer_vks(&mut in_memory_source, Some(jobs), || { + if let Some(p) = pb.lock().unwrap().as_ref() { + p.inc(1) + } + }) + .map_err(|err| anyhow::anyhow!("Failed generating base vk's: {err}"))?; tracing::info!("Generating verification keys for Recursive layer."); - generate_recursive_layer_vks_and_proofs(&mut in_memory_source) - .map_err(|err| anyhow::anyhow!("Failed generating recursive vk's: {err}"))?; + generate_recursive_layer_vks(&mut in_memory_source, Some(jobs), || { + if let Some(p) = pb.lock().unwrap().as_ref() { + p.inc(1) + } + }) + .map_err(|err| anyhow::anyhow!("Failed generating recursive vk's: {err}"))?; tracing::info!("Saving keys & hints"); @@ -63,6 +92,10 @@ fn generate_vks(keystore: &Keystore) -> anyhow::Result<()> { .save_snark_verification_key(vk) .context("save_snark_vk")?; + if let Some(p) = pb.lock().unwrap().as_ref() { + p.inc(1) + } + // Let's also update the commitments file. keystore.save_commitments(&generate_commitments(keystore)?) } @@ -121,6 +154,12 @@ enum Command { GenerateVerificationKeys { #[arg(long)] path: Option, + /// Number of generators to run in parallel - each one consumes around 30 GB of RAM. + #[arg(short, long, default_value_t = 1)] + jobs: usize, + /// If true - disables progress bar. + #[arg(long)] + quiet: bool, }, /// Generates setup keys (used by the CPU prover). #[command(name = "generate-sk")] @@ -208,13 +247,13 @@ fn main() -> anyhow::Result<()> { let opt = Cli::parse(); match opt.command { - Command::GenerateVerificationKeys { path } => { + Command::GenerateVerificationKeys { path, jobs, quiet } => { let keystore = keystore_from_optional_path(path, None); tracing::info!( "Generating verification keys and storing them inside {:?}", keystore.get_base_path() ); - generate_vks(&keystore).context("generate_vks()") + generate_vks(&keystore, jobs, quiet).context("generate_vks()") } Command::UpdateCommitments { dryrun, path } => { let keystore = keystore_from_optional_path(path, None);