Edited at

gonumでopenblasを使うメモ

goやdepは適当に入れておくとする


blas

macの場合は以下。OpenBLAS以外でも、MKL、Atlasでも良さそう。試してはいない。

brew install openblas

これで、/usr/local/opt/openblas/以下にヘッダとライブラリが入る


ビルドするとき

gonumの取得は普通にdep ensureとかすれば良い。depなどを使わない場合は、gonumを入れた上で、ドキュメントの通り、gonum/netlibパッケージをCGO_LDFLAGを指定してgo installする。

CGO_LDFLAGS="-L/usr/local/opt/openblas/lib -lopenblas" go install gonum.org/v1/netlib/blas/netlib

CGO_LDFLAGS="-L/usr/local/opt/openblas/lib -lopenblas" go install gonum.org/v1/netlib/lapack/netlib

gonumの行列・ベクトル計算をOpenBLASを利用するようにする場合は、以下のような設定が必要

import(

"gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/netlib/blas/netlib"
)

func init(){
blas64.Use(netlib.Implementation{})
}

ここではinitに書いているが、プログラムの初期化時に一度呼び出されるように書いておけばどこでも良さそう。

go installした場合はいらないと思うが、depに入れた場合は、go buildgo testをする場合にはCGO_LDFLAGSにblasのパスを指定して実行しなければリンクエラーになる。direnvなどに書いておこう。


適当なベンチマークコード

10万*100の行列と100次元のベクトルの行列ベクトル積をスッと計算してみる。基本行列を作るほうが重いので、initでfillしている。

package main

import (
"math/rand"
"testing"

"gonum.org/v1/gonum/blas/blas64"
"gonum.org/v1/gonum/mat"
"gonum.org/v1/netlib/blas/netlib"
)

var (
m *mat.Dense
v *mat.VecDense
)

func init() {
blas64.Use(netlib.Implementation{})
m = makeRandMat(100000, 100)
v = makeRandVec(100)
}

func makeRandMat(row, col int) *mat.Dense {
data := make([]float64, row*col)
for i := range data {
data[i] = rand.NormFloat64()
}
return mat.NewDense(row, col, data)
}

func makeRandVec(num int) *mat.VecDense {
data := make([]float64, num)
for i := range data {
data[i] = rand.NormFloat64()
}
return mat.NewVecDense(num, data)
}

func BenchmarkMatVecDot(b *testing.B) {
res := mat.NewVecDense(100000, nil)
for i := 0; i < b.N; i++ {
res.MulVec(m, v)
}

}

blas64.Use(netlib.Implementation{}) をコメントアウトした場合としなかった場合でだいたい50%弱高速化している。まぁbrewで適当に入れたOpenBLASとの比較ならこんなものな気はする。というかgonumのデフォルトgo実装もそれなりに早いのね。

MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)

プロセッサ: 3.5GHz Intel Corei7


blas64.Use(netlib.Implementation{})あるとき

goos: darwin

goarch: amd64
pkg: hoge
BenchmarkMatVecDot-4 300 4018419 ns/op
PASS


blas64.Use(netlib.Implementation{})ないとき

goos: darwin

goarch: amd64
pkg: hoge
BenchmarkMatVecDot-4 200 7239200 ns/op
PASS