Skip to content

Commit b9a3eb5

Browse files
author
AztecBot
committed
Merge branch 'next' into merge-train/spartan
2 parents 1d01c59 + b30fe8f commit b9a3eb5

4 files changed

Lines changed: 84 additions & 43 deletions

File tree

barretenberg/cpp/CLAUDE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,27 @@ Key constants to watch:
108108

109109
If C++ static_asserts fail after your changes, update both the assert values AND the corresponding Noir constants, then run `yarn remake-constants`.
110110

111+
## Prover.toml Fixtures
112+
113+
Proof-length-affecting changes (e.g. `CHONK_PROOF_LENGTH` bumps from MegaFlavor entity additions) make the committed `Prover.toml` fixtures stale. `nargo execute --program-dir <crate>` then fails with `Type Array { length: N, typ: Field } is expected to have length N but value Vec(...)`.
114+
115+
Regenerate via the e2e prover full test with fake proofs:
116+
117+
```bash
118+
cd yarn-project
119+
AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn workspace @aztec/end-to-end test full.test
120+
```
121+
122+
`FAKE_PROOFS=1` skips real proving — runs in ~2 min (orchestrator + witness generation only). Writes 12 `Prover.toml` files under `noir-projects/noir-protocol-circuits/crates/<circuit>/Prover.toml`.
123+
124+
For circuits not exercised by `full.test.ts` (`rollup-tx-merge`, `rollup-block-root`, `rollup-block-root-single-tx`, `rollup-block-merge`, `rollup-checkpoint-root`, `rollup-block-root-first-empty-tx`), additionally run:
125+
126+
```bash
127+
AZTEC_GENERATE_TEST_DATA=1 yarn workspace @aztec/prover-client test orchestrator_single_checkpoint
128+
```
129+
130+
Verify with `nargo execute --program-dir noir-projects/noir-protocol-circuits/crates/<crate>` for any previously-failing crate; should print `Circuit witness successfully solved`.
131+
111132
## Verification Keys
112133

113134
**IMPORTANT**: When making barretenberg changes that could affect verification keys, you must verify that VKs haven't changed unexpectedly, or

