Skip to content

perf(sumcheck)!: redesign prover tables for runtime SIMD - #368

Draft
quangvdao wants to merge 72 commits into
mainfrom
codex/sumcheck-kernels
Draft

perf(sumcheck)!: redesign prover tables for runtime SIMD#368
quangvdao wants to merge 72 commits into
mainfrom
codex/sumcheck-kernels

Conversation

@quangvdao

@quangvdao quangvdao commented Aug 6, 2026

Copy link
Copy Markdown

Summary

This draft lands the canonical storage and design contract for a sumcheck prover that selects SIMD operations at runtime. It does not change the transcript or verifier.

It currently lands:

  • It adds extension coefficient access and FpExt4 packing without temporary allocations.
  • It adds one canonical EvaluationTable<F, E> representation that works on every architecture.
  • It adds a portable scalar fold over the table's binding order halves.
  • It adds a scalar product round that shares its reduction policy with dense and sparse EOR.
  • It adds a fused scalar operation that folds two tables and computes the next product round in one pass.
  • It adds an opaque runtime plan with AVX2 and AVX-512 IFMA fp32 folds, product rounds, and fused operations.
  • It moves dense EOR from Vec<E> to EvaluationTable<F, E> and deletes the old dense traversal module.
  • It detects one plan per EOR prover and uses the selected fp32 operations in production rounds.
  • It adds runtime NEON fp32 operations, mixed scalar and NEON fp64 operations, and direct scalar identity-field operations.
  • It keeps one shared packed traversal for NEON, AVX2, and AVX-512 wrappers.
  • It separates the public dispatch surface from fp32, fp64, portable scalar, and differential test implementations.
  • The benchmarks cover dense fp32, fp64, and fp128 EOR as well as layout, packing, and each x86 target function.

The normative design is specs/sumcheck-kernel-architecture.md.

Diff metadata

  • Base: c9ca8e9dd5f19e234a7cd5e3c09fd4089b8454fd (main)
  • Head: ccb6b8a0a47782b1a00eb525c4c7a4ed6e40e7f5
  • Commits: 14
  • Files changed: 54
  • Diff: 5,103 insertions, 569 deletions
  • Normative specification: specs/sumcheck-kernel-architecture.md

Motivation

Before this PR, dense EOR stored extension field evaluations as Vec<E>. That layout works for scalar arithmetic, but SIMD code must repeatedly gather or repack the coefficients. Ice Lake microbenchmarks show the cost. A fold over two persistent contiguous halves takes 56.619 microseconds for 16,384 output rows. Repacking the adjacent layout takes 372.140 microseconds. The scalar path takes 466.053 microseconds.

In the pinned full fp32 profile, a D128 one hot proof with nv=28 takes 6.304 seconds. Sumchecks account for about 4.32 seconds, or 68 percent. The extension opening reduction accounts for 2.232 seconds. Stage 1 takes 1.400 seconds, and stage 2 takes 1.296 seconds.

The previous packed sumcheck design tied packing to compile time types and storage that depended on the register width. It could not give scalar, ARM, AVX2, and AVX-512 code one durable representation. This PR archives that design and specifies runtime selection over one table layout.

Architecture

flowchart LR
    A[Protocol evaluations] --> B[EvaluationTable]
    C[Detected CPU features] --> D[Opaque kernel plan]
    B --> E[Scalar reference operations]
    B --> F[NEON, AVX2, or AVX-512 IFMA operations]
    D --> E
    D --> F
    E --> G[Unchanged round claims and transcript]
    F --> G
Loading

Change overview

Area Before Current implementation and target design
Dense storage Vec<E> with interleaved coefficients One coefficient major EvaluationTable<F, E> allocation
Binding order Adjacent logical pairs, followed by repeated layout work Bit reversed binding order with two contiguous halves per fold
SIMD selection Compile time packed types and local packing Opaque runtime plan selected outside hot loops
Compact digits Materialize extension values before general arithmetic Keep i8 and i16 compact and materialize directly into the table
Sparse one hot data Mixed with dense reduction concerns Sparse indices remain separate from values that preserve row order
Verifier and transcript Existing behavior Unchanged by this redesign

Canonical evaluation storage

EvaluationTable<F, E> owns one flat Box<[F]>. It stores extension coefficients in contiguous slabs, with a private live length and fixed stride. Its constructors cover sparse values that preserve row order and dense multilinear values in bit reversed binding order. Folding can shrink the live length without reallocating or permuting later rounds.

The type exposes live coefficient slices for arithmetic but keeps its allocation shape private. Tests cover extension degrees 1, 2, 4, and 8, constructor order, truncation, inactive storage, empty sparse inputs, and invalid dense lengths.

ExtField<F> now exposes from_base_fn and base_coefficient as its primitive operations that do not allocate. The existing slice and vector operations derive from those primitives, which keeps coefficient conversion in one source of truth.

fold_first_variable_scalar is the portable correctness oracle. It reads the two binding order halves, reuses the field's optimized scalar fold context, writes the first half, and truncates the live rows without allocation or permutation. Differential tests compare every round and the final multilinear evaluation with the existing logical order fold.

Canonical product round

compute_product_round_scalar computes the constant and quadratic coefficients from two binding order tables. It uses w0 * f0 for the constant term and (w1 - w0) * (f1 - f0) for the quadratic term. The existing previous claim formula still derives the linear coefficient.

akita-sumcheck now owns ProductRoundAccumulator and its two reduction policies. The delayed policy sums wide products and reduces once when the field declares that exact. The direct policy reduces every product before adding it. The scalar table operation and sparse EOR traversal use these same implementations. Dense EOR calls the table operations directly. The delayed accumulator rejects fields whose exactness flag is false.

fold_and_compute_product_round_scalar folds both tables and computes the next round in one pass. Each iteration reads the two children for the current variable and the two children for the next variable before it writes either folded output. Differential tests compare both mutated tables and both returned coefficients against separate scalar operations.

Runtime CPU kernels and benchmark coverage

PackedFpExt4::from_coeff_fn and its pack_slice implementation remove temporary coefficient vectors. The benchmark suite now measures packing from the current adjacent layout, folding over persistent halves, root factor accumulation, and coefficient gathering separately.

Portable x86 builds include the existing fp32 AVX2 and AVX-512 arithmetic without changing the compile time HasPacking aliases for other code. akita-field owns the unsafe slice loops that require specific CPU features. akita-prover owns SumcheckKernelPlan, which detects one safe operation before entering a table loop. Its fields and operation choices are private, so a safe caller cannot run AVX2 or AVX-512 code on an unsupported host.

The 512 bit operation is named and guarded as AVX-512 IFMA because its portable release assembly contains vpmadd52luq. Detection and target functions require AVX-512F, AVX-512DQ, and AVX-512IFMA. A host without that exact set uses AVX2 for this operation.

The x86 table loops validate all slice lengths once, then use raw pointers inside complete SIMD chunks. The safe prover operation supplies disjoint coefficient halves and handles short tables with the scalar oracle. Differential tests force every operation that the test host supports.

The runtime plan also selects the fp32 product round separately from the fold. Its packed loop computes the constant and quadratic products in every SIMD lane, sums those packed results across chunks, and reduces the lanes to two ordinary extension field values at the operation boundary. Portable assembly contains only YMM instructions in the AVX2 function. The AVX-512 IFMA function uses ZMM registers and vpmadd52 instructions.

The fused fp32 operation folds both tables and computes the next product round in the same packed pass. It has its own private plan choice, so later measurements can select AVX2 for one operation and IFMA for another. Its loop reads all source chunks before writing either folded output half. Portable assembly confirms vector stores in both x86 functions.

The committed Criterion group contains separate rows for the detected runtime plan, AVX2, and AVX-512 IFMA. A preliminary Ice Lake binary built with global target-cpu=native folded 16,384 output rows in 76.089 microseconds median. The matching scalar row took 466.02 microseconds, so this preliminary result is 6.12 times faster. This is not the acceptance result. The final comparison must use one portable binary and the explicit AVX2 and IFMA rows.

These microbenchmarks are not a full proof performance claim. Dense EOR now uses the runtime operations in production. The exact portable Ice Lake end-to-end measurement is still pending.

The AArch64 path uses the same opaque whole-operation dispatch. FpExt4<Fp32> selects NEON for fold, product, and fused fold plus next product round. FpExt2<Fp64> deliberately mixes operations: the initial product round stays scalar because it measured faster, while fold and fused rounds use NEON. Identity fields use direct degree-one slice kernels, which avoid reconstructing a field value through the generic extension interface.

The shared packed traversal is independent of SIMD width. Thin target-feature wrappers supply the NEON, AVX2, or AVX-512 packed base field. Portable x86 builds compile fp64 AVX2 and AVX-512 candidates, but production x86 fp64 selection stays scalar until the pinned Ice Lake benchmark selects each operation independently.

Dense EOR cutover

ExtensionOpeningTables::Dense now owns coefficient-major witness and factor tables from construction through the final fold. Logical-order vectors are validated once, their unscaled input claim is computed with the existing canonical claim function, and they are converted once into binding order. Later rounds do not convert, repack, allocate, or retain a parallel Vec<E> representation.

ExtensionOpeningReductionTerm<F, E> and ExtensionOpeningReductionProver<F, E> name the base and extension fields directly. Each prover detects one SumcheckKernelPlan during construction. Generic EOR code reaches the plan through SumcheckTableOperations<F>. Its default methods are the canonical scalar operations. FpExt4<Fp32> and FpExt2<Fp64> override the dense operations with field-specific runtime choices. Identity fields use direct scalar slice operations. Other extension shapes keep the scalar defaults.

The old 205-line dense EOR traversal module was deleted. Round zero calls the canonical product operation. Later rounds call the canonical fused fold and next product operation while another round remains. The final short fold uses the canonical fold operation. Sparse and cylindrical terms keep their current representation and behavior in this slice.

Dense field acceptance results

The matched benchmark uses 65,536 dense rows and one Rayon worker on Apple Silicon. Construction and cloning stay outside the measured proof interval.

Field Old row-major EOR Accepted operations Change
fp32 quartic extension 1.811366 ms 1.3728 ms 24.2% faster
fp64 quadratic extension 0.800049 ms 0.80775 ms 0.96% slower, statistically unchanged
fp128 identity field 1.028971 ms 1.0120 ms 1.65% faster

The all-NEON fp64 path measured 0.89332 ms. Selecting the scalar initial product round and NEON fused rounds reduced it to 0.80775 ms. This is why the plan stores a choice per operation rather than one field-wide SIMD tier.

A generic coefficient-slice experiment was rejected. It regressed fp32 to 4.5623 ms, fp64 to 1.2935 ms, and fp128 to 1.0500 ms. The accepted code uses field-shaped kernels while keeping the table and protocol operation as the single public representation and call path.

Protocol and safety

  • The verifier is unchanged.
  • The transcript schedule, challenge order, round polynomials, and intended proof bytes are unchanged.
  • No wire format, proof serialization, or persisted cache changes land in this draft.
  • The table owns its shape invariants. Safe callers cannot independently mutate its stride, length, and backing allocation.
  • The runtime selector is opaque and detects the host CPU, so safe callers cannot force code that needs unsupported CPU features.
  • Scalar reference operations will remain the correctness oracle for every optimized operation.

Breaking changes

This is an intentional breaking API change. ExtField<F> implementors must provide coefficient primitives that do not allocate. EOR terms and provers now name both F and E, and input_claim_from_terms returns its infallible field value directly. Custom application fields implement SumcheckTableOperations<F> to use the scalar defaults or provide accepted optimized operations. No compatibility wrapper or duplicate table representation is added.

The protocol, proof format, transcript, and verifier behavior remain unchanged.

Commit map

  • 6d1bf5c89 removes temporary FpExt4 packing allocations and adds layout microbenchmarks.
  • d0b7cbba4 specifies the canonical table, runtime selection, operation boundaries, rollout order, and performance gates.
  • 83f07e128 adds extension coefficient primitives and EvaluationTable<F, E>.
  • c92aad58e adds the scalar table fold without allocation and adds differential tests over every round.
  • 0433cb9b2 adds opaque runtime selection, AVX2 and AVX-512 IFMA table folds, forced differential tests, and portable benchmark rows.
  • d72c190be adds the scalar product round and moves the existing EOR accumulator policies to their canonical sumcheck owner.
  • 361e99068 adds the fused scalar fold and next product round oracle.
  • a854759c3 adds runtime AVX2 and AVX-512 IFMA product rounds and matched benchmark rows.
  • 6552d7d7e adds runtime AVX2 and AVX-512 IFMA fused operations and matched benchmark rows.
  • 8b1e06f27 moves dense EOR to EvaluationTable<F, E>, deletes the old dense traversal, and preserves validated input claims at the conversion boundary.
  • 93d477df8 stores one runtime plan per EOR prover and dispatches production fp32 dense rounds through the selected operations.
  • 7bad074b4 adds shared packed traversal, production NEON fp32 kernels, mixed scalar and NEON fp64 selection, direct identity-field kernels, and matched dense EOR benchmarks.
  • 3fae22a76 propagates the required sumcheck operation bound through generic PCS tests and profile drivers.
  • ccb6b8a0a separates dispatch, fp32, fp64, portable scalar, and differential test ownership without changing the public API.

Validation completed at ccb6b8a0a

The following passed:

  • Schedule table generation passed, and unrelated generated output was restored.
  • Repository Rust and TOML formatting passed.
  • The Rust file line checks and all 34 script unit tests passed.
  • The dependency boundary checks passed for verifier, prover, config, planner, and setup.
  • cargo machete, typos, and all documentation guardrails passed.
  • Focused field and sumcheck kernel tests passed, including forced NEON fp32 and fp64 differential coverage through 256 rows.
  • All 21 akita-sumcheck library tests passed.
  • The focused scalar and detected plan prover kernel tests passed.
  • Focused EOR tests passed with and without default features.
  • All 255 prover library tests passed with one expected ignored benchmark.
  • All 21 EOR integration tests passed after the production table and runtime dispatch cutover.
  • Clippy passed with warnings denied for akita-field, akita-sumcheck, and akita-prover.
  • Clippy passed for all prover targets and the PCS benchmark surface.
  • Clippy passed for the native and portable x86 akita-pcs field arithmetic benchmark.
  • Portable x86 and AVX-512 IFMA cross compilation passed.
  • The complete portable x86 prover target surface and the dense EOR benchmark compile.
  • The CI-shaped all-target PCS Clippy profile with parallel,disk-persistence passes with warnings denied.
  • The focused native kernel tests pass after the module split, and the entire prover target surface checks for x86_64-unknown-linux-gnu.
  • Release assembly inspection confirmed the expected YMM only AVX2 body and vpmadd52 instructions inside the IFMA target functions.
  • Release assembly inspection also confirmed vectorized stores in both fused target functions.
  • git diff --check passed.

The 7bad074b4 GitHub run exposed missing generic bounds in the end-to-end test and profile helpers before any benchmark ran. 3fae22a76 fixes those compile failures. Checks for ccb6b8a0a are running.

Specification status and remaining work

The specification is active. Dense EOR is now on the production table and runtime operation path. The remaining work is:

  1. run the exact portable AVX2 and AVX-512 IFMA comparison on the pinned Ice Lake host;
  2. measure the dense EOR and full proof gain from the production cutover on Ice Lake;
  3. migrate root sparse reduction with its lazy tensor factor;
  4. migrate stage 2 and add compact i8 and i16 stage 1 operations;
  5. verify identical proof bytes and pinned full proof gains.

The Ice Lake acceptance target for the 16,384-row fp32 fold is at most 75 microseconds median, compared with the measured 466.053-microsecond scalar reference.

Reviewer map

