FFT space arithmetic - #2785
Merged
Merged
Conversation
…l generic and nmod_poly hooks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR refactors
fft_smallfor more easily working with transformed operands, and uses this in various places. This enables huge speedups for algorithms that can reuse the same operand for many multiplications, e.g. matrix multiplication -- the largest speedup I've measured so far is 15x for 64x64fmpz_mat_mulwith 100,000-digit entries.fft_smallmultiplication routines simplify into function calls for creating a plan object, creating operands, transforming operands, doing pointwise operations, and transforming backgrrings for transformednmod_poly,mpn_mod_polyand (signed)mpnintegers. Others can easily be added in the future.fmpz_mat_mul,nmod_poly_mat_mul, complex multiplication (fmpzi_mul), 2x2 matrix multiplication ingr_poly_gcd_hgcd. There is also truncating complex multiplication and matrix multiplication useful foracb_mul,arb_mat_mul, etc., but this is not yet tuned and integrated.This was developed mainly using Claude Fable 5 over a couple of weeks; the code still needs some cleanup.
Important remarks
grtransform rings either need to maintain an internal scratch pool or use destructive output conversions instead of standard conversions. I opted for destructive conversions.fmpz_matmultiplication transformed multiplication barely beats Strassen with unsigned coefficients and not at all with signed coefficients (currently FFT multiplication is only used by default here for n >= 3).flint_fft_small_max_transformed_ring_sizewhich currently defaults to 4 GB. Matrix multiplication still benefits for matrices much larger than this: the multiplication algorithm simply selects a smaller block size than the full matrix.Speedup for
fmpz_mat_mulTimings for integer matrices with uniform (
fmpz_randbits) entries. FFT multiplication kicks in from around 7000-10000 bits for small n, the tuned cutoff increasing with larger n.Note: matrix mulhigh is implemented but not yet used/profiled.
Speedup for
nmod_poly_mat_mulExample timings modulo p = nextprime(2^63), uniform entries.
Note: matrix mulmid is implemented but not yet used/profiled.
Polynomial HGCD
The generic
gr_poly_gcd_hgcdgets an overload for its 2x2 matrix multiplication to allow using FFT instead of Strassen. The speedup for the GCD as a whole is small but measurable. Timings fornmod_poly, p being a 50-bit FFT prime:Timings for p = nextprime(2^63):
Timings for
mpn_mod, p = nextprime(2^127):Complex multiplication
Timings for
fmpzi_mulandfmpzi_sqr, which become wrappers around the newflint_mpn_mul_complexandflint_mpn_sqr_complex:Some nice 10-20% speedups. It should be noted that the speedup for squaring over most of the range just comes from a better Karatsuba variant (see #2781); FFT squaring is only used from 190M bits (vs 44K bits for multiplication).
At 2152336050 bits the 4 GB transform limit kicks in and we fall back to Strassen as before (the new code is 2% slower due to differences in memory allocation).
If I bump the 4 GB limit I get:
but at 6457008150 bits my machine runs out of memory.
Complex mulhigh implemented but not yet used/profiled.