barretenberg/cpp/src/barretenberg/polynomials/polynomial.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -308,15 +308,23 @@ void add_scaled_batch(Polynomial<Fr>& dst,
308308
parallel_for([&](const ThreadChunk& chunk) {
309309
BB_BENCH_TRACY_NAME("add_scaled_batch/chunk");
310310
auto chunk_indices = chunk.range(union_size, min_start);
311+
if (chunk_indices.empty()) {
312+
return;
313+
}
314+
auto chunk_start = chunk_indices.front();
315+
auto chunk_end = chunk_indices.back();
316+
311317
for (size_t k = 0; k < sources.size(); ++k) {
312318
const auto& src = sources[k];
313-
const Fr c = scalars[k];
319+
const Fr& c = scalars[k];
314320
const size_t src_start = src.start_index;
315321
const size_t src_end = src.end_index();
316-
for (size_t i : chunk_indices) {
317-
if (i >= src_start && i < src_end) {
318-
dst.at(i) += c * src[i];
319-
}
322+
323+
const size_t idx_start = std::max(chunk_start, src_start);
324+
const size_t idx_end = std::min(chunk_end + 1, src_end);
325+
326+
for (size_t i = idx_start; i < idx_end; ++i) {
327+
dst.at(i) += c * src[i];
320328
}
321329
}
322330
});

barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,10 @@ template <typename Flavor> void OinkProver<Flavor>::commit_to_z_perm()
186186
template <typename Flavor> void OinkProver<Flavor>::commit_to_masking_poly()
187187
{
188188
if constexpr (flavor_has_gemini_masking<Flavor>()) {
189-
// Gemini masking poly only needs to cover the actual polynomial extent, not full dyadic size
190-
const size_t polynomial_size = prover_instance->polynomials.max_end_index();
191-
prover_instance->polynomials.gemini_masking_poly = Polynomial<FF>::random(polynomial_size);
189+
// virtual_size = dyadic_size matches every other witness poly, so sumcheck's pairwise read
190+
// past end_index lands in the virtual-zero region.
191+
prover_instance->polynomials.gemini_masking_poly = Polynomial<FF>::random(
192+
prover_instance->polynomials.max_end_index(), prover_instance->dyadic_size(), /*start_index=*/0);
192193

193194
// Commit to the masking polynomial and send to transcript
194195
auto masking_commitment = commitment_key.commit(prover_instance->polynomials.gemini_masking_poly);

barretenberg/cpp/src/barretenberg/vm2/constraining/prover.cpp

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -216,27 +216,49 @@ void AvmProver::execute_pcs_rounds()
216216
return static_cast<size_t>(std::distance(polys.begin(), it));
217217
};
218218

219+
auto add_scaled_batched =
220+
[](Polynomial& dst, const std::span<Polynomial>& sources, const std::span<FF>& scalars, const size_t skip_idx) {
221+
const size_t num_slots = bb::get_num_cpus();
222+
std::vector<Polynomial> batched_polys(num_slots);
223+
for (auto& poly : batched_polys) {
224+
poly = Polynomial(dst.size(), dst.virtual_size(), dst.start_index());
225+
}
226+
227+
// Chunks are consumed dynamically via an atomic counter: faster threads naturally pick up
228+
// more chunks while the slot they write to stays fixed for the life of their outer task.
229+
std::atomic<size_t> next_poly(0);
230+
231+
// Accumulate polynomials: each thread picks up the next available polynomial
232+
parallel_for(num_slots, [&](size_t slot_id) {
233+
while (true) {
234+
const size_t poly_id = next_poly.fetch_add(1, std::memory_order_relaxed);
235+
if (poly_id >= sources.size()) {
236+
break;
237+
}
238+
if (poly_id == skip_idx) {
239+
continue;
240+
}
241+
242+
const size_t start_idx = sources[poly_id].start_index();
243+
const size_t end_idx = sources[poly_id].end_index();
244+
for (size_t idx = start_idx; idx < end_idx; idx++) {
245+
batched_polys[slot_id].at(idx) += scalars[poly_id] * sources[poly_id][idx];
246+
}
247+
}
248+
});
249+
250+
for (const auto& poly : batched_polys) {
251+
dst += poly;
252+
}
253+
};
254+
219255
// Batch to be shifted polys in their to_be_shifted form
220256
// Search for poly with largest end index to avoid allocating a zero polynomial of circuit size
221257
size_t max_idx = index_of_max_end_index(shifted_polys);
222258

223259
Polynomial batched_shifted = std::move(shifted_polys[max_idx]);
224260
batched_shifted *= shifted_challenges[max_idx];
225-
{
226-
// Fuse the remaining add_scaled dispatches into a single parallel_for to amortise startup cost.
227-
std::vector<PolynomialSpan<const FF>> sources;
228-
std::vector<FF> scalars;
229-
sources.reserve(shifted_polys.size());
230-
scalars.reserve(shifted_polys.size());
231-
for (size_t idx = 0; idx < shifted_polys.size(); ++idx) {
232-
if (idx != max_idx) {
233-
sources.emplace_back(shifted_polys[idx]);
234-
scalars.push_back(shifted_challenges[idx]);
235-
}
236-
}
237-
add_scaled_batch(
238-
batched_shifted, std::span<const PolynomialSpan<const FF>>(sources), std::span<const FF>(scalars));
239-
}
261+
add_scaled_batched(batched_shifted, shifted_polys, shifted_challenges, max_idx);
240262

241263
// Batch unshifted polys (to avoid allocating a zero polynomial of circuit size, we initialize the batched
242264
// polynomial with the polynomial of the largest size)
@@ -245,25 +267,15 @@ void AvmProver::execute_pcs_rounds()
245267
Polynomial batched_unshifted = std::move(unshifted_polys[max_idx]);
246268
batched_unshifted *= unshifted_challenges[max_idx];
247269
batched_unshifted += batched_shifted;
248-
{
249-
// Only operate in the range of not to be shifted polys, as the contribution for those has already been added.
250-
std::vector<PolynomialSpan<const FF>> sources;
251-
std::vector<FF> scalars;
252-
sources.reserve(unshifted_polys.size());
253-
scalars.reserve(unshifted_polys.size());
254-
for (size_t idx = 0; idx < unshifted_polys.size(); ++idx) {
255-
if (idx >= WIRES_TO_BE_SHIFTED_START_IDX && idx < WIRES_TO_BE_SHIFTED_END_IDX) {
256-
continue;
257-
}
258-
if (idx == max_idx) {
259-
continue;
260-
}
261-
sources.emplace_back(unshifted_polys[idx]);
262-
scalars.push_back(unshifted_challenges[idx]);
263-
}
264-
add_scaled_batch(
265-
batched_unshifted, std::span<const PolynomialSpan<const FF>>(sources), std::span<const FF>(scalars));
266-
}
270+
add_scaled_batched(batched_unshifted,
271+
unshifted_polys.subspan(0, WIRES_TO_BE_SHIFTED_START_IDX),
272+
unshifted_challenges.subspan(0, WIRES_TO_BE_SHIFTED_START_IDX),
273+
max_idx);
274+
add_scaled_batched(batched_unshifted,
275+
unshifted_polys.subspan(WIRES_TO_BE_SHIFTED_END_IDX),
276+
unshifted_challenges.subspan(WIRES_TO_BE_SHIFTED_END_IDX),
277+
max_idx > WIRES_TO_BE_SHIFTED_END_IDX ? max_idx - WIRES_TO_BE_SHIFTED_END_IDX
278+
: unshifted_polys.size());
267279

268280
const size_t circuit_dyadic_size = numeric::round_up_power_2(batched_unshifted.end_index());
269281

@@ -308,5 +320,4 @@ HonkProof AvmProver::construct_proof()
308320

309321
return export_proof();
310322
}
311-
312323
} // namespace bb::avm2

0 commit comments

Comments
 (0)