この記事は、インテル® デベロッパー・ゾーンに公開されている「Numpy/Scipy with Intel® MKL」の日本語参考訳です。
*著者注: この記事は 2014 年 8 月 27 日更新されました。
NumPy/SciPy アプリケーション・ノート
ステップ 1 – 概要
このガイドは、現在 Numpy/SciPy を利用しているユーザーが、インテル® マス・カーネル・ライブラリー (インテル® MKL) の利点を活用することを目的としています。
NumPy は、ベクトルや行列演算を可能な限り BLAS と LAPACK 関数に自動マッピングします。インテル® MKL は、業界標準であるそれらのインターフェイスをサポートしているため、NumPy のスクリプトをわずかに変更するだけでインテル® MKL の最適化の恩恵を受けることができます。
NumPy は、Python* による科学技術計算に必要な基本パッケージです。以下で構成されます:
- 強力な N 次元配列オブジェクト
- 洗練された (ブロードキャスト) 関数
- C/C++ および Fortran コードを統合するためのツール
- 便利な線形代数、フーリエ変換、および乱数機能を提供
NumPy は、科学的な用途に加えて、一般的なデータの効率良い多次元コンテナーとして使用することができます。
NumPy に関する詳細は、http://NumPy.scipy.org/ をご覧ください。
SciPy は、統計、最適化、積分、フーリエ変換、信号および画像処理、ODE (常微分方程式) ソルバーなど多くのモジュールを提供します。SciPy ライブラリーは、高速で使いやすい NumPy の N 次元配列操作を利用しています。そのため、SciPy ライブラリーは、NumPy 配列で動作するように構築され、Python* ユーザー向けに数値積分と最適化ルーチンなど使いやすく効率の良い多くの数値演算ルーチンを提供しています。SciPy に関する詳細は、http://www.scipy.org をご覧ください。
バージョン情報
このアプリケーション・ノートは、Linux* プラットフォーム上で最新のインテル® MKL を使用する NumPy/SciPy ユーザーを支援するために作成されました。
この記事に記載される内容は、インテル® MKL 11.0 以降およびインテル® コンパイラー 13.0 以降に適用されます。この記事に記載される手順は、Python* 2.7 と Python* 3.4 で検証されています。最新の環境では、インテル® MKL 11.2、インテル® コンパイラー 15.0、Numpy 1.8.1、そして SciPy 0.14.0 でも動作確認されています。
ステップ 2 – NumPy と SciPy のソースコードをダウンロードする
NumPy のソースコードは以下からダウンロードできます:
http://www.scipy.org/Download
前提条件
インテル® MKL は以下の方法で入手できます:
インテル® MKL 製品の無料評価版をダウンロードする。
インテル® MKL 製品の無料非商用版* をダウンロードする。
これらは、以下のページで入手できます:
インテル® マス・カーネル・ライブラリー製品ウェブページ
インテル® MKL は、次のスイート製品に同梱されています。
インテル® Parallel Studio XE Cluster Edition/Professional Edition/Composer Edition
ステップ 3 – 設定
ダウンロードした NumPy-x.x.x.tar.gz ファイルを解凍するには、次のコマンドを使用します。
$gunzip numpy-x.x.x.tar.gz $tar -xvf numpy-x.x.x.tar
解凍すると、numpy-x.x.x というディレクトリーが作成されます。
同様に、以下のコマンドで SciPy を解凍します。
$gunzip scipy-x.x.x.tar.gz $tar -xvf scipy-x.x.x.tar.gz
解凍すると、scipy-x.x.x というディレクトリーが作成されます。
NumPy と SciPy の最新のソースコードは、それぞれの Github リポジトリーからも入手できます。
インテル® C++ および Fortran コンパイラーがインストールされ、PATH が設定されていることを確認してください。また、インテル® コンパイラー (C++ と Fortran) およびインテル® MKL のライブラリーの場所が LD_LIBRARY_PATH に設定されていることを確認します。
ステップ 4 – NumPy をビルドおよびインストールする
numpy-x.x.x へ移動します。
site.cfg.example をコピーして site.cfg を作成します
site.cfg を次のように変更します:
インテル® MKL を利用するには、NumPy のトップレベル・ディレクトリーの site.cfg ファイルに以下の行を追加します。以下は、インテル® Parallel Studio XE 2015 の 64 ビット版コンポーネントを使用することを仮定しています:
[mkl] library_dirs = /opt/intel/composer_xe_2015/mkl/lib/intel64 include_dirs = /opt/intel/composer_xe_2015/mkl/include mkl_libs = mkl_rt lapack_libs =
32 ビット版の NumPy をビルドするには、次の行を追加します。
[mkl] library_dirs = /opt/intel/composer_xe_2013/mkl/lib/ia32 include_dirs = /opt/intel/composer_xe_2015/mkl/include mkl_libs = mkl_rt lapack_libs =
numpy/distutils/intelccompiler.py の cc_exe を変更します。
self.cc_exe = 'icc -O3 -g -fPIC -fp-model strict -fomit-frame-pointer -openmp -xhost'
ここでは、速度の最適化とより積極的なループ・フュージョン、ループのブロックのアンロールとジャム、IF 文の畳み込みのため -O3 を、OpenMP* によるスレッド化のために -openmp を、そしてコンパイルするホスト・プロセッサーで利用できる最上位の SIMD 命令を生成するよう -xhost オプションを追加しています。ILP64 インターフェイスを利用する場合、-DMKL_ILP64 を追加してください。
プロセッサー固有のコンパイラー・オプションは、コマンドラインで “icc –help” を実行するか、インテル® コンパイラーのドキュメントをご覧ください。
Fortran コンパイラーの設定は、numpy-x.x.x/numpy/distutil/fcompiler/intel.py にインテル® Fortran コンパイラー向けに以下のオプションを追加します:
IA32 とインテル® 64
ifort -xhost -openmp -fp-model strict -fPIC
最新のソースを使用している場合、この変更はすでに intel.py に反映されています。そのほかのコンパイラーの最適化オプションもここで設定できます。
インテル® MKL の ILP64 インターフェイスを利用する場合、-i8 オプションを追加してください。古いバージョンの NumPy/SciPy を使用している場合、最新の NumPy のバージョンに含まれる intel.py を参考にして、上記のコンパイラー・オプションを変更できます。
インテル® コンパイラーで NumPy をコンパイルしてインストールします: インテル® 64 プラットフォームでは次のコマンドを実行します:
$Python* setup.py config --compiler=intelem build_clib --compiler=intelem build_ext --compiler=intelem install
IA32 では以下を実行します:
$Python* setup.py config --compiler=intel build_clib --compiler=intel build_ext --compiler=intel install
異なる点は、IA32 向けには “intel” を指定し、インテル® 64 向けには “intelem” を指定していることです。–prefix=<インストール先> を指定すると、任意のディレクトリーにインストールできます。
SciPy のビルドとインストール
64 ビットビルド向けにインテル® コンパイラーで SciPy をコンパイルしてインストールします:
$Python* setup.py config --compiler=intelem --fcompiler=intelem build_clib --compiler=intelem --fcompiler=intelem build_ext --compiler=intelem --fcompiler=intelem install
IA32 ビルドでは以下を実行します:
$Python* setup.py config --compiler=intel --fcompiler=intel build_clib --compiler=intel --fcompiler=intel build_ext --compiler=intel --fcompiler=intel install
インテル® MKL とインテル® コンパイラー向けにライブラリーのパスを設定します
インテル® 64 プラットフォーム向けに NumPY/SciPy をビルドするには、次の設定を行います:
$export LD_LIBRARY_PATH=/opt/intel/composer_xe_2015/mkl/lib/intel64:/opt/intel/composer_xe_2015/lib/intel64:$LD_LIBRARY_PATH
IA32 プラットフォーム向けには次のように設定します:
$export LD_LIBRARY_PATH=/opt/intel/composer_xe_2015/mkl/lib/ia32:/opt/intel/composer_xe_2015/lib/ia32:$LD_LIBRARY_PATH
インテル® MKL とインテル® コンパイラーをデフォルト以外の場所にインストールしている場合、LD_LIBRARY_PATH を正しく設定しないと問題が発生する可能性があります。私たちが確認した常にうまく機能する解決策は、Python、NumPy そして SciPy の環境変数 LD_RUN_PATH を設定することです。例えば、IA32 プラットフォームでは次のように設定します:
$export LD_RUN_PATH=/opt/intel/composer_xe_2013/lib/ia32:/opt/intel/composer_xe_2015/mkl/lib/ia32
注: NumPy は CBLAS を使用しているため、より良いパフォーマンスを得るには、配列を定義する際に、列優先の Fortran スタイルよりも、行優先の C スタイルを利用することを推奨します。
付録 A: 例
以下に、Numpy とインテル® MKL がインストールされた環境で、行列乗算を行う Python* スクリプトの例を示します。
import numpy as np import time N = 6000 M = 10000 k_list = [64, 80, 96, 104, 112, 120, 128, 144, 160, 176, 192, 200, 208, 224, 240, 256, 384] def get_gflops(M, N, K): return M*N*(2.0*K-1.0) / 1000**3 np.show_config() for K in k_list: a = np.array(np.random.random((M, N)), dtype=np.double, order='C', copy=False) b = np.array(np.random.random((N, K)), dtype=np.double, order='C', copy=False) A = np.matrix(a, dtype=np.double, copy=False) B = np.matrix(b, dtype=np.double, copy=False) C = A*B start = time.time() C = A*B C = A*B C = A*B C = A*B C = A*B end = time.time() tm = (end-start) / 5.0 print ('{0:4}, {1:9.7}, {2:9.7}'.format(K, tm, get_gflops(M, N, K) / tm))
付録 B: パフォーマンスの比較
LU 分解、コレスキー分解、そして SVD 分解の例をダウンロードするには、Examples.py をクリックしてください。
この記事中のパフォーマンス・チャートは、インテル® MKL 11.1 update 1 を使用して計測しています。
付録 1:
既知の問題:
ifort のコンパイラー・オプションに -O3 もしくは -O2 (デフォルト) を指定した場合、SciPy のテストの 1 つが失敗することが知られています。-O1 オプションを使用することでこれを回避できます。
GNU* コンパイラー・チェーンによるビルド:
前述のように、site.cfg ファイルのインテル® MKL セクションを変更します。GNU* コンパイラーで NumPy と SciPy をビルドするには、site.cfg ファイルで mkl_rt とのリンクのみを指定します。
コンパイラー・オプションを export します:
$export CFLAGS="-fopenmp -m64 -mtune=native -O3 -Wl,--no-as-needed" $export CXXFLAGS="-fopenmp -m64 -mtune=native -O3 -Wl,--no-as-needed" $export LDFLAGS="-ldl -lm" $export FFLAGS="-fopenmp -m64 -mtune=native -O3"
それぞれのソース・ディレクトリーで、NumPy と SciPy の config、build そして install を実行します。
インテルの OpenMP* の代わりに GNU* OpenMP* を利用する場合、MKL_THREADING_LAYER=GNU を設定する必要があります。
NumPy と SciPy は両方とも線形代数関数を持っているため、NumPy BLAS もしくは SciPy BLAS のどちらかを呼び出します。同時に両方を利用するのは MKL でサポートされていないため、両方から呼び出した場合クラッシュする可能性があります。
SciPy BLAS を利用するには、MKL_INTERFACE_LAYER=GNU を設定します。
MKL_THREADING_LAYER と MKL_INTERFACE_LAYER の 2 つの環境変数は、インテル® MKL 11.1 update 3 以降でのみサポートされます。
コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください