github.com/gopherd/gonum@v0.0.4/internal/asm/f32/dot_test.go (about) 1 // Copyright ©2017 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 f32_test 6 7 import ( 8 "fmt" 9 "math" 10 "testing" 11 12 "github.com/gopherd/gonum/floats/scalar" 13 . "github.com/gopherd/gonum/internal/asm/f32" 14 ) 15 16 var dotTests = []struct { 17 x, y []float32 18 sWant float32 // single-precision 19 dWant float64 // double-precision 20 sWantRev float32 // single-precision increment 21 dWantRev float64 // double-precision increment 22 n int 23 ix, iy int 24 }{ 25 { // 0 26 x: []float32{}, 27 y: []float32{}, 28 n: 0, 29 sWant: 0, dWant: 0, 30 sWantRev: 0, dWantRev: 0, 31 ix: 0, iy: 0, 32 }, 33 { // 1 34 x: []float32{0}, 35 y: []float32{0}, 36 n: 1, 37 sWant: 0, dWant: 0, 38 sWantRev: 0, dWantRev: 0, 39 ix: 0, iy: 0, 40 }, 41 { // 2 42 x: []float32{1}, 43 y: []float32{1}, 44 n: 1, 45 sWant: 1, dWant: 1, 46 sWantRev: 1, dWantRev: 1, 47 ix: 0, iy: 0, 48 }, 49 { // 3 50 x: []float32{1, 2, 3, 4, 5, 6, 7, 8}, 51 y: []float32{2, 2, 2, 2, 2, 2, 2, 2}, 52 n: 8, 53 sWant: 72, dWant: 72, 54 sWantRev: 72, dWantRev: 72, 55 ix: 1, iy: 1, 56 }, 57 { // 4 58 x: []float32{math.MaxFloat32}, 59 y: []float32{2}, 60 n: 1, 61 sWant: inf, dWant: 2 * float64(math.MaxFloat32), 62 sWantRev: inf, dWantRev: 2 * float64(math.MaxFloat32), 63 ix: 0, iy: 0, 64 }, 65 { // 5 66 x: []float32{1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2}, 67 y: []float32{3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2}, 68 n: 20, 69 sWant: 70, dWant: 70, 70 sWantRev: 80, dWantRev: 80, 71 ix: 0, iy: 0, 72 }, 73 } 74 75 func TestDotUnitary(t *testing.T) { 76 const xGdVal, yGdVal = 0.5, 0.25 77 for i, test := range dotTests { 78 for _, align := range align2 { 79 prefix := fmt.Sprintf("Test %v (x:%v y:%v)", i, align.x, align.y) 80 xgLn, ygLn := 8+align.x, 8+align.y 81 xg, yg := guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn) 82 x, y := xg[xgLn:len(xg)-xgLn], yg[ygLn:len(yg)-ygLn] 83 res := DotUnitary(x, y) 84 if !same(res, test.sWant) { 85 t.Errorf(msgRes, prefix, res, test.sWant) 86 } 87 if !isValidGuard(xg, xGdVal, xgLn) { 88 t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:]) 89 } 90 if !isValidGuard(yg, yGdVal, ygLn) { 91 t.Errorf(msgGuard, prefix, "y", yg[:ygLn], yg[len(yg)-ygLn:]) 92 } 93 } 94 } 95 } 96 97 func TestDotInc(t *testing.T) { 98 const xGdVal, yGdVal, gdLn = 0.5, 0.25, 8 99 for i, test := range dotTests { 100 for _, inc := range newIncSet(1, 2, 3, 4, 7, 10, -1, -2, -5, -10) { 101 xg, yg := guardIncVector(test.x, xGdVal, inc.x, gdLn), guardIncVector(test.y, yGdVal, inc.y, gdLn) 102 x, y := xg[gdLn:len(xg)-gdLn], yg[gdLn:len(yg)-gdLn] 103 want := test.sWant 104 var ix, iy int 105 if inc.x < 0 { 106 ix = -inc.x * (test.n - 1) 107 } 108 if inc.y < 0 { 109 iy = -inc.y * (test.n - 1) 110 } 111 if inc.x*inc.y < 0 { 112 want = test.sWantRev 113 } 114 prefix := fmt.Sprintf("Test %v (x:%v y:%v) (ix:%v iy:%v)", i, inc.x, inc.y, ix, iy) 115 res := DotInc(x, y, uintptr(test.n), uintptr(inc.x), uintptr(inc.y), uintptr(ix), uintptr(iy)) 116 if !same(res, want) { 117 t.Errorf(msgRes, prefix, res, want) 118 } 119 checkValidIncGuard(t, xg, xGdVal, inc.x, gdLn) 120 checkValidIncGuard(t, yg, yGdVal, inc.y, gdLn) 121 } 122 } 123 } 124 125 func TestDdotUnitary(t *testing.T) { 126 const xGdVal, yGdVal = 0.5, 0.25 127 for i, test := range dotTests { 128 for _, align := range align2 { 129 prefix := fmt.Sprintf("Test %v (x:%v y:%v)", i, align.x, align.y) 130 xgLn, ygLn := 8+align.x, 8+align.y 131 xg, yg := guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn) 132 x, y := xg[xgLn:len(xg)-xgLn], yg[ygLn:len(yg)-ygLn] 133 res := DdotUnitary(x, y) 134 if !scalar.Same(res, test.dWant) { 135 t.Errorf(msgRes, prefix, res, test.dWant) 136 } 137 if !isValidGuard(xg, xGdVal, xgLn) { 138 t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:]) 139 } 140 if !isValidGuard(yg, yGdVal, ygLn) { 141 t.Errorf(msgGuard, prefix, "y", yg[:ygLn], yg[len(yg)-ygLn:]) 142 } 143 } 144 } 145 } 146 147 func TestDdotInc(t *testing.T) { 148 const xGdVal, yGdVal, gdLn = 0.5, 0.25, 8 149 for i, test := range dotTests { 150 for _, inc := range newIncSet(1, 2, 3, 4, 7, 10, -1, -2, -5, -10) { 151 prefix := fmt.Sprintf("Test %v (x:%v y:%v)", i, inc.x, inc.y) 152 xg, yg := guardIncVector(test.x, xGdVal, inc.x, gdLn), guardIncVector(test.y, yGdVal, inc.y, gdLn) 153 x, y := xg[gdLn:len(xg)-gdLn], yg[gdLn:len(yg)-gdLn] 154 want := test.dWant 155 var ix, iy int 156 if inc.x < 0 { 157 ix = -inc.x * (test.n - 1) 158 } 159 if inc.y < 0 { 160 iy = -inc.y * (test.n - 1) 161 } 162 if inc.x*inc.y < 0 { 163 want = test.dWantRev 164 } 165 res := DdotInc(x, y, uintptr(test.n), uintptr(inc.x), uintptr(inc.y), uintptr(ix), uintptr(iy)) 166 if !scalar.Same(res, want) { 167 t.Errorf(msgRes, prefix, res, want) 168 } 169 checkValidIncGuard(t, xg, xGdVal, inc.x, gdLn) 170 checkValidIncGuard(t, yg, yGdVal, inc.y, gdLn) 171 } 172 } 173 }