Skip to content

Commit c183108

Browse files
perf(whir_zk): drop linear_forms after covector build
Take linear_forms by value in prepare_and_sumcheck / prove_blinded_polynomial and drop it as soon as the combined covector has been built. Each Covector in linear_forms holds num_witnesses field elements; for R1CS circuits with 3 matrices (A, B, C) and millions of witnesses this is ~100 MB freed before the WHIR commit phase, where peak memory is hit. Measured peak reduction on provekit (m=20 circuits): - complete_age_check: 880 -> 805 MB (-8.5%) - t_add_dsc_1850: 533 -> 497 MB (-6.8%) - t_add_id_data_1850: 222 -> 203 MB (-8.6%) - poseidon-rounds: 467 -> 467 MB (no change, small linear forms) Protocol-equivalent. Transcript byte-identical. E2E prove+verify passes.
1 parent 0a68627 commit c183108

1 file changed

Lines changed: 6 additions & 5 deletions

File tree

src/protocols/whir_zk/prover.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ where
119119
&mut self,
120120
vectors: Vec<Cow<'_, [F]>>,
121121
g_polys: &[Vec<F>],
122-
linear_forms: &[Box<dyn LinearForm<F>>],
122+
linear_forms: Vec<Box<dyn LinearForm<F>>>,
123123
evaluations: &[F],
124124
) -> PrepareResult<F> {
125125
let num_vectors = self.dims.num_vectors;
@@ -159,7 +159,7 @@ where
159159
let g_claims: Vec<F> = {
160160
let mut buf = vec![F::ZERO; size];
161161
let mut claims = Vec::with_capacity(linear_forms.len());
162-
for w in linear_forms {
162+
for w in &linear_forms {
163163
buf.fill(F::ZERO);
164164
w.accumulate(&mut buf, F::ONE);
165165
claims.push(dot(&buf, &g_poly));
@@ -247,6 +247,8 @@ where
247247
for (coeff, lf) in constraint_rlc_coeffs.iter().zip(linear_forms.iter()) {
248248
lf.accumulate(&mut covector, *coeff);
249249
}
250+
// Only the combined `covector` is needed past this point.
251+
drop(linear_forms);
250252

251253
let mut the_sum: F = constraint_rlc_coeffs
252254
.iter()
@@ -475,7 +477,7 @@ impl<F: FftField> Config<F> {
475477
f_hat_polys: Vec<Vec<F>>,
476478
masking_polys: &[Vec<F>],
477479
g_polys: &[Vec<F>],
478-
linear_forms: &[Box<dyn LinearForm<F>>],
480+
linear_forms: Vec<Box<dyn LinearForm<F>>>,
479481
evaluations: &[F],
480482
) -> BlindedProveResult<F>
481483
where
@@ -682,13 +684,12 @@ impl<F: FftField> Config<F> {
682684
f_hat_polys,
683685
&secrets.masking_polys,
684686
&secrets.g_polys,
685-
&linear_forms,
687+
linear_forms,
686688
&evaluations,
687689
);
688690

689691
// Free fields only needed during Steps 2-6, before Step 7.
690692
drop(f_hat_witness);
691-
drop(linear_forms);
692693

693694
// Step 7: batched blinding polynomial proof.
694695
self.prove_blinding_polynomial(

0 commit comments

Comments
 (0)