Suggested review order:

  1. specs/sumcheck-kernel-architecture.md
  2. crates/akita-field/src/ext/lift.rs
  3. crates/akita-sumcheck/src/evaluation_table.rs
  4. crates/akita-sumcheck/src/accum.rs
  5. crates/akita-prover/src/kernels/sumcheck.rs
  6. crates/akita-field/src/packed/runtime_common.rs
  7. crates/akita-field/src/packed/runtime_neon.rs
  8. crates/akita-field/src/packed/runtime_x86.rs
  9. crates/akita-field/src/packed/ext/mod.rs
  10. crates/akita-pcs/benches/extension_opening_reduction.rs

Add a coefficient-oriented constructor and specialize quartic slice packing so SIMD table transposes do not allocate temporary coefficient vectors. Extend the field benchmark with sumcheck fold and lazy tensor factor-pair layout controls.
Define the canonical coefficient-first evaluation table, binding order, runtime CPU selection, compact and sparse states, migration sequence, and measurable acceptance gates. Archive the compile-time packed-table proposal so there is one live implementation contract.
Add allocation-free ExtField coefficient primitives and a single-allocation coefficient-first table. Provide distinct row-preserving and multilinear binding-order constructors so dense and sparse callers cannot silently share the wrong row semantics.\n\nBREAKING CHANGE: ExtField implementations must provide from_base_fn and base_coefficient.
@cursor

cursor Bot commented Aug 6, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Large, proof-critical prover refactor with breaking field traits, extensive unsafe SIMD dispatch, and dense EOR on new storage—mitigated by unchanged verifier/transcript and scalar oracles, but arithmetic or binding-order bugs would be severe.

Overview
Dense extension-opening reduction and sumcheck hot paths move from row-major Vec<E> to a single coefficient-first EvaluationTable, with CPU-specific folds, product rounds, and fused fold+round chosen at runtime (scalar, NEON, AVX2, AVX-512 IFMA) while the transcript and verifier stay unchanged.

akita-field gains allocation-free extension coefficient access (from_base_fn / base_coefficient), tighter FpExt4 packing (from_coeff_fn, coefficient-oriented pack_slice), optional u16 small product accumulators for compact sumcheck scans, and large shared packed traversals (runtime_common plus thin NEON/x86 wrappers) for folds, product rounds, weighted affine rounds, tensor-factor materialization, and Stage 2 coefficient work. PackedField adds fused sum_four_products; x86 SIMD modules compile more broadly with feature-gated fp128 paths.

Protocol and tooling wire through SumcheckTableOperations<F> on extension types used in EOR/PCS (profile drivers, benches, scheme bounds): dense terms use the table + detected SumcheckKernelPlan instead of the removed dense traversal module. Docs rename the active design frontier from packed-sumcheck to sumcheck-kernel-architecture and document sumcheck table kernels in the book.

Breaking: custom ExtField implementors need the new coefficient primitives; EOR APIs name F and E explicitly and require the sumcheck operations trait for optimized paths.

Reviewed by Cursor Bugbot for commit 261f975. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions github-actions Bot added spec PR contains a spec implementation PR contains implementation of a spec labels Aug 6, 2026
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Documentation blast radius (advisory)

These regions may need doc/spec/book updates based on changed paths.
This is not a merge gate. See docs/documentation.md.

Changed files in this PR: 127

prover-protocol

Prove pipeline, folds, sumcheck stages

Code paths touched:

  • crates/akita-prover/src/protocol/core.rs
  • crates/akita-prover/src/protocol/core/extension_opening_reduction.rs
  • crates/akita-prover/src/protocol/core/fold/extension_claim.rs
  • crates/akita-prover/src/protocol/core/fold/mod.rs
  • crates/akita-prover/src/protocol/core/prove.rs
  • crates/akita-prover/src/protocol/core/root_fold.rs
  • crates/akita-prover/src/protocol/core/root_group.rs
  • crates/akita-prover/src/protocol/core/suffix.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/dense.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/mod.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/prover.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/mod.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/suffix_sums.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/tables.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/tensor_factor.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/term.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/tests.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/witness.rs
  • crates/akita-prover/src/protocol/sumcheck/akita_stage3/mod.rs
  • crates/akita-prover/src/protocol/sumcheck/akita_stage3/product_table.rs
  • crates/akita-prover/src/protocol/sumcheck/akita_stage3/utils.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/class_indexed_product.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/class_indexed_range_leaf.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/class_indexed_state.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/compact_digit_source.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/direct_range_leaf.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/direct_range_leaf/initial_round_deferral.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/direct_range_leaf/live_prefix.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/direct_range_leaf/rounds.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/direct_range_leaf/sparse_low_variables.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/direct_range_leaf/state.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/direct_range_leaf/tests.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/equality_tables.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/mod.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/range_class_tables.rs
  • crates/akita-prover/src/protocol/sumcheck/digit_range/round_accumulation.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/additional_terms.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/coefficient_prefix.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/coefficient_round_fold.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/compact_prefix.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/dense_terms.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/evaluation_trace.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/evaluation_trace/tests.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/lane_prefix.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/lifecycle.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/mod.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/round_flow.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/tests.rs
  • crates/akita-prover/src/protocol/sumcheck/relation_range_image/tests/trace_prefix.rs
  • crates/akita-prover/src/protocol/sumcheck/two_round_prefix/common.rs
  • crates/akita-prover/src/protocol/sumcheck/two_round_prefix/stage1.rs
  • crates/akita-prover/src/protocol/sumcheck/two_round_prefix/stage2.rs
  • crates/akita-sumcheck/src/accum.rs
  • crates/akita-sumcheck/src/affine_polynomial.rs
  • crates/akita-sumcheck/src/affine_product.rs
  • crates/akita-sumcheck/src/evaluation_table.rs
  • crates/akita-sumcheck/src/lib.rs

Consider updating:

  • book/src/how/proving/**
  • book/src/how/recursion.md
  • specs/sumcheck-kernel-architecture.md
  • specs/setup-product-sumcheck.md
  • specs/terminal-fold-cutover.md
  • specs/protocol-field-geometry-cutover.md

commitment-setup

Setup expansion and Ajtai commitment

Code paths touched:

  • crates/akita-prover/src/backend/dense/kernels.rs
  • crates/akita-prover/src/backend/dense/ops.rs
  • crates/akita-prover/src/backend/field_reduction.rs
  • crates/akita-prover/src/backend/multilinear_polynomial/ops.rs
  • crates/akita-prover/src/backend/onehot/ops.rs
  • crates/akita-prover/src/backend/onehot/poly.rs
  • crates/akita-prover/src/backend/onehot/tests.rs
  • crates/akita-prover/src/backend/recursive/setup_prefix_source.rs
  • crates/akita-prover/src/backend/recursive/witness.rs
  • crates/akita-prover/src/backend/sparse_ring/mod.rs
  • crates/akita-prover/src/backend/sparse_ring/ops.rs

Consider updating:

  • book/src/how/commitment.md
  • book/src/usage/commitment-api.md
  • specs/setup-*.md

field-algebra

Field traits, packed SIMD, extension towers

Code paths touched:

  • crates/akita-field/src/compat/jolt.rs
  • crates/akita-field/src/ext/fp_ext2.rs
  • crates/akita-field/src/ext/fp_ext4.rs
  • crates/akita-field/src/ext/fp_ext8.rs
  • crates/akita-field/src/ext/lift.rs
  • crates/akita-field/src/ext/mod.rs
  • crates/akita-field/src/ext/tests.rs
  • crates/akita-field/src/packed/avx2/fp32.rs
  • crates/akita-field/src/packed/avx2/fp64.rs
  • crates/akita-field/src/packed/avx2/mod.rs
  • crates/akita-field/src/packed/avx512/fp32.rs
  • crates/akita-field/src/packed/avx512/fp64.rs
  • crates/akita-field/src/packed/avx512/mod.rs
  • crates/akita-field/src/packed/ext/mod.rs
  • crates/akita-field/src/packed/ext/tests.rs
  • crates/akita-field/src/packed/mod.rs
  • crates/akita-field/src/packed/neon/fp32.rs
  • crates/akita-field/src/packed/runtime_common.rs
  • crates/akita-field/src/packed/runtime_neon.rs
  • crates/akita-field/src/packed/runtime_tensor.rs
  • crates/akita-field/src/packed/runtime_x86.rs
  • crates/akita-field/src/packed/tests.rs
  • crates/akita-field/src/parallel.rs
  • crates/akita-field/src/unreduced/accum.rs
  • crates/akita-field/src/unreduced/mod.rs
  • crates/akita-field/src/unreduced/native_algebra.rs

Consider updating:

  • book/src/foundations/rings-and-fields.md
  • book/src/foundations/ntt-crt.md
  • book/src/how/optimizations.md
  • specs/akita-field-refactor.md
  • specs/crt-ntt-*.md
  • specs/avx-simd-port.md

extension-opening

Extension-opening reduction prover paths

Code paths touched:

  • crates/akita-prover/src/protocol/extension_opening_reduction/dense.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/mod.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/prover.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/mod.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/suffix_sums.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/tables.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/tensor_factor.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/term.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/tests.rs
  • crates/akita-prover/src/protocol/extension_opening_reduction/sparse/witness.rs
  • crates/akita-types/src/extension_opening_reduction.rs

Consider updating:

  • book/src/foundations/extension-opening-reduction.md
  • book/src/how/proving/extension-opening-reduction.md
  • book/src/how/proving/fold-path.md
  • specs/eor-*.md
  • specs/extension-field-*.md
  • specs/protocol-field-geometry-cutover.md

pcs-umbrella

Public PCS API, examples, integration tests

Code paths touched:

  • crates/akita-pcs/benches/extension_opening_reduction.rs
  • crates/akita-pcs/benches/field_arith/kernel.rs
  • crates/akita-pcs/examples/profile/modes.rs
  • crates/akita-pcs/examples/profile/workload/batched_onehot.rs
  • crates/akita-pcs/examples/profile/workload/multi_group.rs
  • crates/akita-pcs/examples/profile/workload/single_group.rs
  • crates/akita-pcs/src/scheme/mod.rs
  • crates/akita-pcs/tests/protocol_soundness.rs
  • crates/akita-pcs/tests/stage1_roundtrip.rs

Consider updating:

  • book/src/usage/**
  • README.md

ci-tooling

CI workflows and repo scripts

Code paths touched:

  • scripts/check-spec-references.sh

Consider updating:

  • docs/ci-test-timing.md
  • docs/documentation.md
  • specs/ci-test-timing.md

book-tooling

Book structure and guardrails

Code paths touched:

  • book/src/foundations/spec-index.md
  • book/src/how/optimizations.md
  • docs/doc-blast-radius.json

Consider updating:

  • book/README.md
  • docs/documentation.md
  • specs/PRUNING.md

Per-PR checklist: spec Status / acceptance criteria; book owning page; AGENTS.md if contracts changed; archive spec after fold.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

CI test timing

  • Report generated: 2026-08-12T22:23:44Z.
  • Source: 261f975 on codex/sumcheck-kernels.
  • Workflow run: 31646292477.
  • Main baseline: 34e2407.
  • Previous run: c3b05f6.

Run summary

Wall s Main wall s Main Δ Ratio Tests Skipped Failed Status
n/a 317.0 n/a n/a 0 0 0 n/a

Slowest tests

No JUnit data available for this run.

Regressions vs main

No per-test regressions above the threshold.

New slow tests

No new tests ≥30s vs main baseline.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit a181130. Configure here.

Comment thread crates/akita-prover/src/kernels/sumcheck/fp32_affine.rs
Drop imports that became unused after the main branch merge so strict no-default Clippy remains clean.
Add one canonical four-product packed operation and reuse the existing exact fp32 backend accumulators in tensor projection maps. This removes three reductions per output coefficient and cuts the pinned Ice Lake dense-factor total by about 40 percent.
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

PCS Profile Benchmark

13 of 13 profiles passed.

Times are medians of 3 measured runs after 1 discarded warmup run. Peak RSS is the largest measured value.

Each sample verifies the same proof first with the configured multi-threaded pool and then with one thread. Both timings reuse the same verifier setup.

Merge-base comparisons are available for 13 of 13 profiles. For matching profiles, the head and merge-base binaries ran interleaved on the same runner.

Benchmark shards

CI shard Profiles
1-fp32-base Fp32 dense nv26, direct setup check
Fp32 one-hot nv30, direct setup check
2-fp64-base Fp64 dense nv26, direct setup check
Fp64 one-hot nv30, direct setup check
3-fp128-base Fp128 dense nv28, direct setup check
Fp128 one-hot nv36, direct setup check
Fp128 one-hot nv36, recursive setup check
4-multi-group-direct Fp128 multi-group, direct setup check
5-multi-group-recursive Fp128 multi-group, recursive setup check
6-multi-group-recursive-w8r2 Fp128 multi-group W8R2, recursive setup check
7-distributed Fp128 one-hot nv32 W2R2, direct setup check
Fp128 one-hot nv32 W4R2, direct setup check
Fp128 one-hot nv32 W8R2, direct setup check

Public opening statements

Public opening statement Profiles
Over Fp32, one committed 26 variable multilinear polynomial with 2^26 coefficients is opened at one 26 coordinate point. Fp32 dense nv26, direct setup check
Over Fp32, one committed 30 variable multilinear polynomial with 2^30 coefficients is opened at one 30 coordinate point. Fp32 one-hot nv30, direct setup check
Over Fp64, one committed 26 variable multilinear polynomial with 2^26 coefficients is opened at one 26 coordinate point. Fp64 dense nv26, direct setup check
Over Fp64, one committed 30 variable multilinear polynomial with 2^30 coefficients is opened at one 30 coordinate point. Fp64 one-hot nv30, direct setup check
Over Fp128, one committed 28 variable multilinear polynomial with 2^28 coefficients is opened at one 28 coordinate point. Fp128 dense nv28, direct setup check
Over Fp128, one committed 36 variable multilinear polynomial with 2^36 coefficients is opened at one 36 coordinate point. Fp128 one-hot nv36, direct setup check
Fp128 one-hot nv36, recursive setup check
Over Fp128, 4 polynomials in 3 groups: one 16 variable polynomial at its own point, one 16 variable polynomial at its own point, and 2 32 variable polynomials at one shared point. Fp128 multi-group, direct setup check
Fp128 multi-group, recursive setup check
Fp128 multi-group W8R2, recursive setup check
Over Fp128, one committed 32 variable multilinear polynomial with 2^32 coefficients is opened at one 32 coordinate point. Fp128 one-hot nv32 W2R2, direct setup check
Fp128 one-hot nv32 W4R2, direct setup check
Fp128 one-hot nv32 W8R2, direct setup check

One-hot profiles generate deterministic witnesses with one 1 in every consecutive chunk of 256 coefficients. This witness shape is not a separate public claim.

Direct evaluates the public setup contribution during Stage 2. Recursive carries the same check through a Stage 3 setup-product sumcheck. Both modes execute the complete fold schedule and terminal verification.

The chunked profiles W2R2, W4R2, W8R2 divide the witness relation into the stated number of exact chunks for the first two fold levels.

Generated profiles may select different A, B, and D ring dimensions at different fold levels. The short profile names omit those dimensions.

Each sample generates deterministic witnesses and opening points, prepares setup, commits, proves, serializes the proof, checks its size, prepares verifier setup, and verifies the claimed openings. It does not test malformed proofs.

Phase time

Profile Setup Commit Prove Verify, multi-threaded Verify, single-threaded
Fp32 dense nv26, direct setup check 0.039 s
+6.5%
0.346 s
-0.3%
1.358 s
-15.3%
15.9 ms
+4.7%
30.8 ms
-0.4%
Fp32 one-hot nv30, direct setup check 0.037 s
-0.7%
0.538 s
+0.8%
1.745 s
-34.4%
16.3 ms
-6.0%
31.1 ms
-0.4%
Fp64 dense nv26, direct setup check 0.061 s
-0.8%
1.047 s
+3.4%
1.347 s
-8.2%
12.7 ms
-2.9%
29.0 ms
-0.1%
Fp64 one-hot nv30, direct setup check 0.046 s
+0.3%
0.314 s
-3.9%
1.239 s
-12.9%
11.6 ms
-1.8%
22.8 ms
-0.2%
Fp128 dense nv28, direct setup check 0.310 s
-0.4%
7.844 s
+0.6%
2.431 s
-1.2%
15.7 ms
+1.5%
94.1 ms
-0.0%
Fp128 one-hot nv36, direct setup check 0.574 s
-0.3%
4.782 s
+3.4%
3.570 s
+1.7%
28.1 ms
-0.7%
210.9 ms
-4.2%
Fp128 one-hot nv36, recursive setup check 3.312 s
+2.6%
5.032 s
+1.5%
5.615 s
+1.5%
20.8 ms
-1.4%
63.0 ms
-3.0%
Fp128 multi-group, direct setup check 0.159 s
-0.0%
1.312 s
-1.6%
1.178 s
+2.2%
16.6 ms
-2.9%
74.8 ms
+0.2%
Fp128 multi-group, recursive setup check 0.769 s
-1.8%
1.605 s
+0.5%
2.208 s
+2.9%
16.6 ms
-2.7%
37.8 ms
-0.5%
Fp128 multi-group W8R2, recursive setup check 0.985 s
-0.2%
1.672 s
-0.6%
5.736 s
+0.9%
28.5 ms
-2.0%
127.6 ms
+0.3%
Fp128 one-hot nv32 W2R2, direct setup check 0.125 s
-0.2%
0.329 s
-1.2%
1.545 s
+1.7%
17.2 ms
+1.3%
68.4 ms
+0.1%
Fp128 one-hot nv32 W4R2, direct setup check 0.127 s
-0.2%
0.329 s
-5.0%
1.881 s
-1.4%
16.6 ms
-0.2%
77.0 ms
-0.0%
Fp128 one-hot nv32 W8R2, direct setup check 0.131 s
+1.2%
0.335 s
+2.4%
3.155 s
-0.4%
22.0 ms
+2.4%
97.8 ms
+0.1%

Memory and setup size

Profile Setup vector Prepared NTT cache Verifier NTT cache Peak RSS
Fp32 dense nv26, direct setup check 16.0 MiB
+0.0%
117.0 MiB
+0.0%
1.2 MiB
+0.0%
1288.3 MiB
+0.0%
Fp32 one-hot nv30, direct setup check 16.0 MiB
+0.0%
117.0 MiB
+0.0%
1.2 MiB
+0.0%
530.8 MiB
-10.8%
Fp64 dense nv26, direct setup check 44.0 MiB
+0.0%
324.0 MiB
+0.0%
2.2 MiB
+0.0%
2482.2 MiB
-0.5%
Fp64 one-hot nv30, direct setup check 32.0 MiB
+0.0%
222.0 MiB
+0.0%
2.2 MiB
+0.0%
743.9 MiB
-19.3%
Fp128 dense nv28, direct setup check 240.0 MiB
+0.0%
1420.0 MiB
+0.0%
1.4 MiB
+0.0%
6739.5 MiB
+0.0%
Fp128 one-hot nv36, direct setup check 688.0 MiB
+0.0%
2501.2 MiB
+0.0%
1.4 MiB
+0.0%
5405.1 MiB
+4.8%
Fp128 one-hot nv36, recursive setup check 1024.0 MiB
+0.0%
2479.0 MiB
+0.0%
1.4 MiB
+0.0%
6843.9 MiB
-0.4%
Fp128 multi-group, direct setup check 256.0 MiB
+0.0%
750.8 MiB
+0.0%
1.6 MiB
+0.0%
1875.0 MiB
+3.8%
Fp128 multi-group, recursive setup check 256.0 MiB
+0.0%
758.8 MiB
+0.0%
1.4 MiB
+0.0%
2035.1 MiB
-1.5%
Fp128 multi-group W8R2, recursive setup check 256.0 MiB
+0.0%
1186.4 MiB
+0.0%
1.4 MiB
+0.0%
3651.6 MiB
-0.0%
Fp128 one-hot nv32 W2R2, direct setup check 128.0 MiB
+0.0%
535.0 MiB
+0.0%
1.4 MiB
+0.0%
1419.7 MiB
+0.3%
Fp128 one-hot nv32 W4R2, direct setup check 128.0 MiB
+0.0%
535.0 MiB
+0.0%
1.4 MiB
+0.0%
1798.9 MiB
+0.0%
Fp128 one-hot nv32 W8R2, direct setup check 128.0 MiB
+0.0%
553.5 MiB
+0.0%
1.4 MiB
+0.0%
2586.7 MiB
+0.0%

Proof size and protocol shape

Profile Fold A/B/D schedule Total proof Fold payload Terminal response Fold levels
Fp32 dense nv26, direct setup check 1024/256/256 → 256/256/256 → 128/128/128 78,070 bytes
+0.0%
29,036 bytes
+0.0%
49,034 bytes
+0.0%
7
+0.0%
Fp32 one-hot nv30, direct setup check 1024/256/256 → 256/256/256 → 128/128/128 78,036 bytes
+0.0%
29,020 bytes
+0.0%
49,016 bytes
+0.0%
7
+0.0%
Fp64 dense nv26, direct setup check 512/256/256 → 64/64/64 84,388 bytes
+0.0%
26,428 bytes
+0.0%
57,960 bytes
+0.0%
7
+0.0%
Fp64 one-hot nv30, direct setup check 512/256/256 → 64/64/64 83,088 bytes
+0.0%
25,096 bytes
+0.0%
57,992 bytes
+0.0%
6
+0.0%
Fp128 dense nv28, direct setup check 256/64/64 → 64/64/64 83,355 bytes
+0.0%
25,676 bytes
+0.0%
57,679 bytes
+0.0%
7
+0.0%
Fp128 one-hot nv36, direct setup check 256/128/128 → 64/64/64 84,330 bytes
+0.0%
26,640 bytes
+0.0%
57,690 bytes
+0.0%
8
+0.0%
Fp128 one-hot nv36, recursive setup check 256/128/128 → 64/64/64 88,459 bytes
+0.0%
30,752 bytes
+0.0%
57,707 bytes
+0.0%
8
+0.0%
Fp128 multi-group, direct setup check 256/64/64 → 64/64/64 83,382 bytes
+0.0%
25,676 bytes
+0.0%
57,706 bytes
+0.0%
7
+0.0%
Fp128 multi-group, recursive setup check 256/64/64 → 64/64/64 87,041 bytes
+0.0%
29,360 bytes
+0.0%
57,681 bytes
+0.0%
8
+0.0%
Fp128 multi-group W8R2, recursive setup check 256/128/64 → 64/64/64 89,945 bytes
+0.0%
32,240 bytes
+0.0%
57,705 bytes
+0.0%
8
+0.0%
Fp128 one-hot nv32 W2R2, direct setup check 256/64/64 → 64/64/64 84,115 bytes
+0.0%
26,416 bytes
+0.0%
57,699 bytes
+0.0%
8
+0.0%
Fp128 one-hot nv32 W4R2, direct setup check 256/64/64 → 64/64/64 85,507 bytes
+0.0%
27,808 bytes
+0.0%
57,699 bytes
+0.0%
8
+0.0%
Fp128 one-hot nv32 W8R2, direct setup check 256/64/64 → 64/64/64 86,006 bytes
+0.0%
28,320 bytes
+0.0%
57,686 bytes
+0.0%
8
+0.0%

Deltas are shown only for profiles with a matching merge-base case. Negative is smaller or faster.

Terminal response components
Workload Folded response (z) Opening values (e) Inner-commitment values (t) Total terminal response
Fp32 dense nv26, direct setup check 21,386 bytes 3,072 bytes 24,576 bytes 49,034 bytes
Fp32 one-hot nv30, direct setup check 21,368 bytes 3,072 bytes 24,576 bytes 49,016 bytes
Fp64 dense nv26, direct setup check 22,120 bytes 3,584 bytes 32,256 bytes 57,960 bytes
Fp64 one-hot nv30, direct setup check 22,152 bytes 3,584 bytes 32,256 bytes 57,992 bytes
Fp128 dense nv28, direct setup check 21,839 bytes 7,168 bytes 28,672 bytes 57,679 bytes
Fp128 one-hot nv36, direct setup check 21,850 bytes 7,168 bytes 28,672 bytes 57,690 bytes
Fp128 one-hot nv36, recursive setup check 21,867 bytes 7,168 bytes 28,672 bytes 57,707 bytes
Fp128 multi-group, direct setup check 21,866 bytes 7,168 bytes 28,672 bytes 57,706 bytes
Fp128 multi-group, recursive setup check 21,841 bytes 7,168 bytes 28,672 bytes 57,681 bytes
Fp128 multi-group W8R2, recursive setup check 21,865 bytes 7,168 bytes 28,672 bytes 57,705 bytes
Fp128 one-hot nv32 W2R2, direct setup check 21,859 bytes 7,168 bytes 28,672 bytes 57,699 bytes
Fp128 one-hot nv32 W4R2, direct setup check 21,859 bytes 7,168 bytes 28,672 bytes 57,699 bytes
Fp128 one-hot nv32 W8R2, direct setup check 21,846 bytes 7,168 bytes 28,672 bytes 57,686 bytes

The z column includes its per-segment length prefixes and Golomb payload; e and t are raw field bytes. These three columns sum exactly to the serialized terminal response.

Detailed schedule and proof-size breakdowns by fold level are available in the uploaded report.md benchmark artifact.

Partition fp32 and fp64 folds and product rounds across Rayon workers while preserving runtime-selected field kernels. Keep fused packed tensor traversal for one worker and use parallel canonical construction for multiworker plans. Add fp64 tensor kernels and large differential coverage.
Resolve the prover streaming and one-hot cutover on main while preserving typed evaluation tables and multicore sumcheck kernels. Keep main's compact exact-prefix state and split profiling modules, and port the branch's live kernel bounds and compact SIMD dispatch.
quangvdao and others added 2 commits August 11, 2026 08:57
Resolve the setup-prefix and late-reduction overlap while preserving the runtime sumcheck table kernels. Take main's canonical compact subfield opening APIs, which subsume the branch's high-half consistency operation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

implementation PR contains implementation of a spec spec PR contains a spec

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant