洋食の日記

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

Numo::OpenBLASでOpenBLASのダウンロードとビルドのタイミングを変えた

はじめに

Numo::OpenBLASで、インストール時のOpenBLASのダウンロードとビルドを、native extensionの作成時に行うようにして、version 0.2.0 としてリリースした。

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)

また、本 version から、OpenBLASのビルドオプションの一部が確認できるようになった。

> require 'numo/openblas'
=> true
> Numo::OpenBLAS::OPENBLAS_VERSION
=> " OpenBLAS 0.3.10 "
> Numo::OpenBLAS::OPENBLAS_CHAR_CORENAME
=> "HASWELL"
> Numo::OpenBLAS::OPENBLAS_NUM_CORES
=> 8

RubyGemsのhooks

前バージョンまでは、RubyGemsのpost_install hookを使って、インストール時のOpenBLASのダウンロードとビルドを行っていた。このRubyGemsのhooksが、動かないことがあるという話があり、自分でも体験したので、どうしたものかな〜と思っていた。また一方、別の話で、OpenBLASのビルド時に自動設定されるオプション(CPUの名前とかコア数とか)が、openblas_config.hに書かれるので、これを参照できないかな〜と思っていた。

この2つを解決するために、native extensionを導入することにした。native extensionをビルドする際に、OpenBLASのダウンロードとビルドを行うようにした(Makefileを作成するextconf.rbにpost_install hookに書いていたものを移植した)。native extensionのビルドは確実に動くので、いい感じになったと思う。ただし、使う側としては「native extensionのビルドがスゴイ重い!!」みたいに見えるようになった。

おわりに

numpyでも、pipでインストールするかcondaでインストールするかで、バックエンドライブラリが違うとかあって、線形代数ライブラリにとって、BLAS/LAPACKをどう使うかは永遠の課題なんだろうなと思う。

github.com