Intel® Math Kernel Libraryを導入してFortranから利用する
この記事の概要
Intel® oneAPIという高性能な数値計算ツールキットがある。 以前は結構な値段だったらしいが、昨年あたりから無料で使えるようになった (Intel® oneAPI FAQ)。
oneAPIにはプロファイラーとか深層学習とか色々便利なツールが含まれている。そのうちの一つのMath Kernel Library(mkl)は、LAPACK95やFFTなど高速な数値計算処理を提供する。 LAPACK95のようなライブラリを自力でダウンロード・ビルド・リンクまでするのはかなり手間だが、これからはoneAPIで一括でもってこられる。
そういうわけでこの記事では、oneAPIのインストール手順を紹介し、使用例としてIntel® Fortran Compiler(ifort) からIntel® Math Kernel Libraryの手続きを呼び出して実行する方法を説明する。
Intel® oneAPI Toolkit のインストール
私はUbuntu上にインストールしたので以下のコマンドで。
おおむね公式ドキュメント( APT - Intel® oneAPI Toolkits Installation Guide for Linux* OS ) の通り。
wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \ | gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list sudo apt update # basekitにはMath Kernel Libraryが含まれる sudo apt install intel-basekit # hpckitにはFortran Compilerが含まれる sudo apt install intel-hpckit # 環境変数の設定はsetvars.shがよしなにやってくれる echo "source /opt/intel/oneapi/setvars.sh" >> zsh.rc
最後の行について、setvars.sh
をShellの起動時に毎回実行させると結構起動がおそくなるので、
alias activate-oneapi="source /opt/intel/oneapi/setvars.sh"
などとしてもいいかもしれない。
インストールが完了したことの確認。
$ ifort --version ifort (IFORT) 2021.5.0 20211109 Copyright (C) 1985-2021 Intel Corporation. All rights reserved. $ mkl_help oneAPI MKL vars.sh Syntax: ...
線型方程式系を解く
mklに含まれるlapack95を使って線型方程式系を解いてみる。
コード
! solve_linear_equation.f90 program main use lapack95, only: getrf, getrs implicit none integer, parameter :: N = 3 integer :: i integer :: ipiv(N) ! pivot indices real :: a(N,N) ! matrix A real :: b(N) ! vector b a(:, :) = reshape( & [2., -1., 1., 1., 1., 2., 1., -1., 3.], & [3, 3] & ) b(:) = [2, 3, -10] print *, "A:" do i=1, N print '(3f6.2)', a(i, :) end do print *, "b:" print '(3f6.2)', b(:) ! LU factorization call getrf(a, ipiv) ! solve linear equations with an LU-factored matrix call getrs(a, ipiv, b) print *, "x:" print '(3f6.2)', b(:) end program main
各手続の取説はこの辺を見ると良いgetrs - Developer Reference for Intel® oneAPI Math Kernel Library - Fortran
lapack95の手続は総称名になっていて、
例えばgetrf
は引数が単精度ならsgetrf
に、
倍精度ならdgetrf
に勝手にリダイレクトしてくれるので型を気にせず使える。
また、純粋手続になっているのでpure functionの中でも使える。
総じて非常に取り回しが良い。
Ref: Intel® MKL Fortran 95 Interfaces for LAPACK Routines vs. Netlib Implementation
コンパイル
# compile ifort -c solve_linear_equations.f90 -c -qmkl # link ifort solve_linear_equations.o -lmkl_lapack95_lp64 -qmkl
-qmklオプションを付けることでコンパイラが lapack95等のmklモジュールを参照してくれる。
Ref: qmkl, Qmkl - Intel® oneAPI DPC++/C++ Compiler Developer Guide and Reference
が、どうやらモジュールはライブラリの実体を含んでおらず
インターフェイスを提供するのみのようで、リンク時には
使用するモジュールに合わせて-lmkl_lapack95_lp64
のようにリンクさせてやる必要がある。
結果
$ ./a.out A: 2.00 1.00 1.00 -1.00 1.00 -1.00 1.00 2.00 3.00 b: 2.00 3.00-10.00 x: 3.00 1.00 -5.00
尚、MacOSでは実行時にDYLD_LIBRARY_PATH
の指定が必要だった。
export DYLD_LIBRARY_PATH="${DYLD_LIBRARY_PATH}:/opt/intel/oneapi/mkl/latest/lib"