Python
scipy
numpy
mkl

pip で MKL にリンクされた numpy, scipy が自動的にインストールされるようにする

先日「conda は Python から openssl から何から何までインストールしてそのくせ conda だけで済むまでに自己完結してないから OS と pip の二重管理を os と conda と pip の三重管理地獄に変えて嫌い、virtualenv-wrapper があれば十分」と同僚に話したところ、「pip で numpy を入れると OpenBLAS にリンクされたものが入って、conda で入る MKL にリンクされたものより遅い」と言われました。自動コンパイルしましょう。

Linux を対象としていますが、OS X や Windows などでも同じことは可能なはずです。

基本的には unnounnoさんの投稿 と同じで、それに追加で pip.conf を書いて numpy, scipy のバイナリパッケージを無効化するだけです。

MKL のインストール

https://software.intel.com/en-us/mkl から "Free Download" をクリック、適当にメールアドレスなどを入力して l_mkl_2018.0.128.tgz(投稿時の最新版)をダウンロードします。これを展開して ./install.sh を実行すると、標準では /opt/intel 以下に MKL がインストールされます。以前はレジストレーションキーなどが求められたようですが、今は不要です。

export LD_LIBRARY_PATH="/opt/intel/mkl/lib/intel64:/opt/intel/lib/intel64:$LD_LIBRARY_PATH"

.zprofile なり .bash_profile なり(あるいは必要なら /etc/profile.d 以下なり /etc/ld.so.conf.d 以下なり)に書いて、LD_LIBRARY_PATH を通します。

numpy と scipy のビルド設定

numpy と scipy はビルド時に ~/.numpy-site.cfg を読みに行きます。そこに以下のように書くと MKL にリンクするよう設定されます。

[mkl]
library_dirs = /opt/intel/mkl/lib/intel64
include_dirs = /opt/intel/mkl/include
mkl_libs = mkl_rt
lapack_libs =

pip の設定

上記の設定だけでは pip で numpy や scipy をインストールしたときにバイナリパッケージが自動的に選択されてしまいます。肝要なのは、numpy, scipy に限りバイナリパッケージを無効化することです。

これは ~/.config/pip/pip.conf (あるいは XDG_CONFIG_HOME を設定している場合 "$XDG_CONFIG_HOME/pip/pip.conf")に以下の記述をすることで実現されます。

[install]
no-binary = numpy,scipy

[wheel]
no-binary = numpy,scipy

この設定が意味するのは、「pip install あるいは pip wheel 時に自動的に --no-binary numpy,scipy オプションを付けなさい」ということです。こうすると、numpy と scipy のインストール時に限りバイナリパッケージを無効化し、毎回手元でコンパイルさせるようにすることができます。

制限

この設定だとコンパイル済みの numpy, scipy はキャッシュされず、インストールする度にコンパイルされることになります。numpy のコンパイルは一分しないくらいなので大して困らないですが、scipy は五分くらい待たされるので人によってはストレスになります。

ワークアラウンドとして、pip wheel scipy をして scipy のコンパイル済み wheel を手元で作っておくことができます。scipy のインストールが必要な場合、pip install scipy-0.19.1-cp36-cp36m-linux_x86_64.whl(ファイル名は OS やバージョンなどにより変わります)とすれば手元でコンパイルされたパッケージがすぐに入ります。

余談

conda 嫌いと言いつつも、わたし自身 conda を使うプロジェクトでの開発もしているので使わざるを得ないです。conda の bin をログイン時には PATH に入れずに、 .zshrc

alias yanaconda="source $HOME/miniconda3/bin/activate"

と書いて yanaconda を実行することで明示的に conda の世界に遷移するようにすることで快適になりました。