Skip to content

Conversation

@Leo-Besancon
Copy link
Collaborator

@Leo-Besancon Leo-Besancon commented Sep 17, 2025

Describe your changes

This PR aims to close #450.

Tasklist:

  • Setup main codegen pipeline
  • Add E2E test pipeline (for binary test)
  • Test the generated code (by proving / verifying the program with a provided trace)
  • Handle all AirScript features relative to main trace
    • Main Boundary constraints
    • Main Transition constraints
    • Public inputs (fixed-lengths)
    • Periodic columns
      • Traits AirBuilderWithPeriodicColumns and BaseAirWithPeriodicColumns
      • implement it on a wrapper struct DebugConstraintBuilderWithPeriodicColumns
      • implement helper check_constraints_with_periodic_columns to check the constraints are valid for a given trace
      • implement the traits for upstream structs needed for prove and verify moved to a followup
  • Add all other E2E tests (note: for E2E relying on buses, I generated the main constraints)

Note that this PR will not include handling of:

  • Aux Boundary constraints
  • Aux Transition constraints

Copy link
Contributor

@adr1anh adr1anh left a comment

Choose a reason for hiding this comment

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

Had a quick sneak peek, but this is great already! Left two small comments about the codegen.

@Leo-Besancon Leo-Besancon marked this pull request as ready for review September 26, 2025 07:35
Copy link
Contributor

@adr1anh adr1anh left a comment

Choose a reason for hiding this comment

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

Looks really good! Just left some minor comments which can be addressed in a follow-up PR.

pub trait AirBuilderWithPeriodicColumns: AirBuilder {
type PeriodicColumnsVar: Field + Into<Self::Expr>;

fn periodic_columns(&self) -> Vec<Self::PeriodicColumnsVar> {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should also return a slice here which we can cast to an array.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is more complicated issue though, since I see below that we're using this to make testing easier.

{
type PeriodicColumnsVar = F;

fn periodic_columns(&self) -> Vec<Self::PeriodicColumnsVar> {
Copy link
Contributor

Choose a reason for hiding this comment

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

While maybe not for this PR, I think we can represent periodic_columns in the DebugConstraintBuilderWithPeriodicColumns struct a bit differently

  • Pad all periodic columns to the maximum length by periodic repetition
  • Transpose the columns so that we have a vector of rows.
  • We just return &self.periodic_columns[self.row_index % col.len()]

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hi! I've created an issue to do this in a followup: #492

main.row_slice(0).unwrap(),
main.row_slice(1).unwrap(),
);
builder.when_first_row().assert_zero::<_>(main_current[0] - AB::Expr::from(AB::F::from_u64(1)));
Copy link
Contributor

Choose a reason for hiding this comment

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

We should be able to call AB::Expr::from_u64().

Copy link
Contributor

Choose a reason for hiding this comment

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

And as a followup, we should be able to replace this with AB::Expr::ONE

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in the latest commit with AB::Expr::ZERO, AB::Expr::ONE and AB::Expr::from_u64()

);
builder.when_first_row().assert_zero::<_>(main_current[3]);
builder.when_transition().assert_zero::<_>(main_next[16] - main_current[16] * ((main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[3] * main_current[1] * main_current[2] + main_current[3] * main_current[3] * (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * main_current[2] + main_current[3] * main_current[1] * (AB::Expr::from(AB::F::from_u64(1)) - main_current[2]) + (AB::Expr::from(AB::F::from_u64(1)) - main_current[1]) * (AB::Expr::from(AB::F::from_u64(1)) - main_current[2])) * main_current[0] - main_current[0] + AB::Expr::from(AB::F::from_u64(1))));
builder.when_transition().assert_zero::<_>(main_next[3] - (main_current[4] + main_current[5] + main_current[6] + main_current[7] + main_current[8] + main_current[9] + main_current[10] + main_current[11] + main_current[12] + main_current[13] + main_current[14] + main_current[15] + AB::Expr::from(AB::F::from_u64(1))) * AB::Expr::from(AB::F::from_u64(2)));
Copy link
Contributor

Choose a reason for hiding this comment

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

Eventually we'd want to replace * AB::Expr::from(AB::F::from_u64(2))) with .double()

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in the latest commit, the only change I needed to introduce was to convert e.g. main_next[16] (an AB::Var) to an AB::Expr with .into() to have the double method available, which seems ok to me.

Copy link
Contributor

@adr1anh adr1anh 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 to me!

@bobbinth bobbinth requested a review from Al-Kindi-0 October 17, 2025 15:15
Copy link
Collaborator

@Al-Kindi-0 Al-Kindi-0 left a comment

Choose a reason for hiding this comment

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

Looks great!
Support and testing for periodic columns and buses will come in a follow up PR once we agree on how our version of P3 backend will look like.

use p3_fri::create_benchmark_fri_params;
use p3_matrix::dense::RowMajorMatrix;
use p3_merkle_tree::MerkleTreeMmcs;
use p3_mersenne_31::Mersenne31;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit (feel free to ignore): we can probably use just Goldilocks to stay consistent throughout

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in the latest commit!

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.

Implement Plonky3 AirBuilder main trace constraints code generation

4 participants