OSDN Git Service

new repo
[bytom/vapor.git] / vendor / gonum.org / v1 / gonum / internal / asm / f64 / dot_test.go
1 // Copyright ©2015 The Gonum Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package f64
6
7 import (
8         "fmt"
9         "math"
10         "testing"
11
12         "golang.org/x/exp/rand"
13 )
14
15 func TestDotUnitary(t *testing.T) {
16         for i, test := range []struct {
17                 xData []float64
18                 yData []float64
19
20                 want float64
21         }{
22                 {
23                         xData: []float64{2},
24                         yData: []float64{-3},
25                         want:  -6,
26                 },
27                 {
28                         xData: []float64{2, 3},
29                         yData: []float64{-3, 4},
30                         want:  6,
31                 },
32                 {
33                         xData: []float64{2, 3, -4},
34                         yData: []float64{-3, 4, 5},
35                         want:  -14,
36                 },
37                 {
38                         xData: []float64{2, 3, -4, -5},
39                         yData: []float64{-3, 4, 5, -6},
40                         want:  16,
41                 },
42                 {
43                         xData: []float64{0, 2, 3, -4, -5},
44                         yData: []float64{0, -3, 4, 5, -6},
45                         want:  16,
46                 },
47                 {
48                         xData: []float64{0, 0, 2, 3, -4, -5},
49                         yData: []float64{0, 1, -3, 4, 5, -6},
50                         want:  16,
51                 },
52                 {
53                         xData: []float64{0, 0, 1, 1, 2, -3, -4},
54                         yData: []float64{0, 1, 0, 3, -4, 5, -6},
55                         want:  4,
56                 },
57                 {
58                         xData: []float64{0, 0, 1, 1, 2, -3, -4, 5},
59                         yData: []float64{0, 1, 0, 3, -4, 5, -6, 7},
60                         want:  39,
61                 },
62         } {
63                 const msgGuard = "test %v: out-of-bounds write to %v argument\nfront guard: %v\nback guard: %v"
64
65                 x, xFront, xBack := newGuardedVector(test.xData, 1)
66                 y, yFront, yBack := newGuardedVector(test.yData, 1)
67                 got := DotUnitary(x, y)
68
69                 if !allNaN(xFront) || !allNaN(xBack) {
70                         t.Errorf(msgGuard, i, "x", xFront, xBack)
71                 }
72                 if !allNaN(yFront) || !allNaN(yBack) {
73                         t.Errorf(msgGuard, i, "y", yFront, yBack)
74                 }
75                 if !equalStrided(test.xData, x, 1) {
76                         t.Errorf("test %v: modified read-only x argument", i)
77                 }
78                 if !equalStrided(test.yData, y, 1) {
79                         t.Errorf("test %v: modified read-only y argument", i)
80                 }
81                 if math.IsNaN(got) {
82                         t.Errorf("test %v: invalid memory read", i)
83                         continue
84                 }
85
86                 if got != test.want {
87                         t.Errorf("test %v: unexpected result. want %v, got %v", i, test.want, got)
88                 }
89         }
90 }
91
92 func TestDotInc(t *testing.T) {
93         for i, test := range []struct {
94                 xData []float64
95                 yData []float64
96
97                 want    float64
98                 wantRev float64 // Result when one of the vectors is reversed.
99         }{
100                 {
101                         xData:   []float64{2},
102                         yData:   []float64{-3},
103                         want:    -6,
104                         wantRev: -6,
105                 },
106                 {
107                         xData:   []float64{2, 3},
108                         yData:   []float64{-3, 4},
109                         want:    6,
110                         wantRev: -1,
111                 },
112                 {
113                         xData:   []float64{2, 3, -4},
114                         yData:   []float64{-3, 4, 5},
115                         want:    -14,
116                         wantRev: 34,
117                 },
118                 {
119                         xData:   []float64{2, 3, -4, -5},
120                         yData:   []float64{-3, 4, 5, -6},
121                         want:    16,
122                         wantRev: 2,
123                 },
124                 {
125                         xData:   []float64{0, 2, 3, -4, -5},
126                         yData:   []float64{0, -3, 4, 5, -6},
127                         want:    16,
128                         wantRev: 34,
129                 },
130                 {
131                         xData:   []float64{0, 0, 2, 3, -4, -5},
132                         yData:   []float64{0, 1, -3, 4, 5, -6},
133                         want:    16,
134                         wantRev: -5,
135                 },
136                 {
137                         xData:   []float64{0, 0, 1, 1, 2, -3, -4},
138                         yData:   []float64{0, 1, 0, 3, -4, 5, -6},
139                         want:    4,
140                         wantRev: -4,
141                 },
142                 {
143                         xData:   []float64{0, 0, 1, 1, 2, -3, -4, 5},
144                         yData:   []float64{0, 1, 0, 3, -4, 5, -6, 7},
145                         want:    39,
146                         wantRev: 3,
147                 },
148         } {
149                 const msgGuard = "%v: out-of-bounds write to %v argument\nfront guard: %v\nback guard: %v"
150
151                 for _, incX := range []int{-7, -3, -2, -1, 1, 2, 3, 7} {
152                         for _, incY := range []int{-7, -3, -2, -1, 1, 2, 3, 7} {
153                                 n := len(test.xData)
154                                 x, xFront, xBack := newGuardedVector(test.xData, incX)
155                                 y, yFront, yBack := newGuardedVector(test.yData, incY)
156
157                                 var ix, iy int
158                                 if incX < 0 {
159                                         ix = (-n + 1) * incX
160                                 }
161                                 if incY < 0 {
162                                         iy = (-n + 1) * incY
163                                 }
164                                 got := DotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
165
166                                 prefix := fmt.Sprintf("test %v, incX = %v, incY = %v", i, incX, incY)
167                                 if !allNaN(xFront) || !allNaN(xBack) {
168                                         t.Errorf(msgGuard, prefix, "x", xFront, xBack)
169                                 }
170                                 if !allNaN(yFront) || !allNaN(yBack) {
171                                         t.Errorf(msgGuard, prefix, "y", yFront, yBack)
172                                 }
173                                 if nonStridedWrite(x, incX) || !equalStrided(test.xData, x, incX) {
174                                         t.Errorf("%v: modified read-only x argument", prefix)
175                                 }
176                                 if nonStridedWrite(y, incY) || !equalStrided(test.yData, y, incY) {
177                                         t.Errorf("%v: modified read-only y argument", prefix)
178                                 }
179                                 if math.IsNaN(got) {
180                                         t.Errorf("%v: invalid memory read", prefix)
181                                         continue
182                                 }
183
184                                 want := test.want
185                                 if incX*incY < 0 {
186                                         want = test.wantRev
187                                 }
188                                 if got != want {
189                                         t.Errorf("%v: unexpected result. want %v, got %v", prefix, want, got)
190                                 }
191                         }
192                 }
193         }
194 }
195
196 func BenchmarkDotUnitaryN1(b *testing.B)      { dotUnitaryBenchmark(b, 1) }
197 func BenchmarkDotUnitaryN2(b *testing.B)      { dotUnitaryBenchmark(b, 2) }
198 func BenchmarkDotUnitaryN3(b *testing.B)      { dotUnitaryBenchmark(b, 3) }
199 func BenchmarkDotUnitaryN4(b *testing.B)      { dotUnitaryBenchmark(b, 4) }
200 func BenchmarkDotUnitaryN10(b *testing.B)     { dotUnitaryBenchmark(b, 10) }
201 func BenchmarkDotUnitaryN100(b *testing.B)    { dotUnitaryBenchmark(b, 100) }
202 func BenchmarkDotUnitaryN1000(b *testing.B)   { dotUnitaryBenchmark(b, 1000) }
203 func BenchmarkDotUnitaryN10000(b *testing.B)  { dotUnitaryBenchmark(b, 10000) }
204 func BenchmarkDotUnitaryN100000(b *testing.B) { dotUnitaryBenchmark(b, 100000) }
205
206 var r float64
207
208 func dotUnitaryBenchmark(b *testing.B, n int) {
209         x := make([]float64, n)
210         for i := range x {
211                 x[i] = rand.Float64()
212         }
213         y := make([]float64, n)
214         for i := range y {
215                 y[i] = rand.Float64()
216         }
217         b.ResetTimer()
218         for i := 0; i < b.N; i++ {
219                 r = DotUnitary(x, y)
220         }
221 }
222
223 func BenchmarkDotIncN1Inc1(b *testing.B) { dotIncBenchmark(b, 1, 1) }
224
225 func BenchmarkDotIncN2Inc1(b *testing.B)  { dotIncBenchmark(b, 2, 1) }
226 func BenchmarkDotIncN2Inc2(b *testing.B)  { dotIncBenchmark(b, 2, 2) }
227 func BenchmarkDotIncN2Inc4(b *testing.B)  { dotIncBenchmark(b, 2, 4) }
228 func BenchmarkDotIncN2Inc10(b *testing.B) { dotIncBenchmark(b, 2, 10) }
229
230 func BenchmarkDotIncN3Inc1(b *testing.B)  { dotIncBenchmark(b, 3, 1) }
231 func BenchmarkDotIncN3Inc2(b *testing.B)  { dotIncBenchmark(b, 3, 2) }
232 func BenchmarkDotIncN3Inc4(b *testing.B)  { dotIncBenchmark(b, 3, 4) }
233 func BenchmarkDotIncN3Inc10(b *testing.B) { dotIncBenchmark(b, 3, 10) }
234
235 func BenchmarkDotIncN4Inc1(b *testing.B)  { dotIncBenchmark(b, 4, 1) }
236 func BenchmarkDotIncN4Inc2(b *testing.B)  { dotIncBenchmark(b, 4, 2) }
237 func BenchmarkDotIncN4Inc4(b *testing.B)  { dotIncBenchmark(b, 4, 4) }
238 func BenchmarkDotIncN4Inc10(b *testing.B) { dotIncBenchmark(b, 4, 10) }
239
240 func BenchmarkDotIncN10Inc1(b *testing.B)  { dotIncBenchmark(b, 10, 1) }
241 func BenchmarkDotIncN10Inc2(b *testing.B)  { dotIncBenchmark(b, 10, 2) }
242 func BenchmarkDotIncN10Inc4(b *testing.B)  { dotIncBenchmark(b, 10, 4) }
243 func BenchmarkDotIncN10Inc10(b *testing.B) { dotIncBenchmark(b, 10, 10) }
244
245 func BenchmarkDotIncN1000Inc1(b *testing.B)  { dotIncBenchmark(b, 1000, 1) }
246 func BenchmarkDotIncN1000Inc2(b *testing.B)  { dotIncBenchmark(b, 1000, 2) }
247 func BenchmarkDotIncN1000Inc4(b *testing.B)  { dotIncBenchmark(b, 1000, 4) }
248 func BenchmarkDotIncN1000Inc10(b *testing.B) { dotIncBenchmark(b, 1000, 10) }
249
250 func BenchmarkDotIncN100000Inc1(b *testing.B)  { dotIncBenchmark(b, 100000, 1) }
251 func BenchmarkDotIncN100000Inc2(b *testing.B)  { dotIncBenchmark(b, 100000, 2) }
252 func BenchmarkDotIncN100000Inc4(b *testing.B)  { dotIncBenchmark(b, 100000, 4) }
253 func BenchmarkDotIncN100000Inc10(b *testing.B) { dotIncBenchmark(b, 100000, 10) }
254
255 func BenchmarkDotIncN100000IncM1(b *testing.B)  { dotIncBenchmark(b, 100000, -1) }
256 func BenchmarkDotIncN100000IncM2(b *testing.B)  { dotIncBenchmark(b, 100000, -2) }
257 func BenchmarkDotIncN100000IncM4(b *testing.B)  { dotIncBenchmark(b, 100000, -4) }
258 func BenchmarkDotIncN100000IncM10(b *testing.B) { dotIncBenchmark(b, 100000, -10) }
259
260 func dotIncBenchmark(b *testing.B, n, inc int) {
261         absInc := inc
262         if inc < 0 {
263                 absInc = -inc
264         }
265         x := make([]float64, (n-1)*absInc+1)
266         for i := range x {
267                 x[i] = rand.Float64()
268         }
269         y := make([]float64, (n-1)*absInc+1)
270         for i := range y {
271                 y[i] = rand.Float64()
272         }
273         var ini int
274         if inc < 0 {
275                 ini = (-n + 1) * inc
276         }
277         b.ResetTimer()
278         for i := 0; i < b.N; i++ {
279                 r = DotInc(x, y, uintptr(n), uintptr(inc), uintptr(inc), uintptr(ini), uintptr(ini))
280         }
281 }