はじめに
CMake1でIntel MKL2を利用する方法をまとめる.本記事は前記事CMakeに関する個人的メモの内容を補うものである.
手順
- Intel® Math Kernel Library Link Line Advisor3を用いて,環境と要求に合ったコマンドラインを調べる.
- 必要なincludeファイルを
add_executable
に併記する - 必要なライブラリを
target_link_libraries
で指定する.
例1 : FFTの利用
mkl_dfti.f90
をadd_executable
に併記する.${MKLROOT}
は筆者の環境では(macでもUbuntuでも)/opt/intel/mkl/
以下であった.
add_executable(${EXECUTABLE}
main.F90
${MKLROOT}/include/mkl_dfti.f90
)
必要なライブラリを追加.
target_link_libraries(${EXECUTABLE}
PRIVATE
# Intel Link Advisor
# https://software.intel.com/en-us/articles/intel-mkl-link-line-advisor
# 32-bit integer
mkl_intel_lp64
# 64-bit integer
# mkl_intel_ilp64
# OpenMP threading
mkl_intel_thread
# Sequential
# mkl_sequential
mkl_core
)
make
された実行ファイルについてldd
コマンドで共有ライブラリを調べると,
libmkl_intel_lp64.so libmkl_intel_thread.so libmkl_core.so
が見えるはずである.
macでは,otool -L
コマンドを用いれば
libmkl_intel_lp64.dylib libmkl_intel_thread.dylib libmkl_core.dylib
が確認できる.
例2 : 静的ライブラリの利用
例1では,ライブラリ名のみを記述すると共有ライブラリがリンクされることがわかった.静的ライブラリを利用したい場合はフルパスでライブラリを記述する.加えて,Linux環境では-Wl,--start-group
と-Wl,--end-group
で囲む.次は,Linux環境でLAPACK95インターフェースを用いた場合の例である.
add_executable(${EXECUTABLE}
main.F90
${MKLROOT}/include/lapack.f90
)
target_link_libraries(${EXECUTABLE}
PRIVATE
-Wl,--start-group
${MKLROOT}/lib/mkl_lapack95_lp64
${MKLROOT}/lib/libmkl_intel_lp64.a
${MKLROOT}/lib/libmkl_intel_thread.a
${MKLROOT}/lib/libmkl_sequential.a
${MKLROOT}/lib/libmkl_core.a
-Wl,--end-group
)
例3 : GFortranでの利用
上の2例はifortの使用を想定していた.現在Intel MKL2は無償で使用が可能である.Link Line Advisorに従えば,GFortranを用いる場合に必要なライブラリも簡単に調べられる.
target_link_libraries(${EXECUTABLE}
PRIVATE
mkl_gf_lp64
# mkl_gnu_thread
mkl_sequential
mkl_core
)
例4 : 大規模配列の利用
$2^{31}-1$以上の要素を持つ配列を利用する場合,mkl_intel_lp64
ではなくmkl_intel_ilp64
ライブラリを利用する.かつコンパイルオプションに-i8
を追加する.
Link Line Advisorが表示するその他のコンパイルオプション
Link Line Advisorを使用すると,上記のMKL関連ライブラリに加えて,いくつかのライブラリをリンクするように指示してくる.例えば,-liomp5 -lpthread -lm -ldl
である.これらを明記しなくても(現状筆者の環境では)プログラムは正常に実行される.
-
-liomp5
あるいはlgomp
OpenMP関連だが,前の記事に示したように以下のように書けば,適切なOpenMPライブラリとリンクされる.つまりGFortranなら-lgomp
,ifortなら-liomp5
等と書き分ける必要はない.
find_package(OpenMP REQUIRED)
#~~~~~
target_link_libraries(${EXECUTABLE}
PRIVATE
#~~~~~
# OpenMP threading
### for ifort
mkl_intel_thread
### for gfortran
# mkl_gnu_thread
OpenMP::OpenMP_Fortran
)
-lpthread
libpthread
はPOSIXスレッドライブラリで,"言語に依存せず主にtaskレベルの並列化に用いられる"4との事で,OpenMPとの併用が可能なようだ.しかし,"OpenMPの命令文を用いる方がより簡潔"4で,"コーディングとデバッグが困難"4とまで書かれている.
自分の書いたコードで利用していなくても,Link Line Advisorが指定しているということは,MKL内部でこれを利用しているのかもしれない.一応このオプションはつけておく方が無難ではないだろうか.
-lm
libm
は数学ライブラリだが,コンパイル時に次のような警告が出る場合がある.
ifort: warning #10315:
specifying -lm before files may supersede the Intel(R) math library and affect performance
この警告メッセージのみを見る限り,このオプションはつけない方が良いと思われる.
-ldl
libdl
でいろいろ検索してみたが,正直よくわからない.IBMのLinux 動的ライブラリーの徹底調査という記事によれば動的ロード(dynamic loading)のためのアプリケーション・プログラム・インターフェース (API) らしい.
終わりに
とりあえず,前の記事と合わせて,自身が使うための一通りの知識を得られた.「CMakeでIntel MKLを利用する方法をまとめる」ことはできたが,MKLのためのいくつかのコンパイルオプションについてはまだ疑問が残っている.わかり次第追記したい.
-
CMake 公式webサイト (https://cmake.org/) ↩
-
Intel® Math Kernel Library, webサイト: https://software.intel.com/en-us/mkl , EULA: https://software.intel.com/en-us/articles/end-user-license-agreement ↩ ↩2
-
Intel® Math Kernel Library Link Line Advisor https://software.intel.com/en-us/articles/intel-mkl-link-line-advisor ↩
-
Threading Fortran Applications for Parallel Performance on Multi-Core Systems,(本文中の""内の文章はこのページの英文を意訳したものである) https://software.intel.com/en-us/articles/threading-fortran-applications-for-parallel-performance-on-multi-core-systems ↩ ↩2 ↩3