1
2
3
4
5
6
7 package simd_test
8
9 import (
10 "simd/archsimd"
11 "testing"
12 )
13
14 func TestFloatMinMax32AMD64(t *testing.T) {
15 for _, tc := range []struct {
16 name string
17 lanes int
18 run func([]float32, []float32, [4][]float32, bool, bool)
19 }{
20 {"Float32x8", 8, floatMinMax32x8},
21 {"Float32x16", 16, floatMinMax32x16},
22 } {
23 t.Run(tc.name, func(t *testing.T) {
24 if tc.lanes == 16 && !archsimd.X86.AVX512() {
25 t.Skip("requires AVX512")
26 }
27 testFloatMinMax32(t, tc.lanes, tc.run)
28 })
29 }
30 }
31
32 func TestFloatMinMax64AMD64(t *testing.T) {
33 for _, tc := range []struct {
34 name string
35 lanes int
36 run func([]float64, []float64, [4][]float64, bool, bool)
37 }{
38 {"Float64x4", 4, floatMinMax64x4},
39 {"Float64x8", 8, floatMinMax64x8},
40 } {
41 t.Run(tc.name, func(t *testing.T) {
42 if tc.lanes == 8 && !archsimd.X86.AVX512() {
43 t.Skip("requires AVX512")
44 }
45 testFloatMinMax64(t, tc.lanes, tc.run)
46 })
47 }
48 }
49
50 func floatMinMaxPlatformConfig() floatMinMaxConfig {
51 return floatMinMaxConfig{allowMasked: archsimd.X86.AVX512()}
52 }
53
54 func floatMinMaxMask32x4() archsimd.Mask32x4 {
55 return archsimd.Mask32x4FromBits(0x5)
56 }
57
58 func floatMinMaxMask64x2() archsimd.Mask64x2 {
59 return archsimd.Mask64x2FromBits(0x1)
60 }
61
62
63 func floatMinMax32x8(a, b []float32, out [4][]float32, reverse, masked bool) {
64 x, y := archsimd.LoadFloat32x8(a), archsimd.LoadFloat32x8(b)
65 var minXY, minYX, maxXY, maxYX archsimd.Float32x8
66 if masked {
67 mask := archsimd.Mask32x8FromBits(0x55)
68 if reverse {
69 minYX, minXY = y.Min(x).Masked(mask), x.Min(y).Masked(mask)
70 maxYX, maxXY = y.Max(x).Masked(mask), x.Max(y).Masked(mask)
71 } else {
72 minXY, minYX = x.Min(y).Masked(mask), y.Min(x).Masked(mask)
73 maxXY, maxYX = x.Max(y).Masked(mask), y.Max(x).Masked(mask)
74 }
75 } else if reverse {
76 minYX, minXY = y.Min(x), x.Min(y)
77 maxYX, maxXY = y.Max(x), x.Max(y)
78 } else {
79 minXY, minYX = x.Min(y), y.Min(x)
80 maxXY, maxYX = x.Max(y), y.Max(x)
81 }
82 minXY.Store(out[0])
83 minYX.Store(out[1])
84 maxXY.Store(out[2])
85 maxYX.Store(out[3])
86 }
87
88
89 func floatMinMax32x16(a, b []float32, out [4][]float32, reverse, masked bool) {
90 x, y := archsimd.LoadFloat32x16(a), archsimd.LoadFloat32x16(b)
91 var minXY, minYX, maxXY, maxYX archsimd.Float32x16
92 if masked {
93 mask := archsimd.Mask32x16FromBits(0x5555)
94 if reverse {
95 minYX, minXY = y.Min(x).Masked(mask), x.Min(y).Masked(mask)
96 maxYX, maxXY = y.Max(x).Masked(mask), x.Max(y).Masked(mask)
97 } else {
98 minXY, minYX = x.Min(y).Masked(mask), y.Min(x).Masked(mask)
99 maxXY, maxYX = x.Max(y).Masked(mask), y.Max(x).Masked(mask)
100 }
101 } else if reverse {
102 minYX, minXY = y.Min(x), x.Min(y)
103 maxYX, maxXY = y.Max(x), x.Max(y)
104 } else {
105 minXY, minYX = x.Min(y), y.Min(x)
106 maxXY, maxYX = x.Max(y), y.Max(x)
107 }
108 minXY.Store(out[0])
109 minYX.Store(out[1])
110 maxXY.Store(out[2])
111 maxYX.Store(out[3])
112 }
113
114
115 func floatMinMax64x4(a, b []float64, out [4][]float64, reverse, masked bool) {
116 x, y := archsimd.LoadFloat64x4(a), archsimd.LoadFloat64x4(b)
117 var minXY, minYX, maxXY, maxYX archsimd.Float64x4
118 if masked {
119 mask := archsimd.Mask64x4FromBits(0x5)
120 if reverse {
121 minYX, minXY = y.Min(x).Masked(mask), x.Min(y).Masked(mask)
122 maxYX, maxXY = y.Max(x).Masked(mask), x.Max(y).Masked(mask)
123 } else {
124 minXY, minYX = x.Min(y).Masked(mask), y.Min(x).Masked(mask)
125 maxXY, maxYX = x.Max(y).Masked(mask), y.Max(x).Masked(mask)
126 }
127 } else if reverse {
128 minYX, minXY = y.Min(x), x.Min(y)
129 maxYX, maxXY = y.Max(x), x.Max(y)
130 } else {
131 minXY, minYX = x.Min(y), y.Min(x)
132 maxXY, maxYX = x.Max(y), y.Max(x)
133 }
134 minXY.Store(out[0])
135 minYX.Store(out[1])
136 maxXY.Store(out[2])
137 maxYX.Store(out[3])
138 }
139
140
141 func floatMinMax64x8(a, b []float64, out [4][]float64, reverse, masked bool) {
142 x, y := archsimd.LoadFloat64x8(a), archsimd.LoadFloat64x8(b)
143 var minXY, minYX, maxXY, maxYX archsimd.Float64x8
144 if masked {
145 mask := archsimd.Mask64x8FromBits(0x55)
146 if reverse {
147 minYX, minXY = y.Min(x).Masked(mask), x.Min(y).Masked(mask)
148 maxYX, maxXY = y.Max(x).Masked(mask), x.Max(y).Masked(mask)
149 } else {
150 minXY, minYX = x.Min(y).Masked(mask), y.Min(x).Masked(mask)
151 maxXY, maxYX = x.Max(y).Masked(mask), y.Max(x).Masked(mask)
152 }
153 } else if reverse {
154 minYX, minXY = y.Min(x), x.Min(y)
155 maxYX, maxXY = y.Max(x), x.Max(y)
156 } else {
157 minXY, minYX = x.Min(y), y.Min(x)
158 maxXY, maxYX = x.Max(y), y.Max(x)
159 }
160 minXY.Store(out[0])
161 minYX.Store(out[1])
162 maxXY.Store(out[2])
163 maxYX.Store(out[3])
164 }
165
View as plain text