洋食の日記

「だ・である」調ではなく「です・ます」調で書きはじめれば良かったなと後悔してる人のブログです

インストール時にOpenBLASをビルドしてNumo::Linalgのバックグラウンドライブラリに使用するGemを作成した

はじめに

Numo::OpenBLASという、タイトルのとおりのものを作成した。

numo-openblas | RubyGems.org | your community gem host

使い方

Gemコマンドでインストールできる。このとき、OpenBLASをダウンロードしてビルドする。

$ gem install numo-openblas

使用方法はrequireするのみで、Numo::NArrayとNumo::Linalgもrequireされる。

require 'numo/openblas'

x = Numo::DFloat.new(5, 2).rand
c = x.transpose.dot(x)
eig_val, eig_vec = Numo::Linalg.eigh(c)

作った理由

Numo::Linalgでは、バックグラウンドライブラリのBLAS/LAPACKを選択することができる。しかし、この設定を間違うと、ライブラリを読み込めず失敗する。これに対して、以前、Autoloaderというものを作成した。これは、/usr/local/libなど、BLAS/LAPACKがいそうなディレクトリを探して、バックグラウンドライブラリとして設定する。OpenBLASをインストールしてある場合、だいたいが、これでうまくいくが、パッケージシステムによって、OpenBLASのビルドオプションが異なるという問題がある。OpenBLASはビルド時のオプションで、純粋にBLASAPIだけを提供するようにできる。これでビルドされた場合、Numo::Linalgのバックエンドライブラリとしては、OpenBLASの他にLAPACKも必要となる。このあたりどうなっているかを、利用者は把握しておく必要がある。また、Autoloaderは、実行速度のために、当たりをつけて検索しているので、ライブラリを見つけられないこともある。

対策法

上記のバックエンドライブラリの問題に対して、Gemのインストール時に、OpenBLASのダウンロードとビルドを行い、それをバックエンドライブラリとしてNumo::Linalgをロードすることにした。いまのところ、Rubyがインストールできたなら、OpenBLASをビルドできるであろう(gccとかなにかしらあるだろう)と想定している。

終わりに

Pythonのnumpyは、Anacondaのサーバーに各種プラットフォームでビルドされたOpenBLASがある。これをダウンロードすることも考えたがやめた。Rubyのデータ分析・機械学習が広まって、一定のコミュニティが形成された後に、Numo::Linalg用として提供されるのが理想かなと思った。また、OpenBLASは、CPUにあわせてビルドを行う。利用者の環境でビルドしたほうが、本来のパフォーマンスが出せるのではないかと思った。もろもろいい感じにしたDocker Imageを用意すれば良いんだろうけど、pip install numpy みたいな感じで、Numo::NArrayとNumo::Linalgをgemコマンドからインストールして、サクッと使いたかった(OpenBLASのビルドに時間がかかるけど...)。

github.com