天皇陛下のお誕生日を祝して M1 mac 購入
M1 mac を購入したので、Fortran をインストールしてみました。私は mac は生まれて初めてで右も左も分からぬ状態なので、話半分で読んでください。買ったのは一番安い macbook air 8G/256G/7GPU ので色は給食のアルマイトの食器の様なねずみ色のやつです。名前は Air ですが、ずっしり重くてどちらかというと Heavy Metal という感じです。
約1.29 kg~
約634g~
Arm 用 gfortran, Rosetta エミュレータで intel 用 gfortran および oneAPI の intel fortran の三種が動くことを確かめました。インストールはいずれもインストーラを動かすだけでできました。
簡単なプログラムで見たところ intel fortran の場合、エミュレーションで動いているにもかかわらず、第四世代 Haswell i7 の4倍くらいのスピードが出ています。同じプログラムでみると ARM 版 gfortran は x86_64 版 gfortran の 1.5 倍くらいの速さで、intel fortran と比較するとプログラムによって速かったり遅かったりします。
ARM ネイティブ gfortran が Rosetta のエミュレーションの intel fortran より遅いのは意外ですが、ネットを流れているベンチマークを見ると、ARM 版 gcc は clang より平均2倍くらい遅いようなので、 GNU コンパイラの問題なのかもしれません。また元々 gfortran は intel fortran より遅く5割増し位な感じなので、合わせるとそんなところかもしれません。
なお、Apple 版 intel fortran は昔から coarray をサポートせず oneAPI 版でもサポートされません。
インストール・メモ
Jacob Williams さんのツイートで intel fortran が動くことが分かっていました。
以下のページから HPC base kit 用のオンライン版インストーラを取ってこれます。登録が必要ですが無料です。
fortran コンパイラだけでいいなら oneAPI base kit の方は要りません。ただ Intel MKL は base kit の方に入っているので、これも入れるならば base kit 用のインストーラも必要になります。
software.intel.com
Mac 版は MPI その他が無く(多分そのせいで coarray もない... MPI 上に実装されているので)、選択できるのは C++ と Fortran のコンパイラだけです。Fortran コンパイラだけインストールしました。
コマンドライン用 Xcode というものが必要になるのですが、ifort でコンパイルしようとすると警告が出て自動でインストールしてくれます。
メモ
コンパイラにパスを通すスクリプトを先に動かす必要があります。
. /opt/intel/oneapi/setvars.sh
ただライブラリへのパスが通っておらず、ネットを検索すると手動でライブラリ位置を指定せよと出てきました。Xcode の前に intel fortran をインストールしたせいかもしれません。
ifort -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib xxxx.f90
めんどくさいので .zshrc に alias を書いてみました。
alias ifort='ifort -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib'
gfortran
奥村先生のページを参考にしました。
oku.edu.mie-u.ac.jp
Homebrew というドブロク造りをイメージしたパッケージマネージャーを x86_64 用と arm64 用それぞれに、ページ画面に表示されたコマンド1行をターミナルにコピペ&実行でインストールして、その後それぞれで brew install gfortran を行えば gfortran がインストールされます。
ARM 版を優先したい場合、実行パスの優先順序を工夫する必要があります。
insider という所に行くと ARM 版が落とせます。
code.visualstudio.com
よく分からない形式の圧縮ファイルをクリックすると、実行ファイルらしきものが出てくるので、ええいままよとそれをアプリケーションのフォルダーにコピーしてみました。これでいいのかよく分かりません。クリックすると vs code が起動します。
visual studio code 起動後は Modern Fortran と Fortran IntelliSense の拡張機能を入れました。何か言われるままにクリックして、文法解釈用の fortls も別途インストールした気がします。漫然とクリックしたのでよく覚えていません。とりあえず問題なく動いています。
実行例
とりあえず昔のプログラムを動かしてみました。
fortran66.hatenablog.com
module m_stamp
implicit none
logical :: first = .true.
real(kind(0.0d0)) :: t0, t1
contains
subroutine stamp(text)
character(len = *), intent(in) :: text
character(len = 8) :: date
character(len = 10) :: time
if (first) then
first = .false.
call cpu_time(t0)
end if
call cpu_time(t1)
call date_and_time(date, time)
print '(6a, 6a, a, g15.3, 2a)', &
date(1:4), '-', date(5:6), '-', date(7:8), ' ', &
time(1:2), ':', time(3:4), ':', time(5:8), ' ', &
' cpu_time =', t1 - t0, '(sec) ::', text
end subroutine stamp
end module m_stamp
module m_cg
implicit none
integer, parameter :: kd = kind(0.0d0)
contains
subroutine cg(a, b, x)
real(kd), intent(in) :: a(:, :), b(:)
real(kd), intent(in out) :: x(:)
real(kd) :: alpha, beta, r2n, r2d, eb2, p(size(b)), q(size(b)), r(size(b))
integer :: i
r = b - matmul(a, x)
p = r
r2n = dot_product(r, r)
eb2 = epsilon(b) * dot_product(b, b)
do i = 1, size(b)
if ( r2n < eb2 ) exit
r2d = r2n
q = matmul(a, p)
alpha = dot_product(p, r) / dot_product(p, q)
x = x + alpha * p
r = r - alpha * q
r2n = dot_product(r, r)
beta = r2n / r2d
p = r + beta * p
end do
end subroutine cg
end module m_cg
program cg_main
use m_cg
use m_stamp
implicit none
integer, parameter :: ns = 2000
real(kd) :: a(ns, ns), b(ns), x(ns)
integer :: i, j
call stamp('make matrix')
do i = 1, ns
b(i) = 1.0_kd
do j = i, ns
a(i, j) = real( 2 * min(i, j) - 1, kd )
a(j, i) = a(i, j)
end do
end do
call stamp('solve Ax = b')
call random_seed()
call random_number(x)
call cg(a, b, x)
x = matmul(a, x) - b
print *, 'difference (rms) =', sqrt( dot_product(x, x) )
call stamp('normal end')
end program cg_main
intel fortran (Rosetta2)
gfortran (ARM64)
gfortran (Rosetta2)
[a] M1:~/fortran% ifort -O2 cg.f90
[a] M1:~/fortran% ./a.out
2021-02-24 02:07:14.7 cpu_time = 0.500E-05(sec) ::make matrix
2021-02-24 02:07:14.7 cpu_time = 0.182E-01(sec) ::solve Ax = b
difference (rms) = 4.684681968851512E-007
2021-02-24 02:07:15.6 cpu_time = 0.945 (sec) ::normal end
[a] M1:~/fortran% gfortran -O2 cg.f90
[a] M1:~/fortran% ./a.out
2021-02-24 02:07:24.3 cpu_time = 0.700E-05(sec) ::make matrix
2021-02-24 02:07:24.3 cpu_time = 0.137E-01(sec) ::solve Ax = b
difference (rms) = 6.6372870430592568E-007
2021-02-24 02:07:26.1 cpu_time = 1.80 (sec) ::normal end
[a] M1:~/fortran% arch -x86_64 /usr/local/bin/gfortran -O2 cg.f90
[a] M1:~/fortran% ./a.out
2021-02-24 02:07:34.2 cpu_time = 0.120E-04(sec) ::make matrix
2021-02-24 02:07:34.2 cpu_time = 0.218E-01(sec) ::solve Ax = b
difference (rms) = 4.3568034320423338E-007
2021-02-24 02:07:36.4 cpu_time = 2.26 (sec) ::normal end
i7 4770
Windows x64 intel fortran
2021-02-24 02:08:36.8 cpu_time = 0.00 (sec) ::make matrix
2021-02-24 02:08:36.9 cpu_time = 0.469E-01(sec) ::solve Ax = b
difference (rms) = 4.077532388488979E-007
2021-02-24 02:08:40.8 cpu_time = 3.95 (sec) ::normal end
続行するには何かキーを押してください . . .
追記:
i7 4770 の計算時間が昔に比べて長くなって計算スピードが遅くなっていますが、実は MKL 付属の linpack benchmark なども遅くなっています。多分 intel chip の specter とかの対策のせいではないかと疑っているのですが面倒なので確かめていません。気のせいかもしれません。