Skip to content

perf: batch-normalized MSM and parallel-gated DoryRoutines vector ops - #27

Merged
markosg04 merged 1 commit into
mainfrom
perf/batch-msm-parallel-routines
Aug 5, 2026
Merged

markosg04 merged 1 commit into
mainfrom
perf/batch-msm-parallel-routines

Conversation

@moodlezoup

Copy link
Copy Markdown
Collaborator

Motivation

Profiling Dory inside Jolt shows the stock arkworks DoryRoutines dominating the reduce-fold rounds' wall clock: msm converts bases to affine one field inversion at a time (into_affine per point), and the vector ops run one full scalar multiplication per element in a serial loop. Jolt has been carrying optimized replacement routines (jolt-dory's JoltG1Routines/JoltG2Routines); this PR upstreams the part that needs nothing beyond stock arkworks, so every consumer of the default backend gets it.

What changed

  • G1Routines::msm / G2Routines::msm: bases convert to affine via CurveGroup::normalize_batch — one shared Montgomery batch inversion — instead of one inversion per point. When every base is already normalized (z = 1, e.g. setup generators, where into_affine is inversion-free), a cheap all-z=1 check keeps the old path so that shape doesn't regress. Under ark-ec/parallel, normalize_batch's affine transformation is itself parallel (cfg_iter!).
  • fixed_base_vector_scalar_mul, fixed_scalar_mul_bases_then_add, fixed_scalar_mul_vs_then_add, fold_field_vectors (both groups): parallelized behind the existing parallel feature, following ark_pairing.rs's cfg-dispatch pattern. Without parallel, the sequential code is exactly as before. The field fold uses with_min_len(1024) so the short vectors of late reduce-fold rounds don't pay rayon's splitting overhead.

Exactness

Group results are identical to the stock routines' — batch normalization and per-point conversion produce the same affine points (including identity handling: normalize_batch maps z = 0 to Affine::identity(), and batch_inversion skips zero elements), and every parallel op is an independent per-element write with no reduction-order dependence. Proofs are byte-identical. New equivalence tests (tests/arkworks/routines.rs) pin the routines against naive references across identity points, already-normalized bases, zero scalars, and empty inputs, and run in both feature modes.

Numbers

n = 4096, best-of-5 (3 for the heavy ops), 12-core Linux, --features backends,parallel:

op before after
G1 msm (z ≠ 1 bases) 14.7 ms 4.1 ms 3.6×
G1 msm (z = 1 bases) 3.7 ms 3.7 ms parity (fast path)
G2 msm (z ≠ 1 bases) 21.7 ms 9.8 ms 2.2×
G1 fixed_base_vector_scalar_mul 176.6 ms 16.5 ms 10.7×
G2 fixed_base_vector_scalar_mul 809.0 ms 69.4 ms 11.7×
G1 fixed_scalar_mul_bases_then_add 188.3 ms 16.6 ms 11.4×
G2 fixed_scalar_mul_bases_then_add 788.6 ms 72.2 ms 10.9×
fold_field_vectors 0.07 ms 0.03 ms 2.3×

Validation

  • cargo fmt --check; clippy clean (-D warnings) on backends,parallel,cache,disk-persistence, +zk, backends alone (sequential mode — not in CI's matrix), and --no-default-features; cargo doc clean
  • nextest: 85/85 (backends,parallel,cache,disk-persistence), 142/142 (+zk), 82/82 (backends, sequential)

🤖 Generated with Claude Code

msm now converts bases to affine with one shared Montgomery batch
inversion (normalize_batch) instead of one field inversion per point,
keeping the free into_affine path when every base is already
normalized (z = 1, the setup-generator shape). The vector ops
(fixed_base_vector_scalar_mul, fixed_scalar_mul_bases_then_add,
fixed_scalar_mul_vs_then_add, fold_field_vectors) parallelize behind
the existing `parallel` feature, following ark_pairing's cfg-dispatch
pattern; without the feature the sequential code is unchanged.

Group results are exact either way, so proofs are byte-identical.
Equivalence tests pin the optimized routines against the naive
reference, including identity points (z = 0), already-normalized
bases, zero scalars, and empty inputs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@moodlezoup
moodlezoup requested a review from markosg04 August 5, 2026 19:24
@markosg04
markosg04 merged commit 9124bf2 into main Aug 5, 2026
9 checks passed
moodlezoup added a commit to a16z/jolt that referenced this pull request Aug 5, 2026
…utines

dory-pcs 0.4.1 ships the batch-normalized MSM (with a z=1 fast path
this version lacked) and the parallel fold upstreamed in a16z/dory#27,
so JoltG1Routines/JoltG2Routines keep only what upstream can't provide:
the GLV vector kernels from jolt-optimizations and the tracing span
labels the profiling telemetry grammar addresses. Byte parity vs the
legacy prover verified across the muldiv ratchet arms (both backends).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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