feat: circuit rendering cmd (#130)

This commit is contained in:
dante
2023-03-01 08:41:18 +00:00
committed by GitHub
parent a48b54f766
commit 1813f1a4d7
7 changed files with 97 additions and 12 deletions

View File

@@ -77,9 +77,22 @@ jobs:
override: true
components: rustfmt, clippy
- name: Mock proving tests (public outputs)
- name: Forward Pass
run: cargo test --release --verbose tests::forward_pass_
render-circuit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Circuit Render
run: cargo test --release --verbose tests::render_circuit_
mock-proving-tests:
runs-on: ubuntu-latest-32-cores
steps:

View File

@@ -65,7 +65,7 @@ required-features = ["ezkl"]
[features]
default = ["ezkl"]
dev-graph = ["halo2_proofs/dev-graph", "plotters"]
render = ["halo2_proofs/dev-graph", "plotters"]
tensorflow = ["dep:tensorflow"]
onnx = ["dep:tract-onnx"]
ezkl = ["onnx", "serde", "serde_json", "log", "colog", "tabled"]

View File

@@ -173,7 +173,8 @@ Usage: ezkl [OPTIONS] <COMMAND>
Commands:
table Loads model and prints model table
forward Loads model and input and runs mock prover (for testing)
render-circuit Renders the model circuit to a .png file. For an overview of how to interpret these plots, see https://zcash.github.io/halo2/user/dev-tools.html
forward Runs a vanilla forward pass, produces a quantized output, and saves it to a .json file
gen-srs Generates a dummy SRS
mock Loads model and input and runs mock prover (for testing)
aggregate Aggregates proofs :)

View File

@@ -155,6 +155,21 @@ pub enum Commands {
model: String,
},
#[cfg(feature = "render")]
/// Renders the model circuit to a .png file. For an overview of how to interpret these plots, see https://zcash.github.io/halo2/user/dev-tools.html
#[command(arg_required_else_help = true)]
RenderCircuit {
/// The path to the .json data file
#[arg(short = 'D', long)]
data: String,
/// The path to the .onnx model file
#[arg(short = 'M', long)]
model: String,
/// Path to save the .png circuit render
#[arg(short = 'O', long)]
output: String,
},
/// Runs a vanilla forward pass, produces a quantized output, and saves it to a .json file
#[command(arg_required_else_help = true)]
Forward {

View File

@@ -6,6 +6,8 @@ use crate::pfsys::evm::aggregation::{
};
use crate::pfsys::evm::single::gen_evm_verifier;
use crate::pfsys::evm::{evm_verify, DeploymentCode};
#[cfg(feature = "render")]
use crate::pfsys::prepare_model_circuit;
use crate::pfsys::{create_keys, load_params_kzg, load_vk, Snark};
use crate::pfsys::{
create_proof_circuit, gen_srs, prepare_data, prepare_model_circuit_and_public_input,
@@ -25,6 +27,8 @@ use halo2_proofs::transcript::{Blake2bRead, Blake2bWrite, Challenge255};
use halo2_proofs::{dev::MockProver, poly::commitment::ParamsProver};
use halo2curves::bn256::{Bn256, Fr, G1Affine};
use log::{info, trace};
#[cfg(feature = "render")]
use plotters::prelude::*;
use snark_verifier::loader::native::NativeLoader;
use snark_verifier::system::halo2::transcript::evm::EvmTranscript;
use std::error::Error;
@@ -151,6 +155,28 @@ pub async fn run(cli: Cli) -> Result<(), Box<dyn Error>> {
let om = Model::from_ezkl_conf(cli)?;
println!("{}", Table::new(om.nodes.flatten()));
}
#[cfg(feature = "render")]
Commands::RenderCircuit {
ref data,
model: _,
ref output,
} => {
let data = prepare_data(data.to_string())?;
let circuit = prepare_model_circuit::<Fr>(&data, &cli.args)?;
info!("Rendering circuit");
// Create the area we want to draw on.
// We could use SVGBackend if we want to render to .svg instead.
// for an overview of how to interpret these plots, see https://zcash.github.io/halo2/user/dev-tools.html
let root = BitMapBackend::new(output, (512, 512)).into_drawing_area();
root.fill(&TRANSPARENT).unwrap();
let root = root.titled("Layout", ("sans-serif", 20))?;
halo2_proofs::dev::CircuitLayout::default()
// We hide labels, else most circuits become impossible to decipher because of overlaid text
.show_labels(false)
.render(cli.args.logrows, &circuit, &root)?;
}
Commands::Forward {
ref data,
model,

View File

@@ -202,6 +202,10 @@ impl Model {
| Commands::Aggregate { model, .. } => {
Model::new(model, cli.args, Mode::Table, visibility)
}
#[cfg(feature = "render")]
Commands::RenderCircuit { model, .. } => {
Model::new(model, cli.args, Mode::Table, visibility)
}
_ => panic!(),
}
}

View File

@@ -112,7 +112,15 @@ macro_rules! test_func {
use crate::mock_public_params;
use crate::forward_pass;
use crate::kzg_prove_and_verify;
use crate::render_circuit;
seq!(N in 0..=15 {
#(#[test_case(TESTS[N])])*
fn render_circuit_(test: &str) {
render_circuit(test.to_string());
}
#(#[test_case(TESTS[N])])*
fn mock_public_outputs_(test: &str) {
mock(test.to_string());
@@ -283,8 +291,25 @@ fn forward_pass(example_name: String) {
format!("./examples/onnx/{}/input_forward.json", example_name).as_str(),
"-M",
format!("./examples/onnx/{}/network.onnx", example_name).as_str(),
// "-K",
// "2", //causes failure
])
.status()
.expect("failed to execute process");
assert!(status.success());
}
// Mock prove (fast, but does not cover some potential issues)
fn render_circuit(example_name: String) {
let status = Command::new(format!("{}/release/ezkl", *CARGO_TARGET_DIR))
.args([
"--bits=16",
"-K=17",
"render-circuit",
"-D",
format!("./examples/onnx/{}/input.json", example_name).as_str(),
"-M",
format!("./examples/onnx/{}/network.onnx", example_name).as_str(),
"-O",
format!("./examples/onnx/{}/render.png", example_name).as_str(),
])
.status()
.expect("failed to execute process");
@@ -302,8 +327,6 @@ fn mock(example_name: String) {
format!("./examples/onnx/{}/input.json", example_name).as_str(),
"-M",
format!("./examples/onnx/{}/network.onnx", example_name).as_str(),
// "-K",
// "2", //causes failure
])
.status()
.expect("failed to execute process");
@@ -322,8 +345,6 @@ fn mock_public_inputs(example_name: String) {
format!("./examples/onnx/{}/input.json", example_name).as_str(),
"-M",
format!("./examples/onnx/{}/network.onnx", example_name).as_str(),
// "-K",
// "2", //causes failure
])
.status()
.expect("failed to execute process");
@@ -342,8 +363,6 @@ fn mock_public_params(example_name: String) {
format!("./examples/onnx/{}/input.json", example_name).as_str(),
"-M",
format!("./examples/onnx/{}/network.onnx", example_name).as_str(),
// "-K",
// "2", //causes failure
])
.status()
.expect("failed to execute process");
@@ -615,7 +634,14 @@ fn kzg_evm_prove_and_verify(example_name: String, with_solidity: bool) {
fn build_ezkl() {
let status = Command::new("cargo")
.args(["build", "--release", "--bin", "ezkl"])
.args([
"build",
"--release",
"--features",
"render",
"--bin",
"ezkl",
])
.status()
.expect("failed to execute process");
assert!(status.success());