JagursをWin10で実行する環境を作る

#目的
Jagursという津波伝播シミュレーションをWindows Subsystem for Linux(WSL)上でコンパイルして付属のサンプルを実行する環境づくりの話です。シミュレーション結果の話ではありません。

このソフトは高度な並列化をされているのと、Intel Fortranコンパイラを前提としているため、~~貧乏人御用達~~gfortranでコンパイルして実行するまで一筋縄ではいきませんでした。また、僕自身がWSLを使ったことがなかったので自分のための半分メモです。


#Jagursとは
津波伝播シミュレーションのソフトウェアです。ソースコードはgitで公開されています。
シミュレーションのモデルとかアルゴリズムの詳しいことは、[公式のgit](https://github.com/jagurs-admin/jagurs)を見てください。ついでに僕が前に書いた[記事](https://qiita.com/iowanman/items/6c44621869774b143ac1)を見てください。

基本的なことは[マニュアル](https://github.com/jagurs-admin/jagurs/blob/master/doc/JAGURS-User-Guide.Jp.V0500.pdf)に書いてるし、記事の内容はマニュアルに沿ったことで書いてます。


#実行環境
HP ProBook 430 G5
CPU: Intel Core i5 (8th)
Memory: 16G
OS: Windows 10 64bit (日本から追い出されてる時に買ったから英語版）
![Clipboard01aaaaaaaaa.png](https://qiita-image-store.s3.amazonaws.com/0/180426/a259738e-a801-3299-d8f7-5ad913328331.png)


#使うもの
~~HPC(High Perfoermance Computer )とか持ってるかたはそれを使ってください。~~
Ubuntu on Windows Subsystem for Linux
gfortran
openmpi
fftw3
PROJ4
気合と根性
Lpic Level 0.5 程度のLinux力　([LPIC](https://www.lpi.org/ja/)とは ~~LinuCの存在は認めないマン~~ )


#WSLとLinuxの導入
Qiita:[WSL（Windows Subsystem for Linux）を使ってみた](https://qiita.com/Brutus/items/f26af71d3cc6f50d1640)
Qiita:[WSLでWindowsにLinux開発環境を構築する](https://qiita.com/taquaki-satwo/items/b379a141492ce8927deb)

WSLとLinuxの導入には先人がたくさんのいい記事を書いてくれてるので、そちらを見てください。
今回導入したLinuxはUbuntu 18.04LTSです（たぶん)。

WSL導入後デフォで放置すると、勝手にSSHが立ち上がるらしいです。
参考：[Cygwin絶対殺すマン ～物理のオタクがWindows Subsystem for Linuxで数値計算できるようになるまで～](https://qiita.com/PikkamanV/items/d308927c395d6e687a6a)

ユーザー名はtorobuにしました。STU48の土路生優里さん([公式](http://www.stu48.com/feature/torobu_yuri), [エケペディア](https://48pedia.org/%E5%9C%9F%E8%B7%AF%E7%94%9F%E5%84%AA%E9%87%8C))からもらってきました。石田みなみさんと迷いましたが、ishida か isida か迷いそうなのでやめました。~~ちなみに、STU48の中で僕の一推しは「石田みなみ」さんです(2018/11/7現在)。~~ 案の定、興味なくなった。(2021/2/9)


#Ubuntuの準備
Ubuntu側で、コンパイラの導入やDevelopment Toolの導入をします。

```shell
$ sudo apt-get install build-essential gfortran
```
これで,automakeなどなど必要そうなものが導入されます。個別に導入できる上級者様はブラウザバックをおすすめします。
導入されたgfortranのバージョンは以下です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180426/acae83c3-2115-b7ae-7ccd-b1b0eaadbd9f.png)

#ライブラリのインストール
JagursをコンパイルするにはHDF5 NetCDF PROJ4 FFTW3 が必要となります。また並列化されてるので、openmpiも導入します。
それぞれをホームディレクトリにダウンロードしてきて、ホームディレクトリ上で展開して、ホームディレクトリ上でコンパイルして、ホームディレクトリに作ったディレクトリにインストールします。
apt-get install でインストールしてもいいんですが、インストール先が不明なのでやめました。
prefix(インストール先)を指定しないと/usr/local以下に導入されるのですが、これをやるとやり直しがすごく大変なので、prefixを毎回指定します。

今回は最適化については何も考慮していません。
カリカリにチューンして最高速度を出したい方は、CFLAGSなどを指定してがんばってください。
僕は-O3に恐怖を覚えるチキンです。

##HDF5
HDF5はNETCDFをコンパイルするのに使います。([公式](https://support.hdfgroup.org/HDF5/))
最新っぽいものをダウンロードして使いました。

```vimL

cd ~/
mkdir hdf5
wget https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.10/hdf5-1.10.4/src/hdf5-1.10.4.tar.gz
tar zxvf  hdf5-1.10.4.tar.gz
cd hdf5-1.10.4
./configure --prefix=/home/torobu/hdf5
make
sudo make install
```
エラーっぽいうものが出てなければ成功です。エラーっぽいものがでてたら、ぐぐってください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180426/928a3c50-643c-bb24-1fd1-17e5da4cef14.png)
ちゃんと出来てたら、bin include lib share のディレクトリが出来上がっているはずです。
小ネタですがmake -j 8 とかすると、makeの時間が短縮されますが、まれにmakeで失敗するようです


環境変数のLD_LIBRARY_PATHに作ったライブラリを登録するために、ホームディレクトリの隠しファイルである.bashrcを編集します。viの使い方がわからない場合は、何か他のを探してください。


```vimL
vi ~/.bashrc
```

.bashrcファイルの一番下に、以下のような感じのものを書き加えます。LD_LIBRARY_PATHと=の間にスペースを入れないでください。=の後ろにスペースもだめです。:の前後にスペースを入れるのも危険です（たぶん）

```vimL
export LD_LIBRARY_PATH=/home/torobu/hdf5/lib:$LD_LIBRARY_PATH
```

書き換えた.bashrcを有効にします。

```vimL
source ~/.bashrc
```

##NetCDF
NetCDF([公式](https://www.unidata.ucar.edu/software/netcdf/))をコンパイルします。手順はHDF5とほぼ同じです。
NetCDF-Fortranを使います。NetCDFだけだと何故か欲しいライブラリが作られないっぽいです（仮）

```viml
cd ~/
mkdir netcdf-fortran
wget https://www.unidata.ucar.edu/downloads/netcdf/ftp/netcdf-fortran-4.4.4.tar.gz
tar zxvf netcdf-fortran-4.4.4.tar.gz
cd netcdf-fortran-4.4.4
./configure --prefix=/home/torobu/netcdf-fortran
make
make check
sudo make install
```

make checkに時間がかかりますが、strongly recomended なので一応やっておきましょう。

最後に、.bashrcに書き加えます。

```vimL
export LD_LIBRARY_PATH=/home/torobu/netcdf-fortran/lib:$LD_LIBRARY_PATH
```

##FFTW3
たぶん分散波とか計算するときにFFTが必要になるっぽいです（しらんけど
[公式](http://www.fftw.org/fftw-3.3.8.tar.gz)

```vimL
cd ~/
mkdir fftw3
wget http://www.fftw.org/fftw-3.3.8.tar.gz
tar zxvf fftw-3.3.8.tar.gz
cd fftw-3.3.8
./configure --prefix=/home/torobu/fftw3
make
make check
sudo make install
```

最後に、.bashrcに書き加えます。

```vimL
export LD_LIBRARY_PATH=/home/torobu/fftw3/lib:$LD_LIBRARY_PATH
```

##PROJ.4
座標系を計算してくれるそうです。日本列島を相手にする程度なら、直交座標系でもいけると思います。

```viml

cd ~/
mkdir proj4
wget http://download.osgeo.org/proj/proj-5.2.0.tar.gz
tar zxvf proj-5.2.0.tar.gz
cd proj-5.2.0
./configure --prefix=/home/torobu/proj4
make
make check
sudo make install
```
インストール先を.bashrcに書き加えてsource .bashrcで有効にします。

##openmpi
僕はopenmpiとmpichとmpiなどなどの役割も違いも全く理解していません。
経験上openmpiのver2系を使うとJagursが動いたので、それを使います。Ver1では何故か動きませんでした。Ver3については未確認です。

```viml

cd ~/
mkdir openmpi
wget https://download.open-mpi.org/release/open-mpi/v2.1/openmpi-2.1.5.tar.gz
tar zxvf openmpi-2.1.5.tar.gz
cd openmpi-2.1.5
./configure --prefix=/home/torobu/openmpi CC=gcc CFLAGS=-O2 FC=gfortran FFLAGS=-O2 CXX=gcc CXXFLAGS=-O2 FC=gfortran FCFLAGS=-O2 F77=gfortran FFLAGS=-O2
make
make chekc
sudo make install
```

openmpiについては、LD_LIBRARY_PATHだけでなくPATHも加えます。

```shell
export LD_LIBRARY_PATH=/home/torobu/openmpi/lib:$LD_LIBRARY_PATH
export PATH=/home/torobu/openmpi/bin:$PATH
````

最終的に以下のような感じになるはずです！（たぶんな！）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180426/320da178-b112-9de4-d852-57fa0dadeb24.png)
もしかしたら不要なライブラリがあるかもしれないし、もしかしたら他に入れた何かを使ってるかもしれないので謎です。

忘れずに source .bashrc してください。


#Jagursのコンパイル

##gitからJagursをclone
僕が唯一知っているgitの使い方です。

```shell
cd ~/
git clone https://github.com/jagurs-admin/jagurs.git
```

##ソースファイルの修正
このソースファイルはintel fortran compiler だと何故かコンパイルできるのに、gfortran だとコンパイルできない箇所があります。read文のformatの扱いに何か問題があるらしいです。
ですので修正します。

```shell
cd jagurs/src
vi mod_multi.f90
```

66～68行目らへんにある箇所を書き換えます。
Fortranは文頭にきっちりと空白を開ける必要があるので気をつけてください。
また、Fortranの入力フォーマットは*(アスタリスク)にすると、何か適当にいい感じでやってくれます。


```fortran:mod_multi.f90
!変更前
         read(arg(1:j-1), '(i)', err=200) istart(num_paramset)
         read(arg(j+1:len_arg), '(i)', err=200) iend(num_paramset)
!変更後
         read(arg(1:j-1), fmt=*, err=200) istart(num_paramset)
         read(arg(j+1:len_arg), fmt=*, err=200) iend(num_paramset)
```

##Makefile編集
Makefileを編集します。デフォで入っている例はintel fortran compiler と MKL(Math kernel library)の使用を前提にしているので、gcc,gfortranでは通用しないオプション等が入っています。

```vim
cd ~/
cd jagurs/src
vi Makefile
```

```make
# FC: Specify Fortran90 compiler command. コンパイラの選択
FC=mpif90
# Added for displacement.
# PRJ4_DIR: Specify PROJ.4 install directory. proj4のインストール先
PROJ4_DIR=/home/torobu/proj4
# CC&CFLAGS: Specify C compiler command and flags.  C/C++コンパイラ
CC=mpicc
CFLAGS=-g  -I$(PROJ4_DIR)/include

# BASE: Specify basic compiler options.　-cppにしたら動いた。
BASE=-cpp #-fpp -assume byterecl

# FFTW3_INCLUDE_DIR: Specify FFTW3 include directory. fftw3のインストール先
FFTW3_INCLUDE_DIR=/home/torobu/fftw3/include

# FFTW3_LIB: Specify linker options to link FFTW3.
FFTW3_LIB=-L/home/torobu/fftw3/lib -lfftw3 #-mkl=sequential

# OPT: Specify compiler options about optimization level. 
OPT=-O2 -fopenmp -I$(FFTW3_INCLUDE_DIR)  -march=native

# NETCDF: Specify the path to NetCDF library.
NETCDF=/home/torobu/netcdf-fortran

# LIBS: Specify linker options.
LIBS=-L$(NETCDF)/lib -lnetcdff -lnetcdf -L/home/torobu/hdf5/lib -lhdf5_hl -lhdf5 -lcurl -lsz -L$(PROJ4_DIR)/lib -lproj $(FFTW3_LIB) # for NetCDF4!

# EXEC: Specify the name of executable.
EXEC=jagurs

################################################################################
### Set parameters here!                                                     ###
################################################################################
# PREC=REAL_DBLE: All calc. (except file I/O) is performed with double precision.
#      DBLE_MATH: Only intrinsic math functions are performed with double precision.
# Else, all calc. is performed with single precision.
#PREC=DBLE_MATH
PREC=REAL_DBLE

# MPI=ON: MPI version is made.
# Else, serial version is made.  MPIをONにして実行してうまく言ったためしがない！
MPI=OFF #ON
```

#Makeする
編集し終わったらコンパイルします。

```vim
make 
```
この時に-jオプションをつけると失敗します(原因はよくわからないけれども少なくとも僕の時は失敗した）

問題なく作成できたら、jagurs (全て小文字) が作られているはずです。
今の環境で実行できるか確認しましょう。特にライブラリ関係を。
以下のコマンドを実行して、 not found がなければ動くはずです。

```vim
ldd jagurs
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180426/beda0401-fbca-20d8-e29a-36bedc2c4364.png)


#Jagursの実行
実行の前にinputディレクトリの中にあるtsun.parを編集します

```vim
cd ~/
cd jagurs/input
vi tsun.par
```

```fortran
!変更前
procx = 4
procy = 4
!変更後
!procx = 4
!procy = 4
```
の二行をコメントアウトします。fortran の namelist のコメントアウトには ! を使います。
消してもいいです。

いよいよ実行です。

```vim
cd ~/
cd jagurs/input
mpirun ../src/jagurs par=tsun.par
```
これでバーっと画面に何か流れ始めて、CPU使用率が１００％になれば成功です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180426/bc571432-c7f0-a5a6-430c-f0b0f41a9853.png)

~~2分間の計算をするのに、245分（約４時間）かかりました。
これはやばい。まじでやばい。
設定等をまったく調整してませんが、僕の経験上、Xeon E5???の16コアを使った時、このサンプル例よりも多い格子数で、実時間×2くらいで終わってた気がします。やっぱりIntel compiler欲しいなぁ・・・~~

```vim
mpirun -n 1 ../src/jagurs par=tsun.par
```
-n 1 するだけで、14分で計算が終わりました。ですが、CPU使用率は100％でした。
"-n 1" を指定しないと、CPUは4コア(論理8コア）しかないのに、もしかしたら8*8=64の並列計算をしてたため効率が著しく悪くなった（かもしれません）

**僕は プロセス と スレッド と ノード の違いが全くわかっておりません**
**理解する気も無いけどな！**


#まとめ
WSL導入した
いろいろライブラリをコンパイルした
Jagursコンパイルした
Jagurs実行した
たぶん計算できてる。
並列計算の扱いは謎

計算結果の可視化だけで３つくらい記事書ける。

#感想

だれか僕に、良いNvidia製GPUがついてて、良いインテル製CPUが乗ってて煩くないデスクトップパソコンください。

おすすめのターミナルエミュレーターを教えてください。
マウススクロールが有効だったり、保存行数が多かったり、マウスの右クリックで貼り付けできたり、マウスで選択できるターミナルまじ希望