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 constant intermediates #2163

Merged
merged 9 commits into from
Dec 17, 2024
Merged

Remove constant intermediates #2163

merged 9 commits into from
Dec 17, 2024

Conversation

Schaeff
Copy link
Collaborator

@Schaeff Schaeff commented Nov 27, 2024

See added test

This propagates knowledge about constant intermediates forward in source order. We could run this backwards as well but I think in practice intermediates are defined before usage.

@Schaeff Schaeff requested a review from gzanitti November 27, 2024 20:28
pilopt/src/lib.rs Outdated Show resolved Hide resolved
pilopt/src/lib.rs Outdated Show resolved Hide resolved
pilopt/tests/optimizer.rs Outdated Show resolved Hide resolved
@@ -465,6 +466,52 @@ fn remove_constant_witness_columns<T: FieldElement>(pil_file: &mut Analyzed<T>)
substitute_polynomial_references(pil_file, constant_polys);
}

/// Identifies intermediate columns that are constrained to a single value, replaces every
/// reference to this column by the value and deletes the column.
/// This assumes that intermediate columns are defined before they are used in source order.
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we can assume that, sorry.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In that case we could run it until we reach a fixed point? Or build a dependency graph first? But that goes further against the idea of having simple steps.

pilopt/src/lib.rs Outdated Show resolved Hide resolved
let ((name, poly_id), mut definition) = symbol
.array_elements()
.zip_eq(definitions.iter().cloned())
.next()
Copy link
Member

Choose a reason for hiding this comment

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

I think we should either properly iterate or check that it is not an array.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's checked line 475. I can add an assert also here for clarity?

Comment on lines 484 to 494
// replace constant intermediate columns by their value
definition.post_visit_expressions_mut(&mut |e| {
if let AlgebraicExpression::Reference(AlgebraicReference { poly_id, .. }) = e {
if let Some((_, value)) = values.get(poly_id) {
*e = AlgebraicExpression::Number(T::from(value.clone()));
}
}
});

// simplify the expression
let definition = simplify_expression(definition.clone());
Copy link
Member

Choose a reason for hiding this comment

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

Should we really iteratively replace the values right away or rather keep the steps simple and run them multiple times? Do we have that many intermediate columns that reference other intermediate columns?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The use case here is that when we build the bus accumulator updates:

    col intermediate_fingerprint_0 = 0;
    col intermediate_fingerprint_1 = 0;
    col intermediate_fingerprint_0_1 = std::prelude::challenge(0, 1) * main::intermediate_fingerprint_0 + 11 * std::prelude::challenge(0, 2) * main::intermediate_fingerprint_1 + 0;
    col intermediate_fingerprint_1_1 = std::prelude::challenge(0, 2) * main::intermediate_fingerprint_0 + std::prelude::challenge(0, 1) * main::intermediate_fingerprint_1 + 0;

All of this should be removed as it's all 0.

We have a lot of intermediates which depend on each other (depending on the number of columns we're sending/receiving), but they typically don't end up being constant. This only happens in some special cases like above.

I think running it twice without memory would work, but writing the case with memory is not that much code. Up to you :)

@leonardoalt
Copy link
Member

Is this waiting for changes or reviews?

pilopt/src/lib.rs Outdated Show resolved Hide resolved
@Schaeff Schaeff requested a review from chriseth December 13, 2024 14:47
@chriseth chriseth added this pull request to the merge queue Dec 17, 2024
Merged via the queue into main with commit 9e9fb90 Dec 17, 2024
16 checks passed
@chriseth chriseth deleted the remove-constant-intermediates branch December 17, 2024 11:04
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.

4 participants