1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00
This commit is contained in:
schaeff 2021-11-09 15:03:09 +01:00
commit 770ef15edc
12 changed files with 30 additions and 36 deletions

View file

@ -0,0 +1 @@
Reduce compiler memory usage using iterators

View file

@ -31,7 +31,7 @@ Create this file under the name `get_hash.zok`:
Compile the program to a form that is usable for zero knowledge proofs. This command writes Compile the program to a form that is usable for zero knowledge proofs. This command writes
the binary to `get_hash`. You can see a textual representation, somewhat analogous to assembler the binary to `get_hash`. You can see a textual representation, somewhat analogous to assembler
coming from a compiler, at `get_hash.ztf` enabled by the `--ztf` command line option. coming from a compiler, at `get_hash.ztf` created by the `inspect` command.
``` ```
{{#include ../../../zokrates_cli/examples/book/rng_tutorial/test.sh:10}} {{#include ../../../zokrates_cli/examples/book/rng_tutorial/test.sh:10}}
``` ```

View file

@ -7,7 +7,7 @@ function zokrates() {
ZOKRATES_STDLIB=$stdlib $bin $* ZOKRATES_STDLIB=$stdlib $bin $*
} }
zokrates compile -i get_hash.zok -o get_hash --ztf zokrates compile -i get_hash.zok -o get_hash && zokrates inspect -i get_hash
zokrates compute-witness --verbose -i get_hash -a 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 zokrates compute-witness --verbose -i get_hash -a 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
mkdir alice bob mkdir alice bob

View file

@ -83,12 +83,6 @@ fn cli_compute<T: Field, I: Iterator<Item = ir::Statement<T>>>(
println!("Computing witness..."); println!("Computing witness...");
let verbose = sub_matches.is_present("verbose"); let verbose = sub_matches.is_present("verbose");
// print deserialized flattened program if in verbose mode
// if verbose {
// println!("{}", ir_prog);
// }
let is_stdin = sub_matches.is_present("stdin"); let is_stdin = sub_matches.is_present("stdin");
let is_abi = sub_matches.is_present("abi"); let is_abi = sub_matches.is_present("abi");

View file

@ -9,7 +9,7 @@ use zokrates_field::Field;
pub fn subcommand() -> App<'static, 'static> { pub fn subcommand() -> App<'static, 'static> {
SubCommand::with_name("inspect") SubCommand::with_name("inspect")
.about("Prints the compiled program in a human readable format") .about("Outputs a compiled program to a file in a human readable format")
.arg( .arg(
Arg::with_name("input") Arg::with_name("input")
.short("i") .short("i")

View file

@ -198,10 +198,6 @@ pub fn compile<'ast, T: Field, E: Into<imports::Error>>(
log::debug!("Flatten"); log::debug!("Flatten");
let program_flattened = FlattenerIterator::from_function_and_config(typed_ast.main, config); let program_flattened = FlattenerIterator::from_function_and_config(typed_ast.main, config);
// // constant propagation after call resolution
// log::debug!("Propagate flat program");
// let program_flattened = program_flattened.propagate();
// convert to ir // convert to ir
log::debug!("Convert to IR"); log::debug!("Convert to IR");
let ir_prog = ir::from_flat::from_flat(program_flattened); let ir_prog = ir::from_flat::from_flat(program_flattened);

View file

@ -635,6 +635,7 @@ pub fn unpack_to_bitwidth<T: Field>(
let solver = Solver::bits(bit_width); let solver = Solver::bits(bit_width);
#[allow(clippy::needless_collect)]
let outputs: Vec<_> = directive_outputs let outputs: Vec<_> = directive_outputs
.iter() .iter()
.enumerate() .enumerate()

View file

@ -1284,6 +1284,8 @@ impl<'ast, T: Field> Flattener<'ast, T> {
// Rename Parameters, assign them to values in call. Resolve complex expressions with definitions // Rename Parameters, assign them to values in call. Resolve complex expressions with definitions
let params_flattened = params.into_iter().map(|e| e.get_field_unchecked()); let params_flattened = params.into_iter().map(|e| e.get_field_unchecked());
let return_values = (0..funct.return_count).map(FlatVariable::public);
for (concrete_argument, formal_argument) in params_flattened.zip(funct.arguments) { for (concrete_argument, formal_argument) in params_flattened.zip(funct.arguments) {
let new_var = self.define(concrete_argument, statements_flattened); let new_var = self.define(concrete_argument, statements_flattened);
replacement_map.insert(formal_argument.id, new_var); replacement_map.insert(formal_argument.id, new_var);
@ -1329,17 +1331,10 @@ impl<'ast, T: Field> Flattener<'ast, T> {
statements_flattened.extend(statements); statements_flattened.extend(statements);
unimplemented!(); return_values
.map(|x| FlatExpression::from(x).apply_substitution(&replacement_map))
// match return_statements.pop().unwrap() { .map(FlatUExpression::with_field)
// FlatStatement::Return(list) => list .collect()
// .expressions
// .into_iter()
// .map(|x| x.apply_substitution(&replacement_map))
// .map(FlatUExpression::with_field)
// .collect(),
// _ => unreachable!(),
// }
} }
/// Flattens an expression /// Flattens an expression
@ -2368,6 +2363,9 @@ impl<'ast, T: Field> Flattener<'ast, T> {
) { ) {
match stat { match stat {
ZirStatement::Return(exprs) => { ZirStatement::Return(exprs) => {
#[allow(clippy::needless_collect)]
// clippy suggests to not collect here, but `statements_flattened` is borrowed in the iterator,
// so we cannot borrow again when extending
let flat_expressions: Vec<_> = exprs let flat_expressions: Vec<_> = exprs
.into_iter() .into_iter()
.map(|expr| self.flatten_expression(statements_flattened, expr)) .map(|expr| self.flatten_expression(statements_flattened, expr))

View file

@ -45,6 +45,10 @@ impl<T: Field> From<FlatExpression<T>> for LinComb<T> {
box FlatExpression::Identifier(v1), box FlatExpression::Identifier(v1),
box FlatExpression::Number(n1), box FlatExpression::Number(n1),
) => LinComb::summand(n1, v1), ) => LinComb::summand(n1, v1),
FlatExpression::Mult(
box FlatExpression::Number(n1),
box FlatExpression::Number(n2),
) => LinComb::summand(n1 * n2, FlatVariable::one()),
e => unreachable!("{}", e), e => unreachable!("{}", e),
} }
} }

View file

@ -19,6 +19,13 @@ pub enum ProgEnum<
Bw6_761Program(ProgIterator<Bw6_761Field, Bw6_761I>), Bw6_761Program(ProgIterator<Bw6_761Field, Bw6_761I>),
} }
type MemoryProgEnum = ProgEnum<
Vec<Statement<Bls12_381Field>>,
Vec<Statement<Bn128Field>>,
Vec<Statement<Bls12_377Field>>,
Vec<Statement<Bw6_761Field>>,
>;
impl< impl<
Bls12_381I: IntoIterator<Item = Statement<Bls12_381Field>>, Bls12_381I: IntoIterator<Item = Statement<Bls12_381Field>>,
Bn128I: IntoIterator<Item = Statement<Bn128Field>>, Bn128I: IntoIterator<Item = Statement<Bn128Field>>,
@ -26,14 +33,7 @@ impl<
Bw6_761I: IntoIterator<Item = Statement<Bw6_761Field>>, Bw6_761I: IntoIterator<Item = Statement<Bw6_761Field>>,
> ProgEnum<Bls12_381I, Bn128I, Bls12_377I, Bw6_761I> > ProgEnum<Bls12_381I, Bn128I, Bls12_377I, Bw6_761I>
{ {
pub fn collect( pub fn collect(self) -> MemoryProgEnum {
self,
) -> ProgEnum<
Vec<Statement<Bls12_381Field>>,
Vec<Statement<Bn128Field>>,
Vec<Statement<Bls12_377Field>>,
Vec<Statement<Bw6_761Field>>,
> {
match self { match self {
ProgEnum::Bls12_381Program(p) => ProgEnum::Bls12_381Program(p.collect()), ProgEnum::Bls12_381Program(p) => ProgEnum::Bls12_381Program(p.collect()),
ProgEnum::Bn128Program(p) => ProgEnum::Bn128Program(p.collect()), ProgEnum::Bn128Program(p) => ProgEnum::Bn128Program(p.collect()),

View file

@ -204,7 +204,7 @@ mod tests {
fn verify() { fn verify() {
let program: Prog<Bn128Field> = Prog { let program: Prog<Bn128Field> = Prog {
arguments: vec![FlatParameter::private(FlatVariable::new(0))], arguments: vec![FlatParameter::private(FlatVariable::new(0))],
returns: vec![FlatVariable::public(0)], return_count: 1,
statements: vec![Statement::constraint( statements: vec![Statement::constraint(
FlatVariable::new(0), FlatVariable::new(0),
FlatVariable::public(0), FlatVariable::public(0),
@ -215,7 +215,7 @@ mod tests {
let interpreter = Interpreter::default(); let interpreter = Interpreter::default();
let witness = interpreter let witness = interpreter
.execute(&program, &vec![Bn128Field::from(42)]) .execute(program.clone(), &vec![Bn128Field::from(42)])
.unwrap(); .unwrap();
let proof = let proof =

View file

@ -234,7 +234,7 @@ mod tests {
fn verify() { fn verify() {
let program: Prog<Bn128Field> = Prog { let program: Prog<Bn128Field> = Prog {
arguments: vec![FlatParameter::private(FlatVariable::new(0))], arguments: vec![FlatParameter::private(FlatVariable::new(0))],
returns: vec![FlatVariable::public(0)], return_count: 1,
statements: vec![Statement::constraint( statements: vec![Statement::constraint(
FlatVariable::new(0), FlatVariable::new(0),
FlatVariable::public(0), FlatVariable::public(0),
@ -245,7 +245,7 @@ mod tests {
let interpreter = Interpreter::default(); let interpreter = Interpreter::default();
let witness = interpreter let witness = interpreter
.execute(&program, &vec![Bn128Field::from(42)]) .execute(program.clone(), &vec![Bn128Field::from(42)])
.unwrap(); .unwrap();
let proof = let proof =