gonum/blas

blas: improve install instructions

Closed this issue · 12 comments

This program will not compile without gonum/internal, with it, it compiles and runs fine.
Quick search showed that gonum/internal is only used in the native implementation so I assumed I would not require it.

package main

import (
    "fmt"
    "github.com/gonum/blas/cgo"
    "github.com/gonum/blas/blas64"
)

func main() {
    blas64.Use(cgo.Implementation{})
    v := blas64.Vector{Inc: 1, Data: []float64{1, 1, 1}}
    fmt.Println("v has length:", blas64.Nrm2(len(v.Data), v))
}
[[~]]$ go build ann
src/github.com/gonum/blas/native/dgemm.go:12:2: cannot find package "github.com/gonum/internal/asm" in any of:
    /usr/lib/go/src/github.com/gonum/internal/asm (from $GOROOT)
    [$GOPATH]/src/github.com/gonum/internal/asm (from $GOPATH)

If it is not possible to remove gonum/internal it should be documented under the README.md

Can you explain how you got your system into a state where github.com/gonum/internal does not exist and github.com/gonum/blas64 does?

The reason internal/asm is required is that blas64 uses blas/native by default, so there is a transitive import of internal/asm. This is not something that we are going to change because the way that it is set up at the moment means that it just works out of the box (if you have used go get to install the user facing packages).

Can you explain why the current set up is actually a problem for you? Why is it a problem that internal/asm exists on your system?

As per the installation instructions: go get github.com/gonum/blas
and did not import github.com/gonum/internal

I noted that it used blas/native by default, but by README.md the native is incomplete.

I prefer to not have extra packages.

I just made a new GOPATH and go get github.com/gonum/blas

[~@~ tempgo]$ ls src/github.com/gonum/ -la
total 0
drwxr-xr-x 11 ~ ~ 280 Jun 17 22:09 blas

go get --help leads me to believe that it should pull in the dependencies? Should I be running a different command?

As per the installation instructions: go get github.com/gonum/blas and did not import github.com/gonum/internal

Maybe we could adjust the README for this, though I don't think it would catch what has happened here.

I noted that it used blas/native by default, but by README.md the native is incomplete.

There is a use dependency graph that I have that describes the situation that may help.

I prefer to not have extra packages.

Why? This approach will cause you pain when working with Go.

I just made a new GOPATH and go get github.com/gonum/blas

This is the cause of your problem. If you look at the dependency graph of your program, you see (relevant edges only) ann -> blas64 -> blas. Doing go get github.com/gonum/blas gets you the blas package and its dependencies (none), and you have ann.go (or whatever it is called) already from your editor, so you have never got the blas64 package by this stage. You call go build on your package, but this does not get any dependencies that are not already there. If ann.go were in a package ann and you were in the ann directory and you did go get ., the blas64 dependency would have been resolved and downloaded correctly.

The reason behind the state of the documentation is that the README was written prior to the advent of blas64 and still, I believe, reflects a reasonable entry into the use of blas that assumes (reasonably?) some level of background with the Go toolchain.

@btracey Do you think we can improve on the docs here?

I agree that I'm a bit fresh on the Go toolchain, and assumed that getting gonum/blas would see that there was a package inside blas64 and would retrieve the dependencies for that package as well.

GOPATH=/tmp/tempgo/ go get github.com/gonum/blas/blas64
retrieved the internal package as suggested.

I'll review the Go toolchain, thanks for the assistance. Feel free to close.

The other alternative is to go get somepackage/... which does a go get for all packages under somepackage/, but this breaks your need to install minimal extra packages.

I'll leave this open for a bit to see if we can improve the docs here.

I agree that it's unfortunate, and indeed this particular aspect confused me at first too (go get sees the package as a path and it's dependencies, but it also downloads repositories at a time, so you get 'extra' packages without their dependencies). The behavior of the go tool is not under our control, so that can't be fixed. blas64 has to import native to have a default implementation, and native needs internal for speed. So I don't see a way to fix the dependency chain.

The last thing available to change is the documentation, but again I don't see what we can do. It's true you need to download internal to use blas64, but you also need to have internal to call distuv.Normal{} (distuv --> stat --> mat64 --> blas64 --> native --> internal). I'm not sure what documentation what would be useful aside from "if you need package foo/bar, say go get foo/bar and not go get foo", which is generic advice across the go ecosystem.

I'm not trying to be dismissive, I'm just not sure what we can do aside from write our own documentation of the go command.

The thing I'm thinking is that we de-prioritise blas installation in the README. This would either be removing the install instructions (not preferred) or adding install instructions for at least blas64 with brief qualifications for each explaining where they would be used.

Currently we are sort of lying in saying go get github.com/gonum/blas is an install command, partly because go get github.com/gonum/blas/... will fall for the majority of users (those that have not previously set up OpenBLAS or another C BLAS library and the CGO_LDFLAGS), and so leave a bad user experience.

@kortschak

The other alternative is to go get somepackage/...

This is what I was looking for actually, found out today and glad you brought it up.

Oh, I see the problem. I had only been reading godoc and not the github documentation. Yes, we should do better.

Please provide step by step guide,i am facing this issue
screenshot from 2017-05-12 15-49-23

"/path/to/OpenBLAS" is not the actual text, you need to swap that with the path to where you installed OpenBLAS