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

Option for partitioned trace committment #336

Merged
merged 14 commits into from
Oct 24, 2024

Conversation

Al-Kindi-0
Copy link
Contributor

Addresses #335.
This still in draft as two points need to be clarified:

  1. Once we have the resulting num_partitions parts we need to hash all of them in order to get a final digest per row of the trace we are committing to. The issue is that directly hashing digests is not possible, or at least I couldn't see how to do it. One pass through the bytes representation but I am not sure this was the desired implementation. For now, the code just uses a naive merge in order to fold all the digests into one digest.
  2. The separation between num_partitions equal to 1 vs greater than 1 is not very elegant but I couldn't see a way to merge handling of the two cases.

@irakliyk
Copy link
Collaborator

Once we have the resulting num_partitions parts we need to hash all of them in order to get a final digest per row of the trace we are committing to. The issue is that directly hashing digests is not possible, or at least I couldn't see how to do it. One pass through the bytes representation but I am not sure this was the desired implementation. For now, the code just uses a naive merge in order to fold all the digests into one digest.

I wonder if we should define a new method on the Hasher trait - something like:

pub trait Hasher {
    fn merge_many(values: &[Self::Digest]) -> Self::Digest;
}

@Al-Kindi-0
Copy link
Contributor Author

I wonder if we should define a new method on the Hasher trait - something like:

pub trait Hasher {
    fn merge_many(values: &[Self::Digest]) -> Self::Digest;
}

I don't see a better solution. I will go with this unless there are any other remarks.

@Al-Kindi-0 Al-Kindi-0 marked this pull request as ready for review October 21, 2024 08:37
Copy link
Collaborator

@irakliyk irakliyk left a comment

Choose a reason for hiding this comment

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

Thank you! Looks good! I left some comments inline.

Another thing I'm wondering is whether it is better to use partition_size rather than num_partitions after all. Or maybe we should use a combination of both - e.g., something like num_partitions and min_partition_size.

The motivation is that we actually compute commitments 3 times: main trace, auxiliary trace, and constraint evaluations. All of these may have different widths. Let's for example assume that we have

  • main race: 72 columns
  • aux trace: 7 columns (degree 2 extension)
  • constraint evaluations: 8 columns (degree 2 extension)

With num_partitions = 4, we'd split things into:

  • main trace: 4 partitions with 18 columns each.
  • aux trace: 3 partitions with 4 columns each + 1 partition with 2 columns
  • constraint evaluations: 4 partitions with 4 columns each.

But if we have num_partitions = 4 and min_partition_size = 8, we'd get the following:

  • main trace: 4 partitions with 18 columns each.
  • aux trace: 1 partition with 8 columns and 1 partition with 6 columns.
  • constraint evaluations: 2 partitions with 8 columns each.

This seems like a slight better arrangement - but also not sure if the complexity is worth it.

We can also specify num_partitions/partition_size separately for each of the 3 components - but not sure if that's worth it either.

cc @TheMenko

air/src/options.rs Outdated Show resolved Hide resolved
prover/src/matrix/row_matrix.rs Outdated Show resolved Hide resolved
prover/src/trace/trace_lde/default/mod.rs Outdated Show resolved Hide resolved
prover/src/lib.rs Outdated Show resolved Hide resolved
prover/src/trace/trace_lde/mod.rs Outdated Show resolved Hide resolved
verifier/src/channel.rs Outdated Show resolved Hide resolved
@TheMenko
Copy link

With num_partitions = 4, we'd split things into:

* main trace: 4 partitions with 18 columns each.
* aux trace: 3 partitions with 4 columns each + 1 partition with 2 columns
* constraint evaluations: 4 partitions with 4 columns each.

This is how GPU code currently operates.

But if we have num_partitions = 4 and min_partition_size = 8, we'd get the following:

* main trace: 4 partitions with 18 columns each.
* aux trace: 1 partition with 8 columns and 1 partition with 6 columns.
* constraint evaluations: 2 partitions with 8 columns each.

This wouldn't be a lot of work on the GPU side. The only thing is that we should measure the performance for these two cases.
My current assumption is that for relatively small number of columns, doing min_partition_size = 8 would have a positive impact.

