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.
12 "golang.org/x/exp/rand"
15 func TestDotUnitary(t *testing.T) {
16 for i, test := range []struct {
28 xData: []float64{2, 3},
29 yData: []float64{-3, 4},
33 xData: []float64{2, 3, -4},
34 yData: []float64{-3, 4, 5},
38 xData: []float64{2, 3, -4, -5},
39 yData: []float64{-3, 4, 5, -6},
43 xData: []float64{0, 2, 3, -4, -5},
44 yData: []float64{0, -3, 4, 5, -6},
48 xData: []float64{0, 0, 2, 3, -4, -5},
49 yData: []float64{0, 1, -3, 4, 5, -6},
53 xData: []float64{0, 0, 1, 1, 2, -3, -4},
54 yData: []float64{0, 1, 0, 3, -4, 5, -6},
58 xData: []float64{0, 0, 1, 1, 2, -3, -4, 5},
59 yData: []float64{0, 1, 0, 3, -4, 5, -6, 7},
63 const msgGuard = "test %v: out-of-bounds write to %v argument\nfront guard: %v\nback guard: %v"
65 x, xFront, xBack := newGuardedVector(test.xData, 1)
66 y, yFront, yBack := newGuardedVector(test.yData, 1)
67 got := DotUnitary(x, y)
69 if !allNaN(xFront) || !allNaN(xBack) {
70 t.Errorf(msgGuard, i, "x", xFront, xBack)
72 if !allNaN(yFront) || !allNaN(yBack) {
73 t.Errorf(msgGuard, i, "y", yFront, yBack)
75 if !equalStrided(test.xData, x, 1) {
76 t.Errorf("test %v: modified read-only x argument", i)
78 if !equalStrided(test.yData, y, 1) {
79 t.Errorf("test %v: modified read-only y argument", i)
82 t.Errorf("test %v: invalid memory read", i)
87 t.Errorf("test %v: unexpected result. want %v, got %v", i, test.want, got)
92 func TestDotInc(t *testing.T) {
93 for i, test := range []struct {
98 wantRev float64 // Result when one of the vectors is reversed.
102 yData: []float64{-3},
107 xData: []float64{2, 3},
108 yData: []float64{-3, 4},
113 xData: []float64{2, 3, -4},
114 yData: []float64{-3, 4, 5},
119 xData: []float64{2, 3, -4, -5},
120 yData: []float64{-3, 4, 5, -6},
125 xData: []float64{0, 2, 3, -4, -5},
126 yData: []float64{0, -3, 4, 5, -6},
131 xData: []float64{0, 0, 2, 3, -4, -5},
132 yData: []float64{0, 1, -3, 4, 5, -6},
137 xData: []float64{0, 0, 1, 1, 2, -3, -4},
138 yData: []float64{0, 1, 0, 3, -4, 5, -6},
143 xData: []float64{0, 0, 1, 1, 2, -3, -4, 5},
144 yData: []float64{0, 1, 0, 3, -4, 5, -6, 7},
149 const msgGuard = "%v: out-of-bounds write to %v argument\nfront guard: %v\nback guard: %v"
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} {
154 x, xFront, xBack := newGuardedVector(test.xData, incX)
155 y, yFront, yBack := newGuardedVector(test.yData, incY)
164 got := DotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
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)
170 if !allNaN(yFront) || !allNaN(yBack) {
171 t.Errorf(msgGuard, prefix, "y", yFront, yBack)
173 if nonStridedWrite(x, incX) || !equalStrided(test.xData, x, incX) {
174 t.Errorf("%v: modified read-only x argument", prefix)
176 if nonStridedWrite(y, incY) || !equalStrided(test.yData, y, incY) {
177 t.Errorf("%v: modified read-only y argument", prefix)
180 t.Errorf("%v: invalid memory read", prefix)
189 t.Errorf("%v: unexpected result. want %v, got %v", prefix, want, got)
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) }
208 func dotUnitaryBenchmark(b *testing.B, n int) {
209 x := make([]float64, n)
211 x[i] = rand.Float64()
213 y := make([]float64, n)
215 y[i] = rand.Float64()
218 for i := 0; i < b.N; i++ {
223 func BenchmarkDotIncN1Inc1(b *testing.B) { dotIncBenchmark(b, 1, 1) }
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) }
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) }
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) }
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) }
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) }
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) }
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) }
260 func dotIncBenchmark(b *testing.B, n, inc int) {
265 x := make([]float64, (n-1)*absInc+1)
267 x[i] = rand.Float64()
269 y := make([]float64, (n-1)*absInc+1)
271 y[i] = rand.Float64()
278 for i := 0; i < b.N; i++ {
279 r = DotInc(x, y, uintptr(n), uintptr(inc), uintptr(inc), uintptr(ini), uintptr(ini))