Abstract
- AnacondaのnumpyはBLAS/LAPACKとしてintel-MKLを使っていて速いらしい
- PIPでnumpyにインストールする際にintel-MKLを指定してビルドすれば同様に速くなるらしい
- Ubuntuの公式リポジトリにinte-MKLが追加されていたのでこれを用いたインストレーションをまとめた
動作確認環境: Ubuntu 20.04
on WSL2
on Windows10 20H2
1. intel MKLを公式リポジトリからインストール(ライセンス注意).なんか選択するとこ出たらデフォルトでok
sudo apt update
sudo apt install intel-mkl
2. 以下のファイルをホームディレクトリ~
に作る.
[mkl]
library_dirs = /usr/lib/x86_64-linux-gnu/
include_dirs = /usr/include/mkl
mkl_libs = mkl_rt
lapack_libs =
3. 以下のファイルを~/.config/pip/
に作る
[install]
no-binary = numpy,scipy
4. ユーザ権限のpipでインストールする.(sudoにしない)
python3 -m pip install numpy
# Defaulting to user installation because normal site-packages is not writeable
# ていわれるけどそれでよい.結局--userオプションつけるのと同じになる(はず)
5. pythonで確認.librariesがmkl_rt
になってればよし.
python3 -c "import numpy; numpy.show_config()"
blas_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/usr/lib/x86_64-linux-gnu/']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/usr/include/mkl']
blas_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/usr/lib/x86_64-linux-gnu/']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/usr/include/mkl']
lapack_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/usr/lib/x86_64-linux-gnu/']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/usr/include/mkl']
lapack_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/usr/lib/x86_64-linux-gnu/']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/usr/include/mkl']
#Background
Pythonの計算ライブラリであるnumpyが依存している計算ライブラリBLAS/LAPPACKには複数の実装有り 1.
そのうちintelがintelのCPU用に最適化したintel-MKLという実装がintel系のアーキテクチャで速いらしい 1, 2, 3.
普通にpip
でnumpy
をインストールするとOpenBLASと呼ばれる実装がインストールされる 4, 5.
一方でANACONDAというPythonディストリビューションをインストールすると,
それについてくるnumpy
のBLASの実装はintel-MKLになっているらしい 2.
このAnacondaはPython本体と周りのライブラリとかを一括して提供する
PythonディストリビューションでもともとはWindows向けの簡単なPython導入環境であった.
ただ,これをLinuxでインストールしようとすると,いちいちWebサイトを開いて,
パッケージをDLしてインストール・コンフィギュレーションしなければいけないっぽく,
またPIPとは別にライブラリ管理をしており,
且つAnacondaですべてのライブラリを網羅しているわけではないらしく,
パッケージ管理周りが大変になりがち 6.
もう少し調べてみると,ちょっと工夫すればpip
でもintel-mkl
実装のnumpy
がインストールできるらしいことを知った 1, 7, 8.
少し古い参考ではintel MKL
のインストールがちょっと複雑であったが,
新しめ(すくなくとも20.04以降)のUbuntuでは公式リポジトリにintel-mkl
がありシンプルになった.
ただそのぶん過去のインストレーション方法に記述の設定を丸コピしてもうまくいかず,
パッケージ管理の仕様もよく分からなかったため,
またわりとあんまり文献がなかったため,備忘録の意味も込めて記事にした.
Details of Installations
Intel-MKLのインストール
普通にapt install
できるのでそれを使う 9.一応アップデートしておく.
sudo apt update
sudo apt install intel-mkl
初回インストール時はライセンスの確認 10やリンクの確認がある.
リンクの確認についてはデフォルトのままでok.多分.一応画面の説明に従ってください.
IntelからパッケージをDLしてパッケージ登録して~とかする場合は
update-alternative
設定やlpconfig
設定が必要 11, 12だったが,
前者はaptでインストールするときに半自動でやってくれるし,
後者は公式リポジトリなので一切不要
ライブラリのインストールフォルダの確認
さて,インストールフォルダを確認しようとdpkg -L intel-mkl
としても
ドキュメントしかインストールされてないように見える.
しかし実際の実装は依存している別のパッケージによって管理されている.
apt-cache depends intel-mkl
intel-mkl
Depends: libmkl-dev
よって今度はlibmkl-dev
のインストールディレクトリを確認するとヘッダファイル(.h
)やライブラリファイル(.so
)がみえる.
> dpkg -L libmkl-dev
...
# header files
/usr/include/mkl/mkl.h
/usr/include/mkl/mkl_blacs.h
/usr/include/mkl/mkl_blas.f90
/usr/include/mkl/mkl_blas.fi
/usr/include/mkl/mkl_blas.h
/usr/include/mkl/mkl_cblas.h
/usr/include/mkl/mkl_cdft.f90
/usr/include/mkl/mkl_cdft.h
/usr/include/mkl/mkl_cdft_types.h
...
# library files. but actually these are just symbolic links
/usr/lib/x86_64-linux-gnu/mkl/libblas.so
/usr/lib/x86_64-linux-gnu/mkl/libblas64.so
/usr/lib/x86_64-linux-gnu/mkl/liblapack.so
/usr/lib/x86_64-linux-gnu/mkl/liblapack64.so
...
しかしじつはこの.so
ファイルはファイルではなくシンボリックリングになっており,
すべて,一個上の親dirにあるlibmkl_rt.so
にリンクされている.
ちなみに以下/lib
となっているのはすべて/usr/lib
に同じ.というのも歴史的な互換性のためにシンボリックリンクになっている 13.
ls /lib/x86_64-linux-gnu/mkl/* -l
lrwxrwxrwx 1 root root 15 Feb 17 2020 /lib/x86_64-linux-gnu/mkl/libblas.so -> ../libmkl_rt.so
lrwxrwxrwx 1 root root 15 Feb 17 2020 /lib/x86_64-linux-gnu/mkl/libblas.so.3 -> ../libmkl_rt.so
lrwxrwxrwx 1 root root 15 Feb 17 2020 /lib/x86_64-linux-gnu/mkl/libblas64.so -> ../libmkl_rt.so
lrwxrwxrwx 1 root root 15 Feb 17 2020 /lib/x86_64-linux-gnu/mkl/libblas64.so.3 -> ../libmkl_rt.so
lrwxrwxrwx 1 root root 15 Feb 17 2020 /lib/x86_64-linux-gnu/mkl/liblapack.so -> ../libmkl_rt.so
lrwxrwxrwx 1 root root 15 Feb 17 2020 /lib/x86_64-linux-gnu/mkl/liblapack.so.3 -> ../libmkl_rt.so
lrwxrwxrwx 1 root root 15 Feb 17 2020 /lib/x86_64-linux-gnu/mkl/liblapack64.so -> ../libmkl_rt.so
lrwxrwxrwx 1 root root 15 Feb 17 2020 /lib/x86_64-linux-gnu/mkl/liblapack64.so.3 -> ../libmkl_rt.so
つまりBLAS/LAPACKはどちらも一個のファイルにまとめられている.
ほかの実装だとたぶん異なる.
そしてこの/lib/x86_64-linux-gnu/libmkl_rt.so
こそがライブラリの実態である.
ls /lib/x86_64-linux-gnu/libmkl_rt.so -l
-rw-r--r-- 1 root root 6581530 Nov 23 2019 /lib/x86_64-linux-gnu/libmkl_rt.so
しかし,この/lib/x86_64-linux-gnu/libmkl_rt.so
というのは先ほどのlibmkl-dev
パッケージには含まれていなかった.
そこでまたlibmkl-dev
パッケージの依存関係を調べてみると
apt-cache depends libmkl-dev
libmkl-dev
|Depends: debconf
Depends: <debconf-2.0>
cdebconf
debconf
Depends: libmkl-rt
...
Depends: pkg-config
pkgconf
...
とのことで,いろいろ表示されたがDepends: libmkl-rt
とまさにドンピシャなパッケージ名が見えたので,
これのインストール先を調べてみると,
dpkg -L libmkl-rt
/.
/usr
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libmkl_rt.so #<-----------これがメインのものと思われる.
/usr/lib/x86_64-linux-gnu/mkl
/usr/share
/usr/share/doc
/usr/share/doc/libmkl-rt
/usr/share/doc/libmkl-rt/copyright
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/libmkl-rt
/usr/lib/x86_64-linux-gnu/mkl/libblas.so.3 #<---ここから4つはlibmkl-devのものと似ているが,微妙に拡張子が違う.
/usr/lib/x86_64-linux-gnu/mkl/libblas64.so.3 # が,同様に上のlibmkl_rt.soを指している
/usr/lib/x86_64-linux-gnu/mkl/liblapack.so.3
/usr/lib/x86_64-linux-gnu/mkl/liblapack64.so.3 #<---ここまで
/usr/share/doc/libmkl-rt/changelog.Debian.gz
numpyをintel-mklをつかってビルドするための設定
以上で知りえた情報をもとにpip
君に
- もともとビルドしてあるバイナリを使わずに
- intel-mklを使って新たにnumpyビルドして
とオーダーするための設定ファイルを書く.
以下のファイルを~/.config/pip/
に作る,
これはnumpy
とscipy
のインストールにおいてはもともとビルドしてあるやつは使わんといてという注文書になる.
このファイルを作らなくてもpip install
じに--no-binary
オプションをつけるのとまったく同じ.
[install]
no-binary = numpy,scipy
以下のファイルをホームディレクトリ~
に作る.
ここで先ほどの情報を用いる.
-
library_dirs
に代入するのはlibmkl_rt.so
が存在するディレクトリ,(libblas.so
とかではない!) -
include_dirs
に代入するのはヘッダファイルが存在しているディレクトリである.
意外とこの情報が手に取りづらく,そもそもaptやpipの仕組みも全然わかってなかったので苦戦した.
[mkl]
library_dirs = /usr/lib/x86_64-linux-gnu/
include_dirs = /usr/include/mkl
mkl_libs = mkl_rt
lapack_libs =
lapack_libs
が空欄なのは多分LAPACKもBLASとおなじファイルに含められているから.
numpyインストール
ユーザ権限のpipでインストールする.(sudoにしない)
python3 -m pip install numpy
# Defaulting to user installation because normal site-packages is not writeable
# ていわれるけどそれでよい.結局--userオプションつけるのと同じになる(はず)
以上でインストールは完了のはず.
numpy実装の内容確認
ほんとにintel MKLでnumpyが入ってるかをpythonで確認.librariesがmkl_rt
になってればよし.
python3 -c "import numpy; numpy.show_config()"
blas_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/usr/lib/x86_64-linux-gnu/']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/usr/include/mkl']
blas_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/usr/lib/x86_64-linux-gnu/']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/usr/include/mkl']
lapack_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/usr/lib/x86_64-linux-gnu/']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/usr/include/mkl']
lapack_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/usr/lib/x86_64-linux-gnu/']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/usr/include/mkl']
Conclusion
苦戦したけどできてしまえばとても簡単.
-
AMDのCPUでも速いらしいので「アーキテクチャで」と書いたがにわか知識 ↩
-
Ubuntu 16.04 上で numpy の環境構築をする > apt (default);2018-06-12; ↩
-
頻繁に使う人は慣れて間違いづらいかもしれないが,忘れたころにまた使うということになりがちな人にとっては,ライブラリ管理が少しでも複雑なのは嫌. ↩
-
ライセンスに関しては各自の責任において確認してください. ↩
-
ldconfig関連の操作は今回は必要ないです.参考サイト等ではデフォルトでないディレクトリ,ホームやオプショナルにインストールしているため,その管理をシステムに伝える必要がありました.が今回はUbuntu公式リポジトリで管理されているので,デフォルトのライブラリディレクトリ
/lib ==> /usr/lib
にインストーられます.「/lib」「/usr/lib」ディレクトリとライブラリ ↩