Skip to content
This repository has been archived by the owner on Aug 16, 2024. It is now read-only.

Commit

Permalink
implement GpuProofConfig abstraction (#37)
Browse files Browse the repository at this point in the history
This PR implements a GpuProofConfig abstraction to remove a dependency
on CSReferenceAssembly structure.

Instantiation of the CSReferenceAssembly structure is expensive so we
need to enable the possibility to supply the pieces of configuration the
prover needs in an alternative way. This abstraction makes it possible
to generate the information either from the CSReferenceAssembly
structure or directly from a Circuit structure.

- [x] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [x] Tests for the changes have been added / updated.
- [x] Documentation comments have been added / updated.
- [x] Code has been formatted via `cargo fmt` and linted via `cargo
check`.
  • Loading branch information
robik75 committed Apr 8, 2024
1 parent 23cb530 commit 0cf3e29
Show file tree
Hide file tree
Showing 9 changed files with 380 additions and 256 deletions.
150 changes: 69 additions & 81 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
57 changes: 16 additions & 41 deletions src/constraint_evaluation.rs
Original file line number Diff line number Diff line change
@@ -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<Base = F>,
CFG: CSConfig,
>(
cs: &CSReferenceAssembly<F, P, CFG>,
pub fn get_evaluators_of_general_purpose_cols(
config: &GpuProofConfig,
selectors_placement: &TreeNode,
) -> Vec<GateEvaluationParams> {
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
Expand Down Expand Up @@ -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<Base = F>,
CFG: CSConfig,
>(
cs: &CSReferenceAssembly<F, P, CFG>,
pub fn get_specialized_evaluators_from_assembly(
config: &GpuProofConfig,
selectors_placement: &TreeNode,
) -> Vec<GateEvaluationParams> {
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
Expand All @@ -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()
Expand All @@ -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,
Expand Down
35 changes: 18 additions & 17 deletions src/data_structures/cache.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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,
};
Expand Down Expand Up @@ -496,13 +494,12 @@ pub(crate) struct CacheStrategy {

impl CacheStrategy {
pub(crate) fn get<
P: PrimeFieldLikeVectorized<Base = F>,
TR: Transcript<F, CompatibleCap = [F; 4]>,
H: TreeHasher<F, Output = TR::CompatibleCap>,
POW: PoWRunner,
A: GoodAllocator,
>(
cs: &CSReferenceAssembly<F, P, ProvingCSConfig>,
config: &GpuProofConfig,
external_witness_data: &WitnessVec<F>,
proof_config: ProofConfig,
setup: &GpuSetup<A>,
Expand All @@ -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::<P, TR, H, POW, A>(
cs,
gpu_prove_from_external_witness_data_with_cache_strategy::<TR, H, POW, A>(
config,
external_witness_data,
proof_config.clone(),
setup,
Expand All @@ -548,27 +546,30 @@ impl CacheStrategy {
}
}

pub(crate) fn get_strategy_candidates<
P: PrimeFieldLikeVectorized<Base = F>,
A: GoodAllocator,
>(
cs: &CSReferenceAssembly<F, P, ProvingCSConfig>,
pub(crate) fn get_strategy_candidates<A: GoodAllocator>(
config: &GpuProofConfig,
proof_config: &ProofConfig,
setup: &GpuSetup<A>,
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();
Expand Down
166 changes: 166 additions & 0 deletions src/gpu_proof_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
use crate::synthesis_utils::{
get_verifier_for_base_layer_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<F, VmWitnessOracle<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<P: PrimeFieldLikeVectorized<Base = F>> From<&TypeErasedGateEvaluationFunction<F, P>>
for EvaluatorData
{
fn from(value: &TypeErasedGateEvaluationFunction<F, P>) -> 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<EXT: FieldExtension<2, BaseField = F>>
From<&TypeErasedGateEvaluationVerificationFunction<F, EXT>> for EvaluatorData
{
fn from(value: &TypeErasedGateEvaluationVerificationFunction<F, EXT>) -> 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<TypeId>,
pub(crate) evaluators_over_specialized_columns: Vec<EvaluatorData>,
pub(crate) offsets_for_specialized_evaluators: Vec<(PerChunkOffset, PerChunkOffset, usize)>,
pub(crate) evaluators_over_general_purpose_columns: Vec<EvaluatorData>,
pub(crate) placement_strategies: HashMap<TypeId, GatePlacementStrategy>,
}

impl GpuProofConfig {
pub fn from_assembly<P: PrimeFieldLikeVectorized<Base = F>>(
cs: &CSReferenceAssembly<F, P, ProvingCSConfig>,
) -> 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<F, EXT>) -> 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))
}

#[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),
}
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
Loading

0 comments on commit 0cf3e29

Please sign in to comment.