Skip to content

feat(polynomials): Accumulator<Fr> + vectorize compute_sum#23210

Draft
notnotraju wants to merge 1 commit into
rk/wasm-simd-02-vectorized-forfrom
rk/wasm-simd-03-accumulator
Draft

feat(polynomials): Accumulator<Fr> + vectorize compute_sum#23210
notnotraju wants to merge 1 commit into
rk/wasm-simd-02-vectorized-forfrom
rk/wasm-simd-03-accumulator

Conversation

@notnotraju
Copy link
Copy Markdown
Contributor

Goal. Introduce `Accumulator` — the reduction counterpart to `Broadcast`. `operator+=(Fr)` for ScalarIndex contributions, `operator+=(VectorField)` for ContiguousVectorIndex contributions, `reduce()` horizontal-adds the N vector lanes with the scalar slot. Migrate `polynomial_arithmetic::compute_sum` as the canonical first user.

Non-goal. Migrate other reduction sites. Accumulator is the primitive that compose with Polynomial's existing operator[]; richer reduction kernels (sumcheck partial-evaluate, MLE fold, IPA inner product) live in follow-up work.

Why this is a separate PR. Accumulator is the third of the adapter types (after Broadcast and the implicit Polynomial proxies). It's the design building block for any kernel that reduces over per-iteration contributions, including the dot-product shape (`acc += a[ctx] * b[ctx]`) needed for IPA. Reviewable independently of the abstraction-layer PR — the diff is one new adapter type + one migrated function + one bench file.

Kernel after migration.
```cpp
PolynomialSpan view{0, std::span(src, n)};
Accumulator acc;
vectorized_for<VECTOR_FIELD_WIDTH>(0, n, [&](auto ctx) { acc += view[ctx]; });
return acc.reduce();
```

V8/WASM bench (N=2^16, n=5 reps). From barretenberg-claude where the code originated; file states are bit-identical:

  • `compute_sum_scalar` median: 582 µs (CV 15%)
  • `compute_sum_full` median: 357 µs (CV 1.7%)
  • Speedup: 1.63×

WASM op-count diff (same bench binary, scalar vs vectorized source):

  • `v128.and` (29-bit mask): 0 → 26
  • `v128.or` (carry): 0 → 7
  • No `extmul_*` — compute_sum is addition-only; SIMD primitives appearing are VectorField's lane-wise add kernel, not Mont-mul. Correct.

Tests. `polynomials_tests` passes everything mt/bb passes today. `CorrectnessGuard` at `compute_sum_bench` startup verifies bit-equality of scalar vs vectorized on 65k random fr's.

Stack.

  • Depends on rk/wasm-simd-02-vectorized-for
  • (No further dependents in this stack; future reduction migrations e.g. IPA inner product will build on this.)

@notnotraju notnotraju added the ci-barretenberg Run all barretenberg/cpp checks. label May 12, 2026
@notnotraju notnotraju force-pushed the rk/wasm-simd-02-vectorized-for branch from 43c0fe0 to 32361fc Compare May 12, 2026 18:46
@notnotraju notnotraju force-pushed the rk/wasm-simd-03-accumulator branch from 852e6ac to 10ce846 Compare May 12, 2026 18:48
@notnotraju notnotraju force-pushed the rk/wasm-simd-02-vectorized-for branch from 32361fc to 60358fd Compare May 12, 2026 23:45
Add Accumulator<Fr>, the reduction-direction companion to Broadcast<Fr>:
holds a scalar Fr slot plus a VectorField<Fr::Params> vector slot, exposes
operator+=(Fr) and operator+=(VectorField), and reduce() to horizontal-add
the vector lanes into the scalar slot at the end. Lets a `vectorized_for`
kernel express a sum (or any pointwise reduction) in one line:

  Accumulator<Fr> acc;
  vectorized_for<VECTOR_FIELD_WIDTH, Fr>(0, n, [&](auto ctx) { acc += view[ctx]; });
  return acc.reduce();

Migrate polynomial_arithmetic::compute_sum to use this pattern. The
vectorized_for call passes Fr so the bulk SIMD path is correctly gated on
simd_supported_v<Fr> (Bn254FrParams only); Polynomial<bb::fq>'s compute_sum
takes the scalar path under WASM as expected.
@notnotraju notnotraju force-pushed the rk/wasm-simd-03-accumulator branch from 10ce846 to 0ecbef7 Compare May 12, 2026 23:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-barretenberg Run all barretenberg/cpp checks.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant