Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
siq1 committed Oct 29, 2024
1 parent 17f2373 commit cf0a571
Show file tree
Hide file tree
Showing 13 changed files with 348 additions and 34 deletions.
4 changes: 2 additions & 2 deletions expander_compiler/src/circuit/layered/opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ impl<C: Config> Circuit<C> {
mod tests {
use crate::circuit::layered;
use crate::field::FieldArith;
use crate::layering::compile;
use crate::layering::{compile, CompileOptions};
use crate::{
circuit::{
config::{Config, GF2Config as C},
Expand Down Expand Up @@ -711,7 +711,7 @@ mod tests {
}
},
}
let (lc, _) = compile(&root);
let (lc, _) = compile(&root, CompileOptions { is_zkcuda: false });
assert_eq!(lc.validate(), Ok(()));
Some(lc)
}
Expand Down
5 changes: 4 additions & 1 deletion expander_compiler/src/circuit/layered/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,10 @@ mod tests {
config.seed = i + 10000;
let root = RootCircuit::<C>::random(&config);
assert_eq!(root.validate(), Ok(()));
let (circuit, _) = crate::layering::compile(&root);
let (circuit, _) = crate::layering::compile(
&root,
crate::layering::CompileOptions { is_zkcuda: false },
);
assert_eq!(circuit.validate(), Ok(()));
let mut buf = Vec::new();
circuit.serialize_into(&mut buf).unwrap();
Expand Down
76 changes: 54 additions & 22 deletions expander_compiler/src/compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ fn print_stat(stat_name: &str, stat: usize, is_last: bool) {
}
}

pub fn compile<C: Config>(
pub fn compile_step_1<C: Config>(
r_source: &ir::source::RootCircuit<C>,
) -> Result<(ir::hint_normalized::RootCircuit<C>, layered::Circuit<C>), Error> {
) -> Result<(ir::hint_normalized::RootCircuit<C>, InputMapping), Error> {
r_source.validate()?;

let mut src_im = InputMapping::new_identity(r_source.input_size());
Expand Down Expand Up @@ -78,19 +78,12 @@ pub fn compile<C: Config>(
r_hint_normalized_opt
.validate()
.map_err(|e| e.prepend("hint normalized ir circuit invalid"))?;
let ho_stats = r_hint_normalized_opt.get_stats();
print_info("built hint normalized ir");
print_stat("numInputs", ho_stats.num_inputs, false);
print_stat("numConstraints", ho_stats.num_constraints, false);
print_stat("numInsns", ho_stats.num_insns, false);
print_stat("numVars", ho_stats.num_variables, false);
print_stat("numTerms", ho_stats.num_terms, true);

let (r_hint_less, mut r_hint_exported) = r_hint_normalized_opt.remove_and_export_hints();
r_hint_exported
.validate()
.map_err(|e| e.prepend("hint exported circuit invalid"))?;
Ok((r_hint_normalized_opt, src_im))
}

pub fn compile_step_2<C: Config>(
r_hint_less: ir::hint_less::RootCircuit<C>,
) -> Result<(ir::dest::RootCircuit<C>, InputMapping), Error> {
let mut hl_im = InputMapping::new_identity(r_hint_less.input_size());

let r_hint_less_opt = optimize_until_fixed_point(&r_hint_less, &mut hl_im, |r| {
Expand Down Expand Up @@ -151,8 +144,12 @@ pub fn compile<C: Config>(
r_dest_opt
.validate_circuit_has_inputs()
.map_err(|e| e.prepend("dest ir circuit invalid"))?;
Ok((r_dest_opt, hl_im))
}

let (mut lc, dest_im) = layering::compile(&r_dest_opt);
pub fn compile_step_3<C: Config>(
mut lc: layered::Circuit<C>,
) -> Result<layered::Circuit<C>, Error> {
lc.validate()
.map_err(|e| e.prepend("layered circuit invalid"))?;

Expand All @@ -172,6 +169,47 @@ pub fn compile<C: Config>(
lc.validate()
.map_err(|e| e.prepend("layered circuit invalid1"))?;
lc.sort_everything(); // for deterministic output
Ok(lc)
}

pub fn compile_step_4<C: Config>(
r_hint_exported: ir::hint_normalized::RootCircuit<C>,
src_im: &mut InputMapping,
) -> Result<ir::hint_normalized::RootCircuit<C>, Error> {
r_hint_exported
.validate()
.map_err(|e| e.prepend("final hint exported circuit invalid"))?;
let r_hint_exported_opt = optimize_until_fixed_point(&r_hint_exported, src_im, |r| {
let (r, im) = r.remove_unreachable();
(r, im)
});
Ok(r_hint_exported_opt)
}

pub fn compile<C: Config>(
r_source: &ir::source::RootCircuit<C>,
) -> Result<(ir::hint_normalized::RootCircuit<C>, layered::Circuit<C>), Error> {
let (r_hint_normalized_opt, mut src_im) = compile_step_1(r_source)?;

let ho_stats = r_hint_normalized_opt.get_stats();
print_info("built hint normalized ir");
print_stat("numInputs", ho_stats.num_inputs, false);
print_stat("numConstraints", ho_stats.num_constraints, false);
print_stat("numInsns", ho_stats.num_insns, false);
print_stat("numVars", ho_stats.num_variables, false);
print_stat("numTerms", ho_stats.num_terms, true);

let (r_hint_less, mut r_hint_exported) = r_hint_normalized_opt.remove_and_export_hints();
r_hint_exported
.validate()
.map_err(|e| e.prepend("hint exported circuit invalid"))?;

let (r_dest_opt, mut hl_im) = compile_step_2(r_hint_less)?;

let (lc, dest_im) =
layering::compile(&r_dest_opt, layering::CompileOptions { is_zkcuda: false });

let lc = compile_step_3(lc)?;

let lc_stats = lc.get_stats();
print_info("built layered circuit");
Expand All @@ -193,14 +231,8 @@ pub fn compile<C: Config>(
.iter()
.map(|&x| x.max(1))
.collect();
r_hint_exported
.validate()
.map_err(|e| e.prepend("final hint exported circuit invalid"))?;

let mut r_hint_exported_opt = optimize_until_fixed_point(&r_hint_exported, &mut src_im, |r| {
let (r, im) = r.remove_unreachable();
(r, im)
});
let mut r_hint_exported_opt = compile_step_4(r_hint_exported, &mut src_im)?;
r_hint_exported_opt.add_back_removed_inputs(&src_im);
r_hint_exported_opt
.validate()
Expand Down
6 changes: 6 additions & 0 deletions expander_compiler/src/frontend/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ impl<F: Field> ToVariableOrValue<F> for &Variable {
}
}

impl Variable {
pub fn id(&self) -> usize {
self.id
}
}

impl<C: Config> Builder<C> {
pub fn new(num_inputs: usize) -> (Self, Vec<Variable>) {
(
Expand Down
10 changes: 5 additions & 5 deletions expander_compiler/src/frontend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ use builder::RootBuilder;

use crate::circuit::{ir, layered};

mod api;
mod builder;
mod circuit;
mod variables;
mod witness;
pub mod api;
pub mod builder;
pub mod circuit;
pub mod variables;
pub mod witness;

pub use circuit::declare_circuit;
pub type API<C> = builder::RootBuilder<C>;
Expand Down
17 changes: 17 additions & 0 deletions expander_compiler/src/layering/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use crate::circuit::{
};
use crate::utils::pool::Pool;

use super::layer_layout::merge_layouts;
use super::layer_layout::{LayerLayout, LayerLayoutContext, LayerReq};
use super::CompileOptions;

pub struct CompileContext<'a, C: Config> {
// the root circuit
Expand Down Expand Up @@ -38,6 +40,8 @@ pub struct CompileContext<'a, C: Config> {
pub input_order: Vec<usize>,

pub root_has_constraints: bool,

pub opts: CompileOptions,
}

pub struct IrContext<'a, C: Config> {
Expand Down Expand Up @@ -112,6 +116,19 @@ impl<'a, C: Config> CompileContext<'a, C> {
}));
}
self.layout_ids = layout_ids;
if self.opts.is_zkcuda {
let layout_vec =
merge_layouts(vec![], (0..self.circuits[&0].lcs[0].vars.len()).collect());
let id = self.layer_layout_pool.add(&LayerLayout {
circuit_id: 0,
layer: 0,
size: layout_vec.len(),
inner: super::layer_layout::LayerLayoutInner::Dense {
placement: layout_vec,
},
});
self.layout_ids[0] = id;
}

// 5. generate wires
let mut layers = Vec::with_capacity(self.circuits[&0].output_layer);
Expand Down
2 changes: 1 addition & 1 deletion expander_compiler/src/layering/layer_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ impl<'a, C: Config> CompileContext<'a, C> {
}
}

fn merge_layouts(s: Vec<Vec<usize>>, additional: Vec<usize>) -> Vec<usize> {
pub fn merge_layouts(s: Vec<Vec<usize>>, additional: Vec<usize>) -> Vec<usize> {
// currently it's a simple greedy algorithm
// sort groups by size, and then place them one by one
// since their size are always 2^n, the result is aligned
Expand Down
10 changes: 9 additions & 1 deletion expander_compiler/src/layering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ mod wire;
#[cfg(test)]
mod tests;

pub fn compile<C: Config>(rc: &ir::dest::RootCircuit<C>) -> (layered::Circuit<C>, InputMapping) {
pub struct CompileOptions {
pub is_zkcuda: bool,
}

pub fn compile<C: Config>(
rc: &ir::dest::RootCircuit<C>,
opts: CompileOptions,
) -> (layered::Circuit<C>, InputMapping) {
let mut ctx = compile::CompileContext {
rc,
circuits: HashMap::new(),
Expand All @@ -27,6 +34,7 @@ pub fn compile<C: Config>(rc: &ir::dest::RootCircuit<C>) -> (layered::Circuit<C>
layers: Vec::new(),
input_order: Vec::new(),
root_has_constraints: false,
opts,
};
ctx.compile();
let l0_size = ctx.compiled_circuits[ctx.layers[0]].num_inputs;
Expand Down
4 changes: 2 additions & 2 deletions expander_compiler/src/layering/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::circuit::{

use crate::field::FieldArith;

use super::compile;
use super::{compile, CompileOptions};

pub fn test_input<C: Config>(
rc: &IrRootCircuit<C>,
Expand All @@ -29,7 +29,7 @@ pub fn compile_and_random_test<C: Config>(
n_tests: usize,
) -> (layered::Circuit<C>, InputMapping) {
assert!(rc.validate().is_ok());
let (lc, input_mapping) = compile(rc);
let (lc, input_mapping) = compile(rc, CompileOptions { is_zkcuda: false });
//print!("{}", lc);
assert_eq!(lc.validate(), Ok(()));
assert_eq!(rc.input_size(), input_mapping.cur_size());
Expand Down
1 change: 1 addition & 0 deletions expander_compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ pub mod frontend;
pub mod hints;
pub mod layering;
pub mod utils;
pub mod zkcuda;
Loading

0 comments on commit cf0a571

Please sign in to comment.