1
2
3
4
5
6
7
8
9
10
11
12
13
14 package simd_test
15
16 import (
17 "simd/archsimd"
18 "testing"
19 )
20
21
22
23 const sveMaxBytes = 32
24
25
26
27 func testSVEBinary[T number, V any](t *testing.T, pool []T, elemBytes, active int,
28 load func([]T) V, f func(V, V) V, store func(V, []T), want func([]T, []T) []T) {
29 t.Helper()
30 count := sveMaxBytes / elemBytes
31 forSlicePair(t, pool, count, func(x, y []T) bool {
32 t.Helper()
33 g := make([]T, count)
34 store(f(load(x), load(y)), g)
35 w := want(x, y)
36 return checkSlicesLogInput(t, g[:active], w[:active], 0.0, func() {
37 t.Helper()
38 t.Logf("x=%v", x)
39 t.Logf("y=%v", y)
40 })
41 })
42 }
43
44 func testInt8sBinary(t *testing.T, f func(_, _ archsimd.Int8s) archsimd.Int8s, want func(_, _ []int8) []int8) {
45 var z archsimd.Int8s
46 testSVEBinary(t, int8s, 1, z.Len(), archsimd.LoadInt8s, f, archsimd.Int8s.Store, want)
47 }
48
49 func testInt16sBinary(t *testing.T, f func(_, _ archsimd.Int16s) archsimd.Int16s, want func(_, _ []int16) []int16) {
50 var z archsimd.Int16s
51 testSVEBinary(t, int16s, 2, z.Len(), archsimd.LoadInt16s, f, archsimd.Int16s.Store, want)
52 }
53
54 func testInt32sBinary(t *testing.T, f func(_, _ archsimd.Int32s) archsimd.Int32s, want func(_, _ []int32) []int32) {
55 var z archsimd.Int32s
56 testSVEBinary(t, int32s, 4, z.Len(), archsimd.LoadInt32s, f, archsimd.Int32s.Store, want)
57 }
58
59 func testInt64sBinary(t *testing.T, f func(_, _ archsimd.Int64s) archsimd.Int64s, want func(_, _ []int64) []int64) {
60 var z archsimd.Int64s
61 testSVEBinary(t, int64s, 8, z.Len(), archsimd.LoadInt64s, f, archsimd.Int64s.Store, want)
62 }
63
64 func testUint8sBinary(t *testing.T, f func(_, _ archsimd.Uint8s) archsimd.Uint8s, want func(_, _ []uint8) []uint8) {
65 var z archsimd.Uint8s
66 testSVEBinary(t, uint8s, 1, z.Len(), archsimd.LoadUint8s, f, archsimd.Uint8s.Store, want)
67 }
68
69 func testFloat32sBinary(t *testing.T, f func(_, _ archsimd.Float32s) archsimd.Float32s, want func(_, _ []float32) []float32) {
70 var z archsimd.Float32s
71 testSVEBinary(t, float32s, 4, z.Len(), archsimd.LoadFloat32s, f, archsimd.Float32s.Store, want)
72 }
73
74 func testFloat64sBinary(t *testing.T, f func(_, _ archsimd.Float64s) archsimd.Float64s, want func(_, _ []float64) []float64) {
75 var z archsimd.Float64s
76 testSVEBinary(t, float64s, 8, z.Len(), archsimd.LoadFloat64s, f, archsimd.Float64s.Store, want)
77 }
78
79 func testUint16sBinary(t *testing.T, f func(_, _ archsimd.Uint16s) archsimd.Uint16s, want func(_, _ []uint16) []uint16) {
80 var z archsimd.Uint16s
81 testSVEBinary(t, uint16s, 2, z.Len(), archsimd.LoadUint16s, f, archsimd.Uint16s.Store, want)
82 }
83
84 func testUint32sBinary(t *testing.T, f func(_, _ archsimd.Uint32s) archsimd.Uint32s, want func(_, _ []uint32) []uint32) {
85 var z archsimd.Uint32s
86 testSVEBinary(t, uint32s, 4, z.Len(), archsimd.LoadUint32s, f, archsimd.Uint32s.Store, want)
87 }
88
89 func testUint64sBinary(t *testing.T, f func(_, _ archsimd.Uint64s) archsimd.Uint64s, want func(_, _ []uint64) []uint64) {
90 var z archsimd.Uint64s
91 testSVEBinary(t, uint64s, 8, z.Len(), archsimd.LoadUint64s, f, archsimd.Uint64s.Store, want)
92 }
93
94 func testInt8sUnary(t *testing.T, f func(archsimd.Int8s) archsimd.Int8s, want func([]int8) []int8) {
95 var z archsimd.Int8s
96 testSVEUnary(t, int8s, 1, z.Len(), archsimd.LoadInt8s, f, archsimd.Int8s.Store, want)
97 }
98
99 func testInt16sUnary(t *testing.T, f func(archsimd.Int16s) archsimd.Int16s, want func([]int16) []int16) {
100 var z archsimd.Int16s
101 testSVEUnary(t, int16s, 2, z.Len(), archsimd.LoadInt16s, f, archsimd.Int16s.Store, want)
102 }
103
104 func testInt32sUnary(t *testing.T, f func(archsimd.Int32s) archsimd.Int32s, want func([]int32) []int32) {
105 var z archsimd.Int32s
106 testSVEUnary(t, int32s, 4, z.Len(), archsimd.LoadInt32s, f, archsimd.Int32s.Store, want)
107 }
108
109 func testInt64sUnary(t *testing.T, f func(archsimd.Int64s) archsimd.Int64s, want func([]int64) []int64) {
110 var z archsimd.Int64s
111 testSVEUnary(t, int64s, 8, z.Len(), archsimd.LoadInt64s, f, archsimd.Int64s.Store, want)
112 }
113
114 func testUint8sUnary(t *testing.T, f func(archsimd.Uint8s) archsimd.Uint8s, want func([]uint8) []uint8) {
115 var z archsimd.Uint8s
116 testSVEUnary(t, uint8s, 1, z.Len(), archsimd.LoadUint8s, f, archsimd.Uint8s.Store, want)
117 }
118
119 func testUint16sUnary(t *testing.T, f func(archsimd.Uint16s) archsimd.Uint16s, want func([]uint16) []uint16) {
120 var z archsimd.Uint16s
121 testSVEUnary(t, uint16s, 2, z.Len(), archsimd.LoadUint16s, f, archsimd.Uint16s.Store, want)
122 }
123
124 func testUint32sUnary(t *testing.T, f func(archsimd.Uint32s) archsimd.Uint32s, want func([]uint32) []uint32) {
125 var z archsimd.Uint32s
126 testSVEUnary(t, uint32s, 4, z.Len(), archsimd.LoadUint32s, f, archsimd.Uint32s.Store, want)
127 }
128
129 func testUint64sUnary(t *testing.T, f func(archsimd.Uint64s) archsimd.Uint64s, want func([]uint64) []uint64) {
130 var z archsimd.Uint64s
131 testSVEUnary(t, uint64s, 8, z.Len(), archsimd.LoadUint64s, f, archsimd.Uint64s.Store, want)
132 }
133
134 func testFloat32sUnary(t *testing.T, f func(archsimd.Float32s) archsimd.Float32s, want func([]float32) []float32) {
135 var z archsimd.Float32s
136 testSVEUnary(t, float32s, 4, z.Len(), archsimd.LoadFloat32s, f, archsimd.Float32s.Store, want)
137 }
138
139 func testFloat64sUnary(t *testing.T, f func(archsimd.Float64s) archsimd.Float64s, want func([]float64) []float64) {
140 var z archsimd.Float64s
141 testSVEUnary(t, float64s, 8, z.Len(), archsimd.LoadFloat64s, f, archsimd.Float64s.Store, want)
142 }
143
144 func TestAddSVE(t *testing.T) {
145 if !archsimd.ARM64.SVE() {
146 t.Skip("no SVE")
147 }
148 testInt8sBinary(t, archsimd.Int8s.Add, addSlice[int8])
149 testInt16sBinary(t, archsimd.Int16s.Add, addSlice[int16])
150 testInt32sBinary(t, archsimd.Int32s.Add, addSlice[int32])
151 testInt64sBinary(t, archsimd.Int64s.Add, addSlice[int64])
152 testUint8sBinary(t, archsimd.Uint8s.Add, addSlice[uint8])
153 testUint16sBinary(t, archsimd.Uint16s.Add, addSlice[uint16])
154 testUint32sBinary(t, archsimd.Uint32s.Add, addSlice[uint32])
155 testUint64sBinary(t, archsimd.Uint64s.Add, addSlice[uint64])
156 testFloat32sBinary(t, archsimd.Float32s.Add, addSlice[float32])
157 testFloat64sBinary(t, archsimd.Float64s.Add, addSlice[float64])
158 }
159
160 func TestSubSVE(t *testing.T) {
161 if !archsimd.ARM64.SVE() {
162 t.Skip("no SVE")
163 }
164 testInt8sBinary(t, archsimd.Int8s.Sub, subSlice[int8])
165 testInt16sBinary(t, archsimd.Int16s.Sub, subSlice[int16])
166 testInt32sBinary(t, archsimd.Int32s.Sub, subSlice[int32])
167 testInt64sBinary(t, archsimd.Int64s.Sub, subSlice[int64])
168 testUint8sBinary(t, archsimd.Uint8s.Sub, subSlice[uint8])
169 testUint16sBinary(t, archsimd.Uint16s.Sub, subSlice[uint16])
170 testUint32sBinary(t, archsimd.Uint32s.Sub, subSlice[uint32])
171 testUint64sBinary(t, archsimd.Uint64s.Sub, subSlice[uint64])
172 testFloat32sBinary(t, archsimd.Float32s.Sub, subSlice[float32])
173 testFloat64sBinary(t, archsimd.Float64s.Sub, subSlice[float64])
174 }
175
176
177
178 func testSVEUnary[T number, V any](t *testing.T, pool []T, elemBytes, active int,
179 load func([]T) V, f func(V) V, store func(V, []T), want func([]T) []T) {
180 t.Helper()
181 count := sveMaxBytes / elemBytes
182 forSlice(t, pool, count, func(x []T) bool {
183 t.Helper()
184 g := make([]T, count)
185 store(f(load(x)), g)
186 w := want(x)
187 return checkSlicesLogInput(t, g[:active], w[:active], 0.0, func() {
188 t.Helper()
189 t.Logf("x=%v", x)
190 })
191 })
192 }
193
194 func TestAbsSVE(t *testing.T) {
195 if !archsimd.ARM64.SVE() {
196 t.Skip("no SVE")
197 }
198 testInt8sUnary(t, archsimd.Int8s.Abs, absSlice[int8])
199 testInt16sUnary(t, archsimd.Int16s.Abs, absSlice[int16])
200 testInt32sUnary(t, archsimd.Int32s.Abs, absSlice[int32])
201 testInt64sUnary(t, archsimd.Int64s.Abs, absSlice[int64])
202 testFloat32sUnary(t, archsimd.Float32s.Abs, absSlice[float32])
203 testFloat64sUnary(t, archsimd.Float64s.Abs, absSlice[float64])
204 }
205
206 func TestNegSVE(t *testing.T) {
207 if !archsimd.ARM64.SVE() {
208 t.Skip("no SVE")
209 }
210 testInt8sUnary(t, archsimd.Int8s.Neg, negSlice[int8])
211 testInt16sUnary(t, archsimd.Int16s.Neg, negSlice[int16])
212 testInt32sUnary(t, archsimd.Int32s.Neg, negSlice[int32])
213 testInt64sUnary(t, archsimd.Int64s.Neg, negSlice[int64])
214 testFloat32sUnary(t, archsimd.Float32s.Neg, negSlice[float32])
215 testFloat64sUnary(t, archsimd.Float64s.Neg, negSlice[float64])
216 }
217
218 func TestSqrtSVE(t *testing.T) {
219 if !archsimd.ARM64.SVE() {
220 t.Skip("no SVE")
221 }
222 testFloat32sUnary(t, archsimd.Float32s.Sqrt, sqrtSlice[float32])
223 testFloat64sUnary(t, archsimd.Float64s.Sqrt, sqrtSlice[float64])
224 }
225
226 func TestCeilSVE(t *testing.T) {
227 if !archsimd.ARM64.SVE() {
228 t.Skip("no SVE")
229 }
230 testFloat32sUnary(t, archsimd.Float32s.Ceil, ceilSlice[float32])
231 testFloat64sUnary(t, archsimd.Float64s.Ceil, ceilSlice[float64])
232 }
233
234 func TestFloorSVE(t *testing.T) {
235 if !archsimd.ARM64.SVE() {
236 t.Skip("no SVE")
237 }
238 testFloat32sUnary(t, archsimd.Float32s.Floor, floorSlice[float32])
239 testFloat64sUnary(t, archsimd.Float64s.Floor, floorSlice[float64])
240 }
241
242 func TestTruncSVE(t *testing.T) {
243 if !archsimd.ARM64.SVE() {
244 t.Skip("no SVE")
245 }
246 testFloat32sUnary(t, archsimd.Float32s.Trunc, truncSlice[float32])
247 testFloat64sUnary(t, archsimd.Float64s.Trunc, truncSlice[float64])
248 }
249
250 func TestRoundSVE(t *testing.T) {
251 if !archsimd.ARM64.SVE() {
252 t.Skip("no SVE")
253 }
254 testFloat32sUnary(t, archsimd.Float32s.Round, roundSlice[float32])
255 testFloat64sUnary(t, archsimd.Float64s.Round, roundSlice[float64])
256 }
257
258 func TestAndSVE(t *testing.T) {
259 if !archsimd.ARM64.SVE() {
260 t.Skip("no SVE")
261 }
262 testInt8sBinary(t, archsimd.Int8s.And, andSlice[int8])
263 testInt16sBinary(t, archsimd.Int16s.And, andSlice[int16])
264 testInt32sBinary(t, archsimd.Int32s.And, andSlice[int32])
265 testInt64sBinary(t, archsimd.Int64s.And, andSlice[int64])
266 testUint8sBinary(t, archsimd.Uint8s.And, andSlice[uint8])
267 testUint16sBinary(t, archsimd.Uint16s.And, andSlice[uint16])
268 testUint32sBinary(t, archsimd.Uint32s.And, andSlice[uint32])
269 testUint64sBinary(t, archsimd.Uint64s.And, andSlice[uint64])
270 }
271
272 func TestOrSVE(t *testing.T) {
273 if !archsimd.ARM64.SVE() {
274 t.Skip("no SVE")
275 }
276 testInt8sBinary(t, archsimd.Int8s.Or, orSlice[int8])
277 testInt16sBinary(t, archsimd.Int16s.Or, orSlice[int16])
278 testInt32sBinary(t, archsimd.Int32s.Or, orSlice[int32])
279 testInt64sBinary(t, archsimd.Int64s.Or, orSlice[int64])
280 testUint8sBinary(t, archsimd.Uint8s.Or, orSlice[uint8])
281 testUint16sBinary(t, archsimd.Uint16s.Or, orSlice[uint16])
282 testUint32sBinary(t, archsimd.Uint32s.Or, orSlice[uint32])
283 testUint64sBinary(t, archsimd.Uint64s.Or, orSlice[uint64])
284 }
285
286 func TestXorSVE(t *testing.T) {
287 if !archsimd.ARM64.SVE() {
288 t.Skip("no SVE")
289 }
290 testInt8sBinary(t, archsimd.Int8s.Xor, xorSlice[int8])
291 testInt16sBinary(t, archsimd.Int16s.Xor, xorSlice[int16])
292 testInt32sBinary(t, archsimd.Int32s.Xor, xorSlice[int32])
293 testInt64sBinary(t, archsimd.Int64s.Xor, xorSlice[int64])
294 testUint8sBinary(t, archsimd.Uint8s.Xor, xorSlice[uint8])
295 testUint16sBinary(t, archsimd.Uint16s.Xor, xorSlice[uint16])
296 testUint32sBinary(t, archsimd.Uint32s.Xor, xorSlice[uint32])
297 testUint64sBinary(t, archsimd.Uint64s.Xor, xorSlice[uint64])
298 }
299
300 func TestAndNotSVE(t *testing.T) {
301 if !archsimd.ARM64.SVE() {
302 t.Skip("no SVE")
303 }
304 testInt8sBinary(t, archsimd.Int8s.AndNot, andNotSlice[int8])
305 testInt16sBinary(t, archsimd.Int16s.AndNot, andNotSlice[int16])
306 testInt32sBinary(t, archsimd.Int32s.AndNot, andNotSlice[int32])
307 testInt64sBinary(t, archsimd.Int64s.AndNot, andNotSlice[int64])
308 testUint8sBinary(t, archsimd.Uint8s.AndNot, andNotSlice[uint8])
309 testUint16sBinary(t, archsimd.Uint16s.AndNot, andNotSlice[uint16])
310 testUint32sBinary(t, archsimd.Uint32s.AndNot, andNotSlice[uint32])
311 testUint64sBinary(t, archsimd.Uint64s.AndNot, andNotSlice[uint64])
312 }
313
314 func TestMulSVE(t *testing.T) {
315 if !archsimd.ARM64.SVE() {
316 t.Skip("no SVE")
317 }
318 testFloat32sBinary(t, archsimd.Float32s.Mul, mulSlice[float32])
319 testFloat64sBinary(t, archsimd.Float64s.Mul, mulSlice[float64])
320
321
322 testInt8sBinary(t, archsimd.Int8s.Mul, mulSlice[int8])
323 testInt16sBinary(t, archsimd.Int16s.Mul, mulSlice[int16])
324 testInt32sBinary(t, archsimd.Int32s.Mul, mulSlice[int32])
325 testInt64sBinary(t, archsimd.Int64s.Mul, mulSlice[int64])
326 testUint8sBinary(t, archsimd.Uint8s.Mul, mulSlice[uint8])
327 testUint16sBinary(t, archsimd.Uint16s.Mul, mulSlice[uint16])
328 testUint32sBinary(t, archsimd.Uint32s.Mul, mulSlice[uint32])
329 testUint64sBinary(t, archsimd.Uint64s.Mul, mulSlice[uint64])
330 if archsimd.ARM64.SVE2() {
331
332 testInt8sBinary(t, archsimd.Int8s.Mul, mulSlice[int8])
333 testInt16sBinary(t, archsimd.Int16s.Mul, mulSlice[int16])
334 testInt32sBinary(t, archsimd.Int32s.Mul, mulSlice[int32])
335 testInt64sBinary(t, archsimd.Int64s.Mul, mulSlice[int64])
336 testUint8sBinary(t, archsimd.Uint8s.Mul, mulSlice[uint8])
337 testUint16sBinary(t, archsimd.Uint16s.Mul, mulSlice[uint16])
338 testUint32sBinary(t, archsimd.Uint32s.Mul, mulSlice[uint32])
339 testUint64sBinary(t, archsimd.Uint64s.Mul, mulSlice[uint64])
340 }
341 }
342
343 func TestMulHighSVE(t *testing.T) {
344 if !archsimd.ARM64.SVE() {
345 t.Skip("no SVE")
346 }
347
348 testInt8sBinary(t, archsimd.Int8s.MulHigh, mulHighSlice[int8])
349 testInt16sBinary(t, archsimd.Int16s.MulHigh, mulHighSlice[int16])
350 testInt32sBinary(t, archsimd.Int32s.MulHigh, mulHighSlice[int32])
351 testInt64sBinary(t, archsimd.Int64s.MulHigh, mulHighSlice[int64])
352 testUint8sBinary(t, archsimd.Uint8s.MulHigh, mulHighSlice[uint8])
353 testUint16sBinary(t, archsimd.Uint16s.MulHigh, mulHighSlice[uint16])
354 testUint32sBinary(t, archsimd.Uint32s.MulHigh, mulHighSlice[uint32])
355 testUint64sBinary(t, archsimd.Uint64s.MulHigh, mulHighSlice[uint64])
356 if archsimd.ARM64.SVE2() {
357
358 testInt8sBinary(t, archsimd.Int8s.MulHigh, mulHighSlice[int8])
359 testInt16sBinary(t, archsimd.Int16s.MulHigh, mulHighSlice[int16])
360 testInt32sBinary(t, archsimd.Int32s.MulHigh, mulHighSlice[int32])
361 testInt64sBinary(t, archsimd.Int64s.MulHigh, mulHighSlice[int64])
362 testUint8sBinary(t, archsimd.Uint8s.MulHigh, mulHighSlice[uint8])
363 testUint16sBinary(t, archsimd.Uint16s.MulHigh, mulHighSlice[uint16])
364 testUint32sBinary(t, archsimd.Uint32s.MulHigh, mulHighSlice[uint32])
365 testUint64sBinary(t, archsimd.Uint64s.MulHigh, mulHighSlice[uint64])
366 }
367 }
368
View as plain text