From 9a8165cd05ededde6d5ff5ac865854dff027864e Mon Sep 17 00:00:00 2001 From: Robert Remen Date: Fri, 16 Feb 2024 12:45:10 +0100 Subject: [PATCH] implement GpuProofConfig abstraction --- Cargo.toml | 2 +- src/constraint_evaluation.rs | 57 ++++-------- src/data_structures/cache.rs | 35 +++---- src/gpu_proof_config.rs | 176 +++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/prover.rs | 115 ++++++++++------------- src/synthesis_utils.rs | 53 ++++++----- src/test.rs | 51 +++++----- 8 files changed, 320 insertions(+), 170 deletions(-) create mode 100644 src/gpu_proof_config.rs diff --git a/Cargo.toml b/Cargo.toml index 7bb0eab..33bb2ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shivini" -version = "0.1.0" +version = "0.2.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/constraint_evaluation.rs b/src/constraint_evaluation.rs index d8ad7cd..ade8473 100644 --- a/src/constraint_evaluation.rs +++ b/src/constraint_evaluation.rs @@ -1,31 +1,20 @@ -use boojum::{ - config::CSConfig, - cs::{ - gates::lookup_marker::LookupFormalGate, - implementations::{reference_cs::CSReferenceAssembly, setup::TreeNode}, - traits::{evaluator::PerChunkOffset, gate::GatePlacementStrategy}, - }, +use crate::gpu_proof_config::GpuProofConfig; +use boojum::cs::{ + gates::lookup_marker::LookupFormalGate, + implementations::setup::TreeNode, + traits::{evaluator::PerChunkOffset, gate::GatePlacementStrategy}, }; use super::*; -pub fn get_evaluators_of_general_purpose_cols< - P: boojum::field::traits::field_like::PrimeFieldLikeVectorized, - CFG: CSConfig, ->( - cs: &CSReferenceAssembly, +pub fn get_evaluators_of_general_purpose_cols( + config: &GpuProofConfig, selectors_placement: &TreeNode, ) -> Vec { let mut gates = vec![]; - for (evaluator_idx, (evaluator, _gate_type_id)) in cs - .evaluation_data_over_general_purpose_columns + for (evaluator_idx, evaluator) in config .evaluators_over_general_purpose_columns .iter() - .zip( - cs.evaluation_data_over_general_purpose_columns - .gate_type_ids_for_general_purpose_columns - .iter(), - ) .enumerate() { if evaluator.debug_name @@ -72,34 +61,21 @@ pub fn get_evaluators_of_general_purpose_cols< gates } -pub fn get_specialized_evaluators_from_assembly< - P: boojum::field::traits::field_like::PrimeFieldLikeVectorized, - CFG: CSConfig, ->( - cs: &CSReferenceAssembly, +pub fn get_specialized_evaluators_from_assembly( + config: &GpuProofConfig, selectors_placement: &TreeNode, ) -> Vec { - if cs - .evaluation_data_over_specialized_columns - .evaluators_over_specialized_columns - .len() - < 1 - { + if config.evaluators_over_specialized_columns.len() < 1 { return vec![]; } let (_deg, _constants_for_gates_over_general_purpose_columns) = selectors_placement.compute_stats(); let mut gates = vec![]; - for (idx, (evaluator, gate_type_id)) in cs - .evaluation_data_over_specialized_columns + for (idx, (evaluator, gate_type_id)) in config .evaluators_over_specialized_columns .iter() - .zip( - cs.evaluation_data_over_specialized_columns - .gate_type_ids_for_specialized_columns - .iter(), - ) + .zip(config.gate_type_ids_for_specialized_columns.iter()) .enumerate() { if evaluator.debug_name @@ -120,7 +96,7 @@ pub fn get_specialized_evaluators_from_assembly< ); let num_terms = evaluator.num_quotient_terms; - let placement_strategy = cs + let placement_strategy = config .placement_strategies .get(&gate_type_id) .copied() @@ -136,9 +112,8 @@ pub fn get_specialized_evaluators_from_assembly< let total_terms = num_terms * num_repetitions; - let (initial_offset, per_repetition_offset, total_constants_available) = cs - .evaluation_data_over_specialized_columns - .offsets_for_specialized_evaluators[idx]; + let (initial_offset, per_repetition_offset, total_constants_available) = + config.offsets_for_specialized_evaluators[idx]; let _placement_data = ( num_repetitions, diff --git a/src/data_structures/cache.rs b/src/data_structures/cache.rs index 5cb9fd8..d26a33b 100644 --- a/src/data_structures/cache.rs +++ b/src/data_structures/cache.rs @@ -1,12 +1,9 @@ -use boojum::config::ProvingCSConfig; use boojum::cs::implementations::pow::PoWRunner; use boojum::cs::implementations::prover::ProofConfig; -use boojum::cs::implementations::reference_cs::CSReferenceAssembly; use boojum::cs::implementations::transcript::Transcript; -use boojum::cs::implementations::verifier::VerificationKey; +use boojum::cs::implementations::verifier::{VerificationKey, VerificationKeyCircuitGeometry}; use boojum::cs::implementations::witness::WitnessVec; use boojum::cs::oracle::TreeHasher; -use boojum::field::traits::field_like::PrimeFieldLikeVectorized; use boojum::worker::Worker; use cudart_sys::CudaError::ErrorMemoryAllocation; use std::collections::BTreeMap; @@ -48,6 +45,7 @@ impl StorageCacheStrategy { } use crate::cs::GpuSetup; +use crate::gpu_proof_config::GpuProofConfig; use crate::prover::{ compute_quotient_degree, gpu_prove_from_external_witness_data_with_cache_strategy, }; @@ -496,13 +494,12 @@ pub(crate) struct CacheStrategy { impl CacheStrategy { pub(crate) fn get< - P: PrimeFieldLikeVectorized, TR: Transcript, H: TreeHasher, POW: PoWRunner, A: GoodAllocator, >( - cs: &CSReferenceAssembly, + config: &GpuProofConfig, external_witness_data: &WitnessVec, proof_config: ProofConfig, setup: &GpuSetup, @@ -515,13 +512,14 @@ impl CacheStrategy { println!("reusing cache strategy"); Ok(*strategy) } else { - let strategies = Self::get_strategy_candidates(cs, &proof_config, setup); + let strategies = + Self::get_strategy_candidates(config, &proof_config, setup, &vk.fixed_parameters); for (_, strategy) in strategies.iter().copied() { _setup_cache_reset(); dry_run_start(); let result = - gpu_prove_from_external_witness_data_with_cache_strategy::( - cs, + gpu_prove_from_external_witness_data_with_cache_strategy::( + config, external_witness_data, proof_config.clone(), setup, @@ -548,27 +546,30 @@ impl CacheStrategy { } } - pub(crate) fn get_strategy_candidates< - P: PrimeFieldLikeVectorized, - A: GoodAllocator, - >( - cs: &CSReferenceAssembly, + pub(crate) fn get_strategy_candidates( + config: &GpuProofConfig, proof_config: &ProofConfig, setup: &GpuSetup, + geometry: &VerificationKeyCircuitGeometry, ) -> Vec<((usize, usize), CacheStrategy)> { let fri_lde_degree = proof_config.fri_lde_factor; - let quotient_degree = compute_quotient_degree(&cs, &setup.selectors_placement); + let quotient_degree = compute_quotient_degree(&config, &setup.selectors_placement); let used_lde_degree = usize::max(quotient_degree, fri_lde_degree); let setup_layout = setup.layout; + let domain_size = geometry.domain_size as usize; + let lookup_parameters = geometry.lookup_parameters; + let total_tables_len = geometry.total_tables_len as usize; + let num_multiplicity_cols = + lookup_parameters.num_multipicities_polys(total_tables_len, domain_size); let trace_layout = TraceLayout { num_variable_cols: setup.variables_hint.len(), num_witness_cols: setup.witnesses_hint.len(), - num_multiplicity_cols: cs.num_multipicities_polys(), + num_multiplicity_cols, }; let arguments_layout = ArgumentsLayout::from_trace_layout_and_lookup_params( trace_layout, quotient_degree, - cs.lookup_parameters.clone(), + geometry.lookup_parameters, ); let setup_num_polys = setup_layout.num_polys(); let trace_num_polys = trace_layout.num_polys(); diff --git a/src/gpu_proof_config.rs b/src/gpu_proof_config.rs new file mode 100644 index 0000000..794d57b --- /dev/null +++ b/src/gpu_proof_config.rs @@ -0,0 +1,176 @@ +use crate::synthesis_utils::{ + get_verifier_for_base_layer_circuit, get_verifier_for_eip4844_circuit, + get_verifier_for_recursive_layer_circuit, +}; +use boojum::config::ProvingCSConfig; +use boojum::cs::implementations::reference_cs::CSReferenceAssembly; +use boojum::cs::implementations::verifier::{ + TypeErasedGateEvaluationVerificationFunction, Verifier, +}; +use boojum::cs::traits::evaluator::{ + GatePlacementType, PerChunkOffset, TypeErasedGateEvaluationFunction, +}; +use boojum::cs::traits::gate::GatePlacementStrategy; +use boojum::field::goldilocks::{GoldilocksExt2, GoldilocksField}; +use boojum::field::traits::field_like::PrimeFieldLikeVectorized; +use boojum::field::FieldExtension; +use circuit_definitions::aux_definitions::witness_oracle::VmWitnessOracle; +use circuit_definitions::circuit_definitions::base_layer::ZkSyncBaseLayerCircuit; +use circuit_definitions::circuit_definitions::recursion_layer::ZkSyncRecursiveLayerCircuit; +use circuit_definitions::ZkSyncDefaultRoundFunction; +use std::any::TypeId; +use std::collections::HashMap; + +type F = GoldilocksField; +type EXT = GoldilocksExt2; +type BaseLayerCircuit = ZkSyncBaseLayerCircuit, ZkSyncDefaultRoundFunction>; +type EIP4844Circuit = circuit_definitions::circuit_definitions::eip4844::EIP4844Circuit< + F, + ZkSyncDefaultRoundFunction, +>; + +pub(crate) struct EvaluatorData { + pub debug_name: String, + pub unique_name: String, + pub max_constraint_degree: usize, + pub num_quotient_terms: usize, + pub total_quotient_terms_over_all_repetitions: usize, + pub num_repetitions_on_row: usize, + pub placement_type: GatePlacementType, +} + +impl> From<&TypeErasedGateEvaluationFunction> + for EvaluatorData +{ + fn from(value: &TypeErasedGateEvaluationFunction) -> Self { + let debug_name = value.debug_name.clone(); + let unique_name = value.unique_name.clone(); + let max_constraint_degree = value.max_constraint_degree; + let num_quotient_terms = value.num_quotient_terms; + let total_quotient_terms_over_all_repetitions = + value.total_quotient_terms_over_all_repetitions; + let num_repetitions_on_row = value.num_repetitions_on_row; + let placement_type = value.placement_type; + Self { + debug_name, + unique_name, + max_constraint_degree, + num_quotient_terms, + total_quotient_terms_over_all_repetitions, + num_repetitions_on_row, + placement_type, + } + } +} + +impl> + From<&TypeErasedGateEvaluationVerificationFunction> for EvaluatorData +{ + fn from(value: &TypeErasedGateEvaluationVerificationFunction) -> Self { + let debug_name = value.debug_name.clone(); + let unique_name = value.unique_name.clone(); + let max_constraint_degree = value.max_constraint_degree; + let num_quotient_terms = value.num_quotient_terms; + let total_quotient_terms_over_all_repetitions = + value.total_quotient_terms_over_all_repetitions; + let num_repetitions_on_row = value.num_repetitions_on_row; + let placement_type = value.placement_type; + Self { + debug_name, + unique_name, + max_constraint_degree, + num_quotient_terms, + total_quotient_terms_over_all_repetitions, + num_repetitions_on_row, + placement_type, + } + } +} + +pub struct GpuProofConfig { + pub(crate) gate_type_ids_for_specialized_columns: Vec, + pub(crate) evaluators_over_specialized_columns: Vec, + pub(crate) offsets_for_specialized_evaluators: Vec<(PerChunkOffset, PerChunkOffset, usize)>, + pub(crate) evaluators_over_general_purpose_columns: Vec, + pub(crate) placement_strategies: HashMap, +} + +impl GpuProofConfig { + pub fn from_assembly>( + cs: &CSReferenceAssembly, + ) -> Self { + let evaluation_data_over_specialized_columns = &cs.evaluation_data_over_specialized_columns; + let gate_type_ids_for_specialized_columns = evaluation_data_over_specialized_columns + .gate_type_ids_for_specialized_columns + .clone(); + let evaluators_over_specialized_columns = evaluation_data_over_specialized_columns + .evaluators_over_specialized_columns + .iter() + .map(|x| x.into()) + .collect(); + let evaluators_over_general_purpose_columns = cs + .evaluation_data_over_general_purpose_columns + .evaluators_over_general_purpose_columns + .iter() + .map(|x| x.into()) + .collect(); + let offsets_for_specialized_evaluators = evaluation_data_over_specialized_columns + .offsets_for_specialized_evaluators + .clone(); + let placement_strategies = cs.placement_strategies.clone(); + Self { + gate_type_ids_for_specialized_columns, + evaluators_over_specialized_columns, + offsets_for_specialized_evaluators, + evaluators_over_general_purpose_columns, + placement_strategies, + } + } + + pub fn from_verifier(verifier: &Verifier) -> Self { + let gate_type_ids_for_specialized_columns = + verifier.gate_type_ids_for_specialized_columns.clone(); + let evaluators_over_specialized_columns = verifier + .evaluators_over_specialized_columns + .iter() + .map(|x| x.into()) + .collect(); + let offsets_for_specialized_evaluators = + verifier.offsets_for_specialized_evaluators.clone(); + let evaluators_over_general_purpose_columns = verifier + .evaluators_over_general_purpose_columns + .iter() + .map(|x| x.into()) + .collect(); + let placement_strategies = verifier.placement_strategies.clone(); + Self { + gate_type_ids_for_specialized_columns, + evaluators_over_specialized_columns, + offsets_for_specialized_evaluators, + evaluators_over_general_purpose_columns, + placement_strategies, + } + } + + pub fn from_base_layer_circuit(circuit: &BaseLayerCircuit) -> Self { + Self::from_verifier(&get_verifier_for_base_layer_circuit(circuit)) + } + + pub fn from_recursive_layer_circuit(circuit: &ZkSyncRecursiveLayerCircuit) -> Self { + Self::from_verifier(&get_verifier_for_recursive_layer_circuit(circuit)) + } + + pub fn from_eip4844_circuit(_circuit: &EIP4844Circuit) -> Self { + Self::from_verifier(&get_verifier_for_eip4844_circuit()) + } + + #[cfg(test)] + pub(crate) fn from_circuit_wrapper(wrapper: &crate::synthesis_utils::CircuitWrapper) -> Self { + use crate::synthesis_utils::CircuitWrapper::*; + match wrapper { + Base(circuit) => Self::from_base_layer_circuit(circuit), + Recursive(circuit) => Self::from_recursive_layer_circuit(circuit), + EIP4844(circuit) => Self::from_eip4844_circuit(circuit), + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 77e989b..8284ad0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,6 +42,7 @@ use copy_permutation::*; use data_structures::*; use lookup::*; use poly::*; +pub mod gpu_proof_config; mod prover; mod quotient; #[cfg(feature = "zksync")] diff --git a/src/prover.rs b/src/prover.rs index b138520..031bd3d 100644 --- a/src/prover.rs +++ b/src/prover.rs @@ -2,7 +2,6 @@ use std::alloc::Global; use std::rc::Rc; use boojum::{ - config::ProvingCSConfig, cs::{ gates::lookup_marker::LookupFormalGate, implementations::{ @@ -10,7 +9,6 @@ use boojum::{ pow::{NoPow, PoWRunner}, proof::{OracleQuery, Proof, SingleRoundQueries}, prover::ProofConfig, - reference_cs::CSReferenceAssembly, setup::TreeNode, transcript::Transcript, utils::{domain_generator_for_size, materialize_powers_serial}, @@ -26,6 +24,7 @@ use boojum::{ }; use crate::cs::GpuSetup; +use crate::gpu_proof_config::GpuProofConfig; use crate::{ arith::{deep_quotient_except_public_inputs, deep_quotient_public_input}, cs::PACKED_PLACEHOLDER_BITMASK, @@ -34,14 +33,12 @@ use crate::{ use super::*; pub fn gpu_prove_from_external_witness_data< - P: boojum::field::traits::field_like::PrimeFieldLikeVectorized, TR: Transcript, H: TreeHasher, POW: PoWRunner, A: GoodAllocator, >( - // service layer reuses assembly for repeated proving, so that just borrow it - cs: &CSReferenceAssembly, + config: &GpuProofConfig, external_witness_data: &WitnessVec, // TODO: read data from Assembly pinned storage proof_config: ProofConfig, setup: &GpuSetup, @@ -49,8 +46,8 @@ pub fn gpu_prove_from_external_witness_data< transcript_params: TR::TransciptParameters, worker: &Worker, ) -> CudaResult> { - let cache_strategy = CacheStrategy::get::( - cs, + let cache_strategy = CacheStrategy::get::( + config, external_witness_data, proof_config.clone(), setup, @@ -58,8 +55,8 @@ pub fn gpu_prove_from_external_witness_data< transcript_params.clone(), worker, )?; - gpu_prove_from_external_witness_data_with_cache_strategy::( - cs, + gpu_prove_from_external_witness_data_with_cache_strategy::( + config, external_witness_data, proof_config, setup, @@ -71,14 +68,12 @@ pub fn gpu_prove_from_external_witness_data< } pub(crate) fn gpu_prove_from_external_witness_data_with_cache_strategy< - P: boojum::field::traits::field_like::PrimeFieldLikeVectorized, TR: Transcript, H: TreeHasher, POW: PoWRunner, A: GoodAllocator, >( - // service layer reuses assembly for repeated proving, so that just borrow it - cs: &CSReferenceAssembly, + config: &GpuProofConfig, external_witness_data: &WitnessVec, // TODO: read data from Assembly pinned storage proof_config: ProofConfig, setup: &GpuSetup, @@ -89,11 +84,6 @@ pub(crate) fn gpu_prove_from_external_witness_data_with_cache_strategy< ) -> CudaResult> { let mut timer = std::time::Instant::now(); let result = { - assert_eq!( - cs.next_available_place_idx(), - 0, - "CS should be empty and hold no data" - ); assert!( is_prover_context_initialized(), "prover context should be initialized" @@ -101,10 +91,14 @@ pub(crate) fn gpu_prove_from_external_witness_data_with_cache_strategy< let num_variable_cols = setup.variables_hint.len(); let num_witness_cols = setup.witnesses_hint.len(); - let num_multiplicity_cols = cs.num_multipicities_polys(); - let domain_size = cs.max_trace_len; + let geometry = vk.fixed_parameters.clone(); + let domain_size = geometry.domain_size as usize; + let lookup_parameters = geometry.lookup_parameters; + let total_tables_len = geometry.total_tables_len as usize; + let num_multiplicity_cols = + lookup_parameters.num_multipicities_polys(total_tables_len, domain_size); let fri_lde_degree = proof_config.fri_lde_factor; - let quotient_degree = compute_quotient_degree(&cs, &setup.selectors_placement); + let quotient_degree = compute_quotient_degree(config, &setup.selectors_placement); let used_lde_degree = usize::max(quotient_degree, fri_lde_degree); let cap_size = setup.setup_tree.cap_size; let setup_cache = SetupCache::new_from_gpu_setup( @@ -135,7 +129,7 @@ pub(crate) fn gpu_prove_from_external_witness_data_with_cache_strategy< let arguments_layout = ArgumentsLayout::from_trace_layout_and_lookup_params( trace_layout, quotient_degree, - cs.lookup_parameters.clone(), + lookup_parameters, ); let mut arguments_cache = ArgumentsCache::new( cache_strategy.arguments, @@ -156,7 +150,7 @@ pub(crate) fn gpu_prove_from_external_witness_data_with_cache_strategy< &setup_cache.aux.variable_indexes, &setup_cache.aux.witness_indexes, &external_witness_data, - &cs.lookup_parameters, + &lookup_parameters, worker, trace_evaluations_storage, )?; @@ -190,8 +184,8 @@ pub(crate) fn gpu_prove_from_external_witness_data_with_cache_strategy< let value = external_witness_data.all_values[variable_idx]; public_inputs_with_locations.push((col, row, value)); } - gpu_prove_from_trace::<_, TR, _, NoPow, _>( - cs, + gpu_prove_from_trace::( + config, public_inputs_with_locations, setup, setup_cache, @@ -211,12 +205,7 @@ pub(crate) fn gpu_prove_from_external_witness_data_with_cache_strategy< result } -pub fn compute_quotient_degree< - P: boojum::field::traits::field_like::PrimeFieldLikeVectorized, ->( - cs: &CSReferenceAssembly, - selectors_placement: &TreeNode, -) -> usize { +pub fn compute_quotient_degree(config: &GpuProofConfig, selectors_placement: &TreeNode) -> usize { let (max_constraint_contribution_degree, _number_of_constant_polys) = selectors_placement.compute_stats(); @@ -227,8 +216,7 @@ pub fn compute_quotient_degree< 0 }; - let max_degree_from_specialized_gates = cs - .evaluation_data_over_specialized_columns + let max_degree_from_specialized_gates = config .evaluators_over_specialized_columns .iter() .map(|el| el.max_constraint_degree - 1) @@ -250,13 +238,12 @@ pub fn compute_quotient_degree< } fn gpu_prove_from_trace< - P: boojum::field::traits::field_like::PrimeFieldLikeVectorized, TR: Transcript, H: TreeHasher, POW: PoWRunner, A: GoodAllocator, >( - cs: &CSReferenceAssembly, + config: &GpuProofConfig, public_inputs_with_locations: Vec<(usize, usize, F)>, setup_base: &GpuSetup, setup_cache: &mut SetupCache, @@ -269,9 +256,16 @@ fn gpu_prove_from_trace< transcript_params: TR::TransciptParameters, worker: &Worker, ) -> CudaResult> { + let geometry = vk.fixed_parameters.clone(); + let domain_size = geometry.domain_size as usize; + let lookup_parameters = geometry.lookup_parameters; + let total_tables_len = geometry.total_tables_len as usize; + let num_multiplicity_cols = + lookup_parameters.num_multipicities_polys(total_tables_len, domain_size); + assert!(domain_size.is_power_of_two()); + assert_eq!(setup_evaluations.domain_size, domain_size); assert!(proof_config.fri_lde_factor.is_power_of_two()); assert!(proof_config.fri_lde_factor > 1); - assert!(cs.max_trace_len.is_power_of_two()); let cap_size = proof_config.merkle_tree_cap_size; assert!(cap_size > 0); @@ -285,10 +279,8 @@ fn gpu_prove_from_trace< } let selectors_placement = setup_base.selectors_placement.clone(); - let domain_size = cs.max_trace_len; // counted in elements of P - assert_eq!(setup_base.constant_columns[0].len(), domain_size); - let quotient_degree = compute_quotient_degree(&cs, &selectors_placement); + let quotient_degree = compute_quotient_degree(config, &selectors_placement); let fri_lde_degree = proof_config.fri_lde_factor; let used_lde_degree = std::cmp::max(fri_lde_degree, quotient_degree); @@ -367,7 +359,7 @@ fn gpu_prove_from_trace< let num_intermediate_partial_product_relations = argument_raw_storage.as_polynomials().partial_products.len(); - let (lookup_beta, powers_of_gamma_for_lookup) = if cs.lookup_parameters + let (lookup_beta, powers_of_gamma_for_lookup) = if geometry.lookup_parameters != LookupParameters::NoLookup { let h_lookup_beta = if is_dry_run()? { @@ -391,16 +383,16 @@ fn gpu_prove_from_trace< .output_placement(lookup_evaluator_id) .expect("lookup gate must be placed"); - let variables_offset = cs.parameters.num_columns_under_copy_permutation; + let variables_offset = geometry.parameters.num_columns_under_copy_permutation; #[allow(unreachable_code)] - let powers_of_gamma = match cs.lookup_parameters { + let powers_of_gamma = match geometry.lookup_parameters { LookupParameters::NoLookup => { unreachable!() } LookupParameters::TableIdAsConstant { .. } | LookupParameters::TableIdAsVariable { .. } => { - let columns_per_subargument = cs.lookup_parameters.columns_per_subargument(); + let columns_per_subargument = geometry.lookup_parameters.columns_per_subargument(); let mut h_powers_of_gamma = vec![]; let mut current = EF::ONE; @@ -432,14 +424,12 @@ fn gpu_prove_from_trace< | a @ LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { width, .. } => { // ensure proper setup assert_eq!( - cs.evaluation_data_over_specialized_columns - .gate_type_ids_for_specialized_columns[0], + config.gate_type_ids_for_specialized_columns[0], std::any::TypeId::of::(), "we expect first specialized gate to be the lookup -" ); - let (initial_offset, offset_per_repetition, _) = cs - .evaluation_data_over_specialized_columns - .offsets_for_specialized_evaluators[0]; + let (initial_offset, offset_per_repetition, _) = + config.offsets_for_specialized_evaluators[0]; assert_eq!(initial_offset.constants_offset, 0); if let LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { @@ -469,7 +459,7 @@ fn gpu_prove_from_trace< &lookup_beta, &powers_of_gamma, variables_offset, - cs.lookup_parameters, + lookup_parameters, &mut argument_raw_storage, )?; @@ -497,21 +487,17 @@ fn gpu_prove_from_trace< let h_alpha = ExtensionField::::from_coeff_in_base(h_alpha); let _alpha: DExt = h_alpha.into(); - let num_lookup_subarguments = cs.num_sublookup_arguments(); - let num_multiplicities_polys = cs.num_multipicities_polys(); + let num_lookup_subarguments = + lookup_parameters.num_sublookup_arguments_for_geometry(&geometry.parameters); + let num_multiplicities_polys = num_multiplicity_cols; let total_num_lookup_argument_terms = num_lookup_subarguments + num_multiplicities_polys; - let total_num_gate_terms_for_specialized_columns = cs - .evaluation_data_over_specialized_columns + let total_num_gate_terms_for_specialized_columns = config .evaluators_over_specialized_columns .iter() - .zip( - cs.evaluation_data_over_specialized_columns - .gate_type_ids_for_specialized_columns - .iter(), - ) + .zip(config.gate_type_ids_for_specialized_columns.iter()) .map(|(evaluator, gate_type_id)| { - let placement_strategy = cs + let placement_strategy = config .placement_strategies .get(gate_type_id) .copied() @@ -529,8 +515,7 @@ fn gpu_prove_from_trace< }) .sum(); - let total_num_gate_terms_for_general_purpose_columns: usize = cs - .evaluation_data_over_general_purpose_columns + let total_num_gate_terms_for_general_purpose_columns: usize = config .evaluators_over_general_purpose_columns .iter() .map(|evaluator| evaluator.total_quotient_terms_over_all_repetitions) @@ -570,13 +555,13 @@ fn gpu_prove_from_trace< let mut quotient = ComplexPoly::::empty(quotient_degree * domain_size)?; - let variables_offset = cs.parameters.num_columns_under_copy_permutation; + let variables_offset = geometry.parameters.num_columns_under_copy_permutation; let general_purpose_gates = - get_evaluators_of_general_purpose_cols(&cs, &setup_base.selectors_placement); + get_evaluators_of_general_purpose_cols(config, &setup_base.selectors_placement); let specialized_gates = - get_specialized_evaluators_from_assembly(&cs, &setup_base.selectors_placement); + get_specialized_evaluators_from_assembly(config, &setup_base.selectors_placement); let num_cols_per_product = quotient_degree; let specialized_cols_challenge_power_offset = total_num_lookup_argument_terms; let general_purpose_cols_challenge_power_offset = @@ -587,7 +572,7 @@ fn gpu_prove_from_trace< trace_cache, setup_cache, arguments_cache, - cs.lookup_parameters, + geometry.lookup_parameters, &setup_base.table_ids_column_idxes, &setup_base.selectors_placement, &specialized_gates, @@ -897,7 +882,7 @@ fn gpu_prove_from_trace< quotient_holder.num_polys_in_base(), domain_size, proof_config, - cs.lookup_parameters.clone(), + geometry.lookup_parameters, num_queries, query_details_for_cosets.clone(), query_idx_and_coset_idx_map, diff --git a/src/synthesis_utils.rs b/src/synthesis_utils.rs index 98c47d3..3d95ca6 100644 --- a/src/synthesis_utils.rs +++ b/src/synthesis_utils.rs @@ -8,7 +8,7 @@ use boojum::cs::implementations::proof::Proof; use boojum::cs::implementations::prover::ProofConfig; use boojum::cs::implementations::reference_cs::{CSReferenceAssembly, CSReferenceImplementation}; use boojum::cs::implementations::setup::FinalizationHintsForProver; -use boojum::cs::implementations::verifier::VerificationKey; +use boojum::cs::implementations::verifier::{VerificationKey, Verifier}; use boojum::cs::traits::GoodAllocator; use boojum::cs::{CSGeometry, GateConfigurationHolder, StaticToolboxHolder}; use boojum::field::goldilocks::{GoldilocksExt2, GoldilocksField}; @@ -150,28 +150,39 @@ impl CircuitWrapper { vk: &VerificationKey, proof: &ZksyncProof, ) -> bool { - let verifier = match self { - CircuitWrapper::Base(_base_circuit) => { - use circuit_definitions::circuit_definitions::verifier_builder::dyn_verifier_builder_for_circuit_type; - - let verifier_builder = - dyn_verifier_builder_for_circuit_type::( - self.numeric_circuit_type(), - ); - verifier_builder.create_verifier() - } - CircuitWrapper::Recursive(recursive_circuit) => { - let verifier_builder = recursive_circuit.into_dyn_verifier_builder(); - verifier_builder.create_verifier() - } - CircuitWrapper::EIP4844(_) => { - EIP4844VerifierBuilder::::dyn_verifier_builder() - .create_verifier() - } - }; - + let verifier = self.get_verifier(); verifier.verify::((), vk, proof) } + + pub(crate) fn get_verifier(&self) -> Verifier { + match self { + CircuitWrapper::Base(inner) => get_verifier_for_base_layer_circuit(inner), + CircuitWrapper::Recursive(inner) => get_verifier_for_recursive_layer_circuit(inner), + CircuitWrapper::EIP4844(_) => get_verifier_for_eip4844_circuit(), + } + } +} + +pub(crate) fn get_verifier_for_base_layer_circuit(circuit: &BaseLayerCircuit) -> Verifier { + use circuit_definitions::circuit_definitions::verifier_builder::dyn_verifier_builder_for_circuit_type; + let verifier_builder = + dyn_verifier_builder_for_circuit_type::( + circuit.numeric_circuit_type(), + ); + verifier_builder.create_verifier() +} + +pub(crate) fn get_verifier_for_recursive_layer_circuit( + circuit: &ZkSyncRecursiveLayerCircuit, +) -> Verifier { + let verifier_builder = circuit.into_dyn_verifier_builder(); + verifier_builder.create_verifier() +} + +pub(crate) fn get_verifier_for_eip4844_circuit() -> Verifier { + let verifier_builder = + EIP4844VerifierBuilder::::dyn_verifier_builder(); + verifier_builder.create_verifier() } #[allow(dead_code)] diff --git a/src/test.rs b/src/test.rs index e50e288..752b2a0 100644 --- a/src/test.rs +++ b/src/test.rs @@ -43,6 +43,7 @@ use boojum::field::traits::field_like::PrimeFieldLikeVectorized; #[allow(dead_code)] pub type DefaultDevCS = CSReferenceAssembly; type P = F; +use crate::gpu_proof_config::GpuProofConfig; use serial_test::serial; #[serial] @@ -80,14 +81,14 @@ fn test_proof_comparison_for_poseidon_gate_with_private_witnesses() { ProvingCSConfig, false, >(finalization_hint.as_ref()); + let config = GpuProofConfig::from_assembly(&reusable_cs); let proof = gpu_prove_from_external_witness_data::< - _, DefaultTranscript, DefaultTreeHasher, NoPow, Global, >( - &reusable_cs, + &config, &witness, prover_config.clone(), &gpu_setup, @@ -335,7 +336,7 @@ fn test_dry_runs() { let witness = proving_cs.witness.unwrap(); let (reusable_cs, _) = init_or_synth_cs_for_sha256::(finalization_hint.as_ref()); - + let config = GpuProofConfig::from_assembly(&reusable_cs); let worker = Worker::new(); let prover_config = init_proof_cfg(); let (setup_base, _setup, vk, setup_tree, vars_hint, wits_hint) = setup_cs.get_full_setup( @@ -355,18 +356,21 @@ fn test_dry_runs() { .unwrap(); assert!(domain_size.is_power_of_two()); - let candidates = - CacheStrategy::get_strategy_candidates(&reusable_cs, &prover_config, &gpu_setup); + let candidates = CacheStrategy::get_strategy_candidates( + &config, + &prover_config, + &gpu_setup, + &vk.fixed_parameters, + ); for (_, strategy) in candidates.iter().copied() { let proof = || { let _ = crate::prover::gpu_prove_from_external_witness_data_with_cache_strategy::< - _, DefaultTranscript, DefaultTreeHasher, NoPow, Global, >( - &reusable_cs, + &config, &witness, prover_config.clone(), &gpu_setup, @@ -439,14 +443,15 @@ fn test_proof_comparison_for_sha256() { let (reusable_cs, _) = init_or_synth_cs_for_sha256::( finalization_hint.as_ref(), ); + let config = GpuProofConfig::from_assembly(&reusable_cs); + let proof = gpu_prove_from_external_witness_data::< - _, DefaultTranscript, DefaultTreeHasher, NoPow, Global, >( - &reusable_cs, + &config, &witness, prover_config.clone(), &gpu_setup, @@ -802,8 +807,8 @@ mod zksync { const DEFAULT_CIRCUIT_INPUT: &str = "default.circuit"; use crate::synthesis_utils::{ - init_cs_for_external_proving, init_or_synthesize_assembly, synth_circuit_for_proving, - synth_circuit_for_setup, CircuitWrapper, + init_or_synthesize_assembly, synth_circuit_for_proving, synth_circuit_for_setup, + CircuitWrapper, }; #[allow(dead_code)] @@ -978,16 +983,14 @@ mod zksync { let gpu_proof = { let proving_cs = synth_circuit_for_proving(circuit.clone(), &finalization_hint); let witness = proving_cs.witness.unwrap(); - let reusable_cs = - init_cs_for_external_proving(circuit.clone(), &finalization_hint); + let config = GpuProofConfig::from_circuit_wrapper(&circuit); let proof = gpu_prove_from_external_witness_data::< - _, DefaultTranscript, DefaultTreeHasher, NoPow, Global, >( - &reusable_cs, + &config, &witness, proof_config.clone(), &gpu_setup, @@ -1128,15 +1131,14 @@ mod zksync { println!("gpu proving"); let gpu_proof = { let witness = proving_cs.witness.as_ref().unwrap(); - let reusable_cs = init_cs_for_external_proving(circuit.clone(), &finalization_hint); + let config = GpuProofConfig::from_circuit_wrapper(&circuit); gpu_prove_from_external_witness_data::< - _, DefaultTranscript, DefaultTreeHasher, NoPow, Global, >( - &reusable_cs, + &config, &witness, proof_cfg.clone(), &gpu_setup, @@ -1191,7 +1193,7 @@ mod zksync { ); let proving_cs = synth_circuit_for_proving(circuit.clone(), &finalization_hint); let witness = proving_cs.witness.unwrap(); - let reusable_cs = init_cs_for_external_proving(circuit.clone(), &finalization_hint); + let config = GpuProofConfig::from_circuit_wrapper(&circuit); let gpu_setup = { let _ctx = ProverContext::create().expect("gpu prover context"); GpuSetup::::from_setup_and_hints( @@ -1205,13 +1207,12 @@ mod zksync { }; let proof_fn = || { let _ = gpu_prove_from_external_witness_data::< - _, DefaultTranscript, DefaultTreeHasher, NoPow, Global, >( - &reusable_cs, + &config, &witness, proof_cfg.clone(), &gpu_setup, @@ -1230,8 +1231,8 @@ mod zksync { // but nice for peace of mind _setup_cache_reset(); let strategy = - CacheStrategy::get::<_, DefaultTranscript, DefaultTreeHasher, NoPow, Global>( - &reusable_cs, + CacheStrategy::get::( + &config, &witness, proof_cfg.clone(), &gpu_setup, @@ -1290,6 +1291,7 @@ mod zksync { let (reusable_cs, _) = init_or_synth_cs_for_sha256::( finalization_hint.as_ref(), ); + let config = GpuProofConfig::from_assembly(&reusable_cs); let mut gpu_setup = GpuSetup::::from_setup_and_hints( setup_base.clone(), clone_reference_tree(&setup_tree), @@ -1301,13 +1303,12 @@ mod zksync { witness.public_inputs_locations = vec![(0, 0)]; gpu_setup.variables_hint[0][0] = PACKED_PLACEHOLDER_BITMASK; let _ = gpu_prove_from_external_witness_data::< - _, DefaultTranscript, DefaultTreeHasher, NoPow, Global, >( - &reusable_cs, + &config, &witness, proof_config.clone(), &gpu_setup,