先日「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 の世界に遷移するようにすることで快適になりました。