Docker を活用して FrontISTR を使う

はじめに

新しいソフトウェアを使うとき、パスを通したり必要な関連ツールをインストールしたりなどに手間がかかることもある中で、Docker は環境構築をワンストップでやってくれる心強い味方です。

今回は、Docker を用いて FrontISTR のチュートリアルデータに対して計算を行うところまでをなぞります。この記事で計算を行う対象とするデータは、https://github.com/FrontISTR/FrontISTR 内の下記2つです。
1. FrontISTR/tutorial/01_elastic_hinge/ (並列でない計算を行うサンプル: 詳細)
2. FrontISTR/tutorial/02_elastic_hinge_parallel/ (4並列での計算を行うサンプル: 詳細)

筆者の環境は下記の通りです。

$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.4
BuildVersion: 19E287

また、以下では特に断らないかぎり

  • 頭に$が付いている行は、コマンドラインでの入力を
  • ...(省略)は、実際の表示ではなく複数の行を筆者が省いたということを

表すものとします。

準備

Docker のインストール

公式ページからダウンロードします。 Mac の場合、公式ページから「Get Started」→「Download for Mac」と進めていき、ダウンロードした dmg ファイルを開いてインストールします。

FrontISTR のリポジトリを取得する

git clone で FrontISTR のリポジトリを取得します。

$ git clone https://github.com/FrontISTR/FrontISTR.git

01_elastic_hinge で計算を行う

01_elastic_hinge のデータがあるディレクトリに移動します。

$ cd FrontISTR/tutorial/01_elastic_hinge/

ここにあるデータは、下記の3つです。

$ ls
hecmw_ctrl.dat	hinge.cnt	hinge.msh

このディレクトリで下記のように Docker コマンドを打っていきます。pull で Docker イメージをダウンロードし、 run で実行します。

$ docker pull registry.gitlab.com/frontistr-commons/frontistr/fistr1:master
...(省略)
$ docker run -it --sig-proxy=false --rm -u $UID -v $PWD:$PWD -w $PWD registry.gitlab.com/frontistr-commons/frontistr/fistr1:master fistr1 -t 1
##################################################################
#                         FrontISTR                              #
##################################################################
---
version:    5.1.0
git_hash:   f0d80dafddb1cebba2e1583de242212afe90db8f
build:
...(省略)
   2940    1.019967E-08
   2941    9.786161E-09
### Relative residual = 9.80439E-09

### summary of linear solver
      2941 iterations      9.804390E-09
    set-up time      :     2.296752E-01
    solver time      :     1.997907E+02
    solver/comm time :     2.049011E+00
    solver/matvec    :     9.468713E+01
    solver/precond   :     9.121138E+01
    solver/1 iter    :     6.793290E-02
    work ratio (%)   :     9.897442E+01

 Start visualize PSF 1 at timestep 1
### FSTR_SOLVE_NLGEOM FINISHED!

 ====================================
    TOTAL TIME (sec) :    237.42
           pre (sec) :      1.92
         solve (sec) :    235.50
 ====================================
 FrontISTR Completed !!

計算が実行されると、そのディレクトリに計算結果のファイルが吐き出されます。

$ ls
0.log			FSTR.msg		hecmw_ctrl.dat		hinge.cnt		hinge.res.0.0		hinge_vis_psf.0000	hinge_vis_psf.0001
FSTR.dbg.0		FSTR.sta		hecmw_vis.ini		hinge.msh		hinge.res.0.1		hinge_vis_psf.0000.pvtu	hinge_vis_psf.0001.pvtu

ここでの動作について

今回の計算は指定した誤差以内になるまで繰り返される設定となっていました。最終的に求まった近似解の誤差が

### Relative residual = 9.80439E-09

として表示されています。今回だとこの値以内に誤差が収まるまで2941ステップかかりました。

この誤差の指定は、.cnt ファイルで行われています。今回だと hinge.cnt 内で下記のように記載されていました。

...(省略)
### Solver Setting
!SOLVER,METHOD=CG,PRECOND=1,ITERLOG=YES,TIMELOG=YES
10000, 1
1.0e-08, 1.0, 0.0
...(省略)

この部分の記載については、コチラを参照してください。
上記の書き方だと、”CG 法で、誤差1.0e-08以内になるまで、反復回数は10000回まで”と指定されていることになります。表示された誤差

### Relative residual = 9.80439E-09

は1.0e-08より小さいので、指定した誤差内に収まる解を導出できたことがわかります。

それではここで、指定誤差以内に収まらなかった場合の挙動を見るべく、指定する誤差を非常に小さく(=厳しく)してみます。hinge.cnt ファイルを編集し、指定を1.0e-08から1.0e-11に変更します。変更後の hinge.cnt はこのようになります。

...(省略)
### Solver Setting
!SOLVER,METHOD=CG,PRECOND=1,ITERLOG=YES,TIMELOG=YES
10000, 1
1.0e-11, 1.0, 0.0
...(省略)

これで、同様に計算を実行します(先ほど実行したものと同じです)。

$ docker run -it --sig-proxy=false --rm -u $UID -v $PWD:$PWD -w $PWD registry.gitlab.com/frontistr-commons/frontistr/fistr1:master fistr1 -t 1
##################################################################
#                         FrontISTR                              #
##################################################################
---
version:    5.1.0
git_hash:   cf08f004f35215177607c9cc343ee0d569c69c92
build:
...(省略)
   2983    1.082149E-09
   2984    1.031376E-09
   2985    9.688531E-10
   2986    9.215005E-10
...(省略)
   3099    9.195451E-10
   3100    1.163612E-09

計算過程を見てみると、1.0e-09前後からさらに小さくするのは難しいようです。最後には下記のように表示され、計算終了となりました。

   9998    3.019380E-08
   9999    3.019371E-08
  10000    3.024391E-08

  #### HEC-MW-SOLVER-W-3001: 
    not converged within certain iterations

### Relative residual = 3.02439E-08

### summary of linear solver
     10001 iterations      3.024391E-08
    set-up time      :     2.403200E-01
    solver time      :     7.189817E+02
    solver/comm time :     7.560029E+00
    solver/matvec    :     3.399811E+02
    solver/precond   :     3.284820E+02
    solver/1 iter    :     7.189098E-02
    work ratio (%)   :     9.894851E+01

 Start visualize PSF 1 at timestep 1
### FSTR_SOLVE_NLGEOM FINISHED!

 ====================================
    TOTAL TIME (sec) :    758.11
           pre (sec) :      1.87
         solve (sec) :    756.23
 ====================================
 FrontISTR Completed !!

このように、 hinge.cnt 内で指定する内容に従って計算が行われます。

02_elastic_hinge_parallel で並列計算をする

次に、並列計算を実行していきます。FrontISTR/tutorial/02_elastic_hinge_parallel が並列計算用のものなので、そちらに移動します。 01_elastic_hinge ディレクトリとは、中に入っているファイルの構成が異なります。

$ ls
hecmw_ctrl.dat		hecmw_part_ctrl.dat	hinge.cnt		hinge.msh

01_elastic_hinge にはなかった、hecmw_part_ctrl.dat というファイルがあります。これは

!PARTITION,TYPE=NODE-BASED,METHOD=PMETIS,DOMAIN=4,UCD=part.inp

という内容のファイルで、メッシュ分割を行うコマンド hecmw_part1 の動作を指定するファイルです。

まず、hecmw_part1 でメッシュを4つに分割します。

$ docker run -it --sig-proxy=false --rm -u $UID -v $PWD:$PWD -w $PWD  registry.gitlab.com/frontistr-commons/frontistr/fistr1:master hecmw_part1
Oct 23 01:42:53 Info: Reading mesh file...
...(省略)
Oct 23 01:43:08 Info: Domain decomposition done

hinge_4.*  という4つのファイルにメッシュが分割されました。

$ ls
hecmw_ctrl.dat		hecmw_part_ctrl.dat	hinge.msh		hinge_4.1		hinge_4.3
hecmw_part.log		hinge.cnt		hinge_4.0		hinge_4.2		part.inp

次に、mpi-run を使って fistr1 を4並列で走らせます。4並列で計算できない(スロットが足りない)場合は下記のようなメッセージが出ます。

$ docker run -it --sig-proxy=false --rm -u $UID -v $PWD:$PWD -w $PWD  registry.gitlab.com/frontistr-commons/frontistr/fistr1:master mpirun -np 4 fistr1 -t 1
--------------------------------------------------------------------------
There are not enough slots available in the system to satisfy the 4
slots that were requested by the application:

  fistr1
...(省略)

また、すでにメッシュを4つに分解しているため、例えばこの -np のあとの数を2に変更するなどしても、うまく動作しない点にご注意ください。

この場合、-oversubscribe というオプションを付与することでプロセスに対してコアが不足している場合でも実行できます。

