what's this?
表題通り, pyenv+poetry環境のnumpy, scipyでmklを使おうとする話.
解決策がわかれば簡単なのだけど, そこにたどり着くまでが意外と長かった...
環境はmac OS 10.14.6 Mojave
pyenvのバージョンは1.2.16-5-g7097f820
poetryのバージョンは1.0.3
です.
結論(解決策)
多分, この記事を見てる人は同じような問題に当たっていち早く解決したいという人が多いでしょうから, 結論(解決策)を先に書きます.
プロジェクト名はmy-project
, 使用するpythonのバージョンは3.7.4として進めます.
mkl
が標準通り/opt/intel/
にインストールされていることとします.
プロジェクトのディレクトリに .venv を作るように設定されていることとします(poetry config virtualenvs.in-project true
).
プロジェクトディレクトリ作成 & pythonバージョン指定(ここは普通)
プロジェクトディレクトリを作成して, pythonのバージョンを指定.
ここまでは普通.
$ mkdir my-project && cd $_
$ pyenv local 3.7.4
仮想環境の設定(普通じゃない)
普通はpoetryが勝手に.venv
を作ってくれるから自分で.venv
を作る必要はないのだが, 今回は
-
.venv/bin/activate
を編集して, mklのための環境変数を設定する -
.venv/pip.conf
を編集して, numpy,scipyをbuildするようにしたりする
ので, 自分で.venv
を作る.
$ python -m venv .venv
mklのための環境変数を設定
$ echo -e "source /opt/intel/bin/compilervars.sh intel64\nsource /opt/intel/mkl/bin/mklvars.sh\nsource /opt/intel/tbb/bin/tbbvars.sh" >> .venv/bin/activate
.venv/pip.conf
を作成し, no-binary=numpy,scipy
,no-use-pep517
を設定.
$ touch .venv/pip.conf && echo -e "[install]\nuse-pep517=false\nno-binary=numpy,scipy" >> .venv/pip.conf
numpyビルド用のコンフィグファイル$HOME/.numpy-site.cfg
を次の内容で作成.
[mkl]
library_dirs = $MKLROOT/lib
include_dirs = $MKLROOT/include
mkl_libs = mkl_rt
lapack_libs =
pyproject.tomlの用意(ここは普通)
準備が整ったのでpoetry init
$ poetry init
This command will guide you through creating your pyproject.toml config.
Package name [my-project]:
Version [0.1.0]:
Description []:
Author [hogehoge, n to skip]:
License []:
Compatible Python versions [^3.7]:
Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your dev dependencies (require-dev) interactively (yes/no) [yes] no
Generated file
[tool.poetry]
name = "my-project"
version = "0.1.0"
description = ""
authors = ["hogehoge"]
[tool.poetry.dependencies]
python = "^3.7"
[tool.poetry.dev-dependencies]
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
Do you confirm generation? (yes/no) [yes]
cythonのインストール
まずはcython
を入れる.
$ poetry add cython
numpyのインストール
次にnumpy
.
$ poetry add numpy
ここで, poetry run python -c "import numpy; numpy.show_config()"
とすると,
Traceback (most recent call last):
(中略)
Original error was: dlopen(/path/to/my-project/.venv/lib/python3.7/site-packages/numpy/core/_multiarray_umath.cpython-37m-darwin.so, 2): Library not loaded: @rpath/libmkl_rt.dylib
Referenced from: /path/to/my-project/.venv/lib/python3.7/site-packages/numpy/core/_multiarray_umath.cpython-37m-darwin.so
Reason: image not found
と出ることがある.1
$ install_name_tool -add_rpath $MKLROOT/lib .venv/lib/python3.7/site-packages/numpy/core/_multiarray_umath.cpython-37m-darwin.so
を実行する.
すると,
$ poetry run python -c "import numpy; numpy.show_config()"
blas_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/include', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
blas_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/include', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
lapack_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/include', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
lapack_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/include', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
となって幸せの予感...
scipyのインストール
最後にscipyを入れる.
ここまでうまくいっていればあとはすんなり行くはず.
(scipyのbuildは時間がかかります.気長に待ってください)
$ poetry add scipy
確認
poetry run python -c "import scipy; scipy.show_config()"
lapack_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/include', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
lapack_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/include', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
blas_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/include', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
blas_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/include', '/opt/intel/compilers_and_libraries_2020.0.166/mac/mkl/lib']
お疲れ様でした.
解決策に至るまで...
上の解決策に至るまでの道のりはそれなりに長かったのです.
その道のりをダイジェストでお送りします(ほぼ自分用のメモ).
読み飛ばして全く問題ないです.
普通にやってみた
$ mkdir my-project
$ pyenv local 3.7.4
$ python -m venv .venv
$ poetry init
.venv/pip.conf
を
[install]
no-binary = numpy,scipy
で作成して, それ以外の~/.numpy-site.cfg
, .venv/bin/activate
は上の解決策と同じように編集.
poetry add numpy
は成功する(rpath追加せなあかんけど)が, poetry add scipy
を実行すると...
[EnvCommandError]
Command ['/path/to/my-project/.venv/bin/pip', 'install', '--no-deps', 'scipy==1.4.1'] errored with the following return code 1, and output:
Collecting scipy==1.4.1
Using cached https://files.pythonhosted.org/packages/04/ab/e2eb3e3f90b9363040a3d885ccc5c79fe20c5b8a3caa8fe3bf47ff653260/scipy-1.4.1.tar.gz
Installing build dependencies: started
Installing build dependencies: still running...
Installing build dependencies: finished with status 'done'
Getting requirements to build wheel: started
Getting requirements to build wheel: finished with status 'done'
Preparing wheel metadata: started
Preparing wheel metadata: finished with status 'error'
...(中略)...
Original error was: dlopen(/private/var/folders/9x/94rd8dwd1vg49h9bt7_0kd0w0000gn/T/pip-build-env-mb4t9me7/overlay/lib/python3.7/site-packages/numpy/core/multiarray.cpython-37m-darwin.so, 2): Library not loaded: @rpath/libmkl_rt.dylib
Referenced from: /private/var/folders/9x/94rd8dwd1vg49h9bt7_0kd0w0000gn/T/pip-build-env-mb4t9me7/overlay/lib/python3.7/site-packages/numpy/core/multiarray.cpython-37m-darwin.so
Reason: image not found
ターミナルが真っ赤になる.
numpyをbuildした後でnumpyをno-binary
から外せばいいのでは?
.venv/pip.conf
を
[install]
no-binary = numpy
としてpoetry add numpy
でnumpyをインストール(ここでもrpathを追加しないとダメだが)した後,.venv/pip.conf
を
[install]
no-binary = scipy
と書き直してpoetry add scipy
とすると...うまく行く.
けどなんか面倒なので...
もうちょっと探ってみる.
pyenvだけで原因調査
端折りますが, pyenvだけでも同じ症状が出る...
/private/var/...
でbuildしてるからダメなのでは?
pyenvだけの環境で--no-build-isolation
をつけてpipでscipyをインストールしてみるとうまく行く.
poetry環境でno-build-isolation
をつけてみる.
poetryでもbuild-isolation
を無効にすればええんやろうと思って,.venv/pip.conf
を
[install]
build-isolation = false
no-binary = numpy,scipy
としてやってみると...
無理でした.
ターミナルが真っ赤です.
泣きそうです.
no-use-pep517
ならいけるのでは?
色々調べてたら,
Use PEP 517 for building source distributions (use --no-use-pep517 to force legacy behaviour).
をpip reference guideで見つける.
...これ--no-use-pep517
ならいけるのでは?
.venv/pip.conf
を
[install]
use-pep517=false
no-binary=numpy,scipy
としてやってみる.
うまくいった.
こうして上の解決策にたどり着く.
まとめ
面倒なのでよほどでない限りやらんほうがええと思う.
参考
-
poetry shell
して仮想環境に入ってからpython
起動してimport numpy
するとこのエラーは出ない...けど, この状態だとpoetry add scipy
が失敗するのでrpathを追加する他ない.
こうなった場合, ↩