Skip to content

Commit

Permalink
Merge jf/ssa (#223)
Browse files Browse the repository at this point in the history
* Revert "Revert "Merge 'jf/ssa' to master (#217)" (#222)"

This reverts commit 7d40c57.

* Add Opcode enum

* Move passing tests to test_data directory

* Remove extra printlns

* Fix Gate Display impl

* Fix Store instructions being deleted

* Some code review changes

* cargo fmt

* Address more PR comments

* Change Result instruction to get only 1 value

* Use inline_map for result instructions

* Port over new_cloned_instruction fix, move more passing examples to test directory

* Re-disable ssa by default

* Change replacement to Mark enum

* Add get_current_value call

* Code review changes

* Don't propagate twice

* Remove comment

* Use Mark::ReplaceWith for function calls

* Cargo fmt

* Fix flipped jmp instructions

* Remove assert

* Minor renamings

* Re-add assert, remove comment

* Fix truncate behavior

* Formatting changes

* Fix frontend errors for 6_array

* Fix 6_arrays

* cargo fmt
  • Loading branch information
jfecher authored Jun 13, 2022
1 parent 7d40c57 commit 2bc0f67
Show file tree
Hide file tree
Showing 66 changed files with 1,942 additions and 2,043 deletions.
2 changes: 1 addition & 1 deletion .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
edition = "2018"
use_small_heuristics="Max"
use_small_heuristics = "Max"
45 changes: 20 additions & 25 deletions crates/acir/src/circuit/gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,69 +44,64 @@ impl Gate {

impl std::fmt::Debug for Gate {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut result = String::new();
match self {
Gate::Arithmetic(a) => {
for i in &a.mul_terms {
result +=
&format!("{:?}x{}*x{} + ", i.0, i.1.witness_index(), i.2.witness_index());
write!(f, "{:?}x{}*x{} + ", i.0, i.1.witness_index(), i.2.witness_index())?;
}
for i in &a.linear_combinations {
result += &format!("{:?}x{} + ", i.0, i.1.witness_index());
write!(f, "{:?}x{} + ", i.0, i.1.witness_index())?;
}
result += &format!("{:?} = 0", a.q_c);
write!(f, "{:?} = 0", a.q_c)
}
Gate::Range(w, s) => {
result = format!("x{} is {} bits", w.witness_index(), s);
write!(f, "x{} is {} bits", w.witness_index(), s)
}
Gate::Directive(Directive::Invert { x, result: r }) => {
result = format!("x{}=1/x{}, or 0", r.witness_index(), x.witness_index());
write!(f, "x{}=1/x{}, or 0", r.witness_index(), x.witness_index())
}
Gate::Directive(Directive::Truncate { a, b, c: _c, bit_size }) => {
result = format!(
write!(
f,
"Truncate: x{} is x{} truncated to {} bits",
b.witness_index(),
a.witness_index(),
bit_size
);
)
}
Gate::Directive(Directive::Quotient { a, b, q, r }) => {
result = format!(
write!(
f,
"Euclidian division: x{} = x{}*x{} + x{}",
a.witness_index(),
q.witness_index(),
b.witness_index(),
r.witness_index()
);
)
}
Gate::Directive(Directive::Oddrange { a, b, r, bit_size }) => {
result = format!(
write!(
f,
"Oddrange: x{} = x{}*2^{} + x{}",
a.witness_index(),
b.witness_index(),
bit_size,
r.witness_index()
);
}
Gate::And(g) => {
dbg!(&g);
}
Gate::Xor(g) => {
dbg!(&g);
}
Gate::GadgetCall(g) => {
dbg!(&g);
)
}
Gate::And(g) => write!(f, "{:?}", g),
Gate::Xor(g) => write!(f, "{:?}", g),
Gate::GadgetCall(g) => write!(f, "{:?}", g),
Gate::Directive(Directive::Split { a, b, bit_size: _ }) => {
result = format!(
write!(
f,
"Split: x{} into x{}...x{}",
a.witness_index(),
b.first().unwrap().witness_index(),
b.last().unwrap().witness_index(),
);
)
}
}
write!(f, "{}", result)
}
}

Expand Down
14 changes: 10 additions & 4 deletions crates/nargo/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ pub fn start_cli() {
App::new("prove")
.about("Create proof for this program")
.arg(Arg::with_name("proof_name").help("The name of the proof").required(true))
.arg(Arg::with_name("interactive").help("pause execution").required(false)),
.arg(
Arg::with_name("show-ssa")
.long("show-ssa")
.help("Emit debug information for the intermediate SSA IR"),
),
)
.get_matches();

Expand Down Expand Up @@ -88,9 +92,11 @@ fn write_to_file(bytes: &[u8], path: &Path) -> String {
}

// helper function which tests noir programs by trying to generate a proof and verify it
pub fn prove_and_verify(proof_name: &str, prg_dir: &Path) -> bool {
pub fn prove_and_verify(proof_name: &str, prg_dir: &Path, show_ssa: bool) -> bool {
let tmp_dir = TempDir::new("p_and_v_tests").unwrap();
println!("prove_with_path(_, {})", show_ssa);
let proof_path =
prove_cmd::prove_with_path(proof_name, prg_dir, &tmp_dir.into_path(), false).unwrap();
verify_cmd::verify_with_path(prg_dir, &proof_path).unwrap()
prove_cmd::prove_with_path(proof_name, prg_dir, &tmp_dir.into_path(), show_ssa).unwrap();

verify_cmd::verify_with_path(prg_dir, &proof_path, show_ssa).unwrap()
}
21 changes: 8 additions & 13 deletions crates/nargo/src/cli/prove_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,21 @@ use crate::{errors::CliError, resolver::Resolver};
use super::{create_dir, write_to_file, PROOFS_DIR, PROOF_EXT, PROVER_INPUT_FILE};

pub(crate) fn run(args: ArgMatches) -> Result<(), CliError> {
let proof_name = args.subcommand_matches("prove").unwrap().value_of("proof_name").unwrap();
let interactive = args.subcommand_matches("prove").unwrap().value_of("interactive");
let mut is_interactive = false;
if let Some(int) = interactive {
if int == "i" {
is_interactive = true;
}
}
prove(proof_name, is_interactive)
let args = args.subcommand_matches("prove").unwrap();
let proof_name = args.value_of("proof_name").unwrap();
let show_ssa = args.is_present("show-ssa");
prove(proof_name, show_ssa)
}

/// In Barretenberg, the proof system adds a zero witness in the first index,
/// So when we add witness values, their index start from 1.
const WITNESS_OFFSET: u32 = 1;

fn prove(proof_name: &str, interactive: bool) -> Result<(), CliError> {
fn prove(proof_name: &str, show_ssa: bool) -> Result<(), CliError> {
let curr_dir = std::env::current_dir().unwrap();
let mut proof_path = PathBuf::new();
proof_path.push(PROOFS_DIR);
let result = prove_with_path(proof_name, curr_dir, proof_path, interactive);
let result = prove_with_path(proof_name, curr_dir, proof_path, show_ssa);
match result {
Ok(_) => Ok(()),
Err(e) => Err(e),
Expand Down Expand Up @@ -89,11 +84,11 @@ pub fn prove_with_path<P: AsRef<Path>>(
proof_name: &str,
program_dir: P,
proof_dir: P,
interactive: bool,
show_ssa: bool,
) -> Result<PathBuf, CliError> {
let driver = Resolver::resolve_root_config(program_dir.as_ref())?;
let backend = crate::backends::ConcreteBackend;
let compiled_program = driver.into_compiled_program(backend.np_language(), interactive);
let compiled_program = driver.into_compiled_program(backend.np_language(), show_ssa);

// Parse the initial witness values
let witness_map = noirc_abi::input_parser::Format::Toml.parse(program_dir, PROVER_INPUT_FILE);
Expand Down
10 changes: 7 additions & 3 deletions crates/nargo/src/cli/verify_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn verify(proof_name: &str) -> Result<bool, CliError> {
proof_path.push(PROOFS_DIR);
proof_path.push(Path::new(proof_name));
proof_path.set_extension(PROOF_EXT);
verify_with_path(&curr_dir, &proof_path)
verify_with_path(&curr_dir, &proof_path, false)
}

fn process_abi_with_verifier_input(
Expand Down Expand Up @@ -77,11 +77,15 @@ pub fn add_dummy_setpub_arr(abi: &mut Abi) {
abi.parameters.push((RESERVED_PUBLIC_ARR.into(), dummy_arr));
}

pub fn verify_with_path<P: AsRef<Path>>(program_dir: P, proof_path: P) -> Result<bool, CliError> {
pub fn verify_with_path<P: AsRef<Path>>(
program_dir: P,
proof_path: P,
show_ssa: bool,
) -> Result<bool, CliError> {
let driver = Resolver::resolve_root_config(program_dir.as_ref())?;
let backend = crate::backends::ConcreteBackend;

let compiled_program = driver.into_compiled_program(backend.np_language(), false);
let compiled_program = driver.into_compiled_program(backend.np_language(), show_ssa);

let mut public_abi = compiled_program.abi.clone().unwrap().public_abi();
add_dummy_setpub_arr(&mut public_abi);
Expand Down
3 changes: 2 additions & 1 deletion crates/nargo/tests/prove_and_verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ mod tests {
match test_name {
Ok(str) => {
if c.path().is_dir() && !conf_data["exclude"].contains(&str) {
let r = nargo::cli::prove_and_verify("pp", &c.path());
println!("prove_and_verify(_, true)");
let r = nargo::cli::prove_and_verify("pp", &c.path(), true);
if conf_data["fail"].contains(&str) {
assert!(!r, "{:?} should not succeed", c.file_name());
} else {
Expand Down
2 changes: 1 addition & 1 deletion crates/nargo/tests/test_data/5_over/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

fn main(mut x : u32, y : u32) {
x = x * x;
constrain (y) == x;
constrain y == x;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 5 additions & 4 deletions crates/nargo/tests/test_data/6_array/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
//Basic tests for arrays

fn main(x : [5]u32 , y : [5]u32 , z : u32, t : u32) {
let c = 2301 as u32;
fn main(x: [5]u32, y: [5]u32, mut z: u32, t: u32) {
let mut c = (z-z+2301) as u32;

//t= t+x[0]-x[0];
z=y[4];
//Test 1:
for i in 0..5 {
c = z*z*y[i];
z = z - c;
z = z - c;
};
constrain (z==0); //y[4]=0, so c and z are always 0

Expand Down Expand Up @@ -41,4 +42,4 @@ fn main(x : [5]u32 , y : [5]u32 , z : u32, t : u32) {
};
};
constrain (z ==11539);
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 9 additions & 0 deletions crates/noir_field/src/generic_ark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,22 @@ impl<F: PrimeField> FieldElement<F> {
let bytes = self.to_bytes();
u128::from_be_bytes(bytes[16..32].try_into().unwrap())
}

pub fn try_into_u128(self) -> Option<u128> {
self.fits_in_u128().then(|| self.to_u128())
}

/// Computes the inverse or returns zero if the inverse does not exist
/// Before using this FieldElement, please ensure that this behaviour is necessary
pub fn inverse(&self) -> FieldElement<F> {
let inv = self.0.inverse().unwrap_or_else(F::zero);
FieldElement(inv)
}

pub fn try_inverse(mut self) -> Option<Self> {
self.0.inverse_in_place().map(|f| FieldElement(*f))
}

// XXX: This method is used while this field element
// implementation is not generic.
pub fn into_repr(self) -> F {
Expand Down
4 changes: 2 additions & 2 deletions crates/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl Driver {
pub fn into_compiled_program(
mut self,
np_language: acvm::Language,
interactive: bool,
show_ssa: bool,
) -> CompiledProgram {
self.build();
// First find the local crate
Expand All @@ -166,7 +166,7 @@ impl Driver {
let evaluator = Evaluator::new(main_function, &self.context);

// Compile Program
let circuit = match evaluator.compile(np_language, interactive) {
let circuit = match evaluator.compile(np_language, show_ssa) {
Ok(circuit) => circuit,
Err(err) => {
// The FileId here will be the file id of the file with the main file
Expand Down
1 change: 0 additions & 1 deletion crates/noirc_evaluator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,3 @@ lazy_static = "1.4.0"
thiserror = "1.0.21"
num-bigint = "0.4"
num-traits = "0.2.8"
if_debug = "0.1.0"
13 changes: 5 additions & 8 deletions crates/noirc_evaluator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@ impl<'a> Evaluator<'a> {
pub fn compile(
mut self,
np_language: Language,
interactive: bool,
enable_logging: bool,
) -> Result<Circuit, RuntimeError> {
// create a new environment for the main context
let mut env = Environment::new(FuncContext::Main);

// First evaluate the main function
if interactive {
self.evaluate_main_alt(&mut env, interactive)?;
if enable_logging {
self.evaluate_main_alt(&mut env, enable_logging)?;
} else {
self.evaluate_main(&mut env)?;
}
Expand Down Expand Up @@ -173,9 +173,6 @@ impl<'a> Evaluator<'a> {
HirBinaryOpKind::Shr | HirBinaryOpKind::Shl => Err(RuntimeErrorKind::Unimplemented(
"Bit shift operations are not currently implemented.".to_owned(),
)),
HirBinaryOpKind::MemberAccess => {
todo!("Member access for structs is unimplemented in the noir backend")
}
}
.map_err(|kind| kind.add_span(op.span))
}
Expand Down Expand Up @@ -208,7 +205,7 @@ impl<'a> Evaluator<'a> {
pub fn evaluate_main_alt(
&mut self,
env: &mut Environment,
interactive: bool,
enable_logging: bool,
) -> Result<(), RuntimeError> {
let mut igen = IRGenerator::new(self.context);
self.parse_abi_alt(env, &mut igen)?;
Expand All @@ -218,7 +215,7 @@ impl<'a> Evaluator<'a> {
ssa::code_gen::evaluate_main(&mut igen, env, main_func_body)?;

//Generates ACIR representation:
igen.context.ir_to_acir(self, interactive)?;
igen.context.ir_to_acir(self, enable_logging)?;
Ok(())
}

Expand Down
Loading

0 comments on commit 2bc0f67

Please sign in to comment.