github.com/gopherd/gonum@v0.0.4/blas/testblas/benchautogen/autogen_bench_level1double.go (about) 1 // Copyright ©2014 The Gonum Authors. All rights reserved. 2 // Use of this code is governed by a BSD-style 3 // license that can be found in the LICENSE file 4 5 // Script for automatic code generation of the benchmark routines. 6 package main 7 8 import ( 9 "fmt" 10 "os" 11 "os/exec" 12 "path/filepath" 13 "strconv" 14 ) 15 16 var gopath string 17 18 var copyrightnotice = []byte(`// Copyright ©2014 The Gonum Authors. All rights reserved. 19 // Use of this code is governed by a BSD-style 20 // license that can be found in the LICENSE file`) 21 22 var autogen = []byte("// Code generated by \"go run $GOPATH/src/github.com/gopherd/gonum/blas/testblas/benchautogen/autogen_bench_level1double.go\"; DO NOT EDIT.\n") 23 24 var imports = []byte(`import( 25 "testing" 26 27 "math/rand" 28 29 "github.com/gopherd/gonum/blas" 30 )`) 31 32 var randomSliceFunction = []byte(`func randomSlice(l, idx int) ([]float64) { 33 if idx < 0{ 34 idx = -idx 35 } 36 s := make([]float64, l * idx) 37 for i := range s { 38 s[i] = rand.Float64() 39 } 40 return s 41 }`) 42 43 const ( 44 posInc1 = 5 45 posInc2 = 3 46 negInc1 = -3 47 negInc2 = -4 48 ) 49 50 var level1Sizes = []struct { 51 lower string 52 upper string 53 camel string 54 size int 55 }{ 56 { 57 lower: "small", 58 upper: "SMALL_SLICE", 59 camel: "Small", 60 size: 10, 61 }, 62 { 63 lower: "medium", 64 upper: "MEDIUM_SLICE", 65 camel: "Medium", 66 size: 1000, 67 }, 68 { 69 lower: "large", 70 upper: "LARGE_SLICE", 71 camel: "Large", 72 size: 100000, 73 }, 74 { 75 lower: "huge", 76 upper: "HUGE_SLICE", 77 camel: "Huge", 78 size: 10000000, 79 }, 80 } 81 82 type level1functionStruct struct { 83 camel string 84 sig string 85 call string 86 extraSetup string 87 oneInput bool 88 extraName string // if have a couple different cases for the same function 89 } 90 91 var level1Functions = []level1functionStruct{ 92 { 93 camel: "Ddot", 94 sig: "n int, x []float64, incX int, y []float64, incY int", 95 call: "n, x, incX, y, incY", 96 oneInput: false, 97 }, 98 { 99 camel: "Dnrm2", 100 sig: "n int, x []float64, incX int", 101 call: "n, x, incX", 102 oneInput: true, 103 }, 104 { 105 camel: "Dasum", 106 sig: "n int, x []float64, incX int", 107 call: "n, x, incX", 108 oneInput: true, 109 }, 110 { 111 camel: "Idamax", 112 sig: "n int, x []float64, incX int", 113 call: "n, x, incX", 114 oneInput: true, 115 }, 116 { 117 camel: "Dswap", 118 sig: "n int, x []float64, incX int, y []float64, incY int", 119 call: "n, x, incX, y, incY", 120 oneInput: false, 121 }, 122 { 123 camel: "Dcopy", 124 sig: "n int, x []float64, incX int, y []float64, incY int", 125 call: "n, x, incX, y, incY", 126 oneInput: false, 127 }, 128 { 129 camel: "Daxpy", 130 sig: "n int, alpha float64, x []float64, incX int, y []float64, incY int", 131 call: "n, alpha, x, incX, y, incY", 132 extraSetup: "alpha := 2.4", 133 oneInput: false, 134 }, 135 { 136 camel: "Drot", 137 sig: "n int, x []float64, incX int, y []float64, incY int, c, s float64", 138 call: "n, x, incX, y, incY, c, s", 139 extraSetup: "c := 0.89725836967\ns:= 0.44150585279", 140 oneInput: false, 141 }, 142 { 143 camel: "Drotm", 144 sig: "n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams", 145 call: "n, x, incX, y, incY, p", 146 extraSetup: "p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375,0}}", 147 oneInput: false, 148 extraName: "OffDia", 149 }, 150 { 151 camel: "Drotm", 152 sig: "n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams", 153 call: "n, x, incX, y, incY, p", 154 extraSetup: "p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}}", 155 oneInput: false, 156 extraName: "Dia", 157 }, 158 { 159 camel: "Drotm", 160 sig: "n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams", 161 call: "n, x, incX, y, incY, p", 162 extraSetup: "p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}}", 163 oneInput: false, 164 extraName: "Resc", 165 }, 166 { 167 camel: "Dscal", 168 sig: "n int, alpha float64, x []float64, incX int", 169 call: "n, alpha, x, incX", 170 extraSetup: "alpha := 2.4", 171 oneInput: true, 172 }, 173 } 174 175 func init() { 176 gopath = os.Getenv("GOPATH") 177 if gopath == "" { 178 panic("gopath not set") 179 } 180 } 181 182 func main() { 183 pkgs := []string{"gonum", "netlib"} 184 for _, pkg := range pkgs { 185 blasPath := filepath.Join(gopath, "src", "gonum.org", "v1", pkg, "blas", pkg) 186 err := level1(blasPath, pkg) 187 if err != nil { 188 fmt.Println(err) 189 os.Exit(1) 190 } 191 192 err = exec.Command("goimports", "-w", blasPath).Run() 193 if err != nil { 194 fmt.Println(err) 195 os.Exit(1) 196 } 197 } 198 } 199 200 func printHeader(f errFile, name string) { 201 f.Write(autogen) 202 f.WriteString("\n\n") 203 f.Write(copyrightnotice) 204 f.WriteString("\n\n") 205 f.WriteString("package " + name) 206 f.WriteString("\n\n") 207 f.Write(imports) 208 f.WriteString("\n\n") 209 } 210 211 // Generate the benchmark scripts for level1 212 func level1(benchPath string, pkgname string) error { 213 // Generate level 1 benchmarks 214 level1Filepath := filepath.Join(benchPath, "level1float64_bench_test.go") 215 var f errFile 216 f.file, f.err = os.Create(level1Filepath) 217 if f.err != nil { 218 return f.err 219 } 220 defer f.file.Close() 221 222 printHeader(f, pkgname) 223 224 // Print all of the constants 225 f.WriteString("const (\n") 226 f.WriteString("\tposInc1 = " + strconv.Itoa(posInc1) + "\n") 227 f.WriteString("\tposInc2 = " + strconv.Itoa(posInc2) + "\n") 228 f.WriteString("\tnegInc1 = " + strconv.Itoa(negInc1) + "\n") 229 f.WriteString("\tnegInc2 = " + strconv.Itoa(negInc2) + "\n") 230 for _, con := range level1Sizes { 231 f.WriteString("\t" + con.upper + " = " + strconv.Itoa(con.size) + "\n") 232 } 233 f.WriteString(")\n") 234 f.WriteString("\n") 235 236 // Write the randomSlice function 237 f.Write(randomSliceFunction) 238 f.WriteString("\n\n") 239 240 // Start writing the benchmarks 241 for _, fun := range level1Functions { 242 writeLevel1Benchmark(fun, f) 243 f.WriteString("\n/* ------------------ */ \n") 244 } 245 246 return f.err 247 } 248 249 func writeLevel1Benchmark(fun level1functionStruct, f errFile) { 250 // First, write the base benchmark file 251 f.WriteString("func benchmark" + fun.camel + fun.extraName + "(b *testing.B, ") 252 f.WriteString(fun.sig) 253 f.WriteString(") {\n") 254 255 f.WriteString("b.ResetTimer()\n") 256 f.WriteString("for i := 0; i < b.N; i++{\n") 257 f.WriteString("\timpl." + fun.camel + "(") 258 259 f.WriteString(fun.call) 260 f.WriteString(")\n}\n}\n") 261 f.WriteString("\n") 262 263 // Write all of the benchmarks to call it 264 for _, sz := range level1Sizes { 265 lambda := func(incX, incY, name string, twoInput bool) { 266 f.WriteString("func Benchmark" + fun.camel + fun.extraName + sz.camel + name + "(b *testing.B){\n") 267 f.WriteString("n := " + sz.upper + "\n") 268 f.WriteString("incX := " + incX + "\n") 269 f.WriteString("x := randomSlice(n, incX)\n") 270 if twoInput { 271 f.WriteString("incY := " + incY + "\n") 272 f.WriteString("y := randomSlice(n, incY)\n") 273 } 274 f.WriteString(fun.extraSetup + "\n") 275 f.WriteString("benchmark" + fun.camel + fun.extraName + "(b, " + fun.call + ")\n") 276 f.WriteString("}\n\n") 277 } 278 if fun.oneInput { 279 lambda("1", "", "UnitaryInc", false) 280 lambda("posInc1", "", "PosInc", false) 281 } else { 282 lambda("1", "1", "BothUnitary", true) 283 lambda("posInc1", "1", "IncUni", true) 284 lambda("1", "negInc1", "UniInc", true) 285 lambda("posInc1", "negInc1", "BothInc", true) 286 } 287 } 288 } 289 290 type errFile struct { 291 file *os.File 292 err error 293 } 294 295 func (f errFile) Write(b []byte) { 296 if f.err != nil { 297 return 298 } 299 _, f.err = f.file.Write(b) 300 } 301 302 func (f errFile) WriteString(s string) { 303 if f.err != nil { 304 return 305 } 306 _, f.err = f.file.WriteString(s) 307 }