はじめに
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はビルド時のオプションで、純粋にBLASのAPIだけを提供するようにできる。これでビルドされた場合、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のビルドに時間がかかるけど...)。