1
2
3
4
5
6
7
8
9
10 package simd_test
11
12 import (
13 "simd/archsimd"
14 "testing"
15 )
16
17 const sveMaskUint16s = sveMaxBytes / 8
18
19
20
21
22 func testSVECompare[T number, V, M any](t *testing.T, pool []T, elemBytes, active int,
23 load func([]T) V, cmp func(V, V) M, store func(M, []uint16), want func(T, T) bool) {
24 t.Helper()
25 count := sveMaxBytes / elemBytes
26 forSlicePair(t, pool, count, func(x, y []T) bool {
27 t.Helper()
28 bits := make([]uint16, sveMaskUint16s)
29 store(cmp(load(x), load(y)), bits)
30 for i := 0; i < active; i++ {
31 b := i * elemBytes
32 got := bits[b/16]>>uint(b%16)&1 == 1
33 if got != want(x[i], y[i]) {
34 t.Errorf("lane %d: got %v, want %v (x=%v y=%v)", i, got, want(x[i], y[i]), x[i], y[i])
35 return false
36 }
37 }
38 return true
39 })
40 }
41
42 func testInt8sCompare(t *testing.T, cmp func(_, _ archsimd.Int8s) archsimd.Mask8s, want func(_, _ int8) bool) {
43 var z archsimd.Int8s
44 testSVECompare(t, int8s, 1, z.Len(), archsimd.LoadInt8s, cmp, archsimd.Mask8s.Store, want)
45 }
46
47 func testInt16sCompare(t *testing.T, cmp func(_, _ archsimd.Int16s) archsimd.Mask16s, want func(_, _ int16) bool) {
48 var z archsimd.Int16s
49 testSVECompare(t, int16s, 2, z.Len(), archsimd.LoadInt16s, cmp, archsimd.Mask16s.Store, want)
50 }
51
52 func testInt32sCompare(t *testing.T, cmp func(_, _ archsimd.Int32s) archsimd.Mask32s, want func(_, _ int32) bool) {
53 var z archsimd.Int32s
54 testSVECompare(t, int32s, 4, z.Len(), archsimd.LoadInt32s, cmp, archsimd.Mask32s.Store, want)
55 }
56
57 func testInt64sCompare(t *testing.T, cmp func(_, _ archsimd.Int64s) archsimd.Mask64s, want func(_, _ int64) bool) {
58 var z archsimd.Int64s
59 testSVECompare(t, int64s, 8, z.Len(), archsimd.LoadInt64s, cmp, archsimd.Mask64s.Store, want)
60 }
61
62 func testUint8sCompare(t *testing.T, cmp func(_, _ archsimd.Uint8s) archsimd.Mask8s, want func(_, _ uint8) bool) {
63 var z archsimd.Uint8s
64 testSVECompare(t, uint8s, 1, z.Len(), archsimd.LoadUint8s, cmp, archsimd.Mask8s.Store, want)
65 }
66
67 func testFloat32sCompare(t *testing.T, cmp func(_, _ archsimd.Float32s) archsimd.Mask32s, want func(_, _ float32) bool) {
68 var z archsimd.Float32s
69 testSVECompare(t, float32s, 4, z.Len(), archsimd.LoadFloat32s, cmp, archsimd.Mask32s.Store, want)
70 }
71
72 func testFloat64sCompare(t *testing.T, cmp func(_, _ archsimd.Float64s) archsimd.Mask64s, want func(_, _ float64) bool) {
73 var z archsimd.Float64s
74 testSVECompare(t, float64s, 8, z.Len(), archsimd.LoadFloat64s, cmp, archsimd.Mask64s.Store, want)
75 }
76
77 func testUint16sCompare(t *testing.T, cmp func(_, _ archsimd.Uint16s) archsimd.Mask16s, want func(_, _ uint16) bool) {
78 var z archsimd.Uint16s
79 testSVECompare(t, uint16s, 2, z.Len(), archsimd.LoadUint16s, cmp, archsimd.Mask16s.Store, want)
80 }
81
82 func testUint32sCompare(t *testing.T, cmp func(_, _ archsimd.Uint32s) archsimd.Mask32s, want func(_, _ uint32) bool) {
83 var z archsimd.Uint32s
84 testSVECompare(t, uint32s, 4, z.Len(), archsimd.LoadUint32s, cmp, archsimd.Mask32s.Store, want)
85 }
86
87 func testUint64sCompare(t *testing.T, cmp func(_, _ archsimd.Uint64s) archsimd.Mask64s, want func(_, _ uint64) bool) {
88 var z archsimd.Uint64s
89 testSVECompare(t, uint64s, 8, z.Len(), archsimd.LoadUint64s, cmp, archsimd.Mask64s.Store, want)
90 }
91
92 func gtWant[T number](a, b T) bool { return a > b }
93 func geWant[T number](a, b T) bool { return a >= b }
94 func eqWant[T number](a, b T) bool { return a == b }
95 func neWant[T number](a, b T) bool { return a != b }
96
97 func TestGreaterSVE(t *testing.T) {
98 if !archsimd.ARM64.SVE() {
99 t.Skip("no SVE")
100 }
101 testInt8sCompare(t, archsimd.Int8s.Greater, gtWant[int8])
102 testInt16sCompare(t, archsimd.Int16s.Greater, gtWant[int16])
103 testInt32sCompare(t, archsimd.Int32s.Greater, gtWant[int32])
104 testInt64sCompare(t, archsimd.Int64s.Greater, gtWant[int64])
105 testUint8sCompare(t, archsimd.Uint8s.Greater, gtWant[uint8])
106 testUint16sCompare(t, archsimd.Uint16s.Greater, gtWant[uint16])
107 testUint32sCompare(t, archsimd.Uint32s.Greater, gtWant[uint32])
108 testUint64sCompare(t, archsimd.Uint64s.Greater, gtWant[uint64])
109 testFloat32sCompare(t, archsimd.Float32s.Greater, gtWant[float32])
110 testFloat64sCompare(t, archsimd.Float64s.Greater, gtWant[float64])
111 }
112
113
114
115 func TestMaskStoreLoadPanicSVE(t *testing.T) {
116 if !archsimd.ARM64.SVE() {
117 t.Skip("no sve")
118 }
119 var z archsimd.Int8s
120 m := z.Greater(z)
121 mustPanic(t, "Store short", func() { m.Store(nil) })
122 mustPanic(t, "LoadMask8s short", func() { archsimd.LoadMask8s(nil) })
123
124 bits := make([]uint16, sveMaskUint16s)
125 m.Store(bits)
126 archsimd.LoadMask8s(bits)
127 }
128
129 func TestEqualSVE(t *testing.T) {
130 if !archsimd.ARM64.SVE() {
131 t.Skip("no SVE")
132 }
133 testInt8sCompare(t, archsimd.Int8s.Equal, eqWant[int8])
134 testInt16sCompare(t, archsimd.Int16s.Equal, eqWant[int16])
135 testInt32sCompare(t, archsimd.Int32s.Equal, eqWant[int32])
136 testInt64sCompare(t, archsimd.Int64s.Equal, eqWant[int64])
137 testUint8sCompare(t, archsimd.Uint8s.Equal, eqWant[uint8])
138 testUint16sCompare(t, archsimd.Uint16s.Equal, eqWant[uint16])
139 testUint32sCompare(t, archsimd.Uint32s.Equal, eqWant[uint32])
140 testUint64sCompare(t, archsimd.Uint64s.Equal, eqWant[uint64])
141 testFloat32sCompare(t, archsimd.Float32s.Equal, eqWant[float32])
142 testFloat64sCompare(t, archsimd.Float64s.Equal, eqWant[float64])
143 }
144
145 func TestNotEqualSVE(t *testing.T) {
146 if !archsimd.ARM64.SVE() {
147 t.Skip("no SVE")
148 }
149 testInt8sCompare(t, archsimd.Int8s.NotEqual, neWant[int8])
150 testInt16sCompare(t, archsimd.Int16s.NotEqual, neWant[int16])
151 testInt32sCompare(t, archsimd.Int32s.NotEqual, neWant[int32])
152 testInt64sCompare(t, archsimd.Int64s.NotEqual, neWant[int64])
153 testUint8sCompare(t, archsimd.Uint8s.NotEqual, neWant[uint8])
154 testUint16sCompare(t, archsimd.Uint16s.NotEqual, neWant[uint16])
155 testUint32sCompare(t, archsimd.Uint32s.NotEqual, neWant[uint32])
156 testUint64sCompare(t, archsimd.Uint64s.NotEqual, neWant[uint64])
157 testFloat32sCompare(t, archsimd.Float32s.NotEqual, neWant[float32])
158 testFloat64sCompare(t, archsimd.Float64s.NotEqual, neWant[float64])
159 }
160
161 func TestGreaterEqualSVE(t *testing.T) {
162 if !archsimd.ARM64.SVE() {
163 t.Skip("no SVE")
164 }
165 testInt8sCompare(t, archsimd.Int8s.GreaterEqual, geWant[int8])
166 testInt16sCompare(t, archsimd.Int16s.GreaterEqual, geWant[int16])
167 testInt32sCompare(t, archsimd.Int32s.GreaterEqual, geWant[int32])
168 testInt64sCompare(t, archsimd.Int64s.GreaterEqual, geWant[int64])
169 testUint8sCompare(t, archsimd.Uint8s.GreaterEqual, geWant[uint8])
170 testUint16sCompare(t, archsimd.Uint16s.GreaterEqual, geWant[uint16])
171 testUint32sCompare(t, archsimd.Uint32s.GreaterEqual, geWant[uint32])
172 testUint64sCompare(t, archsimd.Uint64s.GreaterEqual, geWant[uint64])
173 testFloat32sCompare(t, archsimd.Float32s.GreaterEqual, geWant[float32])
174 testFloat64sCompare(t, archsimd.Float64s.GreaterEqual, geWant[float64])
175 }
176
View as plain text