-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Verifier profiling #3237
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
Draft
Antonio95
wants to merge
52
commits into
staging
Choose a base branch
from
profile_verifier_multirecord
base: staging
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Verifier profiling #3237
Changes from 49 commits
Commits
Show all changes
52 commits
Select commit
Hold shift + click to select a range
cd91986
added machinery to flamegraph/profile the multi-record program
Antonio95 e954ee7
working on multi-transaction flow
Antonio95 89e90bd
splitting commit
Antonio95 340fb72
added benchmarking machinery, polished
Antonio95 0d8b5d3
wip, dirty branch
Antonio95 76525ff
streamlined criterion and flamegraph machinery
Antonio95 6812d61
minor rewording, changed param
Antonio95 148451b
switched to V2 to anchor the pre-changes comparison point
Antonio95 3ea5cf1
added missing file
Antonio95 53d33bb
fixed stale merge conflict; measuring machinery ready
Antonio95 89cb2fc
bhp work
Antonio95 3ecf17e
poseidon speed-up thanks to custom s-box implementation; improved pow…
Antonio95 34143bb
cleanup
Antonio95 3d08c04
added function to get VarunaVersion from ConsensusVersion; switched t…
Antonio95 c55217d
parallelised output verification
Antonio95 7e898fd
replaced two internal states in Poseidon by their concatenation
Antonio95 bda4ac9
Revert "replaced two internal states in Poseidon by their concatenation"
Antonio95 fd28ca3
introduced preprocessed paired BHP bases
Antonio95 239cd4c
removed prints
Antonio95 efa368b
BHP wip
Antonio95 dd09be7
added variable window size to BHP; added BHP setup and size metrics
Antonio95 6306031
feat: varuna performance optimisations
1fd300b
feat: PR comments
ff55075
feat: cargo fmt
cdca9e1
Introduce ANCHOR_TIMES
raychu86 8ec0ab3
Use ConsensusVersion in target construction
raychu86 4570bec
Remove ANCHOR_TIME, derive ANCHOR_HEIGHT from V1 literal
raychu86 2644872
Add consensus tests for ANCHOR_TIMES
raychu86 7e127b9
Add tests
raychu86 29e10a8
Update anchor time height to V15
raychu86 f1096ad
Be explicit about anchor time used for reward calculations
raychu86 9f566f3
nit
raychu86 dab37dd
feat: fail on unwrap
74343e0
Run failing test on current branch
vicsn dbb06d0
Fix test_target_doubling_changes_with_anchor_time expectation
vicsn 9617735
fix(ledger): check subDAG atomicity correctly for a chain of pending …
kaimast e808c03
ci: increase machine size for ledger-narwhal-data job
kaimast aadb2dc
fix(ledger): ensure identical private keys are generated by TestChain…
kaimast a321e28
Revert "feat: fail on unwrap"
davencyw 07109ad
misc(ledger): log solution ID when post-ratify fails
kaimast a3f15bf
fix: restore the old random range algorithm for MerklePuzzle::num_leaves
ljedrz d6aaa54
fix: restore the old choose_weighted algorithm for sample_instructions
ljedrz bee5021
tweak: apply review comments
ljedrz 495209f
tweak: make the reimplementation of legacy rand functions more 1:1
ljedrz 25b50ab
logs: extra block tree caching info
ljedrz fdd65ac
introduced constensus version V16, cleanup
Antonio95 7575a57
updated two benches to varuna version v3 for comparison
Antonio95 35f63a6
Merge branch 'staging' into profile_verifier_multirecord
Antonio95 7f1400b
temporarily added the branch to merge-workflow triggers
Antonio95 1164c45
addressed PR feedback
Antonio95 317611a
Merge branch 'staging' into profile_verifier_multirecord
Antonio95 02cdf49
reduced BHP_NUM_COMBINED_CHUNKS to 4 for CLI flows
Antonio95 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,187 @@ | ||
| // Copyright (c) 2019-2026 Provable Inc. | ||
| // This file is part of the snarkVM library. | ||
|
|
||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at: | ||
|
|
||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| /* | ||
| Performs time measurements on the verification of test circuits with selected batch sizes and parameters. | ||
| - Generate artifacts with: | ||
| cargo bench --bench varuna_verifier --features test -- --generate | ||
| - Artifacts are ignored by git. To clean them, run: | ||
| cargo bench --bench varuna_verifier --features test -- --clean | ||
| - Obtain time measurements (using previously generated artifacts) with: | ||
| cargo bench --bench varuna_verifier --features test | ||
| The --serial feature can be added to deactivate parallelism. | ||
| - Flamegraph (on previously generated artifacts) with: | ||
| cargo flamegraph --bench varuna_verifier --features="test, serial" | ||
| */ | ||
|
|
||
| use snarkvm_algorithms::{ | ||
| AlgebraicSponge, | ||
| SNARK, | ||
| crypto_hash::PoseidonSponge, | ||
| snark::varuna::{ | ||
| CircuitVerifyingKey, | ||
| Proof, | ||
| TestCircuit, | ||
| VarunaHidingMode, | ||
| VarunaSNARK, | ||
| VarunaVersion, | ||
| ahp::AHPForR1CS, | ||
| }, | ||
| }; | ||
| use snarkvm_curves::bls12_377::{Bls12_377, Fq, Fr}; | ||
| use snarkvm_utilities::{CanonicalDeserialize, CanonicalSerialize, FromBytes, TestRng, ToBytes}; | ||
|
|
||
| use std::{collections::BTreeMap, env, path::Path, time::Instant}; | ||
|
|
||
| type VarunaInst = VarunaSNARK<Bls12_377, FS, VarunaHidingMode>; | ||
| type FS = PoseidonSponge<Fq, 2, 1>; | ||
|
|
||
| fn main() { | ||
| /////////////////////////// User defined | ||
|
|
||
| // How many times `verify_batch` runs when not using `--generate`. Larger values | ||
| // help flamegraph / timing stability. | ||
| let n_samples = 10; | ||
|
|
||
| // Each tuple is: (batch_size, num_constraints, num_variables, | ||
| // num_public_inputs) | ||
| let batches = [(30, 50_000, 25_000, 64), (1, 5_000_000, 5_000_000, 1024)]; | ||
|
|
||
| /////////////////////////// | ||
|
|
||
| let generate = env::args().any(|arg| arg == "--generate"); | ||
| let clean = env::args().any(|arg| arg == "--clean"); | ||
| let artifact_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("benches/snark/varuna_verifier_artifacts"); | ||
|
|
||
| if clean { | ||
| if generate { | ||
| panic!( | ||
| "--clean and --generate cannot be used together. Use --generate to generate\\ | ||
| the artifacts, --clean to delete them (and end), and neither to use the existing artifacts." | ||
| ); | ||
| } | ||
| std::fs::remove_dir_all(&artifact_path).unwrap(); | ||
| println!("Artifacts deleted."); | ||
| return; | ||
| } | ||
|
|
||
| if !artifact_path.exists() { | ||
| if !generate { | ||
| panic!("--generate was not passed, but artifacts were not found."); | ||
| } | ||
| std::fs::create_dir(&artifact_path).unwrap(); | ||
| } | ||
|
|
||
| let rng = &mut TestRng::default(); | ||
|
|
||
| let max_vars = *batches.iter().map(|(_, _, num_variables, _)| num_variables).max().unwrap(); | ||
| let max_constraints = *batches.iter().map(|(_, num_constraints, _, _)| num_constraints).max().unwrap(); | ||
| let max_density = 2 * max_constraints; | ||
|
|
||
| let max_degree = AHPForR1CS::<Fr, VarunaHidingMode>::max_degree(max_constraints, max_vars, max_density).unwrap(); | ||
| let universal_srs = VarunaInst::universal_setup(max_degree).unwrap(); | ||
| let universal_prover = &universal_srs.to_universal_prover().unwrap(); | ||
| let universal_verifier = &universal_srs.to_universal_verifier().unwrap(); | ||
| let fs_parameters = FS::sample_parameters(); | ||
|
|
||
| let varuna_version = VarunaVersion::V3; | ||
|
|
||
| let batch_str = batches | ||
| .iter() | ||
| .map(|(batch_size, num_constraints, _, num_public_inputs)| { | ||
| format!("({batch_size} x [{num_public_inputs}, {num_constraints}])") | ||
| }) | ||
| .collect::<Vec<_>>() | ||
| .join(" + "); | ||
|
|
||
| println!("Batches: {batch_str}"); | ||
|
|
||
| let sanitized_batch_str = batch_str.replace(' ', "_"); | ||
|
|
||
| let vk_path = artifact_path.join(format!("vk_{sanitized_batch_str}.bin")); | ||
| let inputs_path = artifact_path.join(format!("inputs_{sanitized_batch_str}.bin")); | ||
| let proof_path = artifact_path.join(format!("proof_{sanitized_batch_str}.bin")); | ||
|
|
||
| if generate { | ||
| println!("Generating artifacts for {batch_str}..."); | ||
|
|
||
| let circuits_and_inputs: Vec<_> = batches | ||
| .iter() | ||
| .map(|&batch| { | ||
| let (batch_size, num_constraints, num_variables, num_public_inputs) = batch; | ||
| let (circuit, public_inputs) = | ||
| TestCircuit::gen_rand(num_public_inputs, num_constraints, num_variables, rng); | ||
| ( | ||
| VarunaInst::circuit_setup(&universal_srs, &circuit).unwrap(), | ||
| vec![circuit; batch_size], | ||
| vec![public_inputs; batch_size], | ||
| ) | ||
| }) | ||
| .collect(); | ||
|
|
||
| let pks_to_circuits = circuits_and_inputs | ||
| .iter() | ||
| .map(|((pk, _), circuits, _)| (pk, circuits.as_slice())) | ||
| .collect::<BTreeMap<_, _>>(); | ||
| let vks_to_inputs = | ||
| circuits_and_inputs.iter().map(|((_, vk), _, inputs)| (vk, inputs.as_slice())).collect::<BTreeMap<_, _>>(); | ||
|
|
||
| let proof = | ||
| VarunaInst::prove_batch(universal_prover, &fs_parameters, varuna_version, &pks_to_circuits, rng).unwrap(); | ||
|
|
||
| let vks = vks_to_inputs.keys().map(|vk| (*vk).clone()).collect::<Vec<_>>(); | ||
| let inputs = vks_to_inputs.values().cloned().collect::<Vec<_>>(); | ||
|
|
||
| let mut vk_buf = Vec::new(); | ||
| CanonicalSerialize::serialize_uncompressed(&vks, &mut vk_buf).unwrap(); | ||
| std::fs::write(&vk_path, vk_buf).expect("Failed to write verifying keys"); | ||
| let mut inputs_buf = Vec::new(); | ||
| CanonicalSerialize::serialize_uncompressed(&inputs, &mut inputs_buf).unwrap(); | ||
| std::fs::write(&inputs_path, inputs_buf).expect("Failed to write inputs"); | ||
| std::fs::write(&proof_path, proof.to_bytes_le().unwrap()).expect("Failed to write proof"); | ||
| } | ||
|
|
||
| // Reload from disk so serialization and verification paths are exercised. | ||
| let vks: Vec<CircuitVerifyingKey<Bls12_377>> = CanonicalDeserialize::deserialize_uncompressed( | ||
| &*std::fs::read(&vk_path).expect("Failed to read verifying keys"), | ||
| ) | ||
| .unwrap(); | ||
| let inputs: Vec<Vec<Vec<Fr>>> = | ||
| CanonicalDeserialize::deserialize_uncompressed(&*std::fs::read(&inputs_path).expect("Failed to read inputs")) | ||
| .unwrap(); | ||
| let proof = Proof::<Bls12_377>::read_le(&*std::fs::read(&proof_path).expect("Failed to read proof")).unwrap(); | ||
| let vks_to_inputs: BTreeMap<_, _> = vks.iter().zip(inputs.iter()).map(|(vk, inp)| (vk, inp.as_slice())).collect(); | ||
|
|
||
| if generate { | ||
| println!("Verifying generated proof for {batch_str}..."); | ||
| assert!( | ||
| VarunaInst::verify_batch(universal_verifier, &fs_parameters, varuna_version, &vks_to_inputs, &proof) | ||
| .unwrap() | ||
| ); | ||
| println!("Verification successful"); | ||
| } else { | ||
| println!("Verifying proof for {batch_str} {n_samples} times..."); | ||
| let timer = Instant::now(); | ||
| for _ in 0..n_samples { | ||
| assert!( | ||
| VarunaInst::verify_batch(universal_verifier, &fs_parameters, varuna_version, &vks_to_inputs, &proof) | ||
| .unwrap() | ||
| ); | ||
| } | ||
| let elapsed = timer.elapsed().as_micros() as f64 / 1000.0; | ||
| let elapsed_avg = elapsed / n_samples as f64; | ||
| println!("Verification successful in {elapsed:.2} ms ({elapsed_avg:.2} ms per sample)"); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The merge-workflow branch filter now includes
profile_verifier_multirecord, which will trigger a large set of expensive CI jobs on that branch. This looks like a temporary profiling branch name and should not be merged into main CI config; please remove it (or replace with a generic mechanism such as tags / parameters if you need opt-in heavy checks).