pip install deeplearning

こちらもどうぞ。http://monthly-hack.com

macでmkl&numpyを構築したかった

numpyの計算を裏でサポートしてくれるmklを導入してみました. ネット上にmacでの導入例が少なく, 調べたり試行錯誤にかなり時間を費やしたので, 報告. mkl&numpyの構築には2つの方法があり, 片方はとても怪しい方法です. そして結論を言ってしまうと構築できていません.

構築できました(追記: 1/30)
pip-install-deeplearning.hatenadiary.jp

numpyを重ねる

pipでnumpyをインストールをした状態で, numpyソースコードのsetup.pyを動かす怪しい荒技です. numpyが重なっている?共存している状態になります. なぜこんなことをするのかも後ほど.

まずIntel MKLを入手します. 以下のサイトから'click here now to register and download'から必要事項を入力してダウンロード, インストールをします.
No Cost Options for Intel Math Kernel Library (MKL), Support Yourself, Royalty-Free | Intel® Developer Zone

次にnumpyのソースコードを入手します(執筆時はv1.10.4). 次のどちらかのサイトからダウンロードできます.
Numerical Python - Browse Files at SourceForge.net
Release v1.10.4 · numpy/numpy · GitHub

ではまずは初期状態を確認します. numpyをインストールしてどのライブラリを使っているか確認します.

pip install numpy
python -c'import numpy; numpy.show_config()'

lapack_opt_info:
    extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
    extra_compile_args = ['-msse3']
    define_macros = [('NO_ATLAS_INFO', 3), ('HAVE_CBLAS', None)]
openblas_lapack_info:
  NOT AVAILABLE
atlas_3_10_blas_threads_info:
  NOT AVAILABLE
atlas_threads_info:
  NOT AVAILABLE
atlas_3_10_threads_info:
  NOT AVAILABLE
atlas_blas_info:
  NOT AVAILABLE
atlas_3_10_blas_info:
  NOT AVAILABLE
atlas_blas_threads_info:
  NOT AVAILABLE
openblas_info:
  NOT AVAILABLE
blas_mkl_info:
  NOT AVAILABLE
blas_opt_info:
    extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
    extra_compile_args = ['-msse3', '-I/System/Library/Frameworks/vecLib.framework/Headers']
    define_macros = [('NO_ATLAS_INFO', 3), ('HAVE_CBLAS', None)]
atlas_info:
  NOT AVAILABLE
atlas_3_10_info:
  NOT AVAILABLE
lapack_mkl_info:
  NOT AVAILABLE
mkl_info:
  NOT AVAILABLE

次にダウンロードしたnumpyのソースコード内から上書きインストールをします. まずはソースコードの内にsite.cfgというファイルを作ります(ファイルの中身は以下). これでインストールしたmklの場所を指定してあげます.

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

configオプションで, ちゃんとmklを認識できているか確認します.

python setup.py config

Running from numpy source directory.
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'test_suite'
  warnings.warn(msg)
blas_opt_info:
blas_mkl_info:
/Users/mutoumasahiro/Downloads/numpy-1.10.4/numpy/distutils/system_info.py:635: UserWarning: Specified path  is invalid.
  warnings.warn('Specified path %s is invalid.' % d)
  FOUND:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/opt/intel/mkl/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/opt/intel/mkl/include']

  FOUND:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/opt/intel/mkl/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/opt/intel/mkl/include']

non-existing path in 'numpy/distutils': 'site.cfg'
F2PY Version 2
lapack_opt_info:
openblas_lapack_info:
  libraries openblas not found in ['/Library/Frameworks/Python.framework/Versions/2.7/lib', '/usr/local/lib', '/usr/lib']
  NOT AVAILABLE

lapack_mkl_info:
mkl_info:
  FOUND:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/opt/intel/mkl/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/opt/intel/mkl/include']

  FOUND:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/opt/intel/mkl/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/opt/intel/mkl/include']

  FOUND:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/opt/intel/mkl/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/opt/intel/mkl/include']

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'define_macros'
  warnings.warn(msg)
running config

いろいろWarningが出ているのですが, よくわかりません. ここらへんを解決できるといいのですが... とりあえずmklを認識できているのを確認したら, インストールします. その後LD_LIBRARY_PATHを通して, show_config()できちんとmklがライブラリとして認識されているのをチェックします.

python setup.py install
export LD_LIBRARY_PATH="/opt/intel/mkl/lib:$LD_LIBRARY_PATH"

cd #エラーが起きるのでnumpyのディレクトリから離れる
python -c'import numpy; numpy.show_config()'

