AWS ParallelCluster と OpenFOAM v2106 で 風を感じるために複数インスタンスで並列計算してみた

AWS ParallelClusterでOpenFOAM v2106の実行例としてベンチマークで有名なモーターバイクのチュートリアルを動かして紹介します。
2021.10.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS ParallelCluster 3 の検証ため複数のインスタンスで並列に計算したいです。そんなときはOpenFOAMを使ってバイクで風を感じたいと思います。

「うおおおおおおおおおおおおおおお」

以前AWS ParallelCluster 2 と Graviton2(Arm)の組み合わせでビル群に風を吹かせたことがありました。

今回はAMDのCPUと、あえてvCPU数の少なめのインスタンスを複数台使って計算してみます。

AWS ParallelCluster

検証に利用したクラスターのスペックは以下です。

項目
AWS ParallelCluster 3.0.0
Job Scheduler Slurm
OS Ubuntu 20.04 LTS
CPU AMD
Head Node c5a.large
Compute Node c5a.4xlarge(16vCPU)

以下のコンフィグからクラスターを作成しています。

Region: ap-northeast-1
Image:
  Os: ubuntu2004
HeadNode:
  InstanceType: c5a.large
  Networking:
    ElasticIp: false
    SubnetId: subnet-035be95eeaa091603
  Ssh:
    KeyName: sandbox-key
  LocalStorage:
    RootVolume:
      Size: 50
      Encrypted: false
      VolumeType: gp3
      Iops: 3000
      Throughput: 125
  Iam:
    S3Access:
      - BucketName: blog-parallelcluster-postinstall
        EnableWriteAccess: False
    AdditionalIamPolicies:
      - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Scheduling:
  Scheduler: slurm
  SlurmQueues:
    - Name: cpu-spot
      ComputeResources:
        - Name: c5a4xlarge
          InstanceType: c5a.4xlarge
          MinCount: 0
          MaxCount: 20
      ComputeSettings:
        LocalStorage:
          RootVolume:
            Size: 35
            Encrypted: false
            VolumeType: gp3
            Iops: 3000
            Throughput: 125
      CapacityType: SPOT
      Networking:
         SubnetIds:
           - subnet-035be95eeaa091603
         PlacementGroup:
           Enabled: true
      Iam:
        S3Access:
          - BucketName: blog-parallelcluster-postinstall
            KeyName: read_only/
            EnableWriteAccess: False
        AdditionalIamPolicies:
          - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
    - Name: high-cpu-spot
      ComputeResources:
        - Name: c5a24xlarge
          InstanceType: c5a.24xlarge
          MinCount: 0
          MaxCount: 10
      ComputeSettings:
        LocalStorage:
          RootVolume:
            Size: 35
            Encrypted: false
            VolumeType: gp3
            Iops: 3000
            Throughput: 125
      CapacityType: SPOT
      Networking:
         SubnetIds:
           - subnet-035be95eeaa091603
         PlacementGroup:
           Enabled: true
      Iam:
        S3Access:
          - BucketName: blog-parallelcluster-postinstall
            KeyName: read_only/
            EnableWriteAccess: False
        AdditionalIamPolicies:
          - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

OpenFOAM v2106の準備

必要なライブラリをインストールします。

sudo apt-get update
sudo apt-get install build-essential autoconf autotools-dev cmake gawk gnuplot -y
sudo apt-get install flex libfl-dev libreadline-dev zlib1g-dev openmpi-bin libopenmpi-dev mpi-default-bin mpi-default-dev -y
sudo apt-get install libgmp-dev libmpfr-dev libmpc-dev -y
sudo apt-get install libscotch-dev libptscotch-dev libfftw3-dev libboost-system-dev libboost-thread-dev libcgal-dev -y

必要なソースコードをダウンロード。

cd /tmp
wget https://dl.openfoam.com/source/v2106/OpenFOAM-v2106.tgz
wget https://dl.openfoam.com/source/v2106/ThirdParty-v2106.tgz

ホームディレクトリ直下にOpenFOAMディレクトリが作成され、ダウンロードしたファイルが展開されます。

mkdir $HOME/OpenFOAM && tar -xzf OpenFOAM-v2106.tgz -C $HOME/OpenFOAM && tar -xzf ThirdParty-v2106.tgz -C $HOME/OpenFOAM

