Lapackをインストールする際に勝手に入るBLASは,Netlibのリファレンス実装で,こいつは速度が遅い.そのためLapack が依存している BLASを,Reference BLAS から OpenBLASに切り替えたときのメモ.(OSは,fedora 23)
そこでまず,LapackがどこからBLASをひっぱてきているのか調べる.
最初に適当にLapackを使ってコンパイルし,実行ファイルが何に依存しているか以下の通り調べる.
$ gfortran -llapack test.f
$ ldd a.out
linux-vdso.so.1 (0x00007ffdc4659000)
liblapack.so.3 => /lib64/liblapack.so.3 (0x00007f6e0ea6d000)
libgfortran.so.3 => /lib64/libgfortran.so.3 (0x00007f6e0e741000)
libm.so.6 => /lib64/libm.so.6 (0x00007f6e0e43e000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f6e0e227000)
libquadmath.so.0 => /lib64/libquadmath.so.0 (0x00007f6e0dfe8000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6e0dc26000)
libblas.so.3 => /lib64/libblas.so.3 (0x00007f6e0b905000)
/lib64/ld-linux-x86-64.so.2 (0x000055bfaf841000)
以上にて,/lib64/libblas.so.3 からBLASをひっぱてきてることがわかった.
次に/lib64/libblas.so.3はシンボリックリンクなので,どこを参照しているか調べる.
$file /lib64/libblas.so.3
/lib64/libblas.so.3: symbolic link to libblas.so.3.5.0
以上より, Lapack → libblas.so.3 → libblas.so.3.5.0 のようにReference BLASを参照していることがわかった.
そこで,Lapack → libblas.so.3 → OpenBLAS のように参照するようにしてあげれば,OpenBLASに切り替えることができる.
まずOpenBLASをインストールする.
#dnf install openblas
次にalternativesコマンドで,OpenBLASに切り替える.使用するOSによっては,すでに登録されている場合があるが(#update-alternatives –list で確認できる),fedoraは登録されていないので,登録作業から始める必要がある.登録の際は,以下のコマンドにて行う.
#alternatives –install リンク名 総称名 選択候補 優先度
alternativesコマンドの詳細は,ココ(https://vinelinux.org/)で確認のこと.
以下コマンドにて,登録を行った.
#alternatives –install /lib64/libblas.so.3 libblas.so.3 /lib64/libblas.so.3.5.0 10
#alternatives –install /lib64/libblas.so.3 libblas.so.3 /lib64/libopenblas.so 20
次に,以下コマンドで設定の状態を確認する.
#update-alternatives –config libblas.so.3
There are 2 programs which provide ‘libblas.so.3’.
Selection Command
———————————————–
1 /lib64/libblas.so.3.5.0
*+ 2 /lib64/libopenblas.so
Enter to keep the current selection[+], or type selection number:
/lib64/libopenblas.so のところに[+]がついていれば,libblas.so.3 は,libblas.so.3.5.0 から libopenblas.soを参照するようになる.( /lib64/libblas.so.3.5.0 のところに[+]がつくように設定を変更すれば,以前と同じReference BLAS を使用することになる.)
最後にOpenBLASに切り替えた効果を確認する.確認用のプログラム(lapack_test.f)を書いてみた.中身は連立一次方程式 Ax=B(A:1000×1000の密行列)をdgesvを使って解くプログラム.
$gfortran -llapack lapack_test.f
Reference BLASの場合
$ ./a.out
DGESV works fine
0.55200000000000005 ←実行時間
OpenBLASの場合
$ ./a.out
DGESV works fine
0.14699999999999999 ←実行時間
確認の結果,上記の例では4倍ほど高速化できていることがわかる.
なお,SuperLUは標準でATLASを使用しており,ATLASとOpenBLASを切り替えて比較してみたが,計算時間はほとんど同じだった.
参考
https://vinelinux.org/docs/vine6/cui-guide/update-alternatives.html
http://www.nag-j.co.jp/fortran/tips/tips_PortableWayToTime.html