Skip to content

Commit

Permalink
Merge branch 'master' into tf/acir-var-euclid
Browse files Browse the repository at this point in the history
* master:
  feat: Optimize euclidean division acir-gen (#3121)
  chore: simplify `AcirVarData` where possible in multiplication (#3124)
  feat: Remove unnecessary truncation of boolean multiplication (#3122)
  chore: use `circuit.get_assert_message` instead of closure/helper function (#3127)
  fix: minor problems with `aztec` publishing (#3095)
  chore: clean up JS dependencies (#3114)
  chore: add call formatter (#3102)
  chore: remove unnecessary clone when executing brillig (#3120)
  feat: return compilation errors from noir_wasm (#3091)
  • Loading branch information
TomAFrench committed Oct 12, 2023
2 parents 50ed8cb + 2c175c0 commit d5192e5
Show file tree
Hide file tree
Showing 30 changed files with 247 additions and 164 deletions.
66 changes: 43 additions & 23 deletions .github/workflows/publish-es-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
noir-ref:
description: The noir reference to checkout
required: false
default: 'master'
npm-tag:
description: Repository Tag to publish under
required: false
Expand All @@ -20,7 +21,7 @@ jobs:
- name: Checkout sources
uses: actions/checkout@v4
with:
ref: ${{ inputs.noir-ref || 'master' }}
ref: ${{ inputs.noir-ref }}

- name: Setup Nix
uses: ./.github/actions/nix
Expand All @@ -32,85 +33,104 @@ jobs:
- name: Enable aztec features
if: ${{ inputs.npm-tag == 'aztec' }}
run: |
echo "\ndefault = [\"aztec\"]" >> compiler/noirc_frontend/Cargo.toml
echo $'\n'"default = [\"aztec\"]"$'\n' >> compiler/noirc_frontend/Cargo.toml
- name: Build wasm package
run: |
nix build -L .#noir_wasm
- uses: actions/upload-artifact@v3
with:
name: noir_wasm
path: |
result/noir_wasm/nodejs
result/noir_wasm/web
build-noirc_abi_wasm:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4
with:
ref: ${{ inputs.noir-ref || 'master' }}
ref: ${{ inputs.noir-ref }}

- name: Setup Nix
uses: ./.github/actions/nix
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
nix-cache-name: ${{ vars.NIX_CACHE_NAME }}
cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }}

- name: Build wasm package
run: |
nix build -L .#noirc_abi_wasm
- uses: actions/upload-artifact@v3
with:
name: noirc_abi_wasm
path: |
result/noirc_abi_wasm/nodejs
result/noirc_abi_wasm/web
build-acvm_js:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4
with:
ref: ${{ inputs.noir-ref || 'master' }}
ref: ${{ inputs.noir-ref }}

- name: Setup Nix
uses: ./.github/actions/nix
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
nix-cache-name: ${{ vars.NIX_CACHE_NAME }}
cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }}

- name: Build wasm package
run: |
nix build -L .#acvm_js
- uses: actions/upload-artifact@v3
with:
name: acvm_js
path: |
result/acvm_js/nodejs
result/acvm_js/web
publish-es-packages:
runs-on: ubuntu-latest
needs: [build-acvm_js, build-noirc_abi_wasm, build-noir_wasm]
steps:

- name: Checkout sources
uses: actions/checkout@v4
with:
ref: ${{ inputs.noir-ref || 'master' }}
ref: ${{ inputs.noir-ref }}

- name: Setup Nix
uses: ./.github/actions/nix
- uses: actions/download-artifact@v3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
nix-cache-name: ${{ vars.NIX_CACHE_NAME }}
cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }}
name: acvm_js
path: acvm-repo/acvm_js
- uses: actions/download-artifact@v3
with:
name: noir_wasm
path: compiler/wasm
- uses: actions/download-artifact@v3
with:
name: noirc_abi_wasm
path: tooling/noirc_abi_wasm

- name: Install Yarn dependencies
run: yarn install

- name: Enable aztec features
if: ${{ inputs.npm-tag == 'aztec' }}
run: |
echo "\ndefault = [\"aztec\"]" >> compiler/noirc_frontend/Cargo.toml
- name: Build ES Packages
run: yarn prepare:publish
run: yarn build:js:only

- name: Prepare nightly version
if: ${{ inputs.npm-tag != 'latest' }}
run: |
yarn nightly:version
- name: Update Version as specific tag
run: |
jq '.version = .version + "-${{ inputs.npm-tag }}"' package.json > package-tmp.json && mv package-tmp.json package.json
yarn nightly:version -- .${{ inputs.npm-tag }}
- name: Authenticate with npm
run: "echo npmAuthToken: ${{ secrets.NPM_TOKEN }} > ~/.yarnrc.yml"
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

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

6 changes: 4 additions & 2 deletions acvm-repo/acvm_js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
"test:browser": "web-test-runner",
"lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0",
"publish": "echo 📡 publishing `$npm_package_name` && yarn npm publish",
"nightly:version": "jq --arg new_version \"-$(git rev-parse --short HEAD)\" '.version = .version + $new_version' package.json > package-tmp.json && mv package-tmp.json package.json",
"clean": "chmod u+w web nodejs || true && rm -rf web nodejs"
"nightly:version": "jq --arg new_version \"-$(git rev-parse --short HEAD)$1\" '.version = .version + $new_version' package.json > package-tmp.json && mv package-tmp.json package.json",
"clean": "chmod u+w web nodejs || true && rm -rf web nodejs",
"build:nix": "nix build -L .#acvm_js",
"install:from:nix": "yarn clean && yarn build:nix && cp -rL ./result/acvm_js/nodejs ./ && cp -rL ./result/acvm_js/web ./"
},
"devDependencies": {
"@esm-bundle/chai": "^4.3.4-fix.0",
Expand Down
26 changes: 5 additions & 21 deletions acvm-repo/acvm_js/src/execute.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use acvm::{
acir::circuit::{Circuit, OpcodeLocation},
acir::circuit::Circuit,
pwg::{ACVMStatus, ErrorLocation, OpcodeResolutionError, ACVM},
};
#[allow(deprecated)]
Expand Down Expand Up @@ -84,17 +84,13 @@ pub async fn execute_circuit_with_black_box_solver(
| OpcodeResolutionError::IndexOutOfBounds {
opcode_location: ErrorLocation::Resolved(opcode_location),
..
} => (
get_assert_message(&circuit.assert_messages, opcode_location),
Some(vec![*opcode_location]),
),
} => {
(circuit.get_assert_message(*opcode_location), Some(vec![*opcode_location]))
}
OpcodeResolutionError::BrilligFunctionFailed { call_stack, .. } => {
let failing_opcode =
call_stack.last().expect("Brillig error call stacks cannot be empty");
(
get_assert_message(&circuit.assert_messages, failing_opcode),
Some(call_stack.clone()),
)
(circuit.get_assert_message(*failing_opcode), Some(call_stack.clone()))
}
_ => (None, None),
};
Expand All @@ -117,15 +113,3 @@ pub async fn execute_circuit_with_black_box_solver(
let witness_map = acvm.finalize();
Ok(witness_map.into())
}

// Searches the slice for `opcode_location`.
// This is functionality equivalent to .get on a map.
fn get_assert_message(
assert_messages: &[(OpcodeLocation, String)],
opcode_location: &OpcodeLocation,
) -> Option<String> {
assert_messages
.iter()
.find(|(loc, _)| loc == opcode_location)
.map(|(_, message)| message.clone())
}
40 changes: 28 additions & 12 deletions compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ impl AcirContext {
}
(AcirVarData::Const(constant), AcirVarData::Expr(expr))
| (AcirVarData::Expr(expr), AcirVarData::Const(constant)) => {
self.add_data(AcirVarData::Expr(&expr * constant))
self.add_data(AcirVarData::from(&expr * constant))
}
(AcirVarData::Witness(lhs_witness), AcirVarData::Witness(rhs_witness)) => {
let mut expr = Expression::default();
Expand Down Expand Up @@ -569,13 +569,29 @@ impl AcirContext {
// When the predicate is 0, the equation always passes.
// When the predicate is 1, the rhs must not be 0.
let zero = self.add_constant(FieldElement::zero());
if self.is_constant_one(&predicate) {
// If the predicate is known to be active, we simply assert that an inverse must exist.
let _inverse = self.inv_var(rhs, predicate)?;
} else {
let rhs_is_zero = self.eq_var(rhs, zero)?;
let rhs_is_not_zero = self.mul_var(rhs_is_zero, predicate)?;
self.assert_eq_var(rhs_is_not_zero, zero, None)?;
let one = self.add_constant(FieldElement::one());

let rhs_expr = self.var_to_expression(rhs)?;
let rhs_is_nonzero_const = rhs_expr.is_const() && !rhs_expr.is_zero();
if !rhs_is_nonzero_const {
match self.var_to_expression(predicate)?.to_const() {
Some(predicate) if predicate.is_zero() => {
// If predicate is known to be inactive, we don't need to lay down constraints.
}

Some(predicate) if predicate.is_one() => {
// If the predicate is known to be active, we simply assert that an inverse must exist.
// This implies that `rhs != 0`.
let _inverse = self.inv_var(rhs, one)?;
}

_ => {
// Otherwise we must handle both potential cases.
let rhs_is_zero = self.eq_var(rhs, zero)?;
let rhs_is_not_zero = self.mul_var(rhs_is_zero, predicate)?;
self.assert_eq_var(rhs_is_not_zero, zero, None)?;
}
}
}

// maximum bit size for q and for [r and rhs]
Expand Down Expand Up @@ -1101,7 +1117,7 @@ impl AcirContext {
// Optimistically try executing the brillig now, if we can complete execution they just return the results.
// This is a temporary measure pending SSA optimizations being applied to Brillig which would remove constant-input opcodes (See #2066)
if let Some(brillig_outputs) =
self.execute_brillig(generated_brillig.byte_code.clone(), &b_inputs, &outputs)
self.execute_brillig(&generated_brillig.byte_code, &b_inputs, &outputs)
{
return Ok(brillig_outputs);
}
Expand Down Expand Up @@ -1188,7 +1204,7 @@ impl AcirContext {

fn execute_brillig(
&mut self,
code: Vec<BrilligOpcode>,
code: &[BrilligOpcode],
inputs: &[BrilligInputs],
outputs_types: &[AcirType],
) -> Option<Vec<AcirValue>> {
Expand Down Expand Up @@ -1461,7 +1477,7 @@ pub(crate) struct AcirVar(usize);
///
/// Returns `None` if complete execution of the Brillig bytecode is not possible.
fn execute_brillig(
code: Vec<BrilligOpcode>,
code: &[BrilligOpcode],
inputs: &[BrilligInputs],
) -> Option<(Registers, Vec<Value>)> {
struct NullBbSolver;
Expand Down Expand Up @@ -1517,7 +1533,7 @@ fn execute_brillig(

// Instantiate a Brillig VM given the solved input registers and memory, along with the Brillig bytecode.
let input_registers = Registers::load(input_register_values);
let mut vm = VM::new(input_registers, input_memory, &code, Vec::new(), &NullBbSolver);
let mut vm = VM::new(input_registers, input_memory, code, Vec::new(), &NullBbSolver);

// Run the Brillig VM on these inputs, bytecode, etc!
let vm_status = vm.process_opcodes();
Expand Down
10 changes: 9 additions & 1 deletion compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,15 @@ fn operator_result_max_bit_size_to_truncate(
match op {
Add => Some(std::cmp::max(lhs_bit_size, rhs_bit_size) + 1),
Subtract => Some(std::cmp::max(lhs_bit_size, rhs_bit_size) + 1),
Multiply => Some(lhs_bit_size + rhs_bit_size),
Multiply => {
if lhs_bit_size == 1 || rhs_bit_size == 1 {
// Truncation is unnecessary as multiplication by a boolean value cannot cause an overflow.
None
} else {
Some(lhs_bit_size + rhs_bit_size)
}
}

ShiftLeft => {
if let Some(rhs_constant) = dfg.get_numeric_constant(rhs) {
// Happy case is that we know precisely by how many bits the the integer will
Expand Down
2 changes: 1 addition & 1 deletion compiler/source-resolver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"test": "ava",
"generate-types": "tsc src/*.ts --declaration --emitDeclarationOnly --outDir types",
"clean": "rm -rf ./lib ./lib-node",
"nightly:version": "jq --arg new_version \"-$(git rev-parse --short HEAD)\" '.version = .version + $new_version' package.json > package-tmp.json && mv package-tmp.json package.json",
"nightly:version": "jq --arg new_version \"-$(git rev-parse --short HEAD)$1\" '.version = .version + $new_version' package.json > package-tmp.json && mv package-tmp.json package.json",
"publish": "echo 📡 publishing `$npm_package_name` && yarn npm publish",
"lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0"
},
Expand Down
1 change: 1 addition & 0 deletions compiler/wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ fm.workspace = true
nargo.workspace = true
noirc_driver.workspace = true
noirc_frontend.workspace = true
noirc_errors.workspace = true
wasm-bindgen.workspace = true
serde.workspace = true
js-sys.workspace = true
Expand Down
7 changes: 5 additions & 2 deletions compiler/wasm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@
"test:node": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\"}' mocha",
"test:browser": "web-test-runner",
"clean": "chmod u+w web nodejs || true && rm -rf ./nodejs ./web ./target ./result",
"nightly:version": "jq --arg new_version \"-$(git rev-parse --short HEAD)\" '.version = .version + $new_version' package.json > package-tmp.json && mv package-tmp.json package.json",
"nightly:version": "jq --arg new_version \"-$(git rev-parse --short HEAD)$1\" '.version = .version + $new_version' package.json > package-tmp.json && mv package-tmp.json package.json",
"publish": "echo 📡 publishing `$npm_package_name` && yarn npm publish",
"lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0"
"lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0",
"build:nix": "nix build -L .#noir_wasm",
"install:from:nix": "yarn clean && yarn build:nix && cp -rL ./result/noir_wasm/nodejs ./ && cp -rL ./result/noir_wasm/web ./"

},
"peerDependencies": {
"@noir-lang/source-resolver": "workspace:*"
Expand Down
8 changes: 6 additions & 2 deletions compiler/wasm/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ pub fn compile(

if contracts.unwrap_or_default() {
let compiled_contract = compile_contract(&mut context, crate_id, &compile_options)
.map_err(|_| JsCompileError::new("Failed to compile contract".to_string()))?
.map_err(|errs| {
JsCompileError::new("Failed to compile contract", errs, &context.file_manager)
})?
.0;

let optimized_contract =
Expand All @@ -68,7 +70,9 @@ pub fn compile(
Ok(<JsValue as JsValueSerdeExt>::from_serde(&preprocessed_contract).unwrap())
} else {
let compiled_program = compile_main(&mut context, crate_id, &compile_options, None, true)
.map_err(|_| JsCompileError::new("Failed to compile program".to_string()))?
.map_err(|errs| {
JsCompileError::new("Failed to compile program", errs, &context.file_manager)
})?
.0;

let optimized_program =
Expand Down
Loading

0 comments on commit d5192e5

Please sign in to comment.