WSLにCode_Aster14.6並列版のインストール

# はじめに
WSLで並列版Code_Asterが構築ができたので共有したいと思います。
先人たちに感謝。

* [Code_Aster14.4の並列化] (https://qiita.com/hiro_kuramoto/items/269ecf6293cfbe38b314)

# 環境
OS : Windows 10
WSL : Ubuntu 18.04 LTS

インストール済みのパッケージの問題でエラーが発生することがあるので新規ディストリビューションを作ってインストールするのも一考です。

* [WSLで使い捨てのUbuntuをポコポコ作る](https://qiita.com/akiraak/items/12646cc0d1746c1bedd5)

# インストール 工程
以下の工程でインストールしていきます。工程３まで実施すれば単一版は動きます。

1. 準備
1. OpenBLAS 
1. Code_Aster with OpenBLAS
1. ScaLAPACK
1. Parmetis, Scotch, MUMPS
1. Petsc
1. 並列版Code_Aster

#1 準備
Windowsの環境変数を読み込むとエラーが出るようなので読み込まないように設定します。

```bash
echo -e "[interop] \nappendWindowsPath = false" |sudo tee /etc/wsl.conf
```
上記を反映するためにwslを再起動します。

次にインストール先 ( /opt )の所有権の変更と必要なパッケージのインストールを行います。

```bash
sudo chown username /opt    #usernameにユーザ名を入れる
sudo apt update
sudo apt install gcc g++ gfortran cmake python3 python3-dev python3-numpy tk tcl bison flex liblapack-dev libblas-dev libboost-all-dev zlib1g-dev libsuperlu-dev grace git libx11-dev swig
```

下記バージョンのソースをサイトからダウンロードして~/softwareに置きます。

| パッケージ | バージョン                            | ダウンロード先                                                   |
|:----------|:-------------------------------------|:----------------------------------------------------------------|
| Code_Aster| aster-full-src-14.6.0-1.noarch.tar.gz| https://www.code-aster.org                                      |
| OpenBLAS  | OpenBLAS-0.2.20.tar.gz               | https://github.com/xianyi/OpenBLAS/                             |
| ScaLAPACK | scalapack_installer.tgz              | http://www.netlib.org/scalapack/#_scalapack_installer_for_linux |
|  | scalapack-2.0.0.tgz              |  |
| Parmetis  | parmetis-4.0.3.tar.gz                | http://glaros.dtc.umn.edu/gkhome/metis/parmetis/download        |
| Petsc     | petsc-3.9.4.tar.gz                   | https://www.mcs.anl.gov/petsc/download/index.html               |
|hypre |hypre_2.14.0.orig.tar.gz| https://launchpad.net/ubuntu/+source/hypre|

##2 OpenBLAS
解凍してインストールしていきます。
利用しているCPUがTargetList.txtにない場合はインストールを失敗するので適当なCPUを指定しておきます。

```bash
cd ~/software
tar xf OpenBLAS-0.2.20.tar.gz 
cd OpenBLAS-0.2.20
make NO_AFFINITY=1 USE_OPENMP=1  TARGET=HASWELL
make PREFIX=/opt/OpenBLAS install  TARGET=HASWELL
echo /opt/OpenBLAS/lib | sudo tee -a /etc/ld.so.conf.d/openblas.conf
sudo ldconfig
```
##3 Code_Aster with OpenBLAS
並列版の前に単一版をインストールします。

```bash
cd ~/software
tar xf aster-full-src-14.6.0-1.noarch.tar.gz
cd aster-full-src-14.6.0
sed -i "s:PREFER_COMPILER\ =\ 'GNU':PREFER_COMPILER\ =\'GNU_without_MATH'\nMATHLIB=\ '/opt/OpenBLAS/lib/libopenblas.a':g" setup.cfg
python3 setup.py install
```

私の環境ではサマリーは以下でした。

```bash
...
--------------------------------------------------------------------------------
     SUMMARY OF INSTALLATION
--------------------------------------------------------------------------------
...

Installation of   : aster 14.6.0
Destination       : /opt/aster
Elapsed time      : 519.89 s
                                                                      [  OK  ]
Installation of   : Code_Aster + 9 of its prerequisites
Destination       : /opt/aster
Elapsed time      : 1330.75 s
                                                                      [  OK  ]
```

テスト計算も実施してみます。

```bash
/opt/aster/bin/as_run --vers=14.6 --test forma01a

...
as_run 2020.0

------------------------------------------------------------
--- DIAGNOSTIC JOB : <A>_ALARM
------------------------------------------------------------
```

アラームが出ますが計算できているようです。

---
ここで並列計算用のホストファイルを作成しておきます。

```bash
echo "$HOSTNAME cpu=$(cat /proc/cpuinfo | grep processor | wc -l)" > /opt/aster/etc/codeaster/mpi_hostfile
```
---

##4 ScaLAPACK
解凍してインストールしていきます。
scalapack.tgzを先に/build/download へ配置してからセットアップします。

```bash
cd ~/software
tar xf scalapack_installer.tgz 
mkdir -p scalapack_installer/build/download
cp scalapack-2.0.0.tgz scalapack_installer/build/download/
mv scalapack_installer/build/download/scalapack-2.0.0.tgz scalapack_installer/build/download/scalapack.tgz
cd scalapack_installer
./setup.py --lapacklib=/opt/OpenBLAS/lib/libopenblas.a --mpicc=mpicc --mpif90=mpif90 --mpiincdir=/usr/lib/x86_64-linux-gnu/openmpi/include --ldflags_c=-fopenmp --ldflags_fc=-fopenmp --prefix=/opt/scalapack
```

##5 Parmetis,Scotch,MUMPS
###5.1 Parmetis
解凍してmetis.hを編集してからインストールします。

```bash
cd ~/software
tar xf parmetis-4.0.3.tar.gz 
cd parmetis-4.0.3
sed -i -e 's/#define IDXTYPEWIDTH 32/#define IDXTYPEWIDTH 64/' metis/include/metis.h
make config prefix=/opt/parmetis-4.0.3 
make
make install
```

###5.2 Scotch
先ほど解凍したaster-full-src-14.6.0/SRC に含まれているscotch-6.0.4-aster7.tar.gz を/opt に解凍します。
解凍したscotch-6.0.4/src に移りビルドします。

```bash
cd /opt
tar xf ~/software/aster-full-src-14.6.0/SRC/scotch-6.0.4-aster7.tar.gz
cd scotch-6.0.4/src
make scotch esmumps ptscotch ptesmumps CCD=mpicc
```

###5.3 MUMPS
これについても、aster-full-src-14.6.0/SRC に含まれている mumps-5.1.2-aster7.tar.gz を/opt に解凍して移動します。

```bash
cd /opt
tar xf ~/software/aster-full-src-14.6.0/SRC/mumps-5.1.2-aster7.tar.gz
cd mumps-5.1.2
```

この場所に下記のようなMakefile.inc を作成します。

<details><summary>**Makefile.inc**（クリックして表示）</summary><div>

```bash:Makefile.inc
################################################################################
ISCOTCH    = -I/opt/aster/public/metis-5.1.0/include -I/opt/parmetis-4.0.3/include -I/opt/scotch-6.0.4/include
LSCOTCH    = -L/opt/aster/public/metis-5.1.0/lib -L/opt/parmetis-4.0.3/lib -L/opt/scotch-6.0.4/lib -L/opt/scalapack/lib -Wl,-Bdynamic -lesmumps -lptscotch -lptscotcherr -lptscotcherrexit -lscotch -lscotcherr -lscotcherrexit 
LPORDDIR = $(topdir)/PORD/lib/
IPORD    = -I$(topdir)/PORD/include/
LPORD    = -L$(LPORDDIR) -lpord
LMETIS    = -L/opt/aster/public/metis-5.1.0/lib -L/opt/parmetis-4.0.3/lib -L/opt/scotch-6.0.4/lib -L/opt/scalapack/lib -Wl,-Bdynamic -lparmetis  -Wl,-Bdynamic -lmetis  
ORDERINGSF  = -Dpord -Dmetis -Dparmetis -Dscotch -Dptscotch
ORDERINGSC  = $(ORDERINGSF)
LORDERINGS = $(LMETIS) $(LPORD) $(LSCOTCH)
IORDERINGSF = $(ISCOTCH)
IORDERINGSC = $(IMETIS) $(IPORD) $(ISCOTCH)
################################################################################

PLAT    =
LIBEXT  = .a
OUTC    = -o 
OUTF    = -o 
RM      = /bin/rm -f
CC      = mpicc
FC      = mpif90
FL      = mpif90
# WARNING: AR must ends with a blank space!
AR      = /usr/bin/ar rcs 
#
RANLIB  = echo

#
INCPAR = -I/opt/aster/public/metis-5.1.0/include -I/opt/parmetis-4.0.3/include -I/opt/scotch-6.0.4/include
LIBPAR = 
#
INCSEQ = -I$(topdir)/libseq
LIBSEQ = -L$(topdir)/libseq -lmpiseq

#
LIBBLAS = -L/opt/aster/public/metis-5.1.0/lib -L/opt/parmetis-4.0.3/lib -L/opt/scotch-6.0.4/lib -L/opt/scalapack/lib -Wl,-Bdynamic -lpthread -lm -lblas -llapack -lscalapack -L/opt/OpenBLAS/lib -lopenblas 
LIBOTHERS =  -L/opt/aster/public/metis-5.1.0/lib -L/opt/parmetis-4.0.3/lib -L/opt/scotch-6.0.4/lib -L/opt/scalapack/lib -Wl,-Bdynamic -ldl -lutil -lpthread   
#Preprocessor defs for calling Fortran from C (-DAdd_ or -DAdd__ or -DUPPER)
CDEFS   = -D_USE_MPI=1 -DHAVE_MPI=1 -D_USE_OPENMP=1 -DHAVE_METIS_H=1 -D_HAVE_METIS=1 -DHAVE_METIS=1 -DHAVE_PARMETIS_H=1 -D_HAVE_PARMETIS=1 -DHAVE_PARMETIS=1 -DHAVE_STDIO_H=1 -DHAVE_SCOTCH=1 -DAdd_ -Dmetis -Dparmetis

#Begin Optimized options
OPTF    = -O -fPIC -DPORD_INTSIZE64 -fopenmp
OPTL    = -O -Wl,--export-dynamic -fopenmp -L/opt/aster/public/metis-5.1.0/lib -L/opt/parmetis-4.0.3/lib -L/opt/scotch-6.0.4/lib -L/opt/scalapack/lib -L/usr/lib -L/usr/lib/x86_64-linux-gnu/openmpi/lib -L/opt/aster/public/metis-5.1.0/lib -L/opt/parmetis-4.0.3/lib -L/opt/scotch-6.0.4/lib -L/opt/scalapack/lib -L/usr//lib -L/usr/lib/x86_64-linux-gnu/openmpi/lib -Lnow -Lrelro -L/opt/aster/public/metis-5.1.0/lib -L/opt/parmetis-4.0.3/lib -L/opt/scotch-6.0.4/lib -L/opt/scalapack/lib -L/usr//lib -L/usr/lib/x86_64-linux-gnu/openmpi/lib -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. -lmpi_usempif08 -lmpi_usempi_ignore_tkr -lmpi_mpifh -lmpi -lgfortran -lquadmath -lpthread -L/opt/aster/public/metis-5.1.0/lib -L/opt/parmetis-4.0.3/lib -L/opt/scotch-6.0.4/lib -L/opt/scalapack/lib -L/usr//lib -L/usr/lib/x86_64-linux-gnu/openmpi/lib
OPTC    = -O -fPIC -fopenmp
#End Optimized options

INCS = $(INCPAR)
LIBS = $(LIBPAR)
LIBSEQNEEDED = 
```

</div></details>

準備ができたらビルドします。

```bash
make all
```

##6 Petsc
これも同じく /opt で解凍します。
/opt/petsc-3.9.4/config/BuildSystem/config/packages にある metis.py ファイルの43~48行目をコメントアウトします。
さらにOpenMPIのライブラリをLD_LIBRARY_PATHに登録してから、configure にhypreの保存先を指定して実行し、ビルドします。

```bash
cd /opt
tar xf ~/software/petsc-3.9.4.tar.gz
cd petsc-3.9.4
sed -i '43,48 s/^/#/g' config/BuildSystem/config/packages/metis.py
export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/openmpi/lib/:$LD_LIBRARY_PATH
./configure --with-debugging=0 COPTFLAGS=-O CXXOPTFLAGS=-O FOPTFLAGS=-O --with-shared-libraries=0 --with-scalapack-dir=/opt/scalapack --PETSC_ARCH=linux-metis-mumps --with-metis-dir=/opt/aster/public/metis-5.1.0 --with-parmetis-dir=/opt/parmetis-4.0.3 --with-ptscotch-dir=/opt/scotch-6.0.4 --LIBS="-lgomp" --with-mumps-dir=/opt/mumps-5.1.2 -with-x=0 --with-blas-lapack-lib=[/opt/OpenBLAS/lib/libopenblas.a] --download-ml=yes --download-hypre=[path/to/hypre]
make PETSC_DIR=/opt/petsc-3.9.4 PETSC_ARCH=linux-metis-mumps all
```

##7 並列版Code_Aster

/opt/aster/etc/codeaster/asrun の mpi_get_procid_cmdの部分を書き換えます。

```bash
sed -i 's/mpi_get_procid_cmd.*/mpi_get_procid_cmd : echo $OMPI_COMM_WORLD_RANK/'  /opt/aster/etc/codeaster/asrun
```

Code_Aster のソースファイル内に並列版Code_Aster のソースファイルがあるので解凍して移動します。

```bash
cd ~/software/aster-full-src-14.6.0/SRC
tar xf aster-14.6.0.tgz
cd aster-14.6.0
```

waftools/mathematics.py の362~364行目をコメントアウトします。

```bash
sed -i '362,364 s/^/#/g' waftools/mathematics.py
```

次に現在のディレクトリ内（aster-full-src-14.6.0/SRC/aster-14.6.0）に下に示すような
Ubuntu_gnu_mpi.py と Ubuntu_gnu.py を作成します。

<details><summary>**Ubuntu_gnu_mpi.py**（クリックして表示）</summary><div>

```python:Ubuntu_gnu_mpi.py
# encoding: utf-8

"""
Fichier de configuration WAF pour version parallèle sur Ubuntu 14.6 :
- Compilateur : GNU
- MPI         : système (OpenMPI, Ubuntu 14.6)
- BLAS        : OpenBLAS
- Scalapack   : système (Ubuntu 14.6)
- PETSc       : 
"""

import Ubuntu_gnu

def configure(self):
    opts = self.options
    Ubuntu_gnu.configure(self)

    self.env.prepend_value('LIBPATH', [
        '/opt/petsc-3.9.4/linux-metis-mumps/lib',
        '/opt/parmetis-4.0.3/lib',
        '/opt/mumps-5.1.2/lib',])

    self.env.prepend_value('INCLUDES', [
        '/opt/petsc-3.9.4/linux-metis-mumps/include',
        '/opt/petsc-3.9.4/include',
        '/usr/include/superlu',
        '/opt/parmetis-4.0.3/include',
        '/opt/mumps-5.1.2/include',])

    self.env.append_value('LIB', ('X11',))

    opts.parallel = True

    opts.enable_mumps  = True
    opts.mumps_version = '5.1.2'
    opts.mumps_libs = 'dmumps zmumps smumps cmumps mumps_common pord metis scalapack openblas esmumps scotch scotcherr'
#    opts.embed_mumps = True

    opts.enable_petsc = True
    opts.petsc_libs='petsc HYPRE ml'
#    opts.petsc_libs='petsc'
#    opts.embed_petsc = True

#    opts.enable_parmetis  = True
    self.env.append_value('LIB_METIS', ('parmetis'))
    self.env.append_value('LIB_SCOTCH', ('ptscotch','ptscotcherr','ptscotcherrexit','ptesmumps'))

```

</div></details>

<details><summary>**Ubuntu_gnu.py**（クリックして表示）</summary><div>

```python:Ubuntu_gnu.py
# encoding: utf-8

"""
Fichier de configuration WAF pour version séquentielle sur Ubuntu 14.6 :
- Compilateur : GNU
- BLAS        : OpenBLAS
"""
import os

def configure(self):
    opts = self.options

    # mfront path
#    self.env.TFELHOME = '/opt/tfel-3.2.0'

    self.env.append_value('LIBPATH', [
        '/opt/aster/public/hdf5-1.10.3/lib',
        '/opt/aster/public/med-4.0.0/lib',
        '/opt/aster/public/metis-5.1.0/lib',
        '/opt/scotch-6.0.4/lib',
        '/opt/scalapack/lib',
        '/opt/OpenBLAS/lib',])
#        '/opt/tfel-3.2.0/lib',

    self.env.append_value('INCLUDES', [
        '/opt/aster/public/hdf5-1.10.3/include',
        '/opt/aster/public/med-4.0.0/include',
        '/opt/aster/public/metis-5.1.0/include',
        '/opt/scotch-6.0.4/include',
        '/opt/scalapack/include',
        '/opt/OpenBLAS/include'])
#        '/opt/tfel-3.2.0/include',

    opts.maths_libs = 'openblas superlu'
#    opts.embed_math = True

    opts.enable_hdf5 = True
    opts.hdf5_libs  = 'hdf5 z'
#    opts.embed_hdf5 = True

    opts.enable_med = True
    opts.med_libs  = 'med stdc++'
#    opts.embed_med  = True

    opts.enable_mfront = False

    opts.enable_scotch = True
#    opts.embed_scotch  = True

    opts.enable_homard = True
#    opts.embed_aster    = True
#    opts.embed_fermetur = True

    # add paths for external programs
#    os.environ['METISDIR'] = '/opt/aster/public/metis-5.1.0'
#    os.environ['GMSH_BIN_DIR'] = '/opt/aster/public/gmsh-3.0.6-Linux/bin'
    os.environ['HOMARD_ASTER_ROOT_DIR'] = '/opt/aster/public/homard-11.12'

    opts.with_prog_metis = True
#    opts.with_prog_gmsh = True
    # salome: only required by few testcases
    # europlexus: not available on all platforms
#    opts.with_prog_miss3d = True
    opts.with_prog_homard = True
#    opts.with_prog_ecrevisse = True
    opts.with_prog_xmgrace = True
```
</div></details>

準備ができたらインストールしていきます。

```bash
export ASTER_ROOT=/opt/aster
export PYTHONPATH=/$ASTER_ROOT/lib/python3.6/site-packages/:$PYTHONPATH
./waf configure --use-config-dir=$ASTER_ROOT/14.6/share/aster --use-config=Ubuntu_gnu_mpi --prefix=$ASTER_ROOT/PAR14.6MUPT
./waf install -p --jobs=1
```

完了したら、ASTKでCode_Aster並列版が使用できるように14.6MUPTという名前で登録します。
/opt/aster/etc/codeaster/ に aster というファイルがありますので、それの最後の行に以下のように追加します。


```vim:/opt/aster/etc/codeaster/aster
# Code_Aster versions
# versions can be absolute paths or relative to ASTER_ROOT
# examples : NEW11, /usr/lib/codeaster/NEW11

# default version (overridden by --vers option)
default_vers : stable

# available versions
# DO NOT EDIT FOLLOWING LINE !
#?vers : VVV?
vers : stable:/opt/aster/14.6/share/aster
vers : 14.6MUPT:/opt/aster/PAR14.6MUPT/share/aster
``` 

以上で全て完了ですが、このインストール方法ではconfig.txtとprofile.shが見つからないといわれるので
所定の位置にそれらのリンクを張ります。

```bash
ln -s /opt/aster/PAR14.6MUPT/share/aster/config.txt /opt/aster/PAR14.6MUPT/config.txt
ln -s /opt/aster/PAR14.6MUPT/share/aster/profile.sh /opt/aster/PAR14.6MUPT/profile.sh
```

並列版を指定してテストしてみます。

```bash
/opt/aster/bin/as_run --vers=PAR14.6MUPT --test forma01a
...

(*) cpu and system times may be not correctly counted using mpirun.

as_run 2020.0

------------------------------------------------------------
--- DIAGNOSTIC JOB : <A>_ALARM
------------------------------------------------------------
```

アラームが出ますがMPIで計算できているようです。
以上で終わりです。ありがとうございました。