1
2
3
4
5
6
7 package simd_test
8
9 import (
10 "math"
11 "simd/archsimd/internal/test_helpers"
12 "testing"
13 )
14
15 type signed interface {
16 ~int | ~int8 | ~int16 | ~int32 | ~int64
17 }
18
19 type integer interface {
20 ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
21 }
22
23 type float interface {
24 ~float32 | ~float64
25 }
26
27 type number interface {
28 ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64
29 }
30
31 func checkSlices[T number](t *testing.T, got, want []T) bool {
32 t.Helper()
33 return test_helpers.CheckSlicesLogInput[T](t, got, want, 0.0, nil)
34 }
35
36 func checkSlicesLogInput[T number](t *testing.T, got, want []T, flakiness float64, logInput func()) bool {
37 t.Helper()
38 return test_helpers.CheckSlicesLogInput[T](t, got, want, flakiness, logInput)
39 }
40
41
42
43
44 func sliceOf[T number](n int) []T {
45 s := make([]T, n)
46 for i := 0; i < n; i++ {
47 s[i] = T(i + 1)
48 }
49 return s
50 }
51
52 func toVect[T signed](b []bool) []T {
53 s := make([]T, len(b))
54 for i := range b {
55 if b[i] {
56 s[i] = -1
57 }
58 }
59 return s
60 }
61
62
63 func s64[T number](s []T) []int64 {
64 var is any = s
65 if r, ok := is.([]int64); ok {
66 return r
67 }
68 r := make([]int64, len(s))
69 for i := range s {
70 r[i] = int64(s[i])
71 }
72 return r
73 }
74
75
76
77
78
79 func Do[T number](t *testing.T, n int, body func(a, c []T)) {
80 a := sliceOf[T](n)
81 b := sliceOf[T](n)
82
83 for i := n; i >= 0; i-- {
84 c := make([]T, n, n)
85 body(a[:i], c)
86 checkSlices(t, c, b)
87 if i > 0 {
88 b[i-1] = T(0)
89 }
90 }
91 }
92
93
94
95 func map3[T, U any](elem func(x, y, z T) U) func(x, y, z []T) []U {
96 return func(x, y, z []T) []U {
97 s := make([]U, len(x))
98 for i := range s {
99 s[i] = elem(x[i], y[i], z[i])
100 }
101 return s
102 }
103 }
104
105
106
107 func map2[T, U any](elem func(x, y T) U) func(x, y []T) []U {
108 return func(x, y []T) []U {
109 s := make([]U, len(x))
110 for i := range s {
111 s[i] = elem(x[i], y[i])
112 }
113 return s
114 }
115 }
116
117
118
119 func map1[T, U any](elem func(x T) U) func(x []T) []U {
120 return func(x []T) []U {
121 s := make([]U, len(x))
122 for i := range s {
123 s[i] = elem(x[i])
124 }
125 return s
126 }
127 }
128
129
130
131
132 func map1n[T, U any](elem func(x T) U, n int) func(x []T) []U {
133 return func(x []T) []U {
134 s := make([]U, n)
135 for i := range min(len(x), n) {
136 s[i] = elem(x[i])
137 }
138 return s
139 }
140 }
141
142
143
144
145 func mapCompare[T number](elem func(x, y T) bool) func(x, y []T) []int64 {
146 return func(x, y []T) []int64 {
147 s := make([]int64, len(x))
148 for i := range s {
149 if elem(x[i], y[i]) {
150 s[i] = -1
151 }
152 }
153 return s
154 }
155 }
156
157
158
159 func nOf[T any](n int, s []T) []T {
160 if len(s) >= n {
161 return s
162 }
163 r := make([]T, n)
164 for i := range r {
165 r[i] = s[i%len(s)]
166 }
167 return r
168 }
169
170 const (
171 PN22 = 1.0 / 1024 / 1024 / 4
172 PN24 = 1.0 / 1024 / 1024 / 16
173 PN53 = PN24 * PN24 / 32
174 F0 = float32(1.0 + 513*PN22/2)
175 F1 = float32(1.0 + 511*PN22*8)
176 Aeasy = float32(2046 * PN53)
177 Ahard = float32(2047 * PN53)
178 )
179
180 var zero = 0.0
181 var nzero = -zero
182 var inf = 1 / zero
183 var ninf = -1 / zero
184 var nan = math.NaN()
185 var snan32 = math.Float32frombits(0x7f800001)
186 var snan64 = math.Float64frombits(0x7ff0000000000001)
187
188
189 const N = 144
190
191 var float32s = nOf(N, []float32{float32(inf), float32(ninf), 1, float32(nan), snan32, -float32(nan), -snan32, float32(zero), 2, float32(nan), float32(zero), 3, float32(-zero), float32(1.0 / zero), float32(-1.0 / zero), 1.0 / 2, 1.0 / 4, 1.0 / 8, 1.0 / 1000, 1.0 / 1000000, 1, -1, 0, 2, -2, 3, -3, math.MaxFloat32, 1 / math.MaxFloat32, 10, -10, 100, 20, -20, 300, -300, -4000, -80, -160, -3200, -64, -4, -8, -16, -32, -64})
192 var float64s = nOf(N, []float64{inf, ninf, nan, snan64, -nan, -snan64, zero, -zero, 1 / zero, -1 / zero, 0.0001, 0.0000001, 1, -1, 0, 2, -2, 3, -3, math.MaxFloat64, 1.0 / math.MaxFloat64, 10, -10, 100, 20, -20, 300, -300, -4000, -80, -16, -32, -64})
193
194 var int32s = nOf(N, []int32{1, -1, 0, 2, 4, 8, 1024, 0xffffff, -0xffffff, 0x55555, 0x77777, 0xccccc, -0x55555, -0x77777, -0xccccc, -4, -8, -16, -32, -64})
195 var uint32s = nOf(N, []uint32{1, 0, 2, 4, 8, 1024, 0xffffff, ^uint32(0xffffff), 0x55555, 0x77777, 0xccccc, ^uint32(0x55555), ^uint32(0x77777), ^uint32(0xccccc)})
196
197 var int64s = nOf(N, []int64{1, -1, 0, 2, 4, 8, 1024, 0xffffff, -0xffffff, 0x55555, 0x77777, 0xccccc, -0x55555, -0x77777, -0xccccc, -4, -8, -16, -32, -64})
198 var uint64s = nOf(N, []uint64{1, 0, 2, 4, 8, 1024, 0xffffff, ^uint64(0xffffff), 0x55555, 0x77777, 0xccccc, ^uint64(0x55555), ^uint64(0x77777), ^uint64(0xccccc)})
199
200 var int16s = nOf(N, []int16{1, -1, 0, 2, 4, 8, 1024, 3, 5, 7, 11, 13, 3000, 5555, 7777, 11111, 32767, 32766, -32767, -32768, -11111, -4, -8, -16, -32, -64})
201 var uint16s = nOf(N, []uint16{1, 0, 2, 4, 8, 1024, 3, 5, 7, 11, 13, 3000, 5555, 7777, 11111, 32767, 32766, 32768, 65535, 45678, 56789})
202
203 var int8s = nOf(N, []int8{0, 1, 2, 3, 5, 7, 11, 22, 33, 55, 77, 121, 127, -1, -2, -3, -5, -7, -11, -77, -121, -127, -128, 4, 8, 16, 32, 64, -4, -8, -16, -32, -64})
204 var uint8s = nOf(N, []uint8{0, 1, 2, 3, 5, 7, 11, 22, 33, 55, 77, 121, 127, 128, 255, 233, 211, 177, 144, 4, 8, 16, 32, 64})
205
206 var bools = nOf(N, []bool{
207 true, false, true, true, false, false, true, true, true, false, false, false, true, true, true, true, false, false, false, false})
208
209 func forSlice[T number](t *testing.T, s []T, n int, f func(a []T) bool) {
210 t.Helper()
211 for i := 0; i < len(s)-n; i++ {
212 if !f(s[i : i+n]) {
213 return
214 }
215 }
216 }
217
218 func forSlicePair[T number](t *testing.T, s []T, n int, f func(a, b []T) bool) {
219 t.Helper()
220 for i := 0; i < len(s)-n; i++ {
221 for j := 0; j < len(s)-n; j++ {
222 if !f(s[i:i+n], s[j:j+n]) {
223 return
224 }
225 }
226 }
227 }
228
229 func forSliceTriple[T number](t *testing.T, s []T, n int, f func(a, b, c []T) bool) {
230 t.Helper()
231 for i := 0; i < len(s)-n; i += 3 {
232 for j := 0; j < len(s)-n; j += 3 {
233 for k := 0; k < len(s)-n; k += 3 {
234 if !f(s[i:i+n], s[j:j+n], s[k:k+n]) {
235 return
236 }
237 }
238 }
239 }
240 }
241
242 func forSlicePairMasked[T number](t *testing.T, s []T, n int, f func(a, b []T, m []bool) bool) {
243 t.Helper()
244 m := bools
245
246 for i := 0; i < len(s)-n; i += 3 {
247 for j := 0; j < len(s)-n; j += 3 {
248 for k := 0; k < len(m)-n; k += 3 {
249 if !f(s[i:i+n], s[j:j+n], m[k:k+n]) {
250 return
251 }
252 }
253 }
254 }
255 }
256
View as plain text