lapack_opt_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/opt/intel/mkl/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/opt/intel/mkl/include']
blas_opt_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/opt/intel/mkl/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/opt/intel/mkl/include']
openblas_lapack_info:
  NOT AVAILABLE
lapack_mkl_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/opt/intel/mkl/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/opt/intel/mkl/include']
blas_mkl_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/opt/intel/mkl/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/opt/intel/mkl/include']
mkl_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/opt/intel/mkl/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/opt/intel/mkl/include']

これで一応成功です. ちなみにpip uninstall numpyが2回できるので, 本当に重なっている?ことがわかります.

ここに辿り着くまで

Numpy/Scipy with Intel® MKL and Intel® Compilers | Intel® Developer Zoneにはmkl&numpyの構築方法が乗っているんですが, Linux仕様のせいか同じことをやってもうまくいきませんでした. 同じようにやって引っかかったのはこちら.

python -c'import numpy; numpy.show_config()'

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/__init__.py", line 180, in <module>
    from . import add_newdocs
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/add_newdocs.py", line 13, in <module>
    from numpy.lib import add_newdoc
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/lib/__init__.py", line 8, in <module>
    from .type_check import *
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/lib/type_check.py", line 11, in <module>
    import numpy.core.numeric as _nx
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/core/__init__.py", line 14, in <module>
    from . import multiarray
ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/core/multiarray.so, 2): Library not loaded: libmkl_rt.dylib
  Referenced from: /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/core/multiarray.so
  Reason: image not found

これの解決法を調べるのが難しくて, もしかして共存させればいいんじゃないかなとふと思いついた次第. とても悪手ですが, 長時間の試行錯誤でだいぶ心が折れていたので動けばいいやと...

Anacondaから入れる

Anacondaがmkl, numpy, scipyなどをまとめて構築してくれます. 先の方法と比べてとても簡単で感覚的にも正攻法です. numpy.show_config()で確認します.

conda install mkl
python -c'import numpy; numpy.show_config()'
lapack_opt_info:
    libraries = ['mkl_lapack95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['//anaconda/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['//anaconda/include']
blas_opt_info:
    libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['//anaconda/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['//anaconda/include']
openblas_lapack_info:
  NOT AVAILABLE
lapack_mkl_info:
    libraries = ['mkl_lapack95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['//anaconda/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['//anaconda/include']
blas_mkl_info:
    libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['//anaconda/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['//anaconda/include']
mkl_info:
    libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['//anaconda/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['//anaconda/include']

詳しくはMKL Optimizations — Continuum documentation
Anacondaを入れていない人はこちらからWhy Anaconda? | Continuum

検証

ここからはテストコードを用いて速度比較及び動作検証を行います. テストコードはこちら
テストのうち'Matrix Multiplication (double precision)'の結果を比較します. これはmn行列とnk行列の内積を計算していて,
m=10000, n=6000
k=[64, 80, 96, 104, 112, 120, 128, 144, 160, 176, 192, 200, 208, 224, 240, 256, 384]
となっています. 結果を見る限りそんなに早くなっていないと思います(後述のubuntuの結果を見ると一目瞭然).
f:id:mutomasahiro1111:20160130010502p:plain

chainerのエラー解消

以前, ブログに書いたchainer/examples/mnist/train_mnist.pyがバグるというお話. これの原因がnumpyを裏で計算しているパッケージによるものという可能性が示唆されていました. そこでanaconda構築したmkl環境で確認したところ, エラーが解消されていました. ということでこの問題の関係方法として'他のライブラリを導入する'が挙げられます.
pip-install-deeplearning.hatenadiary.jp

さいごに

最初のnumpyを重ねた方法でのmklでは, chainer_mnistのエラーが残っていたのでおそらくちゃんとmklライブラリを使っていないと思います. それに対してanacondaはエラーがなくなっているので一応mklライブラリを使っているようです(もちろん他よりは高速化しているのも根拠). またMacBookPro環境ではmklを使ったところでCPUが1枚なので高速化されないのかも知れないです.

そもそも大規模な計算をするならGPU環境でやるので, macbookpro上で高速化するメリットも特に無いです. 今回はmac上でmklを構築した例があまりネット上に出回っていなかったので挑戦してみました. だけどうまくいかないので, これ以上はあがきません. 誰かがこれを見て, 引き継いでくれることを祈ります. 何かあったら教えて下さい.

おまけ

Linux(Ubuntu)上でmkl, numpy構築しました. 参考記事の通りにやるだけでとても簡単. 簡単すぎてmacの恐ろしさを改めて感じました. 明らかに早くなっています.Python - mkl numpyのインストール方法 - Qiita
f:id:mutomasahiro1111:20160129202745p:plain