1273 lines
42 KiB
Diff
1273 lines
42 KiB
Diff
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/arith_386.s vendor/github.com/remyoudompheng/bigfft/arith_386.s
|
||
--- vendor/github.com/remyoudompheng/bigfft/arith_386.s 2021-08-20 15:12:42.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/arith_386.s 1970-01-01 08:00:00.000000000 +0800
|
||
@@ -1,36 +0,0 @@
|
||
-// Trampolines to math/big assembly implementations.
|
||
-
|
||
-#include "textflag.h"
|
||
-
|
||
-// func addVV(z, x, y []Word) (c Word)
|
||
-TEXT ·addVV(SB),NOSPLIT,$0
|
||
- JMP math∕big·addVV(SB)
|
||
-
|
||
-// func subVV(z, x, y []Word) (c Word)
|
||
-TEXT ·subVV(SB),NOSPLIT,$0
|
||
- JMP math∕big·subVV(SB)
|
||
-
|
||
-// func addVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addVW(SB),NOSPLIT,$0
|
||
- JMP math∕big·addVW(SB)
|
||
-
|
||
-// func subVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·subVW(SB),NOSPLIT,$0
|
||
- JMP math∕big·subVW(SB)
|
||
-
|
||
-// func shlVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shlVU(SB),NOSPLIT,$0
|
||
- JMP math∕big·shlVU(SB)
|
||
-
|
||
-// func shrVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shrVU(SB),NOSPLIT,$0
|
||
- JMP math∕big·shrVU(SB)
|
||
-
|
||
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
|
||
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
|
||
- JMP math∕big·mulAddVWW(SB)
|
||
-
|
||
-// func addMulVVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addMulVVW(SB),NOSPLIT,$0
|
||
- JMP math∕big·addMulVVW(SB)
|
||
-
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/arith_amd64.s vendor/github.com/remyoudompheng/bigfft/arith_amd64.s
|
||
--- vendor/github.com/remyoudompheng/bigfft/arith_amd64.s 2021-08-20 15:12:42.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/arith_amd64.s 1970-01-01 08:00:00.000000000 +0800
|
||
@@ -1,38 +0,0 @@
|
||
-// Trampolines to math/big assembly implementations.
|
||
-
|
||
-#include "textflag.h"
|
||
-
|
||
-// func addVV(z, x, y []Word) (c Word)
|
||
-TEXT ·addVV(SB),NOSPLIT,$0
|
||
- JMP math∕big·addVV(SB)
|
||
-
|
||
-// func subVV(z, x, y []Word) (c Word)
|
||
-// (same as addVV except for SBBQ instead of ADCQ and label names)
|
||
-TEXT ·subVV(SB),NOSPLIT,$0
|
||
- JMP math∕big·subVV(SB)
|
||
-
|
||
-// func addVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addVW(SB),NOSPLIT,$0
|
||
- JMP math∕big·addVW(SB)
|
||
-
|
||
-// func subVW(z, x []Word, y Word) (c Word)
|
||
-// (same as addVW except for SUBQ/SBBQ instead of ADDQ/ADCQ and label names)
|
||
-TEXT ·subVW(SB),NOSPLIT,$0
|
||
- JMP math∕big·subVW(SB)
|
||
-
|
||
-// func shlVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shlVU(SB),NOSPLIT,$0
|
||
- JMP math∕big·shlVU(SB)
|
||
-
|
||
-// func shrVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shrVU(SB),NOSPLIT,$0
|
||
- JMP math∕big·shrVU(SB)
|
||
-
|
||
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
|
||
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
|
||
- JMP math∕big·mulAddVWW(SB)
|
||
-
|
||
-// func addMulVVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addMulVVW(SB),NOSPLIT,$0
|
||
- JMP math∕big·addMulVVW(SB)
|
||
-
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/arith_arm64.s vendor/github.com/remyoudompheng/bigfft/arith_arm64.s
|
||
--- vendor/github.com/remyoudompheng/bigfft/arith_arm64.s 2021-08-20 15:12:42.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/arith_arm64.s 1970-01-01 08:00:00.000000000 +0800
|
||
@@ -1,36 +0,0 @@
|
||
-// Trampolines to math/big assembly implementations.
|
||
-
|
||
-#include "textflag.h"
|
||
-
|
||
-// func addVV(z, x, y []Word) (c Word)
|
||
-TEXT ·addVV(SB),NOSPLIT,$0
|
||
- B math∕big·addVV(SB)
|
||
-
|
||
-// func subVV(z, x, y []Word) (c Word)
|
||
-TEXT ·subVV(SB),NOSPLIT,$0
|
||
- B math∕big·subVV(SB)
|
||
-
|
||
-// func addVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addVW(SB),NOSPLIT,$0
|
||
- B math∕big·addVW(SB)
|
||
-
|
||
-// func subVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·subVW(SB),NOSPLIT,$0
|
||
- B math∕big·subVW(SB)
|
||
-
|
||
-// func shlVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shlVU(SB),NOSPLIT,$0
|
||
- B math∕big·shlVU(SB)
|
||
-
|
||
-// func shrVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shrVU(SB),NOSPLIT,$0
|
||
- B math∕big·shrVU(SB)
|
||
-
|
||
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
|
||
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
|
||
- B math∕big·mulAddVWW(SB)
|
||
-
|
||
-// func addMulVVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addMulVVW(SB),NOSPLIT,$0
|
||
- B math∕big·addMulVVW(SB)
|
||
-
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/arith_arm.s vendor/github.com/remyoudompheng/bigfft/arith_arm.s
|
||
--- vendor/github.com/remyoudompheng/bigfft/arith_arm.s 2021-08-20 15:12:42.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/arith_arm.s 1970-01-01 08:00:00.000000000 +0800
|
||
@@ -1,36 +0,0 @@
|
||
-// Trampolines to math/big assembly implementations.
|
||
-
|
||
-#include "textflag.h"
|
||
-
|
||
-// func addVV(z, x, y []Word) (c Word)
|
||
-TEXT ·addVV(SB),NOSPLIT,$0
|
||
- B math∕big·addVV(SB)
|
||
-
|
||
-// func subVV(z, x, y []Word) (c Word)
|
||
-TEXT ·subVV(SB),NOSPLIT,$0
|
||
- B math∕big·subVV(SB)
|
||
-
|
||
-// func addVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addVW(SB),NOSPLIT,$0
|
||
- B math∕big·addVW(SB)
|
||
-
|
||
-// func subVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·subVW(SB),NOSPLIT,$0
|
||
- B math∕big·subVW(SB)
|
||
-
|
||
-// func shlVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shlVU(SB),NOSPLIT,$0
|
||
- B math∕big·shlVU(SB)
|
||
-
|
||
-// func shrVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shrVU(SB),NOSPLIT,$0
|
||
- B math∕big·shrVU(SB)
|
||
-
|
||
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
|
||
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
|
||
- B math∕big·mulAddVWW(SB)
|
||
-
|
||
-// func addMulVVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addMulVVW(SB),NOSPLIT,$0
|
||
- B math∕big·addMulVVW(SB)
|
||
-
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/arith_decl.go vendor/github.com/remyoudompheng/bigfft/arith_decl.go
|
||
--- vendor/github.com/remyoudompheng/bigfft/arith_decl.go 2021-08-20 15:12:42.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/arith_decl.go 2023-07-19 10:40:33.208904639 +0800
|
||
@@ -4,13 +4,30 @@
|
||
|
||
package bigfft
|
||
|
||
-import . "math/big"
|
||
+import (
|
||
+ "math/big"
|
||
+ _ "unsafe"
|
||
+)
|
||
|
||
-// implemented in arith_$GOARCH.s
|
||
+type Word = big.Word
|
||
+
|
||
+//go:linkname addVV math/big.addVV
|
||
func addVV(z, x, y []Word) (c Word)
|
||
+
|
||
+//go:linkname subVV math/big.subVV
|
||
func subVV(z, x, y []Word) (c Word)
|
||
+
|
||
+//go:linkname addVW math/big.addVW
|
||
func addVW(z, x []Word, y Word) (c Word)
|
||
+
|
||
+//go:linkname subVW math/big.subVW
|
||
func subVW(z, x []Word, y Word) (c Word)
|
||
+
|
||
+//go:linkname shlVU math/big.shlVU
|
||
func shlVU(z, x []Word, s uint) (c Word)
|
||
+
|
||
+//go:linkname mulAddVWW math/big.mulAddVWW
|
||
func mulAddVWW(z, x []Word, y, r Word) (c Word)
|
||
+
|
||
+//go:linkname addMulVVW math/big.addMulVVW
|
||
func addMulVVW(z, x []Word, y Word) (c Word)
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/arith_mips64x.s vendor/github.com/remyoudompheng/bigfft/arith_mips64x.s
|
||
--- vendor/github.com/remyoudompheng/bigfft/arith_mips64x.s 2021-08-20 15:12:42.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/arith_mips64x.s 1970-01-01 08:00:00.000000000 +0800
|
||
@@ -1,40 +0,0 @@
|
||
-// Trampolines to math/big assembly implementations.
|
||
-
|
||
-// +build mips64 mips64le
|
||
-
|
||
-#include "textflag.h"
|
||
-
|
||
-// func addVV(z, x, y []Word) (c Word)
|
||
-TEXT ·addVV(SB),NOSPLIT,$0
|
||
- JMP math∕big·addVV(SB)
|
||
-
|
||
-// func subVV(z, x, y []Word) (c Word)
|
||
-// (same as addVV except for SBBQ instead of ADCQ and label names)
|
||
-TEXT ·subVV(SB),NOSPLIT,$0
|
||
- JMP math∕big·subVV(SB)
|
||
-
|
||
-// func addVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addVW(SB),NOSPLIT,$0
|
||
- JMP math∕big·addVW(SB)
|
||
-
|
||
-// func subVW(z, x []Word, y Word) (c Word)
|
||
-// (same as addVW except for SUBQ/SBBQ instead of ADDQ/ADCQ and label names)
|
||
-TEXT ·subVW(SB),NOSPLIT,$0
|
||
- JMP math∕big·subVW(SB)
|
||
-
|
||
-// func shlVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shlVU(SB),NOSPLIT,$0
|
||
- JMP math∕big·shlVU(SB)
|
||
-
|
||
-// func shrVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shrVU(SB),NOSPLIT,$0
|
||
- JMP math∕big·shrVU(SB)
|
||
-
|
||
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
|
||
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
|
||
- JMP math∕big·mulAddVWW(SB)
|
||
-
|
||
-// func addMulVVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addMulVVW(SB),NOSPLIT,$0
|
||
- JMP math∕big·addMulVVW(SB)
|
||
-
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/arith_mipsx.s vendor/github.com/remyoudompheng/bigfft/arith_mipsx.s
|
||
--- vendor/github.com/remyoudompheng/bigfft/arith_mipsx.s 2021-08-20 15:12:42.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/arith_mipsx.s 1970-01-01 08:00:00.000000000 +0800
|
||
@@ -1,40 +0,0 @@
|
||
-// Trampolines to math/big assembly implementations.
|
||
-
|
||
-// +build mips mipsle
|
||
-
|
||
-#include "textflag.h"
|
||
-
|
||
-// func addVV(z, x, y []Word) (c Word)
|
||
-TEXT ·addVV(SB),NOSPLIT,$0
|
||
- JMP math∕big·addVV(SB)
|
||
-
|
||
-// func subVV(z, x, y []Word) (c Word)
|
||
-// (same as addVV except for SBBQ instead of ADCQ and label names)
|
||
-TEXT ·subVV(SB),NOSPLIT,$0
|
||
- JMP math∕big·subVV(SB)
|
||
-
|
||
-// func addVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addVW(SB),NOSPLIT,$0
|
||
- JMP math∕big·addVW(SB)
|
||
-
|
||
-// func subVW(z, x []Word, y Word) (c Word)
|
||
-// (same as addVW except for SUBQ/SBBQ instead of ADDQ/ADCQ and label names)
|
||
-TEXT ·subVW(SB),NOSPLIT,$0
|
||
- JMP math∕big·subVW(SB)
|
||
-
|
||
-// func shlVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shlVU(SB),NOSPLIT,$0
|
||
- JMP math∕big·shlVU(SB)
|
||
-
|
||
-// func shrVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shrVU(SB),NOSPLIT,$0
|
||
- JMP math∕big·shrVU(SB)
|
||
-
|
||
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
|
||
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
|
||
- JMP math∕big·mulAddVWW(SB)
|
||
-
|
||
-// func addMulVVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addMulVVW(SB),NOSPLIT,$0
|
||
- JMP math∕big·addMulVVW(SB)
|
||
-
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/arith_ppc64x.s vendor/github.com/remyoudompheng/bigfft/arith_ppc64x.s
|
||
--- vendor/github.com/remyoudompheng/bigfft/arith_ppc64x.s 2021-08-20 15:12:42.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/arith_ppc64x.s 1970-01-01 08:00:00.000000000 +0800
|
||
@@ -1,38 +0,0 @@
|
||
-// Trampolines to math/big assembly implementations.
|
||
-
|
||
-// +build ppc64 ppc64le
|
||
-
|
||
-#include "textflag.h"
|
||
-
|
||
-// func addVV(z, x, y []Word) (c Word)
|
||
-TEXT ·addVV(SB),NOSPLIT,$0
|
||
- BR math∕big·addVV(SB)
|
||
-
|
||
-// func subVV(z, x, y []Word) (c Word)
|
||
-TEXT ·subVV(SB),NOSPLIT,$0
|
||
- BR math∕big·subVV(SB)
|
||
-
|
||
-// func addVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addVW(SB),NOSPLIT,$0
|
||
- BR math∕big·addVW(SB)
|
||
-
|
||
-// func subVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·subVW(SB),NOSPLIT,$0
|
||
- BR math∕big·subVW(SB)
|
||
-
|
||
-// func shlVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shlVU(SB),NOSPLIT,$0
|
||
- BR math∕big·shlVU(SB)
|
||
-
|
||
-// func shrVU(z, x []Word, s uint) (c Word)
|
||
-TEXT ·shrVU(SB),NOSPLIT,$0
|
||
- BR math∕big·shrVU(SB)
|
||
-
|
||
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
|
||
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
|
||
- BR math∕big·mulAddVWW(SB)
|
||
-
|
||
-// func addMulVVW(z, x []Word, y Word) (c Word)
|
||
-TEXT ·addMulVVW(SB),NOSPLIT,$0
|
||
- BR math∕big·addMulVVW(SB)
|
||
-
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/benchmarks/bench vendor/github.com/remyoudompheng/bigfft/benchmarks/bench
|
||
--- vendor/github.com/remyoudompheng/bigfft/benchmarks/bench 1970-01-01 08:00:00.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/benchmarks/bench 2023-07-19 10:40:33.208904639 +0800
|
||
@@ -0,0 +1,20 @@
|
||
+# Benchmark of combined FFT and math/big (using threshold)
|
||
+# Run on a Core i5-4590 (Go 1.8)
|
||
+BenchmarkMul_1kb 3000000 525 ns/op
|
||
+BenchmarkMul_10kb 100000 19274 ns/op
|
||
+BenchmarkMul_50kb 5000 213375 ns/op
|
||
+BenchmarkMul_100kb 2000 651794 ns/op
|
||
+BenchmarkMul_1Mb 200 8546244 ns/op
|
||
+BenchmarkMul_5Mb 30 49127283 ns/op
|
||
+BenchmarkMul_10Mb 10 109888838 ns/op
|
||
+BenchmarkMul_20Mb 5 227088971 ns/op
|
||
+BenchmarkMul_50Mb 2 731298339 ns/op
|
||
+BenchmarkMul_100Mb 1 1480340166 ns/op
|
||
+
|
||
+BenchmarkMul_1x5Mb 50 28872973 ns/op
|
||
+BenchmarkMul_1x10Mb 20 58841416 ns/op
|
||
+BenchmarkMul_1x20Mb 10 124189252 ns/op
|
||
+BenchmarkMul_1x50Mb 3 349402586 ns/op
|
||
+BenchmarkMul_5x20Mb 10 153528843 ns/op
|
||
+BenchmarkMul_5x50Mb 3 348753322 ns/op
|
||
+
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/benchmarks/bench.big vendor/github.com/remyoudompheng/bigfft/benchmarks/bench.big
|
||
--- vendor/github.com/remyoudompheng/bigfft/benchmarks/bench.big 1970-01-01 08:00:00.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/benchmarks/bench.big 2023-07-19 10:40:33.208904639 +0800
|
||
@@ -0,0 +1,19 @@
|
||
+# Benchmarks run on a Core i5-4590 (Go 1.8)
|
||
+BenchmarkMul_1kb 5000000 298 ns/op
|
||
+BenchmarkMul_10kb 100000 14562 ns/op
|
||
+BenchmarkMul_50kb 10000 204698 ns/op
|
||
+BenchmarkMul_100kb 2000 636230 ns/op
|
||
+BenchmarkMul_1Mb 50 25950594 ns/op
|
||
+BenchmarkMul_5Mb 5 314799939 ns/op
|
||
+BenchmarkMul_10Mb 2 943065686 ns/op
|
||
+BenchmarkMul_20Mb 1 2837283743 ns/op
|
||
+BenchmarkMul_50Mb 1 14329431306 ns/op
|
||
+BenchmarkMul_100Mb 1 42590328264 ns/op
|
||
+
|
||
+BenchmarkMul_1x5Mb 10 126106007 ns/op
|
||
+BenchmarkMul_1x10Mb 5 248876061 ns/op
|
||
+BenchmarkMul_1x20Mb 3 492849546 ns/op
|
||
+BenchmarkMul_1x50Mb 1 1249673962 ns/op
|
||
+BenchmarkMul_5x20Mb 1 1261943492 ns/op
|
||
+BenchmarkMul_5x50Mb 1 3098019651 ns/op
|
||
+
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/benchmarks/bench.fft vendor/github.com/remyoudompheng/bigfft/benchmarks/bench.fft
|
||
--- vendor/github.com/remyoudompheng/bigfft/benchmarks/bench.fft 1970-01-01 08:00:00.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/benchmarks/bench.fft 2023-07-19 10:40:33.208904639 +0800
|
||
@@ -0,0 +1,20 @@
|
||
+# Benchmarks using the mulFFT function only.
|
||
+# Run on a Core i5-4590 (Go 1.8)
|
||
+BenchmarkMul_1kb 200000 9737 ns/op
|
||
+BenchmarkMul_10kb 10000 105408 ns/op
|
||
+BenchmarkMul_50kb 3000 584090 ns/op
|
||
+BenchmarkMul_100kb 2000 973130 ns/op
|
||
+BenchmarkMul_1Mb 200 8622463 ns/op
|
||
+BenchmarkMul_5Mb 30 48602728 ns/op
|
||
+BenchmarkMul_10Mb 10 109184721 ns/op
|
||
+BenchmarkMul_20Mb 5 227053895 ns/op
|
||
+BenchmarkMul_50Mb 2 727421044 ns/op
|
||
+BenchmarkMul_100Mb 1 1550029484 ns/op
|
||
+
|
||
+BenchmarkMul_1x5Mb 50 28827150 ns/op
|
||
+BenchmarkMul_1x10Mb 20 58097775 ns/op
|
||
+BenchmarkMul_1x20Mb 10 124998246 ns/op
|
||
+BenchmarkMul_1x50Mb 3 350045770 ns/op
|
||
+BenchmarkMul_5x20Mb 10 160220847 ns/op
|
||
+BenchmarkMul_5x50Mb 3 350824154 ns/op
|
||
+
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/benchmarks/bench.gmp vendor/github.com/remyoudompheng/bigfft/benchmarks/bench.gmp
|
||
--- vendor/github.com/remyoudompheng/bigfft/benchmarks/bench.gmp 1970-01-01 08:00:00.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/benchmarks/bench.gmp 2023-07-19 10:40:33.208904639 +0800
|
||
@@ -0,0 +1,21 @@
|
||
+# These benchamrks were realised using gmpbench at
|
||
+# http://gmplib.org/gmpbench.html
|
||
+# and converted to the go test output format.
|
||
+# Numbers are for a Core i5-4590 with GMP 6.1.2
|
||
+BenchmarkMul_1kb 47143107 175 ns/op
|
||
+BenchmarkMul_10kb 1321291 7573 ns/op
|
||
+BenchmarkMul_50kb 125645 79693 ns/op
|
||
+BenchmarkMul_100kb 47298 211500 ns/op
|
||
+BenchmarkMul_1Mb 2950 3344500 ns/op
|
||
+BenchmarkMul_5Mb 413 23920000 ns/op
|
||
+BenchmarkMul_10Mb 164 60606000 ns/op
|
||
+BenchmarkMul_20Mb 78 127700000 ns/op
|
||
+BenchmarkMul_50Mb 8 352100000 ns/op
|
||
+BenchmarkMul_100Mb 4 746270000 ns/op
|
||
+
|
||
+BenchmarkMul_1x5Mb 884 11670000 ns/op
|
||
+BenchmarkMul_1x10Mb 337 27174000 ns/op
|
||
+BenchmarkMul_1x20Mb 195 52630000 ns/op
|
||
+BenchmarkMul_1x50Mb 70 131000000 ns/op
|
||
+BenchmarkMul_5x20Mb 134 74188000 ns/op
|
||
+BenchmarkMul_5x50Mb 49 207770000 ns/op
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/benchmarks/scan.big vendor/github.com/remyoudompheng/bigfft/benchmarks/scan.big
|
||
--- vendor/github.com/remyoudompheng/bigfft/benchmarks/scan.big 1970-01-01 08:00:00.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/benchmarks/scan.big 2023-07-19 10:40:33.208904639 +0800
|
||
@@ -0,0 +1,10 @@
|
||
+Benchmarks on a Core i5-4590
|
||
+
|
||
+BenchmarkScan1k-4 200000 9995 ns/op 32 B/op 1 allocs/op
|
||
+BenchmarkScan10k-4 10000 175356 ns/op 57 B/op 1 allocs/op
|
||
+BenchmarkScan100k-4 200 9427422 ns/op 117499 B/op 6 allocs/op
|
||
+BenchmarkScan1M-4 1 1776707489 ns/op 2197961776 B/op 10386 allocs/op
|
||
+BenchmarkScan2M-4 1 6865499995 ns/op 8708998320 B/op 20774 allocs/op
|
||
+BenchmarkScan5M-4 1 42641034189 ns/op 54105679664 B/op 51925 allocs/op
|
||
+BenchmarkScan10M-4 1 151975273589 ns/op 215978795792 B/op 103837 allocs/op
|
||
+
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/benchmarks/scan.bigfft vendor/github.com/remyoudompheng/bigfft/benchmarks/scan.bigfft
|
||
--- vendor/github.com/remyoudompheng/bigfft/benchmarks/scan.bigfft 1970-01-01 08:00:00.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/benchmarks/scan.bigfft 2023-07-19 10:40:33.208904639 +0800
|
||
@@ -0,0 +1,10 @@
|
||
+Benchmarks on a Core i5-4590
|
||
+
|
||
+BenchmarkScan1k-4 200000 10876 ns/op 2784 B/op 13 allocs/op
|
||
+BenchmarkScan10k-4 5000 243806 ns/op 86796 B/op 64 allocs/op
|
||
+BenchmarkScan100k-4 200 6780545 ns/op 1733425 B/op 332 allocs/op
|
||
+BenchmarkScan1M-4 10 144867502 ns/op 41509963 B/op 3130 allocs/op
|
||
+BenchmarkScan2M-4 3 346540778 ns/op 94912754 B/op 6213 allocs/op
|
||
+BenchmarkScan5M-4 1 1069878799 ns/op 278606280 B/op 15444 allocs/op
|
||
+BenchmarkScan10M-4 1 2693328580 ns/op 625284488 B/op 30842 allocs/op
|
||
+
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/calibrate_test.go vendor/github.com/remyoudompheng/bigfft/calibrate_test.go
|
||
--- vendor/github.com/remyoudompheng/bigfft/calibrate_test.go 1970-01-01 08:00:00.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/calibrate_test.go 2023-07-19 10:40:33.208904639 +0800
|
||
@@ -0,0 +1,159 @@
|
||
+// Usage: go test -run=TestCalibrate -calibrate
|
||
+
|
||
+package bigfft
|
||
+
|
||
+import (
|
||
+ "flag"
|
||
+ "fmt"
|
||
+ "testing"
|
||
+ "time"
|
||
+)
|
||
+
|
||
+var calibrate = flag.Bool("calibrate", false, "run calibration test")
|
||
+
|
||
+// measureMul benchmarks math/big versus FFT for a given input size
|
||
+// (in bits).
|
||
+func measureMul(th int) (tBig, tFFT time.Duration) {
|
||
+ bigLoad := func(b *testing.B) { benchmarkMulBig(b, th, th) }
|
||
+ fftLoad := func(b *testing.B) { benchmarkMulFFT(b, th, th) }
|
||
+
|
||
+ res1 := testing.Benchmark(bigLoad)
|
||
+ res2 := testing.Benchmark(fftLoad)
|
||
+ tBig = time.Duration(res1.NsPerOp())
|
||
+ tFFT = time.Duration(res2.NsPerOp())
|
||
+ return
|
||
+}
|
||
+
|
||
+func roundDur(d time.Duration) time.Duration {
|
||
+ if d > 100*time.Millisecond {
|
||
+ return d / time.Millisecond * time.Millisecond
|
||
+ } else {
|
||
+ return d / time.Microsecond * time.Microsecond
|
||
+ }
|
||
+}
|
||
+
|
||
+func TestCalibrateThreshold(t *testing.T) {
|
||
+ if !*calibrate {
|
||
+ t.Log("not calibrating, use -calibrate to do so.")
|
||
+ return
|
||
+ }
|
||
+
|
||
+ lower := int(1e3) // math/big is faster at this size.
|
||
+ upper := int(300e3) // FFT is faster at this size.
|
||
+
|
||
+ var sizes [9]int
|
||
+ var speedups [9]float64
|
||
+ for i := 0; i < 3; i++ {
|
||
+ for idx := 1; idx <= 9; idx++ {
|
||
+ sz := ((10-idx)*lower + idx*upper) / 10
|
||
+ big, fft := measureMul(sz)
|
||
+ spd := float64(big) / float64(fft)
|
||
+ sizes[idx-1] = sz
|
||
+ speedups[idx-1] = spd
|
||
+ fmt.Printf("speedup of FFT over math/big at size %d bits: %.2f (%s vs %s)\n",
|
||
+ sz, spd, roundDur(big), roundDur(fft))
|
||
+ }
|
||
+ narrow := false
|
||
+ for idx, s := range speedups {
|
||
+ if s < .98 {
|
||
+ lower = sizes[idx]
|
||
+ narrow = true
|
||
+ } else {
|
||
+ break
|
||
+ }
|
||
+ }
|
||
+ for idx := range speedups {
|
||
+ if speedups[8-idx] > 1.02 {
|
||
+ upper = sizes[8-idx]
|
||
+ narrow = true
|
||
+ } else {
|
||
+ break
|
||
+ }
|
||
+ }
|
||
+ if lower >= upper {
|
||
+ panic("impossible")
|
||
+ }
|
||
+ if !narrow || (upper-lower) <= 10 {
|
||
+ break
|
||
+ }
|
||
+ }
|
||
+ fmt.Printf("sizes: %d\n", sizes)
|
||
+ fmt.Printf("speedups: %.2f\n", speedups)
|
||
+}
|
||
+
|
||
+func measureFFTSize(w int, k uint) time.Duration {
|
||
+ load := func(b *testing.B) {
|
||
+ x := rndNat(w)
|
||
+ y := rndNat(w)
|
||
+ for i := 0; i < b.N; i++ {
|
||
+ m := (w+w)>>k + 1
|
||
+ xp := polyFromNat(x, k, m)
|
||
+ yp := polyFromNat(y, k, m)
|
||
+ rp := xp.Mul(&yp)
|
||
+ _ = rp.Int()
|
||
+ }
|
||
+ }
|
||
+ res := testing.Benchmark(load)
|
||
+ return time.Duration(res.NsPerOp())
|
||
+}
|
||
+
|
||
+func TestCalibrateFFT(t *testing.T) {
|
||
+ if !*calibrate {
|
||
+ t.Log("not calibrating, use -calibrate to do so.")
|
||
+ return
|
||
+ }
|
||
+
|
||
+ lows := [...]int{10, 10, 10, 10,
|
||
+ 20, 50, 100, 200, 500, // 8
|
||
+ 1000, 2000, 5000, 10000, // 12
|
||
+ 20000, 50000, 100e3, 200e3, // 16
|
||
+ }
|
||
+ his := [...]int{100, 100, 100, 200,
|
||
+ 500, 1000, 2000, 5000, 10000, // 8
|
||
+ 50e3, 100e3, 200e3, 800e3, // 12
|
||
+ 2e6, 5e6, 10e6, 20e6, // 16
|
||
+ }
|
||
+ for k := uint(3); k <= 16; k++ {
|
||
+ // Measure the speedup between k and k+1
|
||
+ low := lows[k] // FFT of size 1<<k known to be faster
|
||
+ hi := his[k] // FFT of size 2<<k known to be faster
|
||
+ var sizes [9]int
|
||
+ var speedups [9]float64
|
||
+ for i := 0; i < 3; i++ {
|
||
+ for idx := 1; idx <= 9; idx++ {
|
||
+ sz := ((10-idx)*low + idx*hi) / 10
|
||
+ t1, t2 := measureFFTSize(sz, k), measureFFTSize(sz, k+1)
|
||
+ spd := float64(t1) / float64(t2)
|
||
+ sizes[idx-1] = sz
|
||
+ speedups[idx-1] = spd
|
||
+ fmt.Printf("speedup of %d vs %d at size %d words: %.2f (%s vs %s)\n",
|
||
+ k+1, k, sz, spd, roundDur(t1), roundDur(t2))
|
||
+ }
|
||
+ narrow := false
|
||
+ for idx, s := range speedups {
|
||
+ if s < .98 {
|
||
+ low = sizes[idx]
|
||
+ narrow = true
|
||
+ } else {
|
||
+ break
|
||
+ }
|
||
+ }
|
||
+ for idx := range speedups {
|
||
+ if speedups[8-idx] > 1.02 {
|
||
+ hi = sizes[8-idx]
|
||
+ narrow = true
|
||
+ } else {
|
||
+ break
|
||
+ }
|
||
+ }
|
||
+ if low >= hi {
|
||
+ panic("impossible")
|
||
+ }
|
||
+ if !narrow || (hi-low) <= 10 {
|
||
+ break
|
||
+ }
|
||
+ }
|
||
+ fmt.Printf("sizes: %d\n", sizes)
|
||
+ fmt.Printf("speedups: %.2f\n", speedups)
|
||
+ }
|
||
+}
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/fermat_test.go vendor/github.com/remyoudompheng/bigfft/fermat_test.go
|
||
--- vendor/github.com/remyoudompheng/bigfft/fermat_test.go 1970-01-01 08:00:00.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/fermat_test.go 2023-07-19 10:40:33.208904639 +0800
|
||
@@ -0,0 +1,153 @@
|
||
+package bigfft
|
||
+
|
||
+import (
|
||
+ "fmt"
|
||
+ "math/big"
|
||
+ "testing"
|
||
+)
|
||
+
|
||
+type (
|
||
+ Int = big.Int
|
||
+)
|
||
+
|
||
+// parseHex reads an hex-formatted number modulo 2^bits+1.
|
||
+func parseHex(s string, bits int) fermat {
|
||
+ z := new(Int)
|
||
+ z, ok := z.SetString(s, 0)
|
||
+ if !ok {
|
||
+ panic(s)
|
||
+ }
|
||
+ f := fermat(z.Bits())
|
||
+ for len(f)*_W <= bits {
|
||
+ f = append(f, 0)
|
||
+ }
|
||
+ return f
|
||
+}
|
||
+
|
||
+func compare(t *testing.T, prefix string, a, b fermat) {
|
||
+ var x, y Int
|
||
+ x.SetBits(a)
|
||
+ y.SetBits(b)
|
||
+ if x.Cmp(&y) != 0 {
|
||
+ t.Errorf("%s: %x != %x", prefix, &x, &y)
|
||
+ }
|
||
+}
|
||
+
|
||
+func TestFermatShift(t *testing.T) {
|
||
+ const n = 4
|
||
+ f := make(fermat, n+1)
|
||
+ for i := 0; i < n; i++ {
|
||
+ f[i] = Word(rnd.Int63())
|
||
+ }
|
||
+ b := big.NewInt(1)
|
||
+ b = b.Lsh(b, uint(n*_W))
|
||
+ b = b.Add(b, big.NewInt(1))
|
||
+ z := make(fermat, len(f)) // Test with uninitialized z.
|
||
+ for shift := -2048; shift < 2048; shift++ {
|
||
+ z.Shift(f, shift)
|
||
+
|
||
+ z2 := new(Int)
|
||
+ z2.SetBits(f)
|
||
+ if shift < 0 {
|
||
+ s2 := (-shift) % (2 * n * _W)
|
||
+ z2 = z2.Lsh(z2, uint(2*n*_W-s2))
|
||
+ } else {
|
||
+ z2 = z2.Lsh(z2, uint(shift))
|
||
+ }
|
||
+ z2 = z2.Mod(z2, b)
|
||
+ compare(t, fmt.Sprintf("shift %d", shift), z, z2.Bits())
|
||
+ }
|
||
+}
|
||
+
|
||
+func TestFermatShiftHalf(t *testing.T) {
|
||
+ const n = 3
|
||
+ f := make(fermat, n+1)
|
||
+ for i := 0; i < n; i++ {
|
||
+ f[i] = ^Word(0)
|
||
+ }
|
||
+ b := big.NewInt(1)
|
||
+ b = b.Lsh(b, uint(n*_W))
|
||
+ b = b.Add(b, big.NewInt(1))
|
||
+ z := make(fermat, len(f)) // Test with uninitialized z.
|
||
+ tmp := make(fermat, len(f))
|
||
+ tmp2 := make(fermat, len(f))
|
||
+ for shift := 0; shift < 16384; shift++ {
|
||
+ // Shift twice by shift/2
|
||
+ z.ShiftHalf(f, shift, tmp)
|
||
+ copy(tmp, z)
|
||
+ z.ShiftHalf(tmp, shift, tmp2)
|
||
+
|
||
+ z2 := new(Int)
|
||
+ z2 = z2.Lsh(new(Int).SetBits(f), uint(shift))
|
||
+ z2 = z2.Mod(z2, b)
|
||
+ compare(t, fmt.Sprintf("shift %d", shift), z, z2.Bits())
|
||
+ }
|
||
+}
|
||
+
|
||
+type test struct{ a, b, c fermat }
|
||
+
|
||
+// addTests is a series of mod 2^256+1 tests.
|
||
+var addTests = []test{
|
||
+ {
|
||
+ parseHex("0x5555555555555555555555555555555555555555555555555555555555555555", 256),
|
||
+ parseHex("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab", 256),
|
||
+ parseHex("0x10000000000000000000000000000000000000000000000000000000000000000", 256),
|
||
+ },
|
||
+ {
|
||
+ parseHex("0x5555555555555555555555555555555555555555555555555555555555555555", 256),
|
||
+ parseHex("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 256),
|
||
+ parseHex("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 256),
|
||
+ },
|
||
+ {
|
||
+ parseHex("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 256),
|
||
+ parseHex("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 256),
|
||
+ parseHex("0x5555555555555555555555555555555555555555555555555555555555555553", 256),
|
||
+ },
|
||
+}
|
||
+
|
||
+func TestFermatAdd(t *testing.T) {
|
||
+ for i, item := range addTests {
|
||
+ z := make(fermat, len(item.a))
|
||
+ z = z.Add(item.a, item.b)
|
||
+ compare(t, fmt.Sprintf("addTests[%d]", i), z, item.c)
|
||
+ }
|
||
+}
|
||
+
|
||
+var mulTests = []test{
|
||
+ { // 3^400 = 3^200 * 3^200
|
||
+ parseHex("0xc21a937a76f3432ffd73d97e447606b683ecf6f6e4a7ae223c2578e26c486a03", 256),
|
||
+ parseHex("0xc21a937a76f3432ffd73d97e447606b683ecf6f6e4a7ae223c2578e26c486a03", 256),
|
||
+ parseHex("0x0e65f4d3508036eaca8faa2b8194ace009c863e44bdc040c459a7127bf8bcc62", 256),
|
||
+ },
|
||
+ { // 2^256 * 2^256 mod (2^256+1) = 1.
|
||
+ parseHex("0x10000000000000000000000000000000000000000000000000000000000000000", 256),
|
||
+ parseHex("0x10000000000000000000000000000000000000000000000000000000000000000", 256),
|
||
+ parseHex("0x1", 256),
|
||
+ },
|
||
+ { // (2^256-1) * (2^256-1) mod (2^256+1) = 4.
|
||
+ parseHex("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 256),
|
||
+ parseHex("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 256),
|
||
+ parseHex("0x4", 256),
|
||
+ },
|
||
+ { // 1<<(64W) * 1<<(64W) mod (1<<64W+1) = 1
|
||
+ fermat{64: 1},
|
||
+ fermat{64: 1},
|
||
+ fermat{0: 1},
|
||
+ },
|
||
+ {
|
||
+ // Test case from issue 1. One of the squares of the Fourier
|
||
+ // transforms was miscomputed.
|
||
+ // The input number is made of 18 words, but we are working modulo 2^1280+1
|
||
+ parseHex("0xfffffffffffffffffffffffeffffffffffffffffffffffffffffffffffff00000000000000000000000100000000000000000000000000000000000000000000000000000000fffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff000100000000000000000000000100000000000000000000000000000000fffefffffffffffffffffffd", 1280),
|
||
+ parseHex("0xfffffffffffffffffffffffeffffffffffffffffffffffffffffffffffff00000000000000000000000100000000000000000000000000000000000000000000000000000000fffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff000100000000000000000000000100000000000000000000000000000000fffefffffffffffffffffffd", 1280),
|
||
+ parseHex("0xfffe00000003fffc0000000000000000fff40003000000000000000000060001fffffffd0001fffffffffffffffe000dfffbfffffffffffffffffffafffe0000000200000000000000000002fff60002fffffffffffffffa00060001ffffffff0000000000000000fffc0007fffe0000000000000007fff8fffdfffffffffffffffffffa00000004fffa0000fffffffffffffff600080000000000000000000a", 1280),
|
||
+ },
|
||
+}
|
||
+
|
||
+func TestFermatMul(t *testing.T) {
|
||
+ for i, item := range mulTests {
|
||
+ z := make(fermat, 3*len(item.a))
|
||
+ z = z.Mul(item.a, item.b)
|
||
+ compare(t, fmt.Sprintf("mulTests[%d]", i), z, item.c)
|
||
+ }
|
||
+}
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/fft_test.go vendor/github.com/remyoudompheng/bigfft/fft_test.go
|
||
--- vendor/github.com/remyoudompheng/bigfft/fft_test.go 1970-01-01 08:00:00.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/fft_test.go 2023-07-19 10:40:33.208904639 +0800
|
||
@@ -0,0 +1,354 @@
|
||
+package bigfft
|
||
+
|
||
+import (
|
||
+ "fmt"
|
||
+ "math/big"
|
||
+ "math/rand"
|
||
+ "testing"
|
||
+)
|
||
+
|
||
+func cmpnat(t *testing.T, x, y nat) int {
|
||
+ var a, b Int
|
||
+ a.SetBits(x)
|
||
+ b.SetBits(y)
|
||
+ c := a.Cmp(&b)
|
||
+ if c != 0 {
|
||
+ t.Logf("a.len=%d, b.len=%d", a.BitLen(), b.BitLen())
|
||
+ for i := 0; i < len(x) || i < len(y); i++ {
|
||
+ var u, v Word
|
||
+ if i < len(x) {
|
||
+ u = x[i]
|
||
+ }
|
||
+ if i < len(y) {
|
||
+ v = y[i]
|
||
+ }
|
||
+ if diff := u ^ v; diff != 0 {
|
||
+ t.Logf("diff at word %d: %x", i, diff)
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+ return c
|
||
+}
|
||
+
|
||
+func TestRoundTripIntPoly(t *testing.T) {
|
||
+ N := 4
|
||
+ step := 500
|
||
+ if testing.Short() {
|
||
+ N = 2
|
||
+ }
|
||
+ // Sizes 12800 and 34300 may cause problems.
|
||
+ for size := 300; size < 50000; size += step {
|
||
+ n := make(nat, size)
|
||
+ for i := 0; i < N; i++ {
|
||
+ for p := range n {
|
||
+ n[p] = Word(rand.Int63())
|
||
+ }
|
||
+ k, m := fftSize(n, nil)
|
||
+ pol := polyFromNat(n, k, m)
|
||
+ n2 := pol.Int()
|
||
+ if cmpnat(t, n, n2) != 0 {
|
||
+ t.Errorf("different n and n2, size=%d, iter=%d", size, i)
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
+func TestFourierSizes(t *testing.T) {
|
||
+ sizes := []int{
|
||
+ 2e3, 3e3, 5e3, 7e3, 10e3, 14e3,
|
||
+ 2e4, 3e4, 5e4, 7e4, 10e4, 14e4,
|
||
+ 2e5, 3e5, 5e5, 7e5, 10e5, 14e5,
|
||
+ 2e6, 3e6, 5e6, 7e6, 10e6, 14e6,
|
||
+ 2e7, 3e7, 5e7, 7e7, 10e7, 14e7,
|
||
+ 2e8, 3e8, 5e8, 7e8, 10e8, 14e8,
|
||
+ }
|
||
+ for _, s := range sizes {
|
||
+ k, m := fftSize(make(nat, s/_W), make(nat, s/_W))
|
||
+ v := valueSize(k, m, 2)
|
||
+ t.Logf("bits=%d => FFT size %d, chunk size = %d, value size = %d",
|
||
+ s, 1<<k, m, v)
|
||
+ needed := 2*m*_W + int(k)
|
||
+ got := v * _W
|
||
+ t.Logf("inefficiency: value/chunk_product=%.2f, fftsize/inputsize=%.2f",
|
||
+ float64(got)/float64(needed), float64(v<<k)/float64(2*s/_W))
|
||
+ if v > 3*m {
|
||
+ t.Errorf("FFT word size %d >> input word size %d", v, m)
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
+func testFourier(t *testing.T, N int, k uint) {
|
||
+ // Random coefficients
|
||
+ src := make([]fermat, 1<<k)
|
||
+ for i := range src {
|
||
+ src[i] = make(fermat, N+1)
|
||
+ for p := 0; p < N; p++ {
|
||
+ src[i][p] = Word(rnd.Int63())
|
||
+ }
|
||
+ }
|
||
+ cmpFourier(t, N, k, src, false)
|
||
+ cmpFourier(t, N, k, src, true)
|
||
+
|
||
+ // Saturated coefficients (b^N-1)
|
||
+ for i := range src {
|
||
+ for p := 0; p < N; p++ {
|
||
+ src[i][p] = ^Word(0)
|
||
+ }
|
||
+ }
|
||
+ cmpFourier(t, N, k, src, false)
|
||
+ cmpFourier(t, N, k, src, true)
|
||
+}
|
||
+
|
||
+// cmpFourier computes the Fourier transform of src
|
||
+// and compares it to the FFT result.
|
||
+func cmpFourier(t *testing.T, N int, k uint, src []fermat, inverse bool) {
|
||
+ t.Logf("testFourier(t, %d, %d, inverse=%v)", N, k, inverse)
|
||
+ ωshift := (4 * N * _W) >> k
|
||
+ if inverse {
|
||
+ ωshift = -ωshift
|
||
+ }
|
||
+ dst1 := make([]fermat, 1<<k)
|
||
+ dst2 := make([]fermat, 1<<k)
|
||
+ for i := range src {
|
||
+ dst1[i] = make(fermat, N+1)
|
||
+ dst2[i] = make(fermat, N+1)
|
||
+ }
|
||
+
|
||
+ // naive transform
|
||
+ tmp := make(fermat, N+1)
|
||
+ tmp2 := make(fermat, N+1)
|
||
+ for i := range src {
|
||
+ for j := range dst1 {
|
||
+ tmp.ShiftHalf(src[i], i*j*ωshift, tmp2)
|
||
+ dst1[j].Add(dst1[j], tmp)
|
||
+ }
|
||
+ }
|
||
+
|
||
+ // fast transform
|
||
+ fourier(dst2, src, inverse, N, k)
|
||
+
|
||
+ for i := range src {
|
||
+ if cmpnat(t, nat(dst1[i]), nat(dst2[i])) != 0 {
|
||
+ var x, y Int
|
||
+ x.SetBits(dst1[i])
|
||
+ y.SetBits(dst2[i])
|
||
+ t.Errorf("difference in dst[%d]: %x %x", i, &x, &y)
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
+func TestFourier(t *testing.T) {
|
||
+ // 1-word transforms.
|
||
+ testFourier(t, 1, 2)
|
||
+ testFourier(t, 1, 3)
|
||
+ testFourier(t, 1, 4)
|
||
+
|
||
+ // 2-word transforms
|
||
+ testFourier(t, 2, 2)
|
||
+ testFourier(t, 2, 3)
|
||
+ testFourier(t, 2, 4)
|
||
+ testFourier(t, 2, 8)
|
||
+
|
||
+ testFourier(t, 4, 4)
|
||
+ testFourier(t, 4, 5)
|
||
+ testFourier(t, 4, 6)
|
||
+ testFourier(t, 4, 8)
|
||
+
|
||
+ // Test a few limit cases. This is when
|
||
+ // N*WordSize is a multiple of 1<<(k-2) but not 1<<(k-1)
|
||
+ if _W == 64 {
|
||
+ testFourier(t, 1, 8)
|
||
+ testFourier(t, 3, 8)
|
||
+ testFourier(t, 5, 8)
|
||
+ testFourier(t, 7, 8)
|
||
+ testFourier(t, 9, 8)
|
||
+ testFourier(t, 11, 8)
|
||
+ }
|
||
+}
|
||
+
|
||
+// Tests Fourier transform and its reciprocal.
|
||
+func TestRoundTripPolyValues(t *testing.T) {
|
||
+ Size := 100000
|
||
+ if testing.Short() {
|
||
+ Size = 50
|
||
+ }
|
||
+ // Build a polynomial from an integer.
|
||
+ n := make(nat, Size)
|
||
+ for p := range n {
|
||
+ n[p] = Word(rand.Int63())
|
||
+ }
|
||
+ k, m := fftSize(n, nil)
|
||
+ pol := polyFromNat(n, k, m)
|
||
+
|
||
+ // Transform it.
|
||
+ f := valueSize(k, m, 1)
|
||
+ values := pol.Transform(f)
|
||
+
|
||
+ // Inverse transform.
|
||
+ pol2 := values.InvTransform()
|
||
+ pol2.m = m
|
||
+
|
||
+ t.Logf("k=%d, m=%d", k, m)
|
||
+
|
||
+ // Evaluate and compare.
|
||
+ n2 := pol2.Int()
|
||
+ if cmpnat(t, n, n2) != 0 {
|
||
+ t.Errorf("different n and n2")
|
||
+ }
|
||
+}
|
||
+
|
||
+var rnd = rand.New(rand.NewSource(0x43de683f473542af))
|
||
+
|
||
+func rndNat(n int) nat {
|
||
+ x := make(nat, n)
|
||
+ for i := 0; i < n; i++ {
|
||
+ x[i] = Word(rnd.Int63()<<1 + rnd.Int63n(2))
|
||
+ }
|
||
+ return x
|
||
+}
|
||
+
|
||
+func TestMul(t *testing.T) {
|
||
+ sizes := []int{1e3, 5e3, 15e3, 25e3, 70e3, 200e3, 500e3}
|
||
+ iters := 10
|
||
+ if testing.Short() {
|
||
+ iters = 1
|
||
+ }
|
||
+
|
||
+ var x, y Int
|
||
+ for i := 0; i < iters; i++ {
|
||
+ for _, size1 := range sizes {
|
||
+ for _, size2 := range sizes {
|
||
+ x.SetBits(rndNat(size1 / _W))
|
||
+ y.SetBits(rndNat(size2 / _W))
|
||
+ z := new(Int).Mul(&x, &y)
|
||
+ z2 := Mul(&x, &y)
|
||
+ if z.Cmp(z2) != 0 {
|
||
+ t.Errorf("z (%d bits) != z2 (%d bits)", z.BitLen(), z2.BitLen())
|
||
+ logbig(t, new(Int).Xor(z, z2))
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
+func logbig(t *testing.T, n *Int) {
|
||
+ s := fmt.Sprintf("%x", n)
|
||
+ for len(s) > 64 {
|
||
+ t.Log(s[:64])
|
||
+ s = s[64:]
|
||
+ }
|
||
+ t.Log(s)
|
||
+}
|
||
+
|
||
+func benchmarkMulBig(b *testing.B, sizex, sizey int) {
|
||
+ mulx := rndNat(sizex / _W)
|
||
+ muly := rndNat(sizey / _W)
|
||
+ b.ResetTimer()
|
||
+ var x, y, z Int
|
||
+ x.SetBits(mulx)
|
||
+ y.SetBits(muly)
|
||
+ for i := 0; i < b.N; i++ {
|
||
+ z.Mul(&x, &y)
|
||
+ }
|
||
+}
|
||
+
|
||
+func benchmarkMulFFT(b *testing.B, sizex, sizey int) {
|
||
+ mulx := rndNat(sizex / _W)
|
||
+ muly := rndNat(sizey / _W)
|
||
+ b.ResetTimer()
|
||
+ var x, y Int
|
||
+ x.SetBits(mulx)
|
||
+ y.SetBits(muly)
|
||
+ for i := 0; i < b.N; i++ {
|
||
+ _ = mulFFT(&x, &y)
|
||
+ }
|
||
+}
|
||
+
|
||
+func BenchmarkMulBig_1kb(b *testing.B) { benchmarkMulBig(b, 1e3, 1e3) }
|
||
+func BenchmarkMulBig_10kb(b *testing.B) { benchmarkMulBig(b, 1e4, 1e4) }
|
||
+func BenchmarkMulBig_50kb(b *testing.B) { benchmarkMulBig(b, 5e4, 5e4) }
|
||
+func BenchmarkMulBig_100kb(b *testing.B) { benchmarkMulBig(b, 1e5, 1e5) }
|
||
+func BenchmarkMulBig_200kb(b *testing.B) { benchmarkMulBig(b, 2e5, 2e5) }
|
||
+func BenchmarkMulBig_500kb(b *testing.B) { benchmarkMulBig(b, 5e5, 5e5) }
|
||
+func BenchmarkMulBig_1Mb(b *testing.B) { benchmarkMulBig(b, 1e6, 1e6) }
|
||
+func BenchmarkMulBig_2Mb(b *testing.B) { benchmarkMulBig(b, 2e6, 2e6) }
|
||
+func BenchmarkMulBig_5Mb(b *testing.B) { benchmarkMulBig(b, 5e6, 5e6) }
|
||
+func BenchmarkMulBig_10Mb(b *testing.B) { benchmarkMulBig(b, 10e6, 10e6) }
|
||
+func BenchmarkMulBig_20Mb(b *testing.B) { benchmarkMulBig(b, 20e6, 20e6) }
|
||
+func BenchmarkMulBig_50Mb(b *testing.B) { benchmarkMulBig(b, 50e6, 50e6) }
|
||
+func BenchmarkMulBig_100Mb(b *testing.B) { benchmarkMulBig(b, 100e6, 100e6) }
|
||
+
|
||
+func BenchmarkMulFFT_1kb(b *testing.B) { benchmarkMulFFT(b, 1e3, 1e3) }
|
||
+func BenchmarkMulFFT_10kb(b *testing.B) { benchmarkMulFFT(b, 1e4, 1e4) }
|
||
+func BenchmarkMulFFT_50kb(b *testing.B) { benchmarkMulFFT(b, 5e4, 5e4) }
|
||
+func BenchmarkMulFFT_100kb(b *testing.B) { benchmarkMulFFT(b, 1e5, 1e5) }
|
||
+func BenchmarkMulFFT_200kb(b *testing.B) { benchmarkMulFFT(b, 2e5, 2e5) }
|
||
+func BenchmarkMulFFT_500kb(b *testing.B) { benchmarkMulFFT(b, 5e5, 5e5) }
|
||
+func BenchmarkMulFFT_1Mb(b *testing.B) { benchmarkMulFFT(b, 1e6, 1e6) }
|
||
+func BenchmarkMulFFT_2Mb(b *testing.B) { benchmarkMulFFT(b, 2e6, 2e6) }
|
||
+func BenchmarkMulFFT_5Mb(b *testing.B) { benchmarkMulFFT(b, 5e6, 5e6) }
|
||
+func BenchmarkMulFFT_10Mb(b *testing.B) { benchmarkMulFFT(b, 10e6, 10e6) }
|
||
+func BenchmarkMulFFT_20Mb(b *testing.B) { benchmarkMulFFT(b, 20e6, 20e6) }
|
||
+func BenchmarkMulFFT_50Mb(b *testing.B) { benchmarkMulFFT(b, 50e6, 50e6) }
|
||
+func BenchmarkMulFFT_100Mb(b *testing.B) { benchmarkMulFFT(b, 100e6, 100e6) }
|
||
+func BenchmarkMulFFT_200Mb(b *testing.B) { benchmarkMulFFT(b, 200e6, 200e6) }
|
||
+func BenchmarkMulFFT_500Mb(b *testing.B) { benchmarkMulFFT(b, 500e6, 500e6) }
|
||
+func BenchmarkMulFFT_1Gb(b *testing.B) { benchmarkMulFFT(b, 1e9, 1e9) }
|
||
+
|
||
+func benchmarkMul(b *testing.B, sizex, sizey int) {
|
||
+ mulx := rndNat(sizex / _W)
|
||
+ muly := rndNat(sizey / _W)
|
||
+ b.ResetTimer()
|
||
+ for i := 0; i < b.N; i++ {
|
||
+ var x, y Int
|
||
+ x.SetBits(mulx)
|
||
+ y.SetBits(muly)
|
||
+ _ = Mul(&x, &y)
|
||
+ }
|
||
+}
|
||
+
|
||
+func BenchmarkMul_50kb(b *testing.B) { benchmarkMul(b, 5e4, 5e4) }
|
||
+func BenchmarkMul_100kb(b *testing.B) { benchmarkMul(b, 1e5, 1e5) }
|
||
+func BenchmarkMul_200kb(b *testing.B) { benchmarkMul(b, 2e5, 2e5) }
|
||
+func BenchmarkMul_500kb(b *testing.B) { benchmarkMul(b, 5e5, 5e5) }
|
||
+func BenchmarkMul_1Mb(b *testing.B) { benchmarkMul(b, 1e6, 1e6) }
|
||
+func BenchmarkMul_2Mb(b *testing.B) { benchmarkMul(b, 2e6, 2e6) }
|
||
+func BenchmarkMul_5Mb(b *testing.B) { benchmarkMul(b, 5e6, 5e6) }
|
||
+func BenchmarkMul_10Mb(b *testing.B) { benchmarkMul(b, 10e6, 10e6) }
|
||
+func BenchmarkMul_20Mb(b *testing.B) { benchmarkMul(b, 20e6, 20e6) }
|
||
+func BenchmarkMul_50Mb(b *testing.B) { benchmarkMul(b, 50e6, 50e6) }
|
||
+func BenchmarkMul_100Mb(b *testing.B) { benchmarkMul(b, 100e6, 100e6) }
|
||
+
|
||
+// Unbalanced multiplication benchmarks
|
||
+func BenchmarkMul_1x5Mb(b *testing.B) { benchmarkMul(b, 1e6, 5e6) }
|
||
+func BenchmarkMul_1x10Mb(b *testing.B) { benchmarkMul(b, 1e6, 10e6) }
|
||
+func BenchmarkMul_1x20Mb(b *testing.B) { benchmarkMul(b, 1e6, 20e6) }
|
||
+func BenchmarkMul_1x50Mb(b *testing.B) { benchmarkMul(b, 1e6, 50e6) }
|
||
+func BenchmarkMul_5x20Mb(b *testing.B) { benchmarkMul(b, 5e6, 20e6) }
|
||
+func BenchmarkMul_5x50Mb(b *testing.B) { benchmarkMul(b, 5e6, 50e6) }
|
||
+
|
||
+func BenchmarkMulBig_1x5Mb(b *testing.B) { benchmarkMulBig(b, 1e6, 5e6) }
|
||
+func BenchmarkMulBig_1x10Mb(b *testing.B) { benchmarkMulBig(b, 1e6, 10e6) }
|
||
+func BenchmarkMulBig_1x20Mb(b *testing.B) { benchmarkMulBig(b, 1e6, 20e6) }
|
||
+func BenchmarkMulBig_1x50Mb(b *testing.B) { benchmarkMulBig(b, 1e6, 50e6) }
|
||
+func BenchmarkMulBig_5x20Mb(b *testing.B) { benchmarkMulBig(b, 5e6, 20e6) }
|
||
+func BenchmarkMulBig_5x50Mb(b *testing.B) { benchmarkMulBig(b, 5e6, 50e6) }
|
||
+
|
||
+func BenchmarkMulFFT_1x5Mb(b *testing.B) { benchmarkMulFFT(b, 1e6, 5e6) }
|
||
+func BenchmarkMulFFT_1x10Mb(b *testing.B) { benchmarkMulFFT(b, 1e6, 10e6) }
|
||
+func BenchmarkMulFFT_1x20Mb(b *testing.B) { benchmarkMulFFT(b, 1e6, 20e6) }
|
||
+func BenchmarkMulFFT_1x50Mb(b *testing.B) { benchmarkMulFFT(b, 1e6, 50e6) }
|
||
+func BenchmarkMulFFT_5x20Mb(b *testing.B) { benchmarkMulFFT(b, 5e6, 20e6) }
|
||
+func BenchmarkMulFFT_5x50Mb(b *testing.B) { benchmarkMulFFT(b, 5e6, 50e6) }
|
||
+
|
||
+func TestIssue1(t *testing.T) {
|
||
+ e := big.NewInt(1)
|
||
+ e.SetBit(e, 132048, 1)
|
||
+ e.Sub(e, big.NewInt(4)) // e == 1<<132048 - 4
|
||
+ g := big.NewInt(0).Set(e)
|
||
+ e.Mul(e, e)
|
||
+ g = Mul(g, g)
|
||
+ if g.Cmp(e) != 0 {
|
||
+ t.Fatal("incorrect Mul result")
|
||
+ }
|
||
+}
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/README vendor/github.com/remyoudompheng/bigfft/README
|
||
--- vendor/github.com/remyoudompheng/bigfft/README 2021-08-20 15:12:42.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/README 2023-07-19 10:40:33.208904639 +0800
|
||
@@ -1,3 +1,14 @@
|
||
+This library is a toy proof-of-concept implementation of the
|
||
+well-known Schonhage-Strassen method for multiplying integers.
|
||
+It is not expected to have a real life usecase outside number
|
||
+theory computations, nor is it expected to be used in any production
|
||
+system.
|
||
+
|
||
+If you are using it in your project, you may want to carefully
|
||
+examine the actual requirement or problem you are trying to solve.
|
||
+
|
||
+# Comparison with the standard library and GMP
|
||
+
|
||
Benchmarking math/big vs. bigfft
|
||
|
||
Number size old ns/op new ns/op delta
|
||
diff -ur --new-file vendor/github.com/remyoudompheng/bigfft/scan_test.go vendor/github.com/remyoudompheng/bigfft/scan_test.go
|
||
--- vendor/github.com/remyoudompheng/bigfft/scan_test.go 1970-01-01 08:00:00.000000000 +0800
|
||
+++ vendor/github.com/remyoudompheng/bigfft/scan_test.go 2023-07-19 10:40:33.208904639 +0800
|
||
@@ -0,0 +1,67 @@
|
||
+package bigfft
|
||
+
|
||
+import (
|
||
+ "math/big"
|
||
+ "testing"
|
||
+ "time"
|
||
+)
|
||
+
|
||
+func TestScan(t *testing.T) {
|
||
+ for size := 10; size <= 1e5; size += 191 {
|
||
+ s := rndStr(size)
|
||
+ x, ok := new(big.Int).SetString(s, 10)
|
||
+ if !ok {
|
||
+ t.Fatal("cannot parse", s)
|
||
+ }
|
||
+ t0 := time.Now()
|
||
+ y := FromDecimalString(s)
|
||
+ if x.Cmp(y) != 0 {
|
||
+ t.Errorf("failed at size %d", size)
|
||
+ } else {
|
||
+ t.Logf("OK for size %d in %s", size, time.Since(t0))
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
+func BenchmarkScanFast1k(b *testing.B) { benchmarkScanFast(1e3, b) }
|
||
+func BenchmarkScanFast10k(b *testing.B) { benchmarkScanFast(10e3, b) }
|
||
+func BenchmarkScanFast100k(b *testing.B) { benchmarkScanFast(100e3, b) }
|
||
+func BenchmarkScanFast1M(b *testing.B) { benchmarkScanFast(1e6, b) }
|
||
+func BenchmarkScanFast2M(b *testing.B) { benchmarkScanFast(2e6, b) }
|
||
+func BenchmarkScanFast5M(b *testing.B) { benchmarkScanFast(5e6, b) }
|
||
+func BenchmarkScanFast10M(b *testing.B) { benchmarkScanFast(10e6, b) }
|
||
+
|
||
+//func BenchmarkScanFast100M(b *testing.B) { benchmarkScanFast(100e6, b) }
|
||
+
|
||
+func benchmarkScanFast(n int, b *testing.B) {
|
||
+ s := rndStr(n)
|
||
+ var x *big.Int
|
||
+ for i := 0; i < b.N; i++ {
|
||
+ x = FromDecimalString(s)
|
||
+ }
|
||
+ _ = x
|
||
+}
|
||
+
|
||
+func BenchmarkScanBig1k(b *testing.B) { benchmarkScanBig(1e3, b) }
|
||
+func BenchmarkScanBig10k(b *testing.B) { benchmarkScanBig(10e3, b) }
|
||
+func BenchmarkScanBig100k(b *testing.B) { benchmarkScanBig(100e3, b) }
|
||
+func BenchmarkScanBig1M(b *testing.B) { benchmarkScanBig(1e6, b) }
|
||
+func BenchmarkScanBig2M(b *testing.B) { benchmarkScanBig(2e6, b) }
|
||
+func BenchmarkScanBig5M(b *testing.B) { benchmarkScanBig(5e6, b) }
|
||
+func BenchmarkScanBig10M(b *testing.B) { benchmarkScanBig(10e6, b) }
|
||
+
|
||
+func benchmarkScanBig(n int, b *testing.B) {
|
||
+ s := rndStr(n)
|
||
+ var x big.Int
|
||
+ for i := 0; i < b.N; i++ {
|
||
+ x.SetString(s, 10)
|
||
+ }
|
||
+}
|
||
+
|
||
+func rndStr(n int) string {
|
||
+ x := make([]byte, n)
|
||
+ for i := 0; i < n; i++ {
|
||
+ x[i] = '0' + byte(rnd.Intn(10))
|
||
+ }
|
||
+ return string(x)
|
||
+}
|
||
diff -ur --new-file vendor/github.com/shirou/gopsutil/host/host_linux_riscv64.go vendor/github.com/shirou/gopsutil/host/host_linux_riscv64.go
|
||
--- vendor/github.com/shirou/gopsutil/host/host_linux_riscv64.go 1970-01-01 08:00:00.000000000 +0800
|
||
+++ vendor/github.com/shirou/gopsutil/host/host_linux_riscv64.go 2023-07-18 21:42:35.443531356 +0800
|
||
@@ -0,0 +1,49 @@
|
||
+// Created by cgo -godefs - DO NOT EDIT
|
||
+// cgo -godefs types_linux.go
|
||
+
|
||
+package host
|
||
+
|
||
+const (
|
||
+ sizeofPtr = 0x8
|
||
+ sizeofShort = 0x2
|
||
+ sizeofInt = 0x4
|
||
+ sizeofLong = 0x8
|
||
+ sizeofLongLong = 0x8
|
||
+ sizeOfUtmp = 0x180
|
||
+)
|
||
+
|
||
+type (
|
||
+ _C_short int16
|
||
+ _C_int int32
|
||
+ _C_long int64
|
||
+ _C_long_long int64
|
||
+)
|
||
+
|
||
+type utmp struct {
|
||
+ Type int16
|
||
+ Pid int32
|
||
+ Line [32]int8
|
||
+ Id [4]int8
|
||
+ User [32]int8
|
||
+ Host [256]int8
|
||
+ Exit exit_status
|
||
+ Session int32
|
||
+ Tv _Ctype_struct___0
|
||
+ Addr_v6 [4]int32
|
||
+ X__glibc_reserved [20]uint8
|
||
+}
|
||
+
|
||
+type exit_status struct {
|
||
+ Termination int16
|
||
+ Exit int16
|
||
+}
|
||
+
|
||
+type timeval struct {
|
||
+ Sec int64
|
||
+ Usec int64
|
||
+}
|
||
+
|
||
+type _Ctype_struct___0 struct {
|
||
+ Sec int32
|
||
+ Usec int32
|
||
+}
|