MKLについて
Intel® oneAPI Math Kernel Library (以下単にMKLと略します)は高度にベクトル化およびスレッド化された線形代数、高速フーリエ変換 (FFT)、ベクトル演算関数、統計関数を含む数値演算ライブラリです。
アプリケーションがBLASやLAPACKのルーチンを呼び出しているのであれば、MKLに置き換えることで性能を大幅に向上させることが期待できます。
まずは結論から
次のスクリプトを実行するだけです。
numpy と scipy をMKLをリンクしてリビルドしてくれます。
#!/bin/bash
PYPI_CACHE_DIR=$HOME/cache/pypi
# ---- YOU MAY NOT NEED TO EDIT BELLOWS ----------
__AUTHOR__="Goichi Iisaka"
__VERSION__="1.0"
__DATE__="Jun 17 2021, Sunny day"
python -m pip install -U pip wheel
# for Build numpy and scipy
cat <<_EOF_ > $HOME/.numpy-site.cfg
[mkl]
library_dirs = $HOME/.local/lib
include_dirs = $HOME/.local/include
mkl_libs = mkl_rt
runtime_library_dirs = $HOME/.local/lib
lapack_libs =
extra_link_args = -Wl,--rpath,$HOME/.local/lib -Wl,--no-as-needed -lmkl_rt -ldl -lpthread -lm
_EOF_
export LD_LIBRARY_PATH=$HOME/.local/lib:${LD_LIBRARY_PATH}
[ -d "${PYPI_CACHE_DIR}" ] || mkdir -p "${PYPI_CACHE_DIR}"
pip download -d ${PYPI_CACHE_DIR} \
mkl-devel mkl-include pybind11 cython
pip install --no-index --find-link ${PYPI_CACHE_DIR} \
mkl-devel mkl-include pybind11 cython
# Fix MKL libs
for F in $HOME/.local/lib/lib*.so.[0-9]
do
[ -f ${F%.*} ] || ln -s $F ${F%.*}
done
pip wheel --no-binary :all: numpy && {
rm -f ${PYPI_CACHE_DIR}/numpy-*.whl
mv numpy-*whl ${PYPI_CACHE_DIR}
pip install --no-index --find-link ${PYPI_CACHE_DIR} --force-reinstall numpy
}
pip wheel --no-deps --no-binary :all: scipy && {
rm -f ${PYPI_CACHE_DIR}/scipy-*.whl
mv scipy-*whl ${PYPI_CACHE_DIR}
pip install --no-index --find-link ${PYPI_CACHE_DIR} --force-reinstall scipy
}
pip wheel --no-deps --no-binary :all: bottleneck && {
rm -f ${PYPI_CACHE_DIR}/Rottleneck-*
mv Bottleneck-*whl ${PYPI_CACHE_DIR}
pip install --no-index --find-link ${PYPI_CACHE_DIR} --force-reinstall bottleneck
}
MKLがリンクされているかを確認
$ python -c "import numpy; numpy.show_config()"
blas_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/home/iisaka/.local/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/home/iisaka/.local/include']
extra_link_args = ['-Wl,--rpath,/home/iisaka/.local/lib', '-Wl,--no-as-needed', '-lmkl_rt', '-ldl', '-lpthread', '-lm']
blas_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/home/iisaka/.local/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/home/iisaka/.local/include']
extra_link_args = ['-Wl,--rpath,/home/iisaka/.local/lib', '-Wl,--no-as-needed', '-lmkl_rt', '-ldl', '-lpthread', '-lm']
lapack_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/home/iisaka/.local/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/home/iisaka/.local/include']
extra_link_args = ['-Wl,--rpath,/home/iisaka/.local/lib', '-Wl,--no-as-needed', '-lmkl_rt', '-ldl', '-lpthread', '-lm']
lapack_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['/home/iisaka/.local/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['/home/iisaka/.local/include']
extra_link_args = ['-Wl,--rpath,/home/iisaka/.local/lib', '-Wl,--no-as-needed', '-lmkl_rt', '-ldl', '-lpthread', '-lm']
blas_mkl_info や lapack_mkl_info が定義されていればOKです。
再度インストールするとき
再度インストールするときは次のようにキャッシュディレクトリを指示します。
$ pip install --no-index -f $HOME/cache/pypi numpy
ビルドに必要なパッケージ
VPSサーバなどでディプロイ直後の状態では最低限次のパッケージをインストールしておけばOKです。
テストは Ubuntu 20.04 で行っています。
#!/bin/bash
sudo apt install -y \
build-essential gfortran python-is-python3 python3-pip \
pkg-config autoconf automake libtool \
liblapack-dev libfftw3-dev
なぜこのスクリプト作ろうとしたのかという経緯
なにげにPYPIを見ていると oneAPI 2021.02 版のランタイムライブラリが登録されていることに気づきました。pip だけでMKLがインストールができるのはとても簡単です。
実際、oneAPI のBaseKit と HPCKit をインストールするとなれば、
結構大げさなことになってしまいます。
ディスクも21GB消費してしまいます。
isaka@dev02:~$ du -sh /opt/intel/oneapi
21G /opt/intel/oneapi
iisaka@dev02:~$ du -sh /opt/intel/oneapi/mkl
3.1G /opt/intel/oneapi/mkl
iisaka@dev02:~$ ls /opt/intel/oneapi/mkl/2021.2.0
benchmarks documentation examples interfaces licensing tools
bin env include lib modulefiles
インテルコンパイラを使い続けるのであれば、何も問題ないかもしれませんが、
numpy や scipy をリビルドするために必要なライブラリは libmkl_rt.so.1 だけなので、クラウドで構築するような場合など少しディスクがもったいないと感じたわけです。
PIPでインストールできるMKLの不具合
pip でインストールされるMKLでは共有ライブラリ名がおかしくて、
*.so になっていないため、リンカーがうまく共有ライブラリを見つけてくれません。
これを修復することもスクリプトにした理由のひとつでした。
既知の制限
scipy をビルドするためには2GBメモリのサーバでは、メモリ不足でビルドに失敗します。