Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up incremental build #1682

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
53 changes: 31 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
[workspace]
exclude = ["sdk"]
members = [
"args",
"circuits",
"cli",
"examples-builder",
Expand Down
23 changes: 23 additions & 0 deletions args/Cargo.toml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm all for improving compilation speed but seems like this comes at the cost of reordering our CLI logic in a somewhat confusing manner, I'm not sure if args should belong outside of the cli.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
categories = ["cryptography"]
description = "MozakVM cli"
edition = "2021"
keywords = ["crypto", "zero-knowledge", "vm"]
license = "All rights reserved"
name = "mozak-cli-args"
readme = "README.md"
repository = "https://github.com/0xmozak/mozak-vm"
version = "0.1.0"

[dependencies]
clap = { version = "4.5", features = [
"derive",
"cargo",
"env",
"unicode",
] }
# TODO(Matthias): implement shell completion for CLI via clap_complete
# clap_complete = "4.3"
clap-verbosity-flag = "2.2"
clap_derive = "4.5"
clio = { version = "0.3", features = ["clap-parse"] }
31 changes: 31 additions & 0 deletions args/src/bench_args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use clap::{Args as Args_, Subcommand};

#[derive(Debug, Args_, Clone)]
#[command(args_conflicts_with_subcommands = true)]
pub struct BenchArgs {
#[command(subcommand)]
pub function: BenchFunction,
}

#[derive(PartialEq, Debug, Subcommand, Clone)]
pub enum BenchFunction {
XorBench {
iterations: u32,
},
NopBench {
iterations: u32,
},
Poseidon2Bench {
input_len: u32,
},
/// Benchmarks (almost) every instruction.
OmniBench {
iterations: u32,
},
SortBench {
n: u32,
},
SortBenchRecursive {
n: u32,
},
}
76 changes: 76 additions & 0 deletions args/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#![deny(clippy::pedantic)]
#![deny(clippy::cargo)]
#![allow(clippy::multiple_crate_versions)]
pub mod bench_args;

use bench_args::BenchArgs;
use clap::{Parser, Subcommand};
use clap_derive::Args;
use clio::{Input, Output};

#[derive(Parser, Debug, Clone)]
#[command(author, version, about, long_about = None)]
pub struct Cli {
#[clap(flatten)]
pub verbose: clap_verbosity_flag::Verbosity,
#[command(subcommand)]
pub command: Command,
/// Debug API, default is OFF, currently only `prove` command is supported
#[arg(short, long)]
pub debug: bool,
}

#[derive(Clone, Debug, Args)]
pub struct RunArgs {
pub elf: Input,
#[arg(long)]
pub system_tape: Option<Input>,
#[arg(long)]
pub self_prog_id: Option<String>,
}

#[derive(Clone, Debug, Args)]
pub struct ProveArgs {
pub elf: Input,
pub proof: Output,
#[arg(long)]
pub system_tape: Option<Input>,
#[arg(long)]
pub self_prog_id: Option<String>,
pub recursive_proof: Option<Output>,
}

#[derive(Clone, Debug, Subcommand)]
pub enum Command {
/// Decode a given ELF and prints the program
Decode { elf: Input },
/// Decode and execute a given ELF. Prints the final state of
/// the registers
Run(RunArgs),
/// Prove and verify the execution of a given ELF
ProveAndVerify(RunArgs),
/// Prove the execution of given ELF and write proof to file.
Prove(ProveArgs),
/// Verify the given proof from file.
Verify { proof: Input },
/// Verify the given recursive proof from file.
VerifyRecursiveProof { proof: Input, verifier_key: Input },
/// Builds a transaction bundle.
BundleTransaction {
/// System tape generated from native execution.
#[arg(long, required = true)]
system_tape: Input,
/// Output file path of the serialized bundle.
#[arg(long, default_value = "bundle")]
bundle: Output,
},
/// Compute the Program Rom Hash of the given ELF.
ProgramRomHash { elf: Input },
/// Compute the Memory Init Hash of the given ELF.
MemoryInitHash { elf: Input },
/// Bench the function with given parameters
Bench(BenchArgs),
}

#[allow(non_upper_case_globals)]
pub const parse: fn() -> Cli = Cli::parse;
2 changes: 2 additions & 0 deletions circuits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ expr = { path = "../expr" }
itertools = "0.12"
log = "0.4"
mozak-circuits-derive = { path = "./derive" }
mozak-cli-args = { path = "../args" }
mozak-examples = { path = "../examples-builder" }
mozak-runner = { path = "../runner" }
mozak-sdk = { path = "../sdk" }
plonky2 = { workspace = true, default-features = false }
Expand Down
47 changes: 47 additions & 0 deletions circuits/src/benches/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
pub mod nop;
Copy link
Collaborator Author

@matthiasgoergens matthiasgoergens May 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file moved here from the CLI.

pub mod omni;
pub mod poseidon2;
pub mod sort;
pub mod xor;

use std::time::Duration;

use anyhow::Result;
pub use mozak_cli_args::bench_args::{BenchArgs, BenchFunction};
use nop::NopBench;
use omni::OmniBench;
use poseidon2::Poseidon2Bench;
use sort::{SortBench, SortBenchRecursive};
use xor::XorBench;

pub(crate) trait Bench {
type Args;
type Prepared;

/// method to be executed to prepare the benchmark
fn prepare(&self, args: &Self::Args) -> Self::Prepared;

/// actual benchmark function, whose execution time is
/// to be measured
fn execute(&self, prepared: Self::Prepared) -> Result<()>;

/// benchmark the `execute` function implemented through the
/// trait `Bench`
fn bench(&self, args: &Self::Args) -> Result<Duration> {
let prepared = self.prepare(args);
let start = std::time::Instant::now();
self.execute(prepared)?;
Ok(start.elapsed())
}
}

pub fn bench(args: &BenchArgs) -> Result<Duration> {
match &args.function {
BenchFunction::XorBench { iterations } => XorBench.bench(iterations),
BenchFunction::NopBench { iterations } => NopBench.bench(iterations),
BenchFunction::OmniBench { iterations } => OmniBench.bench(iterations),
BenchFunction::Poseidon2Bench { input_len } => Poseidon2Bench.bench(input_len),
BenchFunction::SortBench { n } => SortBench.bench(n),
BenchFunction::SortBenchRecursive { n } => SortBenchRecursive.bench(n),
}
}
Loading
Loading