Skip to content

fix: eagerly build precomputed SpMV tables, remove OnceCell (v0.68.0 → v0.68.1)#484

Open
srinathsetty wants to merge 1 commit intomainfrom
fix/eager-precomputed-spmv
Open

fix: eagerly build precomputed SpMV tables, remove OnceCell (v0.68.0 → v0.68.1)#484
srinathsetty wants to merge 1 commit intomainfrom
fix/eager-precomputed-spmv

Conversation

@srinathsetty
Copy link
Collaborator

@srinathsetty srinathsetty commented Mar 21, 2026

Replace OnceCell with plain PrecomputedSparseMatrix fields, built eagerly at construction time:

  • make() helper — single internal constructor that builds all three precomputed tables in parallel via rayon::join
  • Derived Clone — copies precomputed tables alongside matrices (cheap Vec memcpy, no rebuild)
  • Custom Deserialize — rebuilds precomputed tables from the CSR matrices on deserialization (serialized format unchanged)
  • multiply_vec/multiply_vec_pair — use fields directly, no get_or_init
  • Removed precompute_sparse_matrices() — no longer needed; tables are always available

What doesn't change

  • Serialized format (precomputed fields remain #[serde(skip)])
  • Digest computation (still uses OnceCell for lazy caching)
  • Public API surface (only precompute_sparse_matrices() removed)

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR changes R1CSShape cloning behavior to avoid carrying over cached SpMV precomputations and the cached digest when an R1CSShape is cloned, and bumps the crate version accordingly. This targets correctness risks from stale cached precomputations when a cloned shape’s matrices/dimensions are later modified inside the crate.

Changes:

  • Replace #[derive(Clone)] on R1CSShape with a manual Clone impl that resets digest and precomputed_{A,B,C} OnceCells.
  • Keep Serialize/Deserialize behavior (skipping OnceCell fields) consistent with the new clone behavior.
  • Bump crate version from 0.68.0 to 0.68.1.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/r1cs/mod.rs Implements manual Clone for R1CSShape that clears cached digest and SpMV precomputations.
Cargo.toml Version bump to 0.68.1.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Replace OnceCell<PrecomputedSparseMatrix> with eagerly-built
PrecomputedSparseMatrix fields. All R1CSShape construction now goes
through a central make() helper that builds precomputed tables in
parallel. Clone and Deserialize are implemented manually to always
rebuild from the matrices.

This eliminates the stale-cache bug where clone() (e.g., in pad())
could carry over precomputed tables from the original shape, causing
incorrect SpMV results on the cloned shape with different dimensions.

Bump version to 0.68.1.
@srinathsetty srinathsetty force-pushed the fix/eager-precomputed-spmv branch from cae4074 to d1eb2e6 Compare March 21, 2026 22:11
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

src/r1cs/mod.rs:440

  • R1CSShape used to expose a public precompute_sparse_matrices(&self) method, but it has been removed in this PR. Even if it’s now redundant, removing a public method is a breaking API change and is unexpected for a patch bump (0.68.0 → 0.68.1). Consider keeping the method as a no-op/deprecated wrapper for backward compatibility, or bumping the crate version in a way that signals a breaking change.
          || self.precomputed_B.multiply_vec(z),
          || self.precomputed_C.multiply_vec(z),
        )
      },
    );

    Ok((Az, Bz, Cz))
  }

  /// Multiplies A, B, C by two vectors simultaneously in a single pass per matrix.
  /// Returns ((Az1, Bz1, Cz1), (Az2, Bz2, Cz2)).
  pub fn multiply_vec_pair(
    &self,
    z1: &[E::Scalar],
    z2: &[E::Scalar],
  ) -> Result<
    (
      (Vec<E::Scalar>, Vec<E::Scalar>, Vec<E::Scalar>),
      (Vec<E::Scalar>, Vec<E::Scalar>, Vec<E::Scalar>),
    ),

src/r1cs/mod.rs:209

  • make() now eagerly builds PrecomputedSparseMatrix for A/B/C on every construction path (including new(), clone(), pad(), and deserialization). This changes the performance/memory profile substantially vs the previous lazy OnceCell approach (and can make clone() unexpectedly expensive). If the intent is only to avoid stale caches when cloning/padding, consider keeping the OnceCell fields and resetting them in the manual Clone impl (so precompute remains lazy/opt-in).
          || PrecomputedSparseMatrix::from_sparse(&B),
          || PrecomputedSparseMatrix::from_sparse(&C),
        )
      },
    );
    Self {
      num_cons,
      num_vars,
      num_io,
      A,
      B,
      C,
      digest: OnceCell::new(),
      precomputed_A,
      precomputed_B,
      precomputed_C,
    }
  }

  /// Create an object of type `R1CSShape` from the explicitly specified R1CS matrices
  pub fn new(
    num_cons: usize,
    num_vars: usize,
    num_io: usize,
    A: SparseMatrix<E::Scalar>,
    B: SparseMatrix<E::Scalar>,
    C: SparseMatrix<E::Scalar>,
  ) -> Result<R1CSShape<E>, NovaError> {
    let is_valid = |num_cons: usize,
                    num_vars: usize,
                    num_io: usize,

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@srinathsetty srinathsetty changed the title fix: reset precomputed SpMV caches on R1CSShape clone fix: eagerly build precomputed SpMV tables, remove OnceCell (v0.68.0 → v0.68.1) Mar 22, 2026
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