-
Notifications
You must be signed in to change notification settings - Fork 199
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
Switching from pedersen to poseidon causes a bytecode and witness solving blowup #4688
Comments
I think this is the same issue: use dep::std::hash::{pedersen_hash_with_separator, poseidon2::Poseidon2};
global NUM_HASHES = 4;
global HASH_LENGTH = 20;
pub fn pedersen_hash<N>(inputs: [Field; N], hash_index: u32) -> Field {
dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)
}
pub fn poseidon_hash<N>(inputs: [Field; N]) -> Field {
Poseidon2::hash(inputs, inputs.len())
}
fn main(
to_hash: [[Field; HASH_LENGTH]; NUM_HASHES],
enable: [bool; NUM_HASHES]
) -> pub [Field; NUM_HASHES] {
let mut result = [0; NUM_HASHES];
for i in 0..NUM_HASHES {
let enable = enable[i];
let to_hash = to_hash[i];
if enable {
// result[i] = pedersen_hash(to_hash, 0);
result[i] = poseidon_hash(to_hash);
}
}
result
} (run nargo info and play with poseidon/pedersen and removing the if branch) |
# Description ## Problem\* Resolves <!-- Link to GitHub Issue --> ## Summary\* This PR adds some improvements for SSA generation for programs such as in #4688 where we now make more use of information on casted values. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: jfecher <jake@aztecprotocol.com>
# Description ## Problem\* Resolves <!-- Link to GitHub Issue --> ## Summary\* This PR adds some improvements for SSA generation for programs such as in #4688 where we now make more use of information on casted values. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: jfecher <jake@aztecprotocol.com>
Looks like #4716 only reduces this from a circuit of size 74602 to 70650 (-4k) |
Even without if statements, I'm still getting a 4x constraint blowup vs pedersen. |
# Description ## Problem\* Resolves #4826. ## Summary\* When running `nargo info` with the following code: ```rust use dep::std::hash::{pedersen_hash_with_separator, poseidon2::Poseidon2}; global NUM_HASHES = 2; global HASH_LENGTH = 10; #[fold] pub fn poseidon_hash<N>(inputs: [Field; N]) -> Field { Poseidon2::hash(inputs, inputs.len()) } fn main( to_hash: [[Field; HASH_LENGTH]; NUM_HASHES], enable: [bool; NUM_HASHES] ) -> pub [Field; NUM_HASHES] { let mut result = [0; NUM_HASHES]; for i in 0..NUM_HASHES { let enable = enable[i]; let to_hash = to_hash[i]; if enable { result[i] = poseidon_hash(to_hash); } } result } ``` <img width="739" alt="Screenshot 2024-04-17 at 3 46 54 PM" src="https://github.com/noir-lang/noir/assets/43554004/fa31977d-96e9-45f7-8001-43865bc4a83c"> When using `pedersen_hash` we also get 10 opcodes for `main`. Once we get more granularity in our inline types (fold vs. inline for proving) we can most likely fully resolve this issue (#4688). ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings.
# Description ## Problem\* Resolves #4911 and #4688 ## Summary\* ~~We recently included the `#[inline(never)]` attribute to enable developers to optimize codegen.~~ This has now been switched to the name `no_predicates`. The main use-case in mind is for circuits in issue #4688 where inlining a function with heavy array operations when dependent upon witnesses is not always ideal. Specifically when the function being inlined does not need to rely on the predicate for correctness. Originally I had in mind to delay inlining all the way to after ACIR gen and inline the ACIR artifacts. However, this feels overly complex now as we have all the infrastructure to inline functions as we wish during SSA, we could just need to delay the inlining of certain functions to happen after flattening. This PR does exactly what was just mentioned. For example, the new test `no_predicates_numeric_generic_poseidon` gave these results when `poseidon_hash` was not marked with `#[no_predicates_numeric_generic_poseidon]`: <img width="785" alt="ExistingInlineStrategy" src="https://github.com/noir-lang/noir/assets/43554004/f2fc1358-c86c-4f02-999e-414056b87a01"> While when `poseidon_hash` was marked with `#[no_predicates_numeric_generic_poseidon]`: <img width="788" alt="InlineNeverBench" src="https://github.com/noir-lang/noir/assets/43554004/21d729f9-32db-4a32-b592-56f76bf5663d"> ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [X] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings.
@guipublic could you take a look at this? We added the |
I can confirm that 'no_predicates' solves the issue highlighted in the last snippet from the comments. |
# Description ## Problem\* Resolves #4688 ## Summary\* Adding the no_predicates attribute to poseidon2 because hashing operations have no side-effect. ## Additional Context ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings.
# Description ## Problem\* Related to #4688 ## Summary\* Adding the no-predicate attribute to the hash implementations of the stdlib ## Additional Context ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings.
Aim
Aztec is trying to switch from pedersen to poseidon to reduce the constraints used in hashing.
Expected Behavior
We expected witness solving time and bytecode size for ACIR functions (private) to be in the same ballpark. I did expect some issues in brillig (unconstrained) due to #4535 but this problem appears to happen in ACIR, not brillig.
Bug
Switching our account contracts from pedersen to poseidon makes witness solving time to go from < 400ms to 7 seconds.
Account contract entrypoints can dispatch to up to 6 functions that can be public or private. Every dispatch requires hashing a call stack item, that is roughly 250 items for private and 200 items for public (altough some of the items for public are known to be zero at compile time).
Previously, these account functions had in the ballpark of 10k opcodes, and after the switch to poseidon we are seeing 400k+ ACIR opcodes. The flamegraphs for a test run of the sandbox before and after the switch to pedersen can be seen here:
AztecProtocol/aztec-packages#5523 (comment)
Here is a regular noir function equivalent of an account contract entrypoint:
https://github.com/sirasistant/noir-playground/blob/main/src/main.nr#L16
The entrypoint in the repo has been simplified to only dispatch to up to 2 functions instead of 6.
To Reproduce
Project Impact
Blocker
Impact Context
This blocks the switch to Poseidon, since the witness solving blowup makes the sandbox unusable.
Workaround
None
Workaround Description
No response
Additional Context
No response
Installation Method
None
Nargo Version
0.26.0+a6016b46abf6da6de4566cf6d35a675d805dd9b5
NoirJS Version
No response
Would you like to submit a PR for this Issue?
None
Support Needs
No response
The text was updated successfully, but these errors were encountered: