tidb/add-riscv-support-for-vendor.patch
zhangxiang 35001aa01d add riscv support
add riscv support

add riscv support
2023-07-19 14:07:07 +08:00

1273 lines
42 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 mathbig·addVV(SB)
-
-// func subVV(z, x, y []Word) (c Word)
-TEXT ·subVV(SB),NOSPLIT,$0
- JMP mathbig·subVV(SB)
-
-// func addVW(z, x []Word, y Word) (c Word)
-TEXT ·addVW(SB),NOSPLIT,$0
- JMP mathbig·addVW(SB)
-
-// func subVW(z, x []Word, y Word) (c Word)
-TEXT ·subVW(SB),NOSPLIT,$0
- JMP mathbig·subVW(SB)
-
-// func shlVU(z, x []Word, s uint) (c Word)
-TEXT ·shlVU(SB),NOSPLIT,$0
- JMP mathbig·shlVU(SB)
-
-// func shrVU(z, x []Word, s uint) (c Word)
-TEXT ·shrVU(SB),NOSPLIT,$0
- JMP mathbig·shrVU(SB)
-
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
- JMP mathbig·mulAddVWW(SB)
-
-// func addMulVVW(z, x []Word, y Word) (c Word)
-TEXT ·addMulVVW(SB),NOSPLIT,$0
- JMP mathbig·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 mathbig·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 mathbig·subVV(SB)
-
-// func addVW(z, x []Word, y Word) (c Word)
-TEXT ·addVW(SB),NOSPLIT,$0
- JMP mathbig·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 mathbig·subVW(SB)
-
-// func shlVU(z, x []Word, s uint) (c Word)
-TEXT ·shlVU(SB),NOSPLIT,$0
- JMP mathbig·shlVU(SB)
-
-// func shrVU(z, x []Word, s uint) (c Word)
-TEXT ·shrVU(SB),NOSPLIT,$0
- JMP mathbig·shrVU(SB)
-
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
- JMP mathbig·mulAddVWW(SB)
-
-// func addMulVVW(z, x []Word, y Word) (c Word)
-TEXT ·addMulVVW(SB),NOSPLIT,$0
- JMP mathbig·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 mathbig·addVV(SB)
-
-// func subVV(z, x, y []Word) (c Word)
-TEXT ·subVV(SB),NOSPLIT,$0
- B mathbig·subVV(SB)
-
-// func addVW(z, x []Word, y Word) (c Word)
-TEXT ·addVW(SB),NOSPLIT,$0
- B mathbig·addVW(SB)
-
-// func subVW(z, x []Word, y Word) (c Word)
-TEXT ·subVW(SB),NOSPLIT,$0
- B mathbig·subVW(SB)
-
-// func shlVU(z, x []Word, s uint) (c Word)
-TEXT ·shlVU(SB),NOSPLIT,$0
- B mathbig·shlVU(SB)
-
-// func shrVU(z, x []Word, s uint) (c Word)
-TEXT ·shrVU(SB),NOSPLIT,$0
- B mathbig·shrVU(SB)
-
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
- B mathbig·mulAddVWW(SB)
-
-// func addMulVVW(z, x []Word, y Word) (c Word)
-TEXT ·addMulVVW(SB),NOSPLIT,$0
- B mathbig·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 mathbig·addVV(SB)
-
-// func subVV(z, x, y []Word) (c Word)
-TEXT ·subVV(SB),NOSPLIT,$0
- B mathbig·subVV(SB)
-
-// func addVW(z, x []Word, y Word) (c Word)
-TEXT ·addVW(SB),NOSPLIT,$0
- B mathbig·addVW(SB)
-
-// func subVW(z, x []Word, y Word) (c Word)
-TEXT ·subVW(SB),NOSPLIT,$0
- B mathbig·subVW(SB)
-
-// func shlVU(z, x []Word, s uint) (c Word)
-TEXT ·shlVU(SB),NOSPLIT,$0
- B mathbig·shlVU(SB)
-
-// func shrVU(z, x []Word, s uint) (c Word)
-TEXT ·shrVU(SB),NOSPLIT,$0
- B mathbig·shrVU(SB)
-
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
- B mathbig·mulAddVWW(SB)
-
-// func addMulVVW(z, x []Word, y Word) (c Word)
-TEXT ·addMulVVW(SB),NOSPLIT,$0
- B mathbig·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 mathbig·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 mathbig·subVV(SB)
-
-// func addVW(z, x []Word, y Word) (c Word)
-TEXT ·addVW(SB),NOSPLIT,$0
- JMP mathbig·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 mathbig·subVW(SB)
-
-// func shlVU(z, x []Word, s uint) (c Word)
-TEXT ·shlVU(SB),NOSPLIT,$0
- JMP mathbig·shlVU(SB)
-
-// func shrVU(z, x []Word, s uint) (c Word)
-TEXT ·shrVU(SB),NOSPLIT,$0
- JMP mathbig·shrVU(SB)
-
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
- JMP mathbig·mulAddVWW(SB)
-
-// func addMulVVW(z, x []Word, y Word) (c Word)
-TEXT ·addMulVVW(SB),NOSPLIT,$0
- JMP mathbig·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 mathbig·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 mathbig·subVV(SB)
-
-// func addVW(z, x []Word, y Word) (c Word)
-TEXT ·addVW(SB),NOSPLIT,$0
- JMP mathbig·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 mathbig·subVW(SB)
-
-// func shlVU(z, x []Word, s uint) (c Word)
-TEXT ·shlVU(SB),NOSPLIT,$0
- JMP mathbig·shlVU(SB)
-
-// func shrVU(z, x []Word, s uint) (c Word)
-TEXT ·shrVU(SB),NOSPLIT,$0
- JMP mathbig·shrVU(SB)
-
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
- JMP mathbig·mulAddVWW(SB)
-
-// func addMulVVW(z, x []Word, y Word) (c Word)
-TEXT ·addMulVVW(SB),NOSPLIT,$0
- JMP mathbig·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 mathbig·addVV(SB)
-
-// func subVV(z, x, y []Word) (c Word)
-TEXT ·subVV(SB),NOSPLIT,$0
- BR mathbig·subVV(SB)
-
-// func addVW(z, x []Word, y Word) (c Word)
-TEXT ·addVW(SB),NOSPLIT,$0
- BR mathbig·addVW(SB)
-
-// func subVW(z, x []Word, y Word) (c Word)
-TEXT ·subVW(SB),NOSPLIT,$0
- BR mathbig·subVW(SB)
-
-// func shlVU(z, x []Word, s uint) (c Word)
-TEXT ·shlVU(SB),NOSPLIT,$0
- BR mathbig·shlVU(SB)
-
-// func shrVU(z, x []Word, s uint) (c Word)
-TEXT ·shrVU(SB),NOSPLIT,$0
- BR mathbig·shrVU(SB)
-
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
- BR mathbig·mulAddVWW(SB)
-
-// func addMulVVW(z, x []Word, y Word) (c Word)
-TEXT ·addMulVVW(SB),NOSPLIT,$0
- BR mathbig·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
+}