OpenFOAMの環境設定ファイルを読み込みます。

source ~/OpenFOAM/OpenFOAM-v2106/etc/bashrc

実行結果

No completions for /home/ubuntu/OpenFOAM/OpenFOAM-v2106/platforms/linuxARM64GccDPInt32Opt/bin
[ignore if OpenFOAM is not yet compiled]

foamコマンドでOpenFOAMのディレクトリ移動できたらOKです。

foam

下準備完了しました。

$ pwd
/home/ubuntu/OpenFOAM/OpenFOAM-v2106

コンパイル

ヘッドノードでコンパイルできますが、ヘッドノードは高スペックではないことが多いです。コンピュートノードでコンパイルさせます。

コンピュートノード1台のvCPU数を確認します。

sinfo --Node --long

16vCPUであることがわかります。

実行結果

Fri Oct 08 10:36:28 2021
NODELIST                         NODES     PARTITION       STATE CPUS    S:C:T MEMORY TMP_DISK WEIGHT AVAIL_FE REASON
cpu-spot-dy-c5a4xlarge-1             1     cpu-spot*       idle% 16     16:1:1      1        0      1 dynamic, none
cpu-spot-dy-c5a4xlarge-2             1     cpu-spot*       idle~ 16     16:1:1      1        0      1 dynamic, none
...snip...

Allwmakeでコンパイルできるのでスクリプトを作成します。-n 16指定で16vCPUを使うように記述します。./Allwmakeはカレントディレクトリ指定ですが、同階層に以下のスクリプトを作成しジョブを投げれば問題なく実行できます。

オプション 説明
-j 有効なすべてのCPUを利用
-s メッセージ出力を抑える
-l teeアウトプット(標準出力とログファイルに出力)

/home/ubuntu/OpenFOAM/OpenFOAM-v2106/run-compile.sh

#! /bin/bash
#SBATCH -n 16
#SBATCH -J compile
#SBATCH -p cpu-spot
./Allwmake -j -s -l

コンパイルに約1時間15分かかりました。 2021-10-09 15-25-03

インストールテストコマンドで結果確認します。

foamInstallationTest

以下を確認できればOpenFOAMの準備完了です。

実行結果

...snip...
Summary
-------------------------------------------------------------------------------
Base configuration ok.
Critical systems ok.

Done

モーターバイクチュートリアルの準備

チュートリアルで用意されているバイクのモデルを使います。

cp -r ~/OpenFOAM/OpenFOAM-v2106/tutorials/incompressible/simpleFoam/motorBike ~/OpenFOAM/work/

ParaViewで可視化するとバイクにまたがるライダーのモデルです。

作業ディレクトリは以下です。

$ pwd
/home/ubuntu/OpenFOAM/work/motorBike

モデル用ディレクトリを作成します。規定のディレクトリ名ではないと後続のコマンドでエラーになります。

mkdir ./constant/triSurface

motorBikeを作業ディレクトリにコピーします。

cp ~/OpenFOAM/OpenFOAM-v2106/tutorials/resources/geometry/motorBike.obj.gz ./constant/triSurface/
gunzip ./constant/triSurface/motorBike.obj.gz

ファイルを編集します。

vi system/controlDict

終了時間を0.5秒から多少伸ばし1秒にしました。並列で演算するので多少計算負荷をあげる目的です。

controlDict

endTime         1000;

初期条件・境界条件ディレクトリ(0)はデフォルト値を使います。リネームしてコピーしました。

cp -r 0.orig/ 0

並列実行数(vCPUの個数)分のディレクトリに分割するための値設定。

cp system/decomposeParDict.6 system/decomposeParDict
vi system/decomposeParDict

128vCPUを指定しました。合わせて(64 2 1)と修正します。x, y, z方向の分割数を意味します。x方向に64分割、y方向に2分割し合計128分割しています。 X分割Y分割の指定必要

decomposeParDict

numberOfSubdomains 128;

method          hierarchical;

coeffs
{
    n           (64 2 1);
}

特徴線を抽出とメッシュ作成。

コマンド 説明
surfaceFeatureExtract 表面形状ファイルから特徴線を抽出する
blockMes 六面体メッシュを作成
surfaceFeatureExtract SnappyHexMesh - Mesh Wiki
surfaceFeatureExtract
blockMesh
snappyHexMesh -overwrite

特徴線を可視化したかったのですがうまく全体的に表示するフィルタがわからず断念。ParaViewを使いこなせていません。

ブロックメッシュは空間にメッシュが切られています。

並列計算するために分割します。

コマンド 説明
decomposePar 並列計算を行う際の領域分割する
decomposePar

ジョブの作成と実行

コンピュートノードで実行するためのスクリプトを作成します。

項目 説明
#SBATCH -n 128vCPU指定
#SBATCH -J ジョブの名前
#SBATCH -p Partitonの指定
simpleFoam SIMPLE 法を用いた非圧縮性流体の定常乱流解析ソルバー
mpirun 並列実行
-parallel OpenFOAMのソルバーのオプションで並列実行指定

run-bike.sh

#!/bin/bash
#SBATCH -n 128
#SBATCH -J bike
#SBATCH -p cpu-spot
source ~/OpenFOAM/OpenFOAM-v2106/etc/bashrc

mpirun simpleFoam -parallel

ジョブを登録します。

sbatch run-bike.sh

コンピュートノードが起動してきました。しばらく放置します。

実行結果を確認すると約6分半で計算終了しました。

...snip...
ExecutionTime = 375.23 s  ClockTime = 394 s
...snip..

コンピュートノードは後続のジョブがなければ自動的に停止して計算リソースの課金も止まります。

並列実行時は計算終了後に後処理が必要です。

コマンド 説明
reconstructPar 分割された計算結果をひとつに結合する
reconstructPar

もう少し計算したかった

思い他あっさり計算が終わってしまったので条件を変更して試します。

終了時間を10秒にしました。10秒分のデータを取ります。

controlDict

endTime         10000;

計算リソースは128vCPuから256vCPUへ2倍に指定します。

decomposeParDict

numberOfSubdomains 256;

method          hierarchical;

coeffs
{
    n           (64 2 2);
}

ジョブを登録します。

sbatch run-bike2.sh

c5a.4xlargeを16台要求しています。

$ sinfo
PARTITION     AVAIL  TIMELIMIT  NODES  STATE NODELIST
cpu-spot*        up   infinite      4  idle~ cpu-spot-dy-c5a4xlarge-[17-20]
cpu-spot*        up   infinite     16  alloc cpu-spot-dy-c5a4xlarge-[1-16]
high-cpu-spot    up   infinite     10  idle~ high-cpu-spot-dy-c5a24xlarge-[1-10]

コンピュートノードが起動してきました。

16台で起動しジョブを処理中です。STがR(Running)です。放置します。

$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                17  cpu-spot     bike   ubuntu  R       1:38     16 cpu-spot-dy-c5a4xlarge-[1-16]

実行結果から約1時間10分で計算終わりました。

ExecutionTime = 4142.99 s  ClockTime = 4752 s

計算結果の可視化

1時間弱計算したデータは圧縮して11GBになりました。ParaViewで可視化しますが容量が大きくなるとクラウド側で可視化まで行いたくなります。いろいろと用意ができていないためローカルに転送して確認します。

転送してきたデータと同ディレクトリ内にhoge.foamの空ファイルを作成します。

touch paraview.foam

ParaViewで作成したhoge.foamファイルを開きます。

バイクの断面をSliceで見てみたり

StreamTracerで流線をプロットしてみたり

ParaViewを使って可視化し分析するはずですが、あいにく使いこなせていません。

おわりに

ParallelClusterで計算することは簡単なので計算リソースが足りていないときはクラウドもいかがでしょうか。ParallelClusterなら計算リソースはほぼ無尽蔵にあるのでジョブ待ちはないですし、個別にクラスター作成も容易です。

最後にParaViewを使いこなせなくブログ栄えするはずの可視化のクオリティが低くくて本当に残念。以下のリンクの画像は分析とは直接関係ないかもしれませんがブログ栄えしていてうらやましいです。AWS ParallelCluster 3でなにか計算したかっただけなので10台以上のインスタンスと、1時間ほど計算できたので動作検証としては満足しています。

参考