ソースコードは https://github.com/osada-yum/examples/tree/main/GFortran_and_Co-array_Fortran に.
Co-array Fortran
Co-array Fortran はFortranの言語仕様の一部に組込まれているが, gfortran のみでは使えない. この記事はCo-arrayで書かれたプログラムを gfortran により実行するためのメモである.
- Ubuntu20.04では
apt
を使う方法とソースからビルドする方法がある.apt
を使う方法はインストールが楽だがコンパイルが面倒. - ソースからビルドするとラッパースクリプトの
caf
とcafrun
が手に入るためコンパイルは楽になる. - (2022/03/06(日)追記) どうも, Ubuntu18.04では
apt
にopen-coarrays-bin
があり, その中にcaf
とcafrun
が入っている. Ubuntu20.04にはそのパッケージがない.
https://fortran66.hatenablog.com/entry/2018/09/28/220201
https://qiita.com/cure_honey/items/6ef209405d77bcabf70d
最初に失敗話
私のPCでは最初にCo-array Fortranを使っても高速化しなかった. おそらく, gfortran
や mpirun
などのPATHがめちゃくちゃだったせい.(再現ができないので原因が分からない…) 環境の整理をしたら直った.
(どうやら, 実行ファイルを生成したmpiのバージョンと mpirun
するmpiのバージョンが違うと高速化しないらしい? 高速化しないのならば ldd a.out
で動的リンクライブラリのパスを確認した方がよいのかもしれない. 2022/02/07(月)追記)
実行環境
- Ubuntu20.04
- Ubuntu20.04 on VirtualBox6.1.14
$ echo ${PATH} | sed -s "s=${HOME}=~=g"
~/.nvm/versions/node/v16.3.0/bin:~/.cabal/bin:/usr/local/gcc-11.2.0/bin:/opt/bin/:~/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ which gfortran
/usr/local/gcc-11.2.0/bin/gfortran
$ gfortran --version
GNU Fortran (GCC) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ which mpirun
/usr/local/gcc-11.2.0/bin/mpirun
$ mpirun --version
mpirun (Open MPI) 4.1.2
Report bugs to http://www.open-mpi.org/community/help/
gfortranでCo-array Fortranを使う方法
Co-array Fortranのコンパイルのテスト用ファイル.
program coarrays_test
implicit none
integer :: my_image, n_images
my_image = this_image()
n_images = num_images()
print*, "I'm ", my_image, "/", n_images
end program coarrays_test
apt を使う方法
まずは apt
で検索をかけてみる.
$ apt search coarrays
ソート中...
全文検索...
libcaf-mpich-3/focal 2.8.0-1 amd64
Co-Array Fortran libraries (MPICH)
libcaf-openmpi-3/focal,now 2.8.0-1 amd64 [インストール済み、自動]
Co-Array Fortran libraries (OpenMPI)
libcoarrays-dev/focal,now 2.8.0-1 amd64 [インストール済み]
Co-Array Fortran libraries
libcoarrays-mpich-dev/focal 2.8.0-1 amd64
Co-Array Fortran libraries for - development files (MPICH)
libcoarrays-openmpi-dev/focal,now 2.8.0-1 amd64 [インストール済み]
Co-Array Fortran libraries - development files (OpenMPI)
mpich
と openmpi
がある. openmpi
を使うならば.
$ sudo apt install -y libcoarrays-openmpi-dev
実行するには必要なライブラリをリンクする必要があるが, pkg-config
を使えば良い. インストールされた .pc
ファイルを検索すると
$ dpkg -L libcoarrays-openmpi-dev | grep -e '\.pc$'
/usr/lib/x86_64-linux-gnu/pkgconfig/caf-openmpi.pc
/usr/lib/x86_64-linux-gnu/open-coarrays/openmpi/pkgconfig/caf-openmpi.pc
/usr/lib/x86_64-linux-gnu/open-coarrays/openmpi/pkgconfig/caf.pc
OpenMPIを使う場合は, caf-openmpi.pc
を利用する.
$ gfortran -o coarrays_test.out -fcoarray=lib coarrays_test.f90 $(pkg-config --libs --cflags caf-openmpi)
$ mpirun -np 2 ./coarrays_test.out
I'm 1 / 2
I'm 2 / 2
おそらく, -lcaf_openmpi
だけで十分.
$ gfortran -o coarrays_test.out -fcoarray=lib coarrays_test.f90 -lcaf_openmpi
$ mpirun -np 2 ./coarrays_test.out
I'm 1 / 2
I'm 2 / 2
ソースからビルドする方法
http://www.opencoarrays.org/ の https://github.com/sourceryinstitute/OpenCoarrays/tree/master からソースコードをクローンする.
$ git clone https://github.com/sourceryinstitute/OpenCoarrays.git
$ cd OpenCoarrays/
cmakeを使ってビルドとインストールをする.
$ FC=/usr/local/gcc-11.2.0/bin/gfortran cmake -B _build -DBUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/gcc-11.2.0
$ cmake --build _build
$ cmake --build _build --target install
これでラッパースクリプトの caf
と cafrun
が /usr/local/gcc-11.2.0
にインストールされる. FC や PREFIX を変えれば好きな場所にインストールできる. caf
が何をラップしているかを知るためには
$ caf -w
caf wraps /usr/local/gcc-11.2.0/bin/gfortran-11.2.0
caf
のversionを知るためには
$ caf -v
OpenCoarrays Coarray Fortran Compiler Wrapper (caf version 2.9.2-13-g235167d)
Copyright (C) 2015-2020 Sourcery Institute
Copyright (C) 2015-2020 Sourcery, Inc.
OpenCoarrays comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of OpenCoarrays under the terms of the
BSD 3-Clause License. For more information about these matters, see
the file named LICENSE that is distributed with OpenCoarrays.
を実行すればよい.
$ caf -o coarrays_test_caf.out coarrays_test.f90
$ cafrun -np 2 ./coarrays_test_caf.out
I'm 1 / 2
I'm 2 / 2
実行
ソースコードはNAGのチュートリアルからダウンロード https://www.nag-j.co.jp/fortran/coarray/coarrayTutorial_3.html.
$ [ -f quad1.f90 ] || wget https://www.nag-j.co.jp/fortran/coarray/code/quad1.f90
$ [ -f coquad1.f90 ] || wget https://www.nag-j.co.jp/fortran/coarray/code/coquad1.f90
$ [ -f coarrays.f90 ] || wget https://www.nag-j.co.jp/fortran/coarray/code/coarrays.f90
$ gfortran -fcoarray=lib -o coarrays.out quad1.f90 coquad1.f90 coarrays.f90 -lcaf_openmpi
$ caf -o coarrays_caf.out quad1.f90 coquad1.f90 coarrays.f90
apt から
$ mpirun -np 1 ./coarrays.out
Calculated value: 0.90000000000031166
True value (approx): 0.90000000000000002
Relative error 3.4626622556920158E-013
Time taken 9.620 seconds by 1 images, = 9.62 computing power
$ mpirun -np 4 ./coarrays.out
Calculated value: 0.90000000000022018
True value (approx): 0.90000000000000002
Relative error 2.4461913975907617E-013
Time taken 2.742 seconds by 4 images, = 10.97 computing power
caf
$ cafrun -np 1 ./coarrays_caf.out
Calculated value: 0.90000000000031166
True value (approx): 0.90000000000000002
Relative error 3.4626622556920158E-013
Time taken 9.626 seconds by 1 images, = 9.63 computing power
$ cafrun -np 4 ./coarrays_caf.out
Calculated value: 0.90000000000022018
True value (approx): 0.90000000000000002
Relative error 2.4461913975907617E-013
Time taken 2.644 seconds by 4 images, = 10.58 computing power
速度の比較
- aptから
time | speedup | |
---|---|---|
mpirun -np 1 | 9.620 | 1 |
mpirun -np 4 | 2.742 | 3.5083880 |
- caf
time | speedup | |
---|---|---|
cafrun -np 1 | 9.626 | 1 |
cafrun -np 4 | 2.644 | 3.6406959 |
結論
どちらの方法でも速度は大して変わらない. おおよそコア数分のスピードアップをしている.
ビルドの手間とコンパイルの手間を天秤にかけると, コンパイルが楽な caf
を使った方が良いだろう.
参考
- OpenCoarrays
- NAGのチュートリアル
- Ubuntu18.04