$ docker run -it --sig-proxy=false --rm -u $UID -v $PWD:$PWD -w $PWD  registry.gitlab.com/frontistr-commons/frontistr/fistr1:master mpirun -np 4 -oversubscribe fistr1 -t 1
...(省略)
### Relative residual = 9.43589E-09

### summary of linear solver
      2086 iterations      9.435886E-09
    set-up time      :     1.623594E-01
    solver time      :     2.621136E+02
    solver/comm time :     1.002494E+02
    solver/matvec    :     3.755194E+01
    solver/precond   :     8.301867E+01
    solver/1 iter    :     1.256537E-01
    work ratio (%)   :     6.175347E+01

### FSTR_SOLVE_NLGEOM FINISHED!

 ====================================
    TOTAL TIME (sec) :    296.55
           pre (sec) :      1.65
         solve (sec) :    294.90
 ====================================
 FrontISTR Completed !!

無事に計算結果が吐き出されました。

$ ls
0.log			FSTR.dbg.1		hecmw_ctrl.dat		hinge.msh		hinge.res.2.0		hinge_4.1		hinge_vis_psf.0001
1.log			FSTR.dbg.2		hecmw_part.log		hinge.res.0.0		hinge.res.2.1		hinge_4.2		hinge_vis_psf.0001.pvtu
2.log			FSTR.dbg.3		hecmw_part_ctrl.dat	hinge.res.0.1		hinge.res.3.0		hinge_4.3		part.inp
3.log			FSTR.msg		hecmw_vis.ini		hinge.res.1.0		hinge.res.3.1		hinge_vis_psf.0000
FSTR.dbg.0		FSTR.sta		hinge.cnt		hinge.res.1.1		hinge_4.0		hinge_vis_psf.0000.pvtu

実行はできましたが、-oversubscribe なしで実行させるため、メッシュ分割からやり直してみます。

新しく生成したファイルを消して、初期からあったファイルだけに戻します。

$ ls
hecmw_ctrl.dat		hinge.cnt
hecmw_part_ctrl.dat	hinge.msh

hecmw_part_ctrl.datDOMAIN= を4から2に変更します。変更したあとのhecmw_part_ctrl.dat はこのようになります。

!PARTITION,TYPE=NODE-BASED,METHOD=PMETIS,DOMAIN=2,UCD=part.inp

これで hecmw_part1 を実行すると、メッシュが2つに分割されます。

$ docker run -it --sig-proxy=false --rm -u $UID -v $PWD:$PWD -w $PWD  registry.gitlab.com/frontistr-commons/frontistr/fistr1:master hecmw_part1
Oct 23 07:56:41 Info: Reading mesh file...
...(省略)
Oct 23 07:56:54 Info: Domain decomposition done
$ ls
hecmw_ctrl.dat		hinge.cnt		hinge_4.1
hecmw_part.log		hinge.msh		part.inp
hecmw_part_ctrl.dat	hinge_4.0

無事、hinge_4.0hinge_4.1 の2つに分割されました。

それでは、改めて fistr1 を実行します。

$ docker run -it --sig-proxy=false --rm -u $UID -v $PWD:$PWD -w $PWD  registry.gitlab.com/frontistr-commons/frontistr/fistr1:master mpirun -np 2 fistr1 -t 1
...(省略)
### Relative residual = 9.45656E-09

### summary of linear solver
      2077 iterations      9.456556E-09
    set-up time      :     1.124362E+00
    solver time      :     5.686447E+02
    solver/comm time :     2.265372E+02
    solver/matvec    :     9.119144E+01
    solver/precond   :     1.717911E+02
    solver/1 iter    :     2.737817E-01
    work ratio (%)   :     6.016191E+01

 Start visualize PSF 1 at timestep 1
### FSTR_SOLVE_NLGEOM FINISHED!

 ====================================
    TOTAL TIME (sec) :    637.67
           pre (sec) :      3.55
         solve (sec) :    634.12
 ====================================
 FrontISTR Completed !!

-oversubscribe なしで実行できました。

おわりに

この記事では、Docker を活用して FrontISTR の計算を実行する手順を説明しました。Docker を使わずに導入する手順と比べて、計算実行までに至るステップを大幅に省略できます。

弊社では、FOCUS スパコンでの FrontISTR 使用サポートのほか、FrontISTR のカスタマイズも承っております。ご使用の際のお悩みがございましたら、是非とも一度お問い合わせください。