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

Remove generic_const_exprs feature from EVM crate #1246

Merged
merged 2 commits into from
Sep 22, 2023

Conversation

Nashtare
Copy link
Collaborator

@Nashtare Nashtare commented Sep 20, 2023

This PR removes the unstable generic_const_exprs feature from the EVM crate. This alleviates both the risk of weird and unpredictable behavior (cf. what happened on #1235 for instance) induced by the high instability of the feature, and the growing compilation time incurred by type-checker getting stuck. This is notably visible when trying to include an eight STARK module, with compilation time completely blowing-up (7min55 vs 1min45 with 7 modules, i.e. +350% increase, in debug mode).

The approach somewhat follows the one taken in #1024.

It yields a compilation time improvement of around 20% on my machine, for no noticeable performance downgrade (proving time varies between -3% and +2% across several runs between latest main and this branch), although I'd like to extensively ensure this across different test cases and architectures.

In summary, this adds two associated types to the Stark trait, i.e. EvaluationFrame and EvaluationFrameTarget which allow to access the local view of a frame (i.e. local and next rows), replacing the previous StarkEvaluationVars and StarkEvaluationTargets structs.

Side Note: I haven't dealt with starky crate at all, although the same approach could be applied, but I wanted to get validation on the approach before generalizing.

@Nashtare Nashtare self-assigned this Sep 20, 2023
@@ -22,7 +22,16 @@ const QUOTIENT_ORACLE_INDEX: usize = 2;
/// Represents a STARK system.
pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
/// The total number of columns in the trace.
const COLUMNS: usize;
const COLUMNS: usize = Self::EvaluationFrameTarget::COLUMNS;
Copy link
Collaborator Author

@Nashtare Nashtare Sep 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that keeping this const is not technically needed, but it felt cleaner to use it for the fri methods of the trait, rather than rely on Self::EvaluationFrameTarget::COLUMNS directly there.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also leave it as it was so that it's implementer-specified (with some comment emphasizing that both associated consts must be consistent within Stark, Stark::EvaluationFrame and Stark::EvaluationFrameTarget.

@unzvfu unzvfu self-requested a review September 21, 2023 06:37
@Nashtare
Copy link
Collaborator Author

I also tested it on ARM targets, both light and beefy machines, and didn't get any noticeable difference in proving time ($|\delta| &lt; 0.8$%).

Copy link
Contributor

@unzvfu unzvfu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great; solves the problem with a minimum of fuss! Thanks heaps!

It would be nice to have a solution that avoids all those .try_into().unwrap() type conversions (which is a code smell imho), but I can't think of a way to do that without more extensive structural changes, and those type conversions are pretty harmless here anyway.

Comment on lines +246 to +251
let local_values =
TryInto::<[P; NUM_CPU_COLUMNS]>::try_into(vars.get_local_values()).unwrap();
let local_values: &CpuColumnsView<P> = local_values.borrow();
let next_values =
TryInto::<[P; NUM_CPU_COLUMNS]>::try_into(vars.get_next_values()).unwrap();
let next_values: &CpuColumnsView<P> = next_values.borrow();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I feel like this is a bit more idiomatic (and you have used it in other locations):

Suggested change
let local_values =
TryInto::<[P; NUM_CPU_COLUMNS]>::try_into(vars.get_local_values()).unwrap();
let local_values: &CpuColumnsView<P> = local_values.borrow();
let next_values =
TryInto::<[P; NUM_CPU_COLUMNS]>::try_into(vars.get_next_values()).unwrap();
let next_values: &CpuColumnsView<P> = next_values.borrow();
let local_values: &[P; NUM_CPU_COLUMNS] = vars.get_local_values().try_into().unwrap();
let local_values: &CpuColumnsView<P> = local_values.borrow();
let next_values: &[P; NUM_CPU_COLUMNS] = vars.get_next_values().try_into().unwrap();
let next_values: &CpuColumnsView<P> = next_values.borrow();

Same comment applies below, and also in keccak_stark.rs.

@@ -4,7 +4,6 @@
#![allow(clippy::type_complexity)]
#![allow(clippy::field_reassign_with_default)]
#![feature(let_chains)]
#![feature(generic_const_exprs)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥳

@Nashtare Nashtare merged commit d6be2b9 into 0xPolygonZero:main Sep 22, 2023
2 checks passed
@Nashtare
Copy link
Collaborator Author

@unzvfu I'm terribly sorry, I thought my commit addressing your comment had been pushed, will open a follow up PR for cleanup.

eightfilms added a commit to 0xmozak/mozak-vm that referenced this pull request Oct 9, 2023
This PR gets rid of `generic_const_exprs` feature entirely, which has
wasted us many hours of productivity in the past. As much as it is a
cool feature in Rust it is still very much in an unstable state, leading
to a lot of `unconstrained generic const` errors, even though our arrays
were properly constrained.

This PR gets rid of `generic_const_exprs` in the following situations:
- within the `Stark` impl entirely. This ties closely with upstream
changes to the plonky2 evm - when reviewing, it would be useful to refer
to their changes too. It is pretty much the same, except we have an
extra public inputs var. See [this
PR](0xPolygonZero/plonky2#1246) for their
changes. You will notice that I adopted the same stuff basically,
especially in our downstream fork of plonky2.
- within `HASH_SIZE` of the previously generic hasher, which was also
removed upstream previously,
[here](0xPolygonZero/plonky2#1024).
- in other misc use cases, in `prep_table` for example.
eightfilms added a commit to 0xmozak/plonky2 that referenced this pull request Oct 21, 2023
This PR mostly lifts 0xPolygonZero#1246
down into the lib level into the starky crate, getting rid of the
unstable `generic_const_exprs` feature from the crate entirely. This
should work towards the 0xPolygonZero#417
as well.

This would probably warrant a minor version bump in the starky crate to
0.2.0, since this would be an API change for anyone relying on starky.
@Nashtare Nashtare deleted the const_generic_exprs branch January 9, 2024 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants