gonum.org/v1/gonum@v0.14.0/internal/asm/f64/axpy_test.go (about) 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_test 6 7 import ( 8 "fmt" 9 "testing" 10 11 "gonum.org/v1/gonum/floats/scalar" 12 . "gonum.org/v1/gonum/internal/asm/f64" 13 ) 14 15 var axpyTests = []struct { 16 alpha float64 17 x []float64 18 y []float64 19 want []float64 20 wantRev []float64 // Result when x is traversed in reverse direction. 21 }{ 22 { 23 alpha: 0, 24 x: []float64{}, 25 y: []float64{}, 26 want: []float64{}, 27 wantRev: []float64{}, 28 }, 29 { 30 alpha: 0, 31 x: []float64{2}, 32 y: []float64{-3}, 33 want: []float64{-3}, 34 wantRev: []float64{-3}, 35 }, 36 { 37 alpha: 1, 38 x: []float64{2}, 39 y: []float64{-3}, 40 want: []float64{-1}, 41 wantRev: []float64{-1}, 42 }, 43 { 44 alpha: 3, 45 x: []float64{2}, 46 y: []float64{-3}, 47 want: []float64{3}, 48 wantRev: []float64{3}, 49 }, 50 { 51 alpha: -3, 52 x: []float64{2}, 53 y: []float64{-3}, 54 want: []float64{-9}, 55 wantRev: []float64{-9}, 56 }, 57 { 58 alpha: 1, 59 x: []float64{1, 5}, 60 y: []float64{2, -3}, 61 want: []float64{3, 2}, 62 wantRev: []float64{7, -2}, 63 }, 64 { 65 alpha: 1, 66 x: []float64{2, 3, 4}, 67 y: []float64{-3, -2, -1}, 68 want: []float64{-1, 1, 3}, 69 wantRev: []float64{1, 1, 1}, 70 }, 71 { 72 alpha: 0, 73 x: []float64{0, 0, 1, 1, 2, -3, -4}, 74 y: []float64{0, 1, 0, 3, -4, 5, -6}, 75 want: []float64{0, 1, 0, 3, -4, 5, -6}, 76 wantRev: []float64{0, 1, 0, 3, -4, 5, -6}, 77 }, 78 { 79 alpha: 1, 80 x: []float64{0, 0, 1, 1, 2, -3, -4}, 81 y: []float64{0, 1, 0, 3, -4, 5, -6}, 82 want: []float64{0, 1, 1, 4, -2, 2, -10}, 83 wantRev: []float64{-4, -2, 2, 4, -3, 5, -6}, 84 }, 85 { 86 alpha: 3, 87 x: []float64{0, 0, 1, 1, 2, -3, -4}, 88 y: []float64{0, 1, 0, 3, -4, 5, -6}, 89 want: []float64{0, 1, 3, 6, 2, -4, -18}, 90 wantRev: []float64{-12, -8, 6, 6, -1, 5, -6}, 91 }, 92 { 93 alpha: -3, 94 x: []float64{0, 0, 1, 1, 2, -3, -4, 0, 0, 1, 1, 2, -3, -4}, 95 y: []float64{0, 1, 0, 3, -4, 5, -6, 0, 1, 0, 3, -4, 5, -6}, 96 want: []float64{0, 1, -3, 0, -10, 14, 6, 0, 1, -3, 0, -10, 14, 6}, 97 wantRev: []float64{12, 10, -6, 0, -7, 5, -6, 12, 10, -6, 0, -7, 5, -6}, 98 }, 99 { 100 alpha: -5, 101 x: []float64{0, 0, 1, 1, 2, -3, -4, 5, 1, 2, -3, -4, 5}, 102 y: []float64{0, 1, 0, 3, -4, 5, -6, 7, 3, -4, 5, -6, 7}, 103 want: []float64{0, 1, -5, -2, -14, 20, 14, -18, -2, -14, 20, 14, -18}, 104 wantRev: []float64{-25, 21, 15, -7, -9, -20, 14, 22, -7, -9, 0, -6, 7}, 105 }, 106 } 107 108 func TestAxpyUnitary(t *testing.T) { 109 const xGdVal, yGdVal = -1, 0.5 110 for i, test := range axpyTests { 111 for _, align := range align2 { 112 prefix := fmt.Sprintf("Test %v (x:%v y:%v)", i, align.x, align.y) 113 xgLn, ygLn := 4+align.x, 4+align.y 114 xg, yg := guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn) 115 x, y := xg[xgLn:len(xg)-xgLn], yg[ygLn:len(yg)-ygLn] 116 AxpyUnitary(test.alpha, x, y) 117 for i := range test.want { 118 if !scalar.Same(y[i], test.want[i]) { 119 t.Errorf(msgVal, prefix, i, y[i], test.want[i]) 120 } 121 } 122 if !isValidGuard(xg, xGdVal, xgLn) { 123 t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:]) 124 } 125 if !isValidGuard(yg, yGdVal, ygLn) { 126 t.Errorf(msgGuard, prefix, "y", yg[:ygLn], yg[len(yg)-ygLn:]) 127 } 128 if !equalStrided(test.x, x, 1) { 129 t.Errorf("%v: modified read-only x argument", prefix) 130 } 131 } 132 } 133 } 134 135 func TestAxpyUnitaryTo(t *testing.T) { 136 const dstGdVal, xGdVal, yGdVal = 1, -1, 0.5 137 for i, test := range axpyTests { 138 for _, align := range align3 { 139 prefix := fmt.Sprintf("Test %v (x:%v y:%v dst:%v)", i, align.x, align.y, align.dst) 140 141 dgLn, xgLn, ygLn := 4+align.dst, 4+align.x, 4+align.y 142 dstOrig := make([]float64, len(test.x)) 143 xg, yg := guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn) 144 dstg := guardVector(dstOrig, dstGdVal, dgLn) 145 x, y := xg[xgLn:len(xg)-xgLn], yg[ygLn:len(yg)-ygLn] 146 dst := dstg[dgLn : len(dstg)-dgLn] 147 148 AxpyUnitaryTo(dst, test.alpha, x, y) 149 for i := range test.want { 150 if !scalar.Same(dst[i], test.want[i]) { 151 t.Errorf(msgVal, prefix, i, dst[i], test.want[i]) 152 } 153 } 154 if !isValidGuard(xg, xGdVal, xgLn) { 155 t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:]) 156 } 157 if !isValidGuard(yg, yGdVal, ygLn) { 158 t.Errorf(msgGuard, prefix, "y", yg[:ygLn], yg[len(yg)-ygLn:]) 159 } 160 if !isValidGuard(dstg, dstGdVal, dgLn) { 161 t.Errorf(msgGuard, prefix, "dst", dstg[:dgLn], dstg[len(dstg)-dgLn:]) 162 } 163 if !equalStrided(test.x, x, 1) { 164 t.Errorf("%v: modified read-only x argument", prefix) 165 } 166 if !equalStrided(test.y, y, 1) { 167 t.Errorf("%v: modified read-only y argument", prefix) 168 } 169 } 170 } 171 } 172 173 func TestAxpyInc(t *testing.T) { 174 const xGdVal, yGdVal = -1, 0.5 175 gdLn := 4 176 for i, test := range axpyTests { 177 n := len(test.x) 178 for _, inc := range newIncSet(-7, -4, -3, -2, -1, 1, 2, 3, 4, 7) { 179 var ix, iy int 180 if inc.x < 0 { 181 ix = (-n + 1) * inc.x 182 } 183 if inc.y < 0 { 184 iy = (-n + 1) * inc.y 185 } 186 prefix := fmt.Sprintf("test %v, inc.x = %v, inc.y = %v", i, inc.x, inc.y) 187 xg := guardIncVector(test.x, xGdVal, inc.x, gdLn) 188 yg := guardIncVector(test.y, yGdVal, inc.y, gdLn) 189 x, y := xg[gdLn:len(xg)-gdLn], yg[gdLn:len(yg)-gdLn] 190 191 AxpyInc(test.alpha, x, y, uintptr(n), 192 uintptr(inc.x), uintptr(inc.y), uintptr(ix), uintptr(iy)) 193 194 want := test.want 195 if inc.x*inc.y < 0 { 196 want = test.wantRev 197 } 198 if inc.y < 0 { 199 inc.y = -inc.y 200 } 201 for i := range want { 202 if !scalar.Same(y[i*inc.y], want[i]) { 203 t.Errorf(msgVal, prefix, i, y[iy+i*inc.y], want[i]) 204 } 205 } 206 if !equalStrided(test.x, x, inc.x) { 207 t.Errorf("%v: modified read-only x argument", prefix) 208 } 209 checkValidIncGuard(t, xg, xGdVal, inc.x, gdLn) 210 checkValidIncGuard(t, yg, yGdVal, inc.y, gdLn) 211 } 212 } 213 } 214 215 func TestAxpyIncTo(t *testing.T) { 216 const dstGdVal, xGdVal, yGdVal = 1, -1, 0.5 217 var want []float64 218 gdLn := 4 219 for i, test := range axpyTests { 220 n := len(test.x) 221 for _, inc := range newIncToSet(-7, -4, -3, -2, -1, 1, 2, 3, 4, 7) { 222 var ix, iy, idst uintptr 223 if inc.x < 0 { 224 ix = uintptr((-n + 1) * inc.x) 225 } 226 if inc.y < 0 { 227 iy = uintptr((-n + 1) * inc.y) 228 } 229 if inc.dst < 0 { 230 idst = uintptr((-n + 1) * inc.dst) 231 } 232 233 prefix := fmt.Sprintf("Test %v: (x: %v, y: %v, dst:%v)", i, inc.x, inc.y, inc.dst) 234 dstOrig := make([]float64, len(test.want)) 235 xg := guardIncVector(test.x, xGdVal, inc.x, gdLn) 236 yg := guardIncVector(test.y, yGdVal, inc.y, gdLn) 237 dstg := guardIncVector(dstOrig, dstGdVal, inc.dst, gdLn) 238 x, y := xg[gdLn:len(xg)-gdLn], yg[gdLn:len(yg)-gdLn] 239 dst := dstg[gdLn : len(dstg)-gdLn] 240 241 AxpyIncTo(dst, uintptr(inc.dst), idst, 242 test.alpha, x, y, uintptr(n), 243 uintptr(inc.x), uintptr(inc.y), ix, iy) 244 want = test.want 245 if inc.x*inc.y < 0 { 246 want = test.wantRev 247 } 248 iW, incW := 0, 1 249 if inc.y*inc.dst < 0 { 250 iW, incW = len(want)-1, -1 251 } 252 if inc.dst < 0 { 253 inc.dst = -inc.dst 254 } 255 for i := range want { 256 if !scalar.Same(dst[i*inc.dst], want[iW+i*incW]) { 257 t.Errorf(msgVal, prefix, i, dst[i*inc.dst], want[iW+i*incW]) 258 } 259 } 260 261 checkValidIncGuard(t, xg, xGdVal, inc.x, gdLn) 262 checkValidIncGuard(t, yg, yGdVal, inc.y, gdLn) 263 checkValidIncGuard(t, dstg, dstGdVal, inc.dst, gdLn) 264 if !equalStrided(test.x, x, inc.x) { 265 t.Errorf("%v: modified read-only x argument", prefix) 266 } 267 if !equalStrided(test.y, y, inc.y) { 268 t.Errorf("%v: modified read-only y argument", prefix) 269 } 270 } 271 } 272 }