LoginSignup
3
6

More than 3 years have passed since last update.

Let NUMPY installed by PIP be as fast as that by ANACONDA (on Ubuntu 20.04)

Last updated at Posted at 2020-12-07

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

input
sudo apt update
sudo apt install intel-mkl

2. 以下のファイルをホームディレクトリ~に作る.

~/numpy-site.cfg
[mkl]
library_dirs = /usr/lib/x86_64-linux-gnu/
include_dirs = /usr/include/mkl
mkl_libs = mkl_rt
lapack_libs =

3. 以下のファイルを~/.config/pip/に作る

~/.config/pip/pip.conf
[install]
no-binary = numpy,scipy

4. ユーザ権限のpipでインストールする.(sudoにしない)

input
python3 -m pip install numpy
# Defaulting to user installation because normal site-packages is not writeable
# ていわれるけどそれでよい.結局--userオプションつけるのと同じになる(はず)

5. pythonで確認.librariesがmkl_rtになってればよし.

input
python3 -c "import numpy; numpy.show_config()"
output
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

普通にpipnumpyをインストールすると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.一応アップデートしておく.

input
sudo apt update
sudo apt install intel-mkl

初回インストール時はライセンスの確認 10やリンクの確認がある.
リンクの確認についてはデフォルトのままでok.多分.一応画面の説明に従ってください.

IntelからパッケージをDLしてパッケージ登録して~とかする場合は
update-alternative設定やlpconfig設定が必要 11, 12だったが,
前者はaptでインストールするときに半自動でやってくれるし,
後者は公式リポジトリなので一切不要

ライブラリのインストールフォルダの確認

さて,インストールフォルダを確認しようとdpkg -L intel-mklとしても
ドキュメントしかインストールされてないように見える.

しかし実際の実装は依存している別のパッケージによって管理されている.

input
apt-cache depends intel-mkl
output
intel-mkl
    Depends: libmkl-dev

よって今度はlibmkl-devのインストールディレクトリを確認するとヘッダファイル(.h)やライブラリファイル(.so)がみえる.

input
> dpkg -L libmkl-dev
output
...
# 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.

input
ls /lib/x86_64-linux-gnu/mkl/* -l
output
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こそがライブラリの実態である.

input
ls /lib/x86_64-linux-gnu/libmkl_rt.so -l
output
-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パッケージの依存関係を調べてみると

input
apt-cache depends libmkl-dev
output
libmkl-dev
 |Depends: debconf
  Depends: <debconf-2.0>
    cdebconf
    debconf
  Depends: libmkl-rt
...
  Depends: pkg-config
    pkgconf
...

とのことで,いろいろ表示されたがDepends: libmkl-rtとまさにドンピシャなパッケージ名が見えたので,
これのインストール先を調べてみると,

input
dpkg -L libmkl-rt
output
/.
/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/に作る,
これはnumpyscipyのインストールにおいてはもともとビルドしてあるやつは使わんといてという注文書になる.
このファイルを作らなくてもpip installじに--no-binaryオプションをつけるのとまったく同じ.

~/.config/pip/pip.conf
[install]
no-binary = numpy,scipy

以下のファイルをホームディレクトリ~に作る.
ここで先ほどの情報を用いる.

  • library_dirsに代入するのはlibmkl_rt.soが存在するディレクトリ,(libblas.soとかではない!)
  • include_dirsに代入するのはヘッダファイルが存在しているディレクトリである.

意外とこの情報が手に取りづらく,そもそもaptやpipの仕組みも全然わかってなかったので苦戦した.

~/numpy-site.cfg
[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にしない)

input
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になってればよし.

input
python3 -c "import numpy; numpy.show_config()"
output
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

苦戦したけどできてしまえばとても簡単.


  1. Ubuntu 16.04 上で numpy の環境構築をする > 概要;2018-06-12; 

  2. Anaconda の NumPy が高速みたいなので試してみた; 2020-03-27; 

  3. AMDのCPUでも速いらしいので「アーキテクチャで」と書いたがにわか知識 

  4. Ubuntu 16.04 上で numpy の環境構築をする > apt (default);2018-06-12; 

  5. numpyで MKL を使う; 2018年10月13日; numpy, scipyがMKLにリンクされているか確認 

  6. 頻繁に使う人は慣れて間違いづらいかもしれないが,忘れたころにまた使うということになりがちな人にとっては,ライブラリ管理が少しでも複雑なのは嫌. 

  7. NumPy/SciPy で Intel MKL を利用する (2019年11月版); 2019年11月13日;  

  8. numpy で MKL を使う; 2018年10月13日; 

  9. Intel MKLの各Linuxへのインストール方法; 2020年08月28日; 

  10. ライセンスに関しては各自の責任において確認してください. 

  11. Ubuntu 16.04 上で numpy の環境構築をする > apt (mkl);2018-06-12; 

  12. ldconfig関連の操作は今回は必要ないです.参考サイト等ではデフォルトでないディレクトリ,ホームやオプショナルにインストールしているため,その管理をシステムに伝える必要がありました.が今回はUbuntu公式リポジトリで管理されているので,デフォルトのライブラリディレクトリ/lib ==> /usr/libにインストーられます.「/lib」「/usr/lib」ディレクトリとライブラリ 

  13. Linuxのディレクトリについて; 2016年10月12日に更新; 

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6