1
2
3
4
5
6
7 package simd_test
8
9 import (
10 "reflect"
11 "simd/archsimd"
12 "testing"
13 )
14
15 var sink any
16
17 func TestType(t *testing.T) {
18
19
20
21
22
23
24
25 type alias = archsimd.Int32x4
26 type vecT archsimd.Int32x4
27 type myStruct struct {
28 x alias
29 y *archsimd.Int32x4
30 z vecT
31 }
32 vals := [4]int32{1, 2, 3, 4}
33 v := myStruct{x: archsimd.LoadInt32x4Array(&vals)}
34 want := []int32{12, 24, 36, 48}
35 y := archsimd.LoadInt32x4Array(&vals)
36 v.y = &y
37 sink = y
38
39 v.z = vecT(archsimd.LoadInt32x4Array(&[4]int32{10, 20, 30, 40}))
40 *v.y = v.y.Add(v.x).Add(archsimd.Int32x4(v.z))
41
42 got := [4]int32{}
43 v.y.StoreArray(&got)
44 checkSlices(t, got[:], want)
45 }
46
47 func TestUncomparable(t *testing.T) {
48
49 var x, y any = archsimd.LoadUint32x4Array(&[4]uint32{1, 2, 3, 4}), archsimd.LoadUint32x4Array(&[4]uint32{5, 6, 7, 8})
50 shouldPanic := func(fn func()) {
51 defer func() {
52 if recover() == nil {
53 panic("did not panic")
54 }
55 }()
56 fn()
57 }
58 shouldPanic(func() { _ = x == y })
59 }
60
61 func TestFuncValue(t *testing.T) {
62
63 xv := [4]int32{1, 2, 3, 4}
64 yv := [4]int32{5, 6, 7, 8}
65 want := []int32{6, 8, 10, 12}
66 x := archsimd.LoadInt32x4Array(&xv)
67 y := archsimd.LoadInt32x4Array(&yv)
68 fn := archsimd.Int32x4.Add
69 sink = fn
70 x = fn(x, y)
71 got := [4]int32{}
72 x.StoreArray(&got)
73 checkSlices(t, got[:], want)
74 }
75
76 func TestReflectMethod(t *testing.T) {
77
78
79 xv := [4]int32{1, 2, 3, 4}
80 yv := [4]int32{5, 6, 7, 8}
81 want := []int32{6, 8, 10, 12}
82 x := archsimd.LoadInt32x4Array(&xv)
83 y := archsimd.LoadInt32x4Array(&yv)
84 m, ok := reflect.TypeOf(x).MethodByName("Add")
85 if !ok {
86 t.Fatal("Add method not found")
87 }
88 fn := m.Func.Interface().(func(x, y archsimd.Int32x4) archsimd.Int32x4)
89 x = fn(x, y)
90 got := [4]int32{}
91 x.StoreArray(&got)
92 checkSlices(t, got[:], want)
93 }
94
95 func TestVectorConversion(t *testing.T) {
96 xv := [4]int32{1, 2, 3, 4}
97 x := archsimd.LoadInt32x4Array(&xv)
98 xPromoted := x.ToBits().ReshapeToUint64s().BitsToInt64()
99 xPromotedDemoted := xPromoted.ToBits().ReshapeToUint32s().BitsToInt32()
100 got := [4]int32{}
101 xPromotedDemoted.StoreArray(&got)
102 for i := range 4 {
103 if xv[i] != got[i] {
104 t.Errorf("Result at %d incorrect: want %d, got %d", i, xv[i], got[i])
105 }
106 }
107 }
108
109 func TestMaskConversion(t *testing.T) {
110 x := archsimd.LoadInt32x4([]int32{5, 0, 7, 0})
111 mask := archsimd.Int32x4{}.Sub(x).ToMask()
112 y := archsimd.LoadInt32x4([]int32{1, 2, 3, 4}).Add(x).Masked(mask)
113 want := [4]int32{6, 0, 10, 0}
114 got := make([]int32, 4)
115 y.Store(got)
116 checkSlices(t, got[:], want[:])
117 }
118
119 func TestBroadcastUint32x4(t *testing.T) {
120 s := make([]uint32, 4, 4)
121 archsimd.BroadcastUint32x4(123456789).Store(s)
122 checkSlices(t, s, []uint32{123456789, 123456789, 123456789, 123456789})
123 }
124
125 func TestBroadcastFloat32x4(t *testing.T) {
126 s := make([]float32, 4, 4)
127 archsimd.BroadcastFloat32x4(3.14).Store(s)
128 checkSlices(t, s, []float32{3.14, 3.14, 3.14, 3.14})
129 }
130
131 func TestBroadcastFloat64x2(t *testing.T) {
132 s := make([]float64, 2, 2)
133 archsimd.BroadcastFloat64x2(3.14).Store(s)
134 checkSlices(t, s, []float64{3.14, 3.14})
135 }
136
137 func TestBroadcastUint64x2(t *testing.T) {
138 s := make([]uint64, 2, 2)
139 archsimd.BroadcastUint64x2(123456789012345).Store(s)
140 checkSlices(t, s, []uint64{123456789012345, 123456789012345})
141 }
142
143 func TestBroadcastUint16x8(t *testing.T) {
144 s := make([]uint16, 8, 8)
145 archsimd.BroadcastUint16x8(12345).Store(s)
146 checkSlices(t, s, []uint16{12345, 12345, 12345, 12345, 12345, 12345, 12345, 12345})
147 }
148
149 func TestBroadcastInt8x16(t *testing.T) {
150 s := make([]int8, 16, 16)
151 archsimd.BroadcastInt8x16(-123).Store(s)
152 checkSlices(t, s, []int8{-123, -123, -123, -123, -123, -123, -123, -123,
153 -123, -123, -123, -123, -123, -123, -123, -123})
154 }
155
156 func TestBroadcastUint8x16(t *testing.T) {
157 s := make([]uint8, 16, 16)
158 archsimd.BroadcastUint8x16(200).Store(s)
159 checkSlices(t, s, []uint8{200, 200, 200, 200, 200, 200, 200, 200,
160 200, 200, 200, 200, 200, 200, 200, 200})
161 }
162
163 func TestBroadcastInt16x8(t *testing.T) {
164 s := make([]int16, 8, 8)
165 archsimd.BroadcastInt16x8(-12345).Store(s)
166 checkSlices(t, s, []int16{-12345, -12345, -12345, -12345, -12345, -12345, -12345, -12345})
167 }
168
169 func TestBroadcastInt32x4(t *testing.T) {
170 s := make([]int32, 4, 4)
171 archsimd.BroadcastInt32x4(-123456789).Store(s)
172 checkSlices(t, s, []int32{-123456789, -123456789, -123456789, -123456789})
173 }
174
175 func TestBroadcastInt64x2(t *testing.T) {
176 s := make([]int64, 2, 2)
177 archsimd.BroadcastInt64x2(-123456789).Store(s)
178 checkSlices(t, s, []int64{-123456789, -123456789})
179 }
180
181 func TestString(t *testing.T) {
182 x := archsimd.LoadUint32x4([]uint32{0, 1, 2, 3})
183 y := archsimd.LoadInt64x2([]int64{-44, -5})
184 z := archsimd.LoadFloat32x4([]float32{0.5, 1.5, -2.5, 3.5e9})
185 w := archsimd.LoadFloat64x2([]float64{-2.5, 3.5e9})
186
187 sx := "{0,1,2,3}"
188 sy := "{-44,-5}"
189 sz := "{0.5,1.5,-2.5,3.5e+09}"
190 sw := "{-2.5,3.5e+09}"
191
192 if x.String() != sx {
193 t.Errorf("x=%s wanted %s", x, sx)
194 }
195 if y.String() != sy {
196 t.Errorf("y=%s wanted %s", y, sy)
197 }
198 if z.String() != sz {
199 t.Errorf("z=%s wanted %s", z, sz)
200 }
201 if w.String() != sw {
202 t.Errorf("w=%s wanted %s", w, sw)
203 }
204 t.Logf("w=%s", w)
205 t.Logf("x=%s", x)
206 t.Logf("y=%s", y)
207 t.Logf("z=%s", z)
208 }
209
210 func stringy[T interface{ String() string }](v T) string {
211 return v.String()
212 }
213
214 func double[T interface{ Add(T) T }](v T) T {
215 return v.Add(v)
216 }
217
218
219 func TestTypeParam(t *testing.T) {
220 x := archsimd.LoadInt64x2([]int64{1, 1})
221 y := archsimd.LoadInt64x2([]int64{1, 1})
222 if got := stringy(x); got != y.String() {
223 t.Fatalf("string(x) = %q, want %q", got, y.String())
224 }
225 var want, got [2]int64
226 y.Add(y).StoreArray(&want)
227 double(x).StoreArray(&got)
228 if got != want {
229 t.Fatalf("double(x) = %v, want %v", got, want)
230 }
231 }
232
233 func TestManyFloats(t *testing.T) {
234
235
236
237
238 testManyFloats(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
239 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32)
240 }
241
242 var float64Sink float64
243
244
245 func testManyFloats(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16,
246 a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32 float64) {
247 float64Sink += a1
248 float64Sink *= a2
249 float64Sink -= a3
250 float64Sink /= a4
251 float64Sink += a5
252 float64Sink *= a6
253 float64Sink -= a7
254 float64Sink /= a8
255 float64Sink += a9
256 float64Sink *= a10
257 float64Sink -= a11
258 float64Sink /= a12
259 float64Sink += a13
260 float64Sink *= a14
261 float64Sink -= a15
262 float64Sink /= a16
263 float64Sink += a17
264 float64Sink *= a18
265 float64Sink -= a19
266 float64Sink /= a20
267 float64Sink += a21
268 float64Sink *= a22
269 float64Sink -= a23
270 float64Sink /= a24
271 float64Sink += a25
272 float64Sink *= a26
273 float64Sink -= a27
274 float64Sink /= a28
275 float64Sink += a29
276 float64Sink *= a30
277 float64Sink -= a31
278 float64Sink /= a32
279 }
280
281 func TestSlicesInt8SetElem(t *testing.T) {
282 a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
283 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
284 v := archsimd.LoadInt8x16(a)
285
286 v = v.SetElem(3, 13)
287 a[3] = 13
288
289 b := make([]int8, 16, 16)
290 v.Store(b)
291 checkSlices(t, a, b)
292 }
293
294 func TestSlicesInt8GetElem(t *testing.T) {
295 a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
296 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
297 v := archsimd.LoadInt8x16(a)
298 e := v.GetElem(2)
299 if e != a[2] {
300 t.Errorf("GetElem(2) = %d != a[2] = %d", e, a[2])
301 }
302
303 }
304
305 var seventeen = uint8(17)
306
307 func TestSlicesInt8GetElem16(t *testing.T) {
308 defer func() {
309 if r := recover(); r != nil {
310 t.Logf("Saw EXPECTED panic %v", r)
311 } else {
312 t.Errorf("Did not see expected panic")
313 }
314 }()
315 a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
316 v := archsimd.LoadInt8x16(a)
317 e := v.GetElem(seventeen - 1)
318 t.Errorf("Should have panicked, e=%v", e)
319 }
320
321 func TestSlicesInt8GetElem16const(t *testing.T) {
322 defer func() {
323 if r := recover(); r != nil {
324 t.Logf("Saw EXPECTED panic %v", r)
325 } else {
326 t.Errorf("Did not see expected panic")
327 }
328 }()
329 a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
330 v := archsimd.LoadInt8x16(a)
331 e := v.GetElem(16)
332 t.Errorf("Should have panicked, e=%v", e)
333 }
334
335 func TestSlicesInt8GetElem15(t *testing.T) {
336 a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
337 v := archsimd.LoadInt8x16(a)
338 e := v.GetElem(seventeen - 2)
339 if e != a[15] {
340 t.Errorf("GetElem(15) = %d != a[15] = %d", e, a[15])
341 }
342 }
343
344 func TestSlicesInt8GetElem15const(t *testing.T) {
345 a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
346 v := archsimd.LoadInt8x16(a)
347 e := v.GetElem(15)
348 if e != a[15] {
349 t.Errorf("GetElem(15) = %d != a[15] = %d", e, a[15])
350 }
351 }
352
353 func TestSlicesInt8SetElem17(t *testing.T) {
354 defer func() {
355 if r := recover(); r != nil {
356 t.Logf("Saw EXPECTED panic %v", r)
357 } else {
358 t.Errorf("Did not see expected panic")
359 }
360 }()
361 a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
362 v := archsimd.LoadInt8x16(a)
363 e := v.SetElem(seventeen, 18).GetElem(2)
364 t.Errorf("Should have panicked, e=%v", e)
365 }
366
367 func TestSlicesInt8SetElem17const(t *testing.T) {
368 defer func() {
369 if r := recover(); r != nil {
370 t.Logf("Saw EXPECTED panic %v", r)
371 } else {
372 t.Errorf("Did not see expected panic")
373 }
374 }()
375 a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
376 v := archsimd.LoadInt8x16(a)
377 e := v.SetElem(17, 18).GetElem(2)
378 t.Errorf("Should have panicked, e=%v", e)
379 }
380
View as plain text