@Al-Kindi-0
Copy link
Contributor Author

@irakliyk , I added a proposal to implement your idea of minimal partition size and it is included in the penultimate commit

Copy link
Collaborator

@irakliyk irakliyk left a comment

Choose a reason for hiding this comment

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

Thank you! Looks good! I've added a few more comments. The main one is about potentially introducing PartitionOptions struct.

air/src/options.rs Outdated Show resolved Hide resolved
air/src/options.rs Outdated Show resolved Hide resolved
air/src/options.rs Outdated Show resolved Hide resolved
verifier/src/channel.rs Show resolved Hide resolved
prover/src/trace/trace_lde/default/tests.rs Outdated Show resolved Hide resolved
prover/src/lib.rs Outdated Show resolved Hide resolved
prover/src/trace/trace_lde/default/mod.rs Outdated Show resolved Hide resolved
@Al-Kindi-0
Copy link
Contributor Author

I have also benchmarked the code to get an idea on the delta after this PR. The results are logical:

Next

Generated 128 private-public key pairs in 4294 ms
Signed 128 messages in 1 ms
Verified 128 signature in 2866 ms
Generating proof for verifying 128 Lamport+ signatures
INFO     generate_proof [ 4.73s | 6.95% / 100.00% ]
INFO     ┝━ generate_execution_trace [ 956ms | 20.19% ] num_cols: 22
INFO     ┝━ build_domain [ 3.48ms | 0.07% ] trace_length: 131072 | lde_domain_size: 1048576
INFO     ┝━ commit_to_main_trace_segment [ 1.02s | 0.00% / 21.60% ]
INFO     │  ┝━ extend_execution_trace [ 924ms | 19.51% ] num_cols: 22 | blowup: 8
INFO     │  ┕━ compute_execution_trace_commitment [ 98.6ms | 2.08% ] commitment_domain_size: 1048576
INFO     ┝━ evaluate_constraints [ 1.39s | 29.46% ] ce_domain_size: 1048576
INFO     ┝━ commit_to_constraint_evaluations [ 784ms | 0.00% / 16.55% ]
INFO     │  ┝━ build_composition_poly_columns [ 112ms | 2.37% ] num_columns: 6
INFO     │  ┝━ evaluate_composition_poly_columns [ 570ms | 12.04% ]
INFO     │  ┕━ compute_constraint_evaluation_commitment [ 101ms | 2.14% ] log_domain_size: 20
INFO     ┝━ build_deep_composition_poly [ 103ms | 2.19% ]
INFO     ┝━ evaluate_deep_composition_poly [ 71.7ms | 1.52% ]
INFO     ┝━ compute_fri_layers [ 53.2ms | 1.12% ] num_layers: 4
INFO     ┝━ determine_query_positions [ 343µs | 0.01% ] grinding_factor: 16 | num_positions: 28
INFO     ┕━ build_proof_object [ 16.0ms | 0.34% ]
---------------------
Proof generated in 4733 ms
Proof size: 94.4 KB
Proof security: 99 bits (55 proven)
Proof hash: e74c7a32f4c8f137a161d531915117df744146d401614778caf8b6ad00cadfb1
---------------------
Proof verified in 2.3 ms

num_partitions=1 & min_partition_size=1

Generated 128 private-public key pairs in 4341 ms
Signed 128 messages in 1 ms
Verified 128 signature in 2906 ms
Generating proof for verifying 128 Lamport+ signatures
INFO     generate_proof [ 4.78s | 6.99% / 100.00% ]
INFO     ┝━ generate_execution_trace [ 951ms | 19.87% ] num_cols: 22
INFO     ┝━ build_domain [ 3.70ms | 0.08% ] trace_length: 131072 | lde_domain_size: 1048576
INFO     ┝━ commit_to_main_trace_segment [ 1.04s | 0.00% / 21.78% ]
INFO     │  ┝━ extend_execution_trace [ 938ms | 19.62% ] num_cols: 22 | blowup: 8
INFO     │  ┕━ compute_execution_trace_commitment [ 104ms | 2.17% ] commitment_domain_size: 1048576
INFO     ┝━ evaluate_constraints [ 1.40s | 29.36% ] ce_domain_size: 1048576
INFO     ┝━ commit_to_constraint_evaluations [ 799ms | 0.00% / 16.70% ]
INFO     │  ┝━ build_composition_poly_columns [ 109ms | 2.28% ] num_columns: 6
INFO     │  ┝━ evaluate_composition_poly_columns [ 584ms | 12.20% ]
INFO     │  ┕━ compute_constraint_evaluation_commitment [ 106ms | 2.22% ] log_domain_size: 20
INFO     ┝━ build_deep_composition_poly [ 105ms | 2.19% ]
INFO     ┝━ evaluate_deep_composition_poly [ 73.2ms | 1.53% ]
INFO     ┝━ compute_fri_layers [ 54.9ms | 1.15% ] num_layers: 4
INFO     ┝━ determine_query_positions [ 230µs | 0.00% ] grinding_factor: 16 | num_positions: 28
INFO     ┕━ build_proof_object [ 16.0ms | 0.33% ]
---------------------
Proof generated in 4783 ms
Proof size: 95.0 KB
Proof security: 99 bits (55 proven)
Proof hash: c57076047ef71a4eab840140bca38f7b4ab61470dfb15905974b1ec333fcdb8b
---------------------
Proof verified in 2.4 ms

num_partitions=2 & min_partition_size=4

Generated 128 private-public key pairs in 4512 ms
Signed 128 messages in 1 ms
Verified 128 signature in 3047 ms
Generating proof for verifying 128 Lamport+ signatures
INFO     generate_proof [ 4.91s | 6.51% / 100.00% ]
INFO     ┝━ generate_execution_trace [ 941ms | 19.17% ] num_cols: 22
INFO     ┝━ build_domain [ 3.54ms | 0.07% ] trace_length: 131072 | lde_domain_size: 1048576
INFO     ┝━ commit_to_main_trace_segment [ 1.13s | 0.00% / 23.02% ]
INFO     │  ┝━ extend_execution_trace [ 946ms | 19.29% ] num_cols: 22 | blowup: 8
INFO     │  ┕━ compute_execution_trace_commitment [ 183ms | 3.74% ] commitment_domain_size: 1048576
INFO     ┝━ evaluate_constraints [ 1.45s | 29.45% ] ce_domain_size: 1048576
INFO     ┝━ commit_to_constraint_evaluations [ 818ms | 0.00% / 16.67% ]
INFO     │  ┝━ build_composition_poly_columns [ 129ms | 2.64% ] num_columns: 6
INFO     │  ┝━ evaluate_composition_poly_columns [ 581ms | 11.84% ]
INFO     │  ┕━ compute_constraint_evaluation_commitment [ 108ms | 2.20% ] log_domain_size: 20
INFO     ┝━ build_deep_composition_poly [ 106ms | 2.16% ]
INFO     ┝━ evaluate_deep_composition_poly [ 72.1ms | 1.47% ]
INFO     ┝━ compute_fri_layers [ 54.7ms | 1.11% ] num_layers: 4
INFO     ┝━ determine_query_positions [ 1.19ms | 0.02% ] grinding_factor: 16 | num_positions: 28
INFO     ┕━ build_proof_object [ 16.5ms | 0.34% ]
---------------------
Proof generated in 4907 ms
Proof size: 96.0 KB
Proof security: 99 bits (55 proven)
Proof hash: f8fc4c8d1fab445366f6556ada92c04770981cf188ffd56dd0e7cabc274c920e
---------------------
Proof verified in 2.2 ms

Copy link
Collaborator

@irakliyk irakliyk left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you! I left a few more small comments inline.

air/src/options.rs Outdated Show resolved Hide resolved
air/src/options.rs Outdated Show resolved Hide resolved
air/src/options.rs Outdated Show resolved Hide resolved
air/src/options.rs Outdated Show resolved Hide resolved
prover/src/lib.rs Outdated Show resolved Hide resolved
verifier/src/channel.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@irakliyk irakliyk left a comment

Choose a reason for hiding this comment

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

All looks good! Thank you!

@irakliyk irakliyk merged commit 6204d61 into facebook:next Oct 24, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants