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

chore(ssa refactor): SSA refactor main #1628

Merged
merged 21 commits into from
Jun 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6210550
disable mac tests
kevaundray Jun 9, 2023
66e7297
feat: added support for modulo ops on brillig (#1621)
sirasistant Jun 9, 2023
6bd5a8d
feat(brillig): foreign call/oracle compilation (#1600)
ludamad Jun 9, 2023
03d5040
feat: add support for assert in brillig (#1603)
guipublic Jun 9, 2023
055b892
Merge remote-tracking branch 'origin/master' into kw/brillig-main
kevaundray Jun 10, 2023
c5da92c
chore(ssa refactor): Separate Brillig only logic from Brillig-SSA gen…
kevaundray Jun 12, 2023
e66fb0c
chore(ssa_refactor): Improve foreign call compilation (#1644)
vezenovm Jun 13, 2023
f7f2647
feat: Brillig array inputs and outputs (#1630)
vezenovm Jun 13, 2023
2893855
chore(brillig): master into brillig main (#1663)
sirasistant Jun 13, 2023
3050b44
feat(brillig): Added cast instruction (#1649)
sirasistant Jun 14, 2023
870ffe7
feat(brillig): Add unique labeling and remove relative jumps (#1652)
sirasistant Jun 15, 2023
db930da
Merge remote-tracking branch 'origin/master' into kw/brillig-main
kevaundray Jun 15, 2023
69ae632
Merge remote-tracking branch 'origin/master' into kw/brillig-main
kevaundray Jun 15, 2023
2313a5e
fix `is_signed` method
kevaundray Jun 15, 2023
6f49402
feat(brillig): added basic array operations (#1716)
sirasistant Jun 16, 2023
7b999e8
feat(brillig): runtime memory allocation (#1732)
sirasistant Jun 16, 2023
6261dc8
chore(brillig): Add a register abstraction/optimization (#1737)
ludamad Jun 16, 2023
a2c454e
Merge remote-tracking branch 'origin/master' into kw/brillig-main
kevaundray Jun 16, 2023
8703de5
merge fix: AcirType is now an enum
kevaundray Jun 16, 2023
408303b
merge fix: foreign calls
kevaundray Jun 16, 2023
90d1ad4
fix: Oracle output resolution (#1740)
vezenovm Jun 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ result
*.pk
*.vk
**/Verifier.toml
**/target
54 changes: 51 additions & 3 deletions crates/nargo/src/ops/execute.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use acvm::pwg::{solve, Blocks, PartialWitnessGeneratorStatus};
use acvm::acir::brillig_vm::ForeignCallResult;
use acvm::acir::circuit::Opcode;
use acvm::pwg::{solve, Blocks, PartialWitnessGeneratorStatus, UnresolvedBrilligCall};
use acvm::PartialWitnessGenerator;
use acvm::{acir::circuit::Circuit, acir::native_types::WitnessMap};

Expand All @@ -11,8 +13,54 @@ pub fn execute_circuit(
) -> Result<WitnessMap, NargoError> {
let mut blocks = Blocks::default();
let solver_status = solve(backend, &mut initial_witness, &mut blocks, circuit.opcodes)?;
if matches!(solver_status, PartialWitnessGeneratorStatus::RequiresOracleData { .. }) {
todo!("Add oracle support to nargo execute")

// TODO(#1615): Nargo only supports "oracle_print_**_impl" functions that print a singular value or an array and nothing else
// This should be expanded in a general logging refactor
if let PartialWitnessGeneratorStatus::RequiresOracleData {
unresolved_brillig_calls,
required_oracle_data,
unsolved_opcodes,
} = solver_status
{
if !required_oracle_data.is_empty() {
unreachable!("oracles are not supported by nargo execute")
}
for unresolved_brillig_call in unresolved_brillig_calls {
let UnresolvedBrilligCall { foreign_call_wait_info, mut brillig } =
unresolved_brillig_call;

// Execute foreign calls
// TODO(#1615): "oracle_print_impl" and "oracle_print_array_impl" are just identity funcs
if foreign_call_wait_info.function == "oracle_print_impl" {
let values = &foreign_call_wait_info.inputs[0];
println!("{:?}", values[0].to_field().to_hex());
brillig.foreign_call_results.push(ForeignCallResult {
values: vec![vec![foreign_call_wait_info.inputs[0][0]]],
});
} else if foreign_call_wait_info.function == "oracle_print_array_impl" {
let mut outputs_hex = Vec::new();
for value in foreign_call_wait_info.inputs.clone() {
outputs_hex.push(value[0].to_field().to_hex());
}
// Join all of the hex strings using a comma
let comma_separated_elements = outputs_hex.join(", ");
let output_witnesses_string = "[".to_owned() + &comma_separated_elements + "]";
println!("{output_witnesses_string}");
brillig.foreign_call_results.push(ForeignCallResult {
values: vec![vec![foreign_call_wait_info.inputs[0][0]]],
});
}

let mut next_opcodes_for_solving = vec![Opcode::Brillig(brillig)];
next_opcodes_for_solving.extend_from_slice(&unsolved_opcodes[..]);

let solver_status =
solve(backend, &mut initial_witness, &mut blocks, next_opcodes_for_solving)?;
if matches!(solver_status, PartialWitnessGeneratorStatus::RequiresOracleData { .. }) {
todo!("Add multiple foreign call support to nargo execute")
// TODO 1557
}
}
}

Ok(initial_witness)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = ["1", "2", "3"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Tests a very simple program.
//
// The features being tested are array reads and writes

fn main(x: [Field; 3]) {
read_array(x);
read_write_array(x);
}

unconstrained fn read_array(x: [Field; 3]) {
assert(x[0] == 1);
let y = [1, 5, 27];

assert(y[x[0]] == 5);
}

unconstrained fn read_write_array(x: [Field; 3]) {
let mut y = x;

y[0] = 5;

assert(y[0] == 5);
assert(y[1] == 2);
assert(y[2] == 3);

assert(x[0] == 1);
assert(x[1] == 2);
assert(x[2] == 3);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = "1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Tests a very simple program.
//
// The features being tested is using assert on brillig
fn main(x: Field) {
assert(1 == conditional(x as bool));
}

unconstrained fn conditional(x : bool) -> Field {
assert(x);
1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = "0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Tests a very simple program.
//
// The features being tested is using assert on brillig
fn main(x: Field) {
assert(1 == conditional(x as bool));
}

unconstrained fn conditional(x : bool) -> Field {
assert(x);
1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Tests a very simple Brillig function.
//
// The features being tested are cast operations on brillig
fn main() {
bool_casts();
field_casts();
uint_casts();
int_casts();
mixed_casts();
}

unconstrained fn bool_casts() {
assert(false == 0 as bool);
assert(true == 1 as bool);
assert(true == 3 as bool);
}

unconstrained fn field_casts() {
assert(5 as u8 as Field == 5);
assert(16 as u4 as Field == 0);
}

unconstrained fn uint_casts() {
let x: u32 = 100;
assert(x as u2 == 0);
assert(x as u4 == 4);
assert(x as u6 == 36);
assert(x as u8 == 100);
assert(x as u64 == 100);
assert(x as u126 == 100);
}

unconstrained fn int_casts() {
let x: i32 = 100;
assert(x as i2 == 0);
assert(x as i4 == 4);
assert(x as i6 == -28 as i6);
assert(x as i8 == 100);
assert(x as i8 == 100);
assert(x as i8 == 100);
}


unconstrained fn mixed_casts() {
assert(100 as u32 as i32 as u32 == 100);
assert(13 as u4 as i2 as u32 == 1);
assert(15 as u4 as i2 as u32 == 3);
assert(1 as u8 as bool == true);
assert(true as i8 == 1);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,35 @@
use dep::std;

struct myStruct {
foo: Field,
foo_arr: [Field; 2],
}

// Tests a very simple program.
//
// The features being tested is the identity function in Brillig
fn main(x : Field) {
assert(x == identity(x));
// TODO: add support for array comparison
let arr = identity_array([x, x]);
assert(x == arr[0]);
assert(x == arr[1]);

let s = myStruct { foo: x, foo_arr: [x, x] };
let identity_struct = identity_struct(s);
assert(x == identity_struct.foo);
assert(x == identity_struct.foo_arr[0]);
assert(x == identity_struct.foo_arr[1]);
}

unconstrained fn identity(x : Field) -> Field {
x
}

unconstrained fn identity_array(arr : [Field; 2]) -> [Field; 2] {
arr
}

unconstrained fn identity_struct(s : myStruct) -> myStruct {
s
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Tests a very simple program.
//
// The features being tested is modulo operations on brillig
fn main() {
assert(modulo(47, 3) == 2);
assert(modulo(2, 3) == 2);
assert(signed_modulo(5, 3) == 2);
assert(signed_modulo(2, 3) == 2);

let minus_two: i4 = 14;
let minus_three: i4 = 13;
let minus_five: i4 = 11;

// (5 / -3) * -3 + 2 = -1 * -3 + 2 = 3 + 2 = 5
assert(signed_modulo(5, minus_three) == 2);
// (-5 / 3) * 3 - 2 = -1 * 3 - 2 = -3 - 2 = -5
assert(signed_modulo(minus_five, 3) == minus_two);
// (-5 / -3) * -3 - 2 = 1 * -3 - 2 = -3 - 2 = -5
assert(signed_modulo(minus_five, minus_three) == minus_two);
}

unconstrained fn modulo(x: u32, y: u32) -> u32 {
x % y
}

unconstrained fn signed_modulo(x: i4, y: i4) -> i4 {
x % y
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x = "10"

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Tests oracle usage in brillig/unconstrained functions
fn main(x: Field) {
// call through a brillig wrapper
oracle_print_array_wrapper([x, x]);

// TODO(#1615) Nargo currently only supports resolving one foreign call
// oracle_print_wrapper(x);
}

#[oracle(oracle_print_impl)]
unconstrained fn oracle_print(_x : Field) -> Field {}

unconstrained fn oracle_print_wrapper(x: Field) {
oracle_print(x);
}

#[oracle(oracle_print_array_impl)]
unconstrained fn oracle_print_array(_arr : [Field; 2]) -> Field {}

unconstrained fn oracle_print_array_wrapper(arr: [Field; 2]) {
oracle_print_array(arr);
}


2 changes: 1 addition & 1 deletion crates/nargo_cli/tests/test_data_ssa_refactor/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ exclude = []


# List of tests (as their directory name) expecting to fail: if the test pass, we report an error.
fail = [""]
fail = ["brillig_assert_fail"]
Loading