AWS ParallelClusterでOpenFOAMを並列実行してみる

2020.12.07

OpenFOAMの計算処理をクラウドのHPCクラスター環境(ParallelCluster)で並列実行してみます。 下のような画像は見かけるとは思うのですけど、まず何したらこういうシュミレーションができるのかわからないと思います。というわけでクラスター構築から計算、可視化に至るまでの工程をやってみました。

概要

  • Graviton2(Arm)を使ったHPCクラスター環境(ParallelCluster)
  • OpenFOAMの計算を64vCPUの2インスタンスで合計128vCPUで並列実行
  • 1vCPUと、128vCPU指定のジョブ登録パターンの紹介

こちらのビル郡のモデルに前方から風を吹かせます。

ビル群の周りに風洞となる囲いを用意し、半透明で表示しているのがその囲いです。

HPCクラスター環境(ParallelCluster)で計算すると風が流れを可視化できるというのをやってみます。

AWS ParallelClusterとは

AWSがサポートするオープンソースのクラスター管理ツールです。HPCクラスター環境を簡単に作成、管理できます。ようはクラウドHPC環境を手軽に構築できるツールです。HPCクラスターの裏側は様々なAWSのサービスを組み合わせで動いています。

Graviton2とは

コスパがいいならHPC分野でも試してみたくなりますよね?試してみましょう!

AWS ParallelCluster環境構築

まずParallelClusterでクラスターを作成するための管理コマンドの準備はこちらから。

クラスターは前回の検証で作成したものを流用しています。

項目
ParallelCluster 2.10.0
JobScheduler Slurm
OS Ubuntu 18.04 LTS
AMI aws-parallelcluster-2.10.0-ubuntu-1804-lts-hvm-arm64-202011172100
Architecture Arm(Graviton2)
HeadNode c6g.large
ComputeNode c6g.16xlarge(64vCPU)

OpenFOAMはソースからParallelClusterのヘッドノードでビルドしました。前回Graviton2(Arm)インスタンスと同様の手順でビルドできました。ヘッドノードはc6g.large(vCPU:2)だったこともあり、コンパイル終了まで2時間半かかりました。

項目 バージョン
OpenFOAM v20 06
Open MPI 4.0.5
gcc 7.5.0

クラスター環境で計算してみる

本題のビル郡に風を流すチュートリアル(windAuroundBuildings)をクラスター環境で動作検証に利用します。

ParallelClusterのヘッドノードのhomeディレクトリと/sharedディレクトリはコンピューノードにデフォルトで共有されます。計算結果が数GBになるため/sharedディレクトリへコピーしています。

$ cp -r /home/ubuntu/OpenFOAM/OpenFOAM-v2006/tutorials/incompressible/simpleFoam/windAroundBuildings/ /shared/windAuroundBuildings

チュートリアルファイルの設定変更

計算の制御設定は controlDict ファイルを編集します。

$ cd /shared/windAuroundBuildings
$ vi system/controlDict

計算終了時間を400msから1,000ms(1秒)に変更しました。計算処理にかかる時間が1秒というわけではありません。計算後、風の流れる様子を動画のように再生できるのですがその時間が1秒分になります。つまり、実際の計算処理は時間を伸ばした分だけ大きくなります。

controlDict

endTime         1000;

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

$ cp -r 0.orig/ 0

OpenFOAMの準備

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

PraViewで確認するとビル郡には細かくメッシュが切られていました。

空間にもメッシュが切られています。

クラスターで計算

手始めにシングルコア(1vCPU指定)でコンピューノードを使って計算させます。ヘッドノードに登録するジョブのスクリプトを作成します。Partitionが2つあるクラスター環境のため最初にPartitonNameを確認します。 c6g.16xlargeを起動できる PartitionNameが16x のPartitionを指定して実行させます。

$ scontrol show partition
PartitionName=16x
   AllowGroups=ALL AllowAccounts=ALL AllowQos=ALL
   AllocNodes=ALL Default=NO QoS=N/A
   DefaultTime=NONE DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO
   MaxNodes=UNLIMITED MaxTime=UNLIMITED MinNodes=0 LLN=NO MaxCPUsPerNode=UNLIMITED
   Nodes=16x-dy-c6g16xlarge-[1-8]
   PriorityJobFactor=1 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO
   OverTimeLimit=NONE PreemptMode=OFF
   State=UP TotalCPUs=512 TotalNodes=8 SelectTypeParameters=NONE
   JobDefaults=(null)
   DefMemPerNode=UNLIMITED MaxMemPerNode=UNLIMITED

PartitionName=2x
   AllowGroups=ALL AllowAccounts=ALL AllowQos=ALL
   AllocNodes=ALL Default=YES QoS=N/A
   DefaultTime=NONE DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO
   MaxNodes=UNLIMITED MaxTime=UNLIMITED MinNodes=0 LLN=NO MaxCPUsPerNode=UNLIMITED
   Nodes=2x-dy-c6g2xlarge-[1-32]
   PriorityJobFactor=1 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO
   OverTimeLimit=NONE PreemptMode=OFF
   State=UP TotalCPUs=256 TotalNodes=32 SelectTypeParameters=NONE
   JobDefaults=(null)
   DefMemPerNode=UNLIMITED MaxMemPerNode=UNLIMITED
項目 説明
#SBATCH -n 1 1vCPU指定
#SBATCH -J OpenFOAM ジョブの名前
#SBATCH -p 16x Partitonの指定
simpleFoam SIMPLE 法を用いた非圧縮性流体の定常乱流解析ソルバー

run_blog1.sh

#!/bin/bash
#SBATCH -n 1
#SBATCH -J OpenFOAM
#SBATCH -p 16x

source ~/OpenFOAM/OpenFOAM-v2006/etc/bashrc
cd /shared/windAuroundBuildings

simpleFoam

ジョブ登録

$ sbatch run_blog1.sh

キューを確認。c6g.16xlargeが1台起動してきました。計算が終わるまで待ちます。 ジョブ実行中の標準出力内容はヘッドノードのhomeディレクトリに保存されます。

$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                13       16x OpenFOAM   ubuntu  R       0:04      1 16x-dy-c6g16xlarge-1

計算終了。実行時間はシングルコアで 15分24秒 でした。

---省略---
ExecutionTime = 924.38 s  ClockTime = 943 s
---省略---
parProfiling:
    reduce    : avg = 0s
                min = 0s (processor 0)
                max = 0s (processor 0)
    all-all   : avg = 0s
                min = 0s (processor 0)
                max = 0s (processor 0)
End

計算結果の可視化

ParaViewで可視化用に hoge.foam を作成。.foamの拡張子であれば任意の名前でOKです。

$ cd /shared
$ touch windAuroundBuildings/paraview.foam

ローカルへ転送して可視化したいいので圧縮。2GBになりました。

$ tar -zcvf windAuroundBuildings.tar.gz windAuroundBuildings

ParaViewで開くとビル郡に風が流れている様子を確認できます。ParallelClusterのクラスター環境でOpenFOAMを実行できることを確認できました。

スライスして断面を確認することもできます。ただのついたてみたいですが...

ついたてをいい感じに半透明にしたり、流れを矢印にしたりと可視化方法はいろいろあります。

クラスターで並列実行してみる

クラスター環境なのにシングルコアで実行しても面白くないですね。64vCPUのインスタンス2台を使って、1台のインスタンスではできないコア数の128vCPUで計算してみましょう。

同じようにチュートリアルファイルをコピーし、初期設定のここまではまったく同じです。

$ cp -r /home/ubuntu/OpenFOAM/OpenFOAM-v2006/tutorials/incompressible/simpleFoam/windAroundBuildings/ /shared/windAuroundBuildings_parallel
$ cd /shared/windAuroundBuildings_parallel/
$ vi system/controlDict # 1000(秒)に書き換え
$ cp -r 0.orig/ 0

並列実行準備

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

$ vi system/decomposeParDict

6から128に変更。

decomposeParDict

numberOfSubdomains 128;

メッシュ作成。

$ surfaceFeatureExtract
$ blockMesh
$ snappyHexMesh -overwrite
コマンド 説明
decomposePar 並列計算を行う際の領域分割する
$ decomposePar

分割した分だけのディレクトリが作成されます。 decomposePar前は 8個 だったディレクトリが 136個 になりました。

Befor

$ ls -U1 | wc -l
8

After

$ ls -U1 | wc -l
136

並列実行

並列実行用のジョブ作成。

項目 説明
#SBATCH -n 128 128vCPU指定
mpirun 並列実行
-parallel OpenFOAMのソルバーのオプションで並列実行指定

run_blog2.sh

#!/bin/bash
#SBATCH -n 128
#SBATCH -J OpenFOAM
#SBATCH -p 16x
source ~/OpenFOAM/OpenFOAM-v2006/etc/bashrc
cd /shared/windAuroundBuildings_parallel

mpirun simpleFoam -parallel

ジョブ登録

$ sbatch run_blog2.sh

64vCPUのインスタンス2台(NODES:2)がコンピューノードとして起動してきます。

$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                16       16x OpenFOAM   ubuntu CF       0:34      2 16x-dy-c6g16xlarge-[1-2]

計算終了。実行時間は128vCPUで 2分5秒 でした。約7倍早く計算が終了しました。パワーが違います。

---省略---
ExecutionTime = 125.85 s  ClockTime = 165 s
---省略---
parProfiling:
    reduce    : avg = 94.8041s
                min = 57.42s (processor 0)
                max = 105.52s (processor 124)
    all-all   : avg = 37.7317s
                min = 19.82s (processor 0)
                max = 46.36s (processor 55)
End

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

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

並列実行後の計算結果も同様にParaViewで可視化できました。

おわりに

ParallelCluster + Graviton2(Arm)はまだ開拓者が少なさそうなので検証しました。結果、OpenFOAMは動作しノード間をまたがった計算を容易に実行することが確認できました。ParallelClusterのクラスター構築もGraviton2だからといって特別なお作法なく利用することができました。 ちなみにOpenFOAMは初心者です。並列実行したかっただけなので触りながら覚えていきました。可視化ひとつとってもParaView力不足でとうまく表現できなくまだまだ勉強が必要です。

以上、網走の大村でした。

参考

PENGUINITIS - 計算の制御の設定
surfaceFeatureExtract コマンド | 株式会社ソフトフロー
PENGUINITIS - 領域分割
SnappyHexMesh - Mesh Wiki
windAroundBuildings - YouTube