Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
82 changes: 63 additions & 19 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,79 @@ jobs:
uses: actions/checkout@v4

- name: Install Nargo
uses: noir-lang/[email protected].3
uses: noir-lang/[email protected].4
with:
toolchain: 1.0.0-beta.3
toolchain: 1.0.0-beta.17

- name: Install bb
run: |
npm install -g bbup
bbup -nv 1.0.0-beta.3
sudo apt install libc++-dev
curl -L https://raw.githubusercontent.com/AztecProtocol/aztec-packages/refs/heads/next/barretenberg/bbup/install | bash
~/.bb/bbup -nv 1.0.0-beta.17

- name: Build Noir benchmark programs
run: nargo export

- name: Generate gates report
- name: Generate gate report
run: ./scripts/build-gates-report.sh
env:
BACKEND: /home/runner/.bb/bb
BACKEND: /home/runner/.bb/bb


- name: Store ACIR opcode benchmark result
uses: benchmark-action/github-action-benchmark@v1
with:
name: "ACIR Opcodes"
tool: "customSmallerIsBetter"
output-file-path: "benchmark-opcodes.json"
gh-pages-branch: "gh-pages"
benchmark-data-dir-path: "dev/bench"
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: ${{ github.ref == 'refs/heads/master' }}
comment-always: ${{ contains( github.event.pull_request.labels.*.name, 'bench-show') }}
comment-on-alert: true
alert-threshold: "101%"
fail-on-alert: false
max-items-in-chart: 50

- name: Compare gates reports
id: gates_diff
uses: noir-lang/noir-gates-diff@dbe920a8dcc3370af4be4f702ca9cef29317bec1
- name: Store gates benchmark result
uses: benchmark-action/github-action-benchmark@v1
with:
report: gates_report.json
summaryQuantile: 0.9 # only display the 10% most significant circuit size diffs in the summary (defaults to 20%)
name: "Circuit Size"
tool: "customSmallerIsBetter"
output-file-path: "benchmark-circuit.json"
gh-pages-branch: "gh-pages"
benchmark-data-dir-path: "dev/bench"
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: ${{ github.ref == 'refs/heads/master' }}
comment-always: ${{ contains( github.event.pull_request.labels.*.name, 'bench-show') }}
comment-on-alert: true
alert-threshold: "101%"
fail-on-alert: false
max-items-in-chart: 50
skip-fetch-gh-pages: true

- name: Delete export files
run: rm -rf export

- name: Build Brillig benchmark programs
run: nargo export --force-brillig

- name: Generate brillig report
run: ./scripts/build-brillig-report.sh

- name: Add gates diff to sticky comment
if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target'
uses: marocchino/sticky-pull-request-comment@v2
- name: Store brillig benchmark result
uses: benchmark-action/github-action-benchmark@v1
with:
# delete the comment in case changes no longer impact circuit sizes
delete: ${{ !steps.gates_diff.outputs.markdown }}
message: ${{ steps.gates_diff.outputs.markdown }}
name: "Brillig Bytecode Size"
tool: "customSmallerIsBetter"
output-file-path: "benchmark-brillig.json"
gh-pages-branch: "gh-pages"
benchmark-data-dir-path: "dev/bench"
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: ${{ github.ref == 'refs/heads/master' }}
comment-always: ${{ contains( github.event.pull_request.labels.*.name, 'bench-show') }}
comment-on-alert: true
alert-threshold: "101%"
fail-on-alert: false
max-items-in-chart: 50
skip-fetch-gh-pages: true
29 changes: 29 additions & 0 deletions scripts/build-brillig-report.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -e

INSPECTOR=${INSPECTOR:-noir-inspector}
cd $(dirname "$0")/../

artifacts_path="./export"
artifacts=$(ls $artifacts_path)

# Start the JSON array
REPORTS=$(jq --null-input '[]')

for artifact in $artifacts; do
# Get and format the opcode info
OP_CODE_INFO=$($INSPECTOR info --json "$artifacts_path/$artifact")

# Simplified jq expression to output only package_name and opcodes from unconstrained_functions
REPORTS=$(echo $OP_CODE_INFO | jq -c '.programs[0] | del(.functions)' | jq -c --argjson old_reports $REPORTS '$old_reports + [.]')
done

echo $REPORTS | jq '{ programs: . }' > brillig_report.json

# Convert brillig report to benchmark format
output_file_brillig="benchmark-brillig.json"
jq -r '[.programs[] | .unconstrained_functions[] | {
"name": (if (.package_name // "") == "" then .name else "\(.package_name | sub("^null/"; ""))/\(.name)" end),
"unit": "opcodes",
"value": (.opcodes // 0)
}]' brillig_report.json > $output_file_brillig
17 changes: 17 additions & 0 deletions scripts/build-gates-report.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,21 @@ done

echo "]}" >> gates_report.json

# Convert the gates report into separate benchmark files
output_file_opcodes="benchmark-opcodes.json"
output_file_circuit="benchmark-circuit.json"

# Convert gates report - opcodes
jq -r '[.programs[] | {
"name": "\(.package_name)/main",
"unit": "acir_opcodes",
"value": (.functions[0].acir_opcodes // 0)
}]' gates_report.json > $output_file_opcodes

# Convert gates report - circuit size
jq -r '[.programs[] | {
"name": "\(.package_name)/main",
"unit": "circuit_size",
"value": (.functions[0].circuit_size // 0)
}]' gates_report.json > $output_file_circuit

77 changes: 75 additions & 2 deletions src/bench.nr
Original file line number Diff line number Diff line change
@@ -1,6 +1,79 @@
use super::poseidon2;
use super::{poseidon, poseidon2};

// Poseidon2 benchmarks
#[export]
fn poseidon2_length_10(input: [Field; 10]) -> Field {
fn poseidon2_hash_1(input: [Field; 1]) -> Field {
poseidon2::Poseidon2::hash(input, input.len())
}

#[export]
fn poseidon2_hash_2(input: [Field; 2]) -> Field {
poseidon2::Poseidon2::hash(input, input.len())
}

#[export]
fn poseidon2_hash_4(input: [Field; 4]) -> Field {
poseidon2::Poseidon2::hash(input, input.len())
}

#[export]
fn poseidon2_hash_8(input: [Field; 8]) -> Field {
poseidon2::Poseidon2::hash(input, input.len())
}

#[export]
fn poseidon2_hash_10(input: [Field; 10]) -> Field {
poseidon2::Poseidon2::hash(input, input.len())
}

#[export]
fn poseidon2_hash_20(input: [Field; 20]) -> Field {
poseidon2::Poseidon2::hash(input, input.len())
}

// Poseidon benchmarks
#[export]
fn poseidon_hash_1(input: [Field; 1]) -> Field {
poseidon::bn254::hash_1(input)
}

#[export]
fn poseidon_hash_2(input: [Field; 2]) -> Field {
poseidon::bn254::hash_2(input)
}

#[export]
fn poseidon_hash_4(input: [Field; 4]) -> Field {
poseidon::bn254::hash_4(input)
}

#[export]
fn poseidon_hash_8(input: [Field; 8]) -> Field {
poseidon::bn254::hash_8(input)
}

// Variable-length sponge benchmarks
#[export]
fn poseidon_sponge_1(input: [Field; 1]) -> Field {
poseidon::bn254::sponge(input)
}

#[export]
fn poseidon_sponge_4(input: [Field; 4]) -> Field {
poseidon::bn254::sponge(input)
}

#[export]
fn poseidon_sponge_8(input: [Field; 8]) -> Field {
poseidon::bn254::sponge(input)
}

#[export]
fn poseidon_sponge_16(input: [Field; 16]) -> Field {
poseidon::bn254::sponge(input)
}

#[export]
fn poseidon_sponge_32(input: [Field; 32]) -> Field {
poseidon::bn254::sponge(input)
}