--- /dev/null
+// Copyright 2014 The Gonum Authors. All rights reserved.
+// Use of this code is governed by a BSD-style
+// license that can be found in the LICENSE file
+
+// Script for automatic code generation of the benchmark routines.
+package main
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "path"
+ "path/filepath"
+ "strconv"
+)
+
+var gopath string
+
+var copyrightnotice = []byte(`// Copyright 2014 The Gonum Authors. All rights reserved.
+// Use of this code is governed by a BSD-style
+// license that can be found in the LICENSE file`)
+
+var autogen = []byte("// Code generated by \"go run gonum.org/v1/gonum/blas/testblas/benchautogen/autogen_bench_level1double.go\"; DO NOT EDIT.\n")
+
+var imports = []byte(`import(
+ "golang.org/x/exp/rand"
+ "testing"
+
+ "gonum.org/v1/gonum/blas"
+)`)
+
+var randomSliceFunction = []byte(`func randomSlice(l, idx int) ([]float64) {
+ if idx < 0{
+ idx = -idx
+ }
+ s := make([]float64, l * idx)
+ for i := range s {
+ s[i] = rand.Float64()
+ }
+ return s
+}`)
+
+const (
+ posInc1 = 5
+ posInc2 = 3
+ negInc1 = -3
+ negInc2 = -4
+)
+
+var level1Sizes = []struct {
+ lower string
+ upper string
+ camel string
+ size int
+}{
+ {
+ lower: "small",
+ upper: "SMALL_SLICE",
+ camel: "Small",
+ size: 10,
+ },
+ {
+ lower: "medium",
+ upper: "MEDIUM_SLICE",
+ camel: "Medium",
+ size: 1000,
+ },
+ {
+ lower: "large",
+ upper: "LARGE_SLICE",
+ camel: "Large",
+ size: 100000,
+ },
+ {
+ lower: "huge",
+ upper: "HUGE_SLICE",
+ camel: "Huge",
+ size: 10000000,
+ },
+}
+
+type level1functionStruct struct {
+ camel string
+ sig string
+ call string
+ extraSetup string
+ oneInput bool
+ extraName string // if have a couple different cases for the same function
+}
+
+var level1Functions = []level1functionStruct{
+ {
+ camel: "Ddot",
+ sig: "n int, x []float64, incX int, y []float64, incY int",
+ call: "n, x, incX, y, incY",
+ oneInput: false,
+ },
+ {
+ camel: "Dnrm2",
+ sig: "n int, x []float64, incX int",
+ call: "n, x, incX",
+ oneInput: true,
+ },
+ {
+ camel: "Dasum",
+ sig: "n int, x []float64, incX int",
+ call: "n, x, incX",
+ oneInput: true,
+ },
+ {
+ camel: "Idamax",
+ sig: "n int, x []float64, incX int",
+ call: "n, x, incX",
+ oneInput: true,
+ },
+ {
+ camel: "Dswap",
+ sig: "n int, x []float64, incX int, y []float64, incY int",
+ call: "n, x, incX, y, incY",
+ oneInput: false,
+ },
+ {
+ camel: "Dcopy",
+ sig: "n int, x []float64, incX int, y []float64, incY int",
+ call: "n, x, incX, y, incY",
+ oneInput: false,
+ },
+ {
+ camel: "Daxpy",
+ sig: "n int, alpha float64, x []float64, incX int, y []float64, incY int",
+ call: "n, alpha, x, incX, y, incY",
+ extraSetup: "alpha := 2.4",
+ oneInput: false,
+ },
+ {
+ camel: "Drot",
+ sig: "n int, x []float64, incX int, y []float64, incY int, c, s float64",
+ call: "n, x, incX, y, incY, c, s",
+ extraSetup: "c := 0.89725836967\ns:= 0.44150585279",
+ oneInput: false,
+ },
+ {
+ camel: "Drotm",
+ sig: "n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams",
+ call: "n, x, incX, y, incY, p",
+ extraSetup: "p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375,0}}",
+ oneInput: false,
+ extraName: "OffDia",
+ },
+ {
+ camel: "Drotm",
+ sig: "n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams",
+ call: "n, x, incX, y, incY, p",
+ extraSetup: "p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}}",
+ oneInput: false,
+ extraName: "Dia",
+ },
+ {
+ camel: "Drotm",
+ sig: "n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams",
+ call: "n, x, incX, y, incY, p",
+ extraSetup: "p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}}",
+ oneInput: false,
+ extraName: "Resc",
+ },
+ {
+ camel: "Dscal",
+ sig: "n int, alpha float64, x []float64, incX int",
+ call: "n, alpha, x, incX",
+ extraSetup: "alpha := 2.4",
+ oneInput: true,
+ },
+}
+
+func init() {
+ gopath = os.Getenv("GOPATH")
+ if gopath == "" {
+ panic("gopath not set")
+ }
+}
+
+func main() {
+ blasPath := filepath.Join(gopath, "src", "gonum.org", "v1", "gonum", "blas")
+
+ pkgs := []struct{ name string }{{name: "native"}, {name: "cgo"}}
+
+ for _, pkg := range pkgs {
+ err := level1(filepath.Join(blasPath, pkg.name), pkg.name)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ err = exec.Command("go", "fmt", path.Join("gonum.org", "v1", "gonum", "blas", pkg.name)).Run()
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ }
+}
+
+func printHeader(f *os.File, name string) error {
+ if _, err := f.Write(autogen); err != nil {
+ return err
+ }
+ f.WriteString("\n\n")
+ f.Write(copyrightnotice)
+ f.WriteString("\n\n")
+ f.WriteString("package " + name)
+ f.WriteString("\n\n")
+ f.Write(imports)
+ f.WriteString("\n\n")
+ return nil
+}
+
+// Generate the benchmark scripts for level1
+func level1(benchPath string, pkgname string) error {
+ // Generate level 1 benchmarks
+ level1Filepath := filepath.Join(benchPath, "level1doubleBench_auto_test.go")
+ f, err := os.Create(level1Filepath)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ defer f.Close()
+ printHeader(f, pkgname)
+
+ // Print all of the constants
+ f.WriteString("const (\n")
+ f.WriteString("\tposInc1 = " + strconv.Itoa(posInc1) + "\n")
+ f.WriteString("\tposInc2 = " + strconv.Itoa(posInc2) + "\n")
+ f.WriteString("\tnegInc1 = " + strconv.Itoa(negInc1) + "\n")
+ f.WriteString("\tnegInc2 = " + strconv.Itoa(negInc2) + "\n")
+ for _, con := range level1Sizes {
+ f.WriteString("\t" + con.upper + " = " + strconv.Itoa(con.size) + "\n")
+ }
+ f.WriteString(")\n")
+ f.WriteString("\n")
+
+ // Write the randomSlice function
+ f.Write(randomSliceFunction)
+ f.WriteString("\n\n")
+
+ // Start writing the benchmarks
+ for _, fun := range level1Functions {
+ writeLevel1Benchmark(fun, f)
+ f.WriteString("\n/* ------------------ */ \n")
+ }
+
+ return nil
+}
+
+func writeLevel1Benchmark(fun level1functionStruct, f *os.File) {
+ // First, write the base benchmark file
+ f.WriteString("func benchmark" + fun.camel + fun.extraName + "(b *testing.B, ")
+ f.WriteString(fun.sig)
+ f.WriteString(") {\n")
+
+ f.WriteString("b.ResetTimer()\n")
+ f.WriteString("for i := 0; i < b.N; i++{\n")
+ f.WriteString("\timpl." + fun.camel + "(")
+
+ f.WriteString(fun.call)
+ f.WriteString(")\n}\n}\n")
+ f.WriteString("\n")
+
+ // Write all of the benchmarks to call it
+ for _, sz := range level1Sizes {
+ lambda := func(incX, incY, name string, twoInput bool) {
+ f.WriteString("func Benchmark" + fun.camel + fun.extraName + sz.camel + name + "(b *testing.B){\n")
+ f.WriteString("n := " + sz.upper + "\n")
+ f.WriteString("incX := " + incX + "\n")
+ f.WriteString("x := randomSlice(n, incX)\n")
+ if twoInput {
+ f.WriteString("incY := " + incY + "\n")
+ f.WriteString("y := randomSlice(n, incY)\n")
+ }
+ f.WriteString(fun.extraSetup + "\n")
+ f.WriteString("benchmark" + fun.camel + fun.extraName + "(b, " + fun.call + ")\n")
+ f.WriteString("}\n\n")
+ }
+ if fun.oneInput {
+ lambda("1", "", "UnitaryInc", false)
+ lambda("posInc1", "", "PosInc", false)
+ } else {
+ lambda("1", "1", "BothUnitary", true)
+ lambda("posInc1", "1", "IncUni", true)
+ lambda("1", "negInc1", "UniInc", true)
+ lambda("posInc1", "negInc1", "BothInc", true)
+ }
+ }
+}