Skip to content

perf(bz): word-sized modulus arithmetic for the lattice tier's lift and CLD stages #8691

Description

@kim-em

Current state. #8543 deliverable 1 landed (#8670): the lattice-tier loop's .degenerate arm now reads the all-ones certificate off the same CLD lattice build the classifier already ran, byte-identical, 1.27×/1.62×/1.82× at SD4/SD5/SD6. This issue is deliverable 3 of #8543, scoped as its own work item: word-sized modulus arithmetic in the lattice tier's lift and CLD stages.

Where the time goes. Recovery-pipeline sub-stage profile at the first k ≥ floor (carica-class machine, hex_lattice_spike-style):

input lift CLD build LLL+cut RREF
SD4 deg16 1.9ms 0.39ms 3.04ms (57%) 0.05ms
SD5 deg32 15.4ms 9.3ms 75.8ms (75%) 0.05ms
SD6 deg64 91ms 98.9ms 2161ms (92%) 0.06ms

The LLL reduction dominates and is integer Gram-Schmidt (not modular), so ZMod64/Montgomery does not apply to it — that is out of scope here (a separate word-sized/float LLL path would be its own issue). The word-sizable modular hot spots are the lift and CLD build, and they matter most at the SD4 / r=16 crossover, where the mod-pᵃ modulus fits 64 bits. At SD5/SD6 the modulus exceeds 2⁶⁴ and the big-integer path must stay; the win there is negligible (and those cases are already "won" versus the Isabelle comparator).

Deliverables.

  1. Word-sized poly-mod-pᵃ layer. No polynomial type over a composite word-sized modulus exists yet (FpPoly is prime-only). Scalar Montgomery over an odd word-sized modulus does exist — HexArith.MontCtx needs only p % 2 = 1, and an odd prime power pᵃ < 2⁶⁴ qualifies. Build a small WordPolyMod-style layer (UInt64 residue arrays mod m, Montgomery multiply, monic division, reduce) with proven arithmetic. This is the landable first unit.
  2. Route cldQuotientMod through it under a guard. cldQuotientMod f g p a = reduceModPow (f · g') p aDensePoly.divMod _ g → reduce, all poly arithmetic mod pᵃ. Dispatch on Odd p ∧ pᵃ < 2⁶⁴; big-integer fallback otherwise. Prove cldQuotientMod = cldQuotientModWord under the guard so the CLD columns, indicators, and conformance stay byte-identical.
  3. Same pattern for the lift. Route multifactorLiftQuadratic / quadraticHenselStep's mod-p^(2^i) poly arithmetic through the word-sized layer while p^(2^i) < 2⁶⁴, big-integer continuation past that. (Note the coupling: this touches HexHensel, which is more heavily proof-coupled than the CLD stage — land deliverable 2's data separately, and prefer the CLD stage first.)

Verification. Conformance byte-identical (hexbz_emit_fixtures, bz_flint.py, bz_trace_gate.py); hex_lattice_spike core ratios recorded before/after per deliverable, with special attention to SD4 (r=16); runFactorLatticeAdvSwinnertonDyerSD{3,4}Checksum stay inside the verify budget; no change to factorFast semantics; no sorry/axiom; the CI-gated HexBerlekampZassenhausMathlib layer stays green.

Context. Descends from #8543 deliverable 3 (that umbrella issue is closed; deliverable 1 landed as #8670, deliverable 2 was deprioritized after measurement showed SD5/SD6 do a single lift+recover step, and deliverable 4 — re-measuring the classical/lattice crossover and revisiting the dispatch threshold — should follow once this lands, since it is what actually moves the r=16 seam). The scalar Montgomery infrastructure is in HexArith/Montgomery/Context.lean and HexModArith/HotLoop.lean.

🤖 Prepared with Claude Code

Metadata

Metadata

Assignees

Labels

featurePlanner-dispatched implementation work

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions