Files
gonum/blas/cgo/generate_blas.go
2017-05-23 00:03:03 -06:00

979 lines
24 KiB
Go

// Copyright ©2016 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
// generate_blas creates a blas.go file from the provided C header file
// with optionally added documentation from the documentation package.
package main
import (
"bytes"
"fmt"
"go/ast"
"go/format"
"io/ioutil"
"log"
"strings"
"text/template"
"github.com/cznic/cc"
"gonum.org/v1/gonum/internal/binding"
)
const (
header = "cblas.h"
documentation = "../native"
target = "blas.go"
typ = "Implementation"
prefix = "cblas_"
warning = "Float32 implementations are autogenerated and not directly tested."
)
const (
cribDocs = true
elideRepeat = true
noteOrigin = true
separateFuncs = false
)
var skip = map[string]bool{
"cblas_errprn": true,
"cblas_srotg": true,
"cblas_srotmg": true,
"cblas_srotm": true,
"cblas_drotg": true,
"cblas_drotmg": true,
"cblas_drotm": true,
"cblas_crotg": true,
"cblas_zrotg": true,
"cblas_cdotu_sub": true,
"cblas_cdotc_sub": true,
"cblas_zdotu_sub": true,
"cblas_zdotc_sub": true,
// ATLAS extensions.
"cblas_csrot": true,
"cblas_zdrot": true,
}
var cToGoType = map[string]string{
"int": "int",
"float": "float32",
"double": "float64",
}
var blasEnums = map[string]*template.Template{
"CBLAS_ORDER": template.Must(template.New("order").Parse("order")),
"CBLAS_DIAG": template.Must(template.New("diag").Parse("blas.Diag")),
"CBLAS_TRANSPOSE": template.Must(template.New("trans").Parse("blas.Transpose")),
"CBLAS_UPLO": template.Must(template.New("uplo").Parse("blas.Uplo")),
"CBLAS_SIDE": template.Must(template.New("side").Parse("blas.Side")),
}
var cgoEnums = map[string]*template.Template{
"CBLAS_ORDER": template.Must(template.New("order").Parse("C.enum_CBLAS_ORDER(rowMajor)")),
"CBLAS_DIAG": template.Must(template.New("diag").Parse("C.enum_CBLAS_DIAG({{.}})")),
"CBLAS_TRANSPOSE": template.Must(template.New("trans").Parse("C.enum_CBLAS_TRANSPOSE({{.}})")),
"CBLAS_UPLO": template.Must(template.New("uplo").Parse("C.enum_CBLAS_UPLO({{.}})")),
"CBLAS_SIDE": template.Must(template.New("side").Parse("C.enum_CBLAS_SIDE({{.}})")),
}
var cgoTypes = map[binding.TypeKey]*template.Template{
{Kind: cc.Void, IsPointer: true}: template.Must(template.New("void*").Parse(
`unsafe.Pointer(&{{.}}{{if eq . "alpha" "beta"}}{{else}}[0]{{end}})`,
)),
}
var (
complex64Type = map[binding.TypeKey]*template.Template{
{Kind: cc.Void, IsPointer: true}: template.Must(template.New("void*").Parse(
`{{if eq . "alpha" "beta"}}complex64{{else}}[]complex64{{end}}`,
))}
complex128Type = map[binding.TypeKey]*template.Template{
{Kind: cc.Void, IsPointer: true}: template.Must(template.New("void*").Parse(
`{{if eq . "alpha" "beta"}}complex128{{else}}[]complex128{{end}}`,
))}
)
var names = map[string]string{
"uplo": "ul",
"trans": "t",
"transA": "tA",
"transB": "tB",
"side": "s",
"diag": "d",
}
func shorten(n string) string {
s, ok := names[n]
if ok {
return s
}
return n
}
func main() {
decls, err := binding.Declarations(header)
if err != nil {
log.Fatal(err)
}
var docs map[string]map[string][]*ast.Comment
if cribDocs {
docs, err = binding.DocComments(documentation)
if err != nil {
log.Fatal(err)
}
}
var buf bytes.Buffer
h, err := template.New("handwritten").Parse(handwritten)
if err != nil {
log.Fatal(err)
}
err = h.Execute(&buf, header)
if err != nil {
log.Fatal(err)
}
var n int
for _, d := range decls {
if !strings.HasPrefix(d.Name, prefix) || skip[d.Name] {
continue
}
if n != 0 && (separateFuncs || cribDocs) {
buf.WriteByte('\n')
}
n++
goSignature(&buf, d, docs[typ])
if noteOrigin {
fmt.Fprintf(&buf, "\t// declared at %s %s %s ...\n\n", d.Position(), d.Return, d.Name)
}
parameterChecks(&buf, d, parameterCheckRules)
buf.WriteByte('\t')
cgoCall(&buf, d)
buf.WriteString("}\n")
}
b, err := format.Source(buf.Bytes())
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile(target, b, 0664)
if err != nil {
log.Fatal(err)
}
}
func goSignature(buf *bytes.Buffer, d binding.Declaration, docs map[string][]*ast.Comment) {
blasName := strings.TrimPrefix(d.Name, prefix)
goName := binding.UpperCaseFirst(blasName)
if docs != nil {
if doc, ok := docs[goName]; ok {
if strings.Contains(doc[len(doc)-1].Text, warning) {
doc = doc[:len(doc)-2]
}
for _, c := range doc {
buf.WriteString(c.Text)
buf.WriteByte('\n')
}
}
}
parameters := d.Parameters()
var voidPtrType map[binding.TypeKey]*template.Template
for _, p := range parameters {
if p.Kind() == cc.Ptr && p.Elem().Kind() == cc.Void {
switch {
case blasName[0] == 'c', blasName[1] == 'c' && blasName[0] != 'z':
voidPtrType = complex64Type
case blasName[0] == 'z', blasName[1] == 'z':
voidPtrType = complex128Type
}
break
}
}
fmt.Fprintf(buf, "func (%s) %s(", typ, goName)
c := 0
for i, p := range parameters {
if p.Kind() == cc.Enum && binding.GoTypeForEnum(p.Type(), "", blasEnums) == "order" {
continue
}
if c != 0 {
buf.WriteString(", ")
}
c++
n := shorten(binding.LowerCaseFirst(p.Name()))
var this, next string
if p.Kind() == cc.Enum {
this = binding.GoTypeForEnum(p.Type(), n, blasEnums)
} else {
this = binding.GoTypeFor(p.Type(), n, voidPtrType)
}
if elideRepeat && i < len(parameters)-1 && p.Type().Kind() == parameters[i+1].Type().Kind() {
p := parameters[i+1]
n := shorten(binding.LowerCaseFirst(p.Name()))
if p.Kind() == cc.Enum {
next = binding.GoTypeForEnum(p.Type(), n, blasEnums)
} else {
next = binding.GoTypeFor(p.Type(), n, voidPtrType)
}
}
if next == this {
buf.WriteString(n)
} else {
fmt.Fprintf(buf, "%s %s", n, this)
}
}
if d.Return.Kind() != cc.Void {
fmt.Fprintf(buf, ") %s {\n", cToGoType[d.Return.String()])
} else {
buf.WriteString(") {\n")
}
}
func parameterChecks(buf *bytes.Buffer, d binding.Declaration, rules []func(*bytes.Buffer, binding.Declaration, binding.Parameter) bool) {
done := make(map[int]bool)
for _, p := range d.Parameters() {
for i, r := range rules {
if done[i] {
continue
}
done[i] = r(buf, d, p)
}
}
}
func cgoCall(buf *bytes.Buffer, d binding.Declaration) {
if d.Return.Kind() != cc.Void {
fmt.Fprintf(buf, "return %s(", cToGoType[d.Return.String()])
}
fmt.Fprintf(buf, "C.%s(", d.Name)
for i, p := range d.Parameters() {
if i != 0 {
buf.WriteString(", ")
}
if p.Type().Kind() == cc.Enum {
buf.WriteString(binding.CgoConversionForEnum(shorten(binding.LowerCaseFirst(p.Name())), p.Type(), cgoEnums))
} else {
buf.WriteString(binding.CgoConversionFor(shorten(binding.LowerCaseFirst(p.Name())), p.Type(), cgoTypes))
}
}
if d.Return.Kind() != cc.Void {
buf.WriteString(")")
}
buf.WriteString(")\n")
}
var parameterCheckRules = []func(*bytes.Buffer, binding.Declaration, binding.Parameter) bool{
trans,
uplo,
diag,
side,
shape,
apShape,
zeroInc,
sidedShape,
mvShape,
rkShape,
gemmShape,
scalShape,
amaxShape,
nrmSumShape,
vectorShape,
othersShape,
noWork,
}
func amaxShape(buf *bytes.Buffer, d binding.Declaration, p binding.Parameter) bool {
switch d.Name {
case "cblas_isamax", "cblas_idamax", "cblas_icamax", "cblas_izamax":
default:
return true
}
if d.CParameters[len(d.CParameters)-1] != p.Parameter {
return false // Come back later.
}
fmt.Fprint(buf, ` if n == 0 || incX < 0 {
return -1
}
if incX > 0 && (n-1)*incX >= len(x) {
panic("blas: x index out of range")
}
`)
return true
}
func apShape(buf *bytes.Buffer, _ binding.Declaration, p binding.Parameter) bool {
n := binding.LowerCaseFirst(p.Name())
if n != "ap" {
return false
}
fmt.Fprint(buf, ` if n*(n+1)/2 > len(ap) {
panic("blas: index of ap out of range")
}
`)
return true
}
func diag(buf *bytes.Buffer, _ binding.Declaration, p binding.Parameter) bool {
if p.Name() != "Diag" {
return false
}
fmt.Fprint(buf, ` if d != blas.NonUnit && d != blas.Unit {
panic("blas: illegal diagonal")
}
`)
return true
}
func gemmShape(buf *bytes.Buffer, d binding.Declaration, p binding.Parameter) bool {
switch d.Name {
case "cblas_sgemm", "cblas_dgemm", "cblas_cgemm", "cblas_zgemm":
default:
return true
}
if d.CParameters[len(d.CParameters)-1] != p.Parameter {
return false // Come back later.
}
fmt.Fprint(buf, ` var rowA, colA, rowB, colB int
if tA == blas.NoTrans {
rowA, colA = m, k
} else {
rowA, colA = k, m
}
if tB == blas.NoTrans {
rowB, colB = k, n
} else {
rowB, colB = n, k
}
if lda*(rowA-1)+colA > len(a) || lda < max(1, colA) {
panic("blas: index of a out of range")
}
if ldb*(rowB-1)+colB > len(b) || ldb < max(1, colB) {
panic("blas: index of b out of range")
}
if ldc*(m-1)+n > len(c) || ldc < max(1, n) {
panic("blas: index of c out of range")
}
`)
return true
}
func mvShape(buf *bytes.Buffer, d binding.Declaration, p binding.Parameter) bool {
switch d.Name {
case "cblas_sgbmv", "cblas_dgbmv", "cblas_cgbmv", "cblas_zgbmv",
"cblas_sgemv", "cblas_dgemv", "cblas_cgemv", "cblas_zgemv":
default:
return true
}
if d.CParameters[len(d.CParameters)-1] != p.Parameter {
return false // Come back later.
}
fmt.Fprint(buf, ` var lenX, lenY int
if tA == blas.NoTrans {
lenX, lenY = n, m
} else {
lenX, lenY = m, n
}
if (incX > 0 && (lenX-1)*incX >= len(x)) || (incX < 0 && (1-lenX)*incX >= len(x)) {
panic("blas: x index out of range")
}
if (incY > 0 && (lenY-1)*incY >= len(y)) || (incY < 0 && (1-lenY)*incY >= len(y)) {
panic("blas: y index out of range")
}
`)
return true
}
func noWork(buf *bytes.Buffer, d binding.Declaration, p binding.Parameter) bool {
var hasN, hasLda, hasLdb bool
for _, p := range d.Parameters() {
switch shorten(binding.LowerCaseFirst(p.Name())) {
case "n":
hasN = true
case "lda":
hasLda = true
case "ldb":
hasLdb = true
}
}
if !hasN || hasLda || hasLdb {
return true
}
if d.CParameters[len(d.CParameters)-1] != p.Parameter {
return false // Come back later.
}
var value string
switch d.Return.String() {
case "int":
value = " -1"
case "float", "double":
value = " 0"
}
fmt.Fprintf(buf, ` if n == 0 {
return%s
}
`, value)
return true
}
func nrmSumShape(buf *bytes.Buffer, d binding.Declaration, p binding.Parameter) bool {
switch d.Name {
case "cblas_snrm2", "cblas_dnrm2", "cblas_scnrm2", "cblas_dznrm2",
"cblas_sasum", "cblas_dasum", "cblas_scasum", "cblas_dzasum":
default:
return true
}
if d.CParameters[len(d.CParameters)-1] != p.Parameter {
return false // Come back later.
}
fmt.Fprint(buf, ` if incX < 0 {
return 0
}
if incX > 0 && (n-1)*incX >= len(x) {
panic("blas: x index out of range")
}
`)
return true
}
func rkShape(buf *bytes.Buffer, d binding.Declaration, p binding.Parameter) bool {
switch d.Name {
case "cblas_ssyrk", "cblas_dsyrk", "cblas_csyrk", "cblas_zsyrk",
"cblas_ssyr2k", "cblas_dsyr2k", "cblas_csyr2k", "cblas_zsyr2k",
"cblas_cherk", "cblas_zherk", "cblas_cher2k", "cblas_zher2k":
default:
return true
}
if d.CParameters[len(d.CParameters)-1] != p.Parameter {
return false // Come back later.
}
fmt.Fprint(buf, ` var row, col int
if t == blas.NoTrans {
row, col = n, k
} else {
row, col = k, n
}
`)
has := make(map[string]bool)
for _, p := range d.Parameters() {
if p.Kind() != cc.Ptr {
continue
}
has[shorten(binding.LowerCaseFirst(p.Name()))] = true
}
for _, label := range []string{"a", "b"} {
if has[label] {
fmt.Fprintf(buf, ` if ld%[1]s*(row-1)+col > len(%[1]s) || ld%[1]s < max(1, col) {
panic("blas: index of %[1]s out of range")
}
`, label)
}
}
if has["c"] {
fmt.Fprint(buf, ` if ldc*(n-1)+n > len(c) || ldc < max(1, n) {
panic("blas: index of c out of range")
}
`)
}
return true
}
func scalShape(buf *bytes.Buffer, d binding.Declaration, p binding.Parameter) bool {
switch d.Name {
case "cblas_sscal", "cblas_dscal", "cblas_cscal", "cblas_zscal", "cblas_csscal":
default:
return true
}
if d.CParameters[len(d.CParameters)-1] != p.Parameter {
return false // Come back later.
}
fmt.Fprint(buf, ` if incX < 0 {
return
}
if incX > 0 && (n-1)*incX >= len(x) {
panic("blas: x index out of range")
}
`)
return true
}
func shape(buf *bytes.Buffer, _ binding.Declaration, p binding.Parameter) bool {
switch n := binding.LowerCaseFirst(p.Name()); n {
case "m", "n", "k", "kL", "kU":
fmt.Fprintf(buf, ` if %[1]s < 0 {
panic("blas: %[1]s < 0")
}
`, n)
return false
}
return false
}
func side(buf *bytes.Buffer, _ binding.Declaration, p binding.Parameter) bool {
if p.Name() != "Side" {
return false
}
fmt.Fprint(buf, ` if s != blas.Left && s != blas.Right {
panic("blas: illegal side")
}
`)
return true
}
func sidedShape(buf *bytes.Buffer, d binding.Declaration, p binding.Parameter) bool {
var hasS, hasA, hasB, hasC bool
for _, p := range d.Parameters() {
switch shorten(binding.LowerCaseFirst(p.Name())) {
case "s":
hasS = true
case "a":
hasA = true
case "b":
hasB = true
case "c":
hasC = true
}
}
if !hasS {
return true
}
if d.CParameters[len(d.CParameters)-1] != p.Parameter {
return false // Come back later.
}
if hasA && hasB {
fmt.Fprint(buf, ` var k int
if s == blas.Left {
k = m
} else {
k = n
}
if lda*(k-1)+k > len(a) || lda < max(1, k) {
panic("blas: index of a out of range")
}
if ldb*(m-1)+n > len(b) || ldb < max(1, n) {
panic("blas: index of b out of range")
}
`)
} else {
return true
}
if hasC {
fmt.Fprint(buf, ` if ldc*(m-1)+n > len(c) || ldc < max(1, n) {
panic("blas: index of c out of range")
}
`)
}
return true
}
func trans(buf *bytes.Buffer, d binding.Declaration, p binding.Parameter) bool {
switch n := shorten(binding.LowerCaseFirst(p.Name())); n {
case "t", "tA", "tB":
switch {
case strings.HasPrefix(d.Name, "cblas_ch"), strings.HasPrefix(d.Name, "cblas_zh"):
fmt.Fprintf(buf, ` if %[1]s != blas.NoTrans && %[1]s != blas.ConjTrans {
panic("blas: illegal transpose")
}
`, n)
case strings.HasPrefix(d.Name, "cblas_cs"), strings.HasPrefix(d.Name, "cblas_zs"):
fmt.Fprintf(buf, ` if %[1]s != blas.NoTrans && %[1]s != blas.Trans {
panic("blas: illegal transpose")
}
`, n)
default:
fmt.Fprintf(buf, ` if %[1]s != blas.NoTrans && %[1]s != blas.Trans && %[1]s != blas.ConjTrans {
panic("blas: illegal transpose")
}
`, n)
}
}
return false
}
func uplo(buf *bytes.Buffer, _ binding.Declaration, p binding.Parameter) bool {
if p.Name() != "Uplo" {
return false
}
fmt.Fprint(buf, ` if ul != blas.Upper && ul != blas.Lower {
panic("blas: illegal triangle")
}
`)
return true
}
func vectorShape(buf *bytes.Buffer, d binding.Declaration, p binding.Parameter) bool {
switch d.Name {
case "cblas_sgbmv", "cblas_dgbmv", "cblas_cgbmv", "cblas_zgbmv",
"cblas_sgemv", "cblas_dgemv", "cblas_cgemv", "cblas_zgemv",
"cblas_sscal", "cblas_dscal", "cblas_cscal", "cblas_zscal", "cblas_csscal",
"cblas_isamax", "cblas_idamax", "cblas_icamax", "cblas_izamax",
"cblas_snrm2", "cblas_dnrm2", "cblas_scnrm2", "cblas_dznrm2",
"cblas_sasum", "cblas_dasum", "cblas_scasum", "cblas_dzasum":
return true
}
var hasN, hasM, hasIncX, hasIncY bool
for _, p := range d.Parameters() {
switch shorten(binding.LowerCaseFirst(p.Name())) {
case "n":
hasN = true
case "m":
hasM = true
case "incX":
hasIncX = true
case "incY":
hasIncY = true
}
}
if !hasN && !hasM {
return true
}
if d.CParameters[len(d.CParameters)-1] != p.Parameter {
return false // Come back later.
}
var label string
if hasM {
label = "m"
} else {
label = "n"
}
if hasIncX {
fmt.Fprintf(buf, ` if (incX > 0 && (%[1]s-1)*incX >= len(x)) || (incX < 0 && (1-%[1]s)*incX >= len(x)) {
panic("blas: x index out of range")
}
`, label)
}
if hasIncY {
fmt.Fprint(buf, ` if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
panic("blas: y index out of range")
}
`)
}
return true
}
func zeroInc(buf *bytes.Buffer, _ binding.Declaration, p binding.Parameter) bool {
switch n := binding.LowerCaseFirst(p.Name()); n {
case "incX":
fmt.Fprintf(buf, ` if incX == 0 {
panic("blas: zero x index increment")
}
`)
case "incY":
fmt.Fprintf(buf, ` if incY == 0 {
panic("blas: zero y index increment")
}
`)
return true
}
return false
}
func othersShape(buf *bytes.Buffer, d binding.Declaration, p binding.Parameter) bool {
switch d.Name {
case "cblas_sgemm", "cblas_dgemm", "cblas_cgemm", "cblas_zgemm",
"cblas_ssyrk", "cblas_dsyrk", "cblas_csyrk", "cblas_zsyrk",
"cblas_ssyr2k", "cblas_dsyr2k", "cblas_csyr2k", "cblas_zsyr2k",
"cblas_cherk", "cblas_zherk", "cblas_cher2k", "cblas_zher2k":
return true
}
has := make(map[string]bool)
for _, p := range d.Parameters() {
has[shorten(binding.LowerCaseFirst(p.Name()))] = true
}
if !has["a"] || has["s"] {
return true
}
if d.CParameters[len(d.CParameters)-1] != p.Parameter {
return false // Come back later.
}
switch {
case has["kL"] && has["kU"]:
fmt.Fprintf(buf, ` if lda*(m-1)+kL+kU+1 > len(a) || lda < kL+kU+1 {
panic("blas: index of a out of range")
}
`)
case has["m"]:
fmt.Fprintf(buf, ` if lda*(m-1)+n > len(a) || lda < max(1, n) {
panic("blas: index of a out of range")
}
`)
case has["k"]:
fmt.Fprintf(buf, ` if lda*(n-1)+k+1 > len(a) || lda < k+1 {
panic("blas: index of a out of range")
}
`)
default:
fmt.Fprintf(buf, ` if lda*(n-1)+n > len(a) || lda < max(1, n) {
panic("blas: index of a out of range")
}
`)
}
return true
}
const handwritten = `// Do not manually edit this file. It was created by the generate_blas.go from {{.}}.
// Copyright ©2014 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cgo
/*
#cgo CFLAGS: -g -O2
#include "{{.}}"
*/
import "C"
import (
"unsafe"
"github.com/gonum/blas"
)
// Type check assertions:
var (
_ blas.Float32 = Implementation{}
_ blas.Float64 = Implementation{}
_ blas.Complex64 = Implementation{}
_ blas.Complex128 = Implementation{}
)
// Type order is used to specify the matrix storage format. We still interact with
// an API that allows client calls to specify order, so this is here to document that fact.
type order int
const (
rowMajor order = 101 + iota
)
func max(a, b int) int {
if a > b {
return a
}
return b
}
type Implementation struct{}
// Special cases...
type srotmParams struct {
flag float32
h [4]float32
}
type drotmParams struct {
flag float64
h [4]float64
}
func (Implementation) Srotg(a float32, b float32) (c float32, s float32, r float32, z float32) {
C.cblas_srotg((*C.float)(&a), (*C.float)(&b), (*C.float)(&c), (*C.float)(&s))
return c, s, a, b
}
func (Implementation) Srotmg(d1 float32, d2 float32, b1 float32, b2 float32) (p blas.SrotmParams, rd1 float32, rd2 float32, rb1 float32) {
var pi srotmParams
C.cblas_srotmg((*C.float)(&d1), (*C.float)(&d2), (*C.float)(&b1), C.float(b2), (*C.float)(unsafe.Pointer(&pi)))
return blas.SrotmParams{Flag: blas.Flag(pi.flag), H: pi.h}, d1, d2, b1
}
func (Implementation) Srotm(n int, x []float32, incX int, y []float32, incY int, p blas.SrotmParams) {
if n < 0 {
panic("blas: n < 0")
}
if incX == 0 {
panic("blas: zero x index increment")
}
if incY == 0 {
panic("blas: zero y index increment")
}
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
panic("blas: x index out of range")
}
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
panic("blas: y index out of range")
}
if p.Flag < blas.Identity || p.Flag > blas.Diagonal {
panic("blas: illegal blas.Flag value")
}
if n == 0 {
return
}
pi := srotmParams{
flag: float32(p.Flag),
h: p.H,
}
C.cblas_srotm(C.int(n), (*C.float)(&x[0]), C.int(incX), (*C.float)(&y[0]), C.int(incY), (*C.float)(unsafe.Pointer(&pi)))
}
func (Implementation) Drotg(a float64, b float64) (c float64, s float64, r float64, z float64) {
C.cblas_drotg((*C.double)(&a), (*C.double)(&b), (*C.double)(&c), (*C.double)(&s))
return c, s, a, b
}
func (Implementation) Drotmg(d1 float64, d2 float64, b1 float64, b2 float64) (p blas.DrotmParams, rd1 float64, rd2 float64, rb1 float64) {
var pi drotmParams
C.cblas_drotmg((*C.double)(&d1), (*C.double)(&d2), (*C.double)(&b1), C.double(b2), (*C.double)(unsafe.Pointer(&pi)))
return blas.DrotmParams{Flag: blas.Flag(pi.flag), H: pi.h}, d1, d2, b1
}
func (Implementation) Drotm(n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams) {
if n < 0 {
panic("blas: n < 0")
}
if incX == 0 {
panic("blas: zero x index increment")
}
if incY == 0 {
panic("blas: zero y index increment")
}
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
panic("blas: x index out of range")
}
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
panic("blas: y index out of range")
}
if p.Flag < blas.Identity || p.Flag > blas.Diagonal {
panic("blas: illegal blas.Flag value")
}
if n == 0 {
return
}
pi := drotmParams{
flag: float64(p.Flag),
h: p.H,
}
C.cblas_drotm(C.int(n), (*C.double)(&x[0]), C.int(incX), (*C.double)(&y[0]), C.int(incY), (*C.double)(unsafe.Pointer(&pi)))
}
func (Implementation) Cdotu(n int, x []complex64, incX int, y []complex64, incY int) (dotu complex64) {
if n < 0 {
panic("blas: n < 0")
}
if incX == 0 {
panic("blas: zero x index increment")
}
if incY == 0 {
panic("blas: zero y index increment")
}
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
panic("blas: x index out of range")
}
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
panic("blas: y index out of range")
}
if n == 0 {
return 0
}
C.cblas_cdotu_sub(C.int(n), unsafe.Pointer(&x[0]), C.int(incX), unsafe.Pointer(&y[0]), C.int(incY), unsafe.Pointer(&dotu))
return dotu
}
func (Implementation) Cdotc(n int, x []complex64, incX int, y []complex64, incY int) (dotc complex64) {
if n < 0 {
panic("blas: n < 0")
}
if incX == 0 {
panic("blas: zero x index increment")
}
if incY == 0 {
panic("blas: zero y index increment")
}
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
panic("blas: x index out of range")
}
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
panic("blas: y index out of range")
}
if n == 0 {
return 0
}
C.cblas_cdotc_sub(C.int(n), unsafe.Pointer(&x[0]), C.int(incX), unsafe.Pointer(&y[0]), C.int(incY), unsafe.Pointer(&dotc))
return dotc
}
func (Implementation) Zdotu(n int, x []complex128, incX int, y []complex128, incY int) (dotu complex128) {
if n < 0 {
panic("blas: n < 0")
}
if incX == 0 {
panic("blas: zero x index increment")
}
if incY == 0 {
panic("blas: zero y index increment")
}
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
panic("blas: x index out of range")
}
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
panic("blas: y index out of range")
}
if n == 0 {
return 0
}
C.cblas_zdotu_sub(C.int(n), unsafe.Pointer(&x[0]), C.int(incX), unsafe.Pointer(&y[0]), C.int(incY), unsafe.Pointer(&dotu))
return dotu
}
func (Implementation) Zdotc(n int, x []complex128, incX int, y []complex128, incY int) (dotc complex128) {
if n < 0 {
panic("blas: n < 0")
}
if incX == 0 {
panic("blas: zero x index increment")
}
if incY == 0 {
panic("blas: zero y index increment")
}
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
panic("blas: x index out of range")
}
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
panic("blas: y index out of range")
}
if n == 0 {
return 0
}
C.cblas_zdotc_sub(C.int(n), unsafe.Pointer(&x[0]), C.int(incX), unsafe.Pointer(&y[0]), C.int(incY), unsafe.Pointer(&dotc))
return dotc
}
// Generated cases ...
`