本記事は、Arm-Mac版のnAG FortranコンパイラでOpenBLASを利用する方法をご紹介します。
1. OpenBLASのインストール
Homebrewを用いてOpenBLASをインストールします。
brew install openblas
2. テストプログラムの作成
次に、動作の確認をするための簡単なテストプログラム(以下は連立方程式を解くコード)を作成します。以下のコードをtest.f90
という名前のファイルに保存してください:
program main implicit none integer, parameter :: n = 3 integer info integer ipiv(n) double precision a(n, n), b(n) a = reshape( [ 33D0, 16D0, 72D0, & -24D0, -10D0, -57D0, & -8D0, -4D0, -17D0 ], [3,3], order=[2,1] ) b = [ -359D0, 281D0, 85D0 ] call dgesv(n, 1, a, n, ipiv, b, n, info) print '((f9.4))', b end program
3. プログラムのコンパイル・リンク方法
OpenBLASを利用するプログラムのビルド方法を以下に示します。(以下はtest.f90をビルドする例)
3.1 OpenBLAS (LAPACK機能を含む)用してコンパイル・リンクする場合
OpenBLASに含まれているLAPACKとBLASを利用する場合(OpenBLASにはBLASだけではなくLAPACKも含まれています)nagfor test.f90 -L/opt/homebrew/opt/openblas/lib -lopenblas -L/opt/homebrew/Cellar/gcc/13.2.0/lib/gcc/current -lquadmath
3.2 nAGのLAPACKとOpenBLASを使用してコンパイル・リンクする場合
(カレントディレクトリにnAG Fortranコンパイラでビルドしたliblapack.aがある場合)nagfor test.f90 -L. -llapack -L/opt/homebrew/opt/openblas/lib -lopenblas -L/opt/homebrew/Cellar/gcc/13.2.0/lib/gcc/current -lquadmath
3.3 nAGでビルドしたLAPACKとBLAS (refblas) を使用してコンパイル・リンクする場合
(カレントディレクトリにnAGでビルドしたliblapack.a及びlibrefblas.aがある場合)nagfor test.f90 -L. -llapack -lrefblas
4. パフォーマンスの比較(ご参考)
以下は、`test2.f90` という連立方程式を解くプログラムで計測した実行時間の参考としての結果です。これらの結果は環境や設定によって変動する可能性があるため、あくまで参考程度としてください。
- OpenBLAS (LAPACK機能を含む): 実行時間: 3.19 秒
- nAG LAPACK + OpenBLAS: 実行時間: 5.27 秒
- nAG LAPACK + nAG BLAS (refblas): 実行時間: 140.66 秒
コンパイラ nAG Fortran Compiler 7.1 (nagfor)
test2.f90は以下の通りです。
program main
use ISO_FORTRAN_ENV, only : int64
implicit none
integer, parameter :: n = 10000
integer info
integer(int64) t1, t2, t_rate, t_max, diff
integer ipiv(n)
double precision, allocatable :: a(:,:), b(:)
! Allocate and initialize
allocate(a(n,n), b(n))
call random_number(a)
call random_number(b)
! Get the starting count
call system_clock(t1)
! Solve the linear system
call dgesv(n, 1, a, n, ipiv, b, n, info)
! Get the ending count, rate and maximum count
call system_clock(t2, t_rate, t_max)
! Calculate the difference in counts
if (t2 < t1) then
diff = (t_max - t1) + t2 + 1
else
diff = t2 - t1
endif
! Print the time taken to solve the system
print "(A, F8.2)", "Time it took was:", diff/dble(t_rate), " seconds"
! Print solution status
if (info == 0) then
print *, 'Solution found'
else
print *, 'Solution not found, info = ', info
end if
end program main