はじめに
ParallelCluster で GROMACS を動かす方法を学習する英語のワークショップ Gromacs with AWS ParallelCluster があります。ParallelCluster は AWS が提供する OSS で、AWS でハイパフォーマンスコンピューティング (HPC) クラスターをデプロイして管理
英語のワークショップを日本語に整理してまとめます。
概要
GROMACS を ParallelCluster で動かすワークショップです。Spack を利用して GROMACS をインストールして、複数 ComputeNode で稼働する内容を確認します。
この記事では、 hpc6a を利用するためリージョンは、オハイオを利用します。
ParallelCluster UI を導入
ParallelCluster UI を導入します。ParallelCluster は CLI でも実行できますが、より視覚的にわかりやすく管理できる UI が便利なので、これで行います。
上記のリンクを参照して Deploy ParallelCluster UI ボタンを押します。
メールアドレスを指定します。テンポラリーパスワードが送付されます。
Ohio リージョンを指定していることを確認して Create stack を押します。だいたい 20 分待機すると、ParallelCluster の UI が立ち上がってきます。
テンポラリーパスワードのお知らせがメールで送られます。
ParallelCluster UI の URL を Output で確認可能
Cognito の画面が表示され、メールアドレスとパスワードを入れてログインします。
ParallelCluster UI の画面が開かれます。
1 画面から複数の Region を選択可能です。us-east-2 を選択します。
ParallelCluster の作成
ParallelCluster UI 上で、クラスターを作成します。今回の手順で作成する AWS リソースを表形式で紹介します
Parameter | Description |
---|---|
Shared Storage | 1.2 TB の容量を持つ FSx for Luster を作成し、/shared にマウントする |
HeadNode | HeadNode で c5a.2xlarge のインスタンスを作成する。8 vCPU, 16 GB メモリ。 |
Compute Queue | hpc6a.48xlarge のインスタンスを利用。96 物理コアと 384 GB メモリ。 |
Spot Queue | c6i.32xlarge のインスタンスを、スポットインスタンスとして指定。64 物理コアと 288 GB メモリを利用。重要なのはスポットインスタンスを指定するため、最大 90% の低価格なインスタンスを指定可能。 |
Note : インスタンスの違い
Instance Size | Cores | Memory (GiB) | EFA Network Bandwidth (Gbps) | Network Bandwidth (Gbps)* | On-Demand Price |
---|---|---|---|---|---|
hpc6a.48xlarge | 96 | 384 | 100 | 25 | $2.88 |
c6i.32xlarge | 64 | 288 | 50 | 25 | $5.44 |
ワークショップの URL に添付されている Download Template でテンプレートファイル (gromacs-config-multi-queue.yaml) をダウンロードします。
Create cluster を with a template を選択します。
Cluster の名前や VPC や OS などを選択します。Slurm としての外部のデータベース (MySQL or MariaDB) を用意するとジョブの実行履歴を保存できるようになしますが、今回は設定しません。
HeadNode に関する設定を入れます。Allowed IPs は、環境にあわせて変更してください。
ComputeNode の Subnet を指定します。
- ※ Subnet の設定で、「Auto-assign public IPv4 address」が Yes でないと、Cluster の作成に失敗するので事前に確認する。
- ※ 指定した Subnet で hpc6a が利用できるか確認する。以下の実行例だと、オハイオリージョンでは、us-east-2b AZ のみ利用可能なことがわかる。
> aws ec2 describe-instance-type-offerings \
--location-type "availability-zone" \
--filters "Name=instance-type,Values=hpc6a.48xlarge" \
--region us-east-2 \
--query "InstanceTypeOfferings[*].[Location]" \
--output text
us-east-2b
以下の画像の指定は Subnet の指定を間違っているので、のちの手順で起動が失敗しています。正しく us-east-2b
の Subnet を選択しましょう。
Shared Storage は、デフォルトのまま FSx for Luster で次に行きます。
Create を押します。
Cluster が作成される様子が確認できます。
約 15 分後、ParallelCluster の作成が Complete になりました。
以下の代表的なリソースが作成されています。
- HeadNode
- FSx for Luster
HeadNode 上で Spack のインストール
Spack は Linux などで利用できるパッケージマネージャーです。科学技術系で利用されるソフトウェアを簡単にインストールできます。Spack は特定の言語に関連付けられていません。 Python または R でソフトウェア スタックを構築し、C、C++、または Fortran で書かれたライブラリにリンクし、コンパイラやターゲット固有のマイクロアーキテクチャを簡単に交換できます。
HeadNode に SSH を行います。Shell のボタンで Systems Manager 経由でリモートアクセスが可能です。
個人的には別途 SSH を行う方がすきなので、SSH をします。
ssh ec2-user@....
mount の状況を確認すると、/shared
に FSx for Luster がマウントされています。
[root@ip-10-6-13-4 ec2-user]# df -hT
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs tmpfs 3.9G 1.2M 3.9G 1% /run
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/nvme0n1p1 xfs 200G 20G 181G 10% /
tmpfs tmpfs 784M 12K 784M 1% /run/user/42
tmpfs tmpfs 784M 40K 784M 1% /run/user/1000
10.6.3.36@tcp:/wtkr5bev lustre 1.2T 324M 1.2T 1% /shared
NFS で公開している領域もあります。
[root@ip-10-6-13-4 ec2-user]# exportfs
/home 10.6.0.0/16
/opt/parallelcluster/shared
10.6.0.0/16
/opt/parallelcluster/shared_login_nodes
10.6.0.0/16
/opt/intel 10.6.0.0/16
/opt/slurm 10.6.0.0/16
Spack をインストールするため、root で git clone を行います。この環境変数で指定している /shared/spack
は、FSx for Luster の領域です。HeadNode 上でインストール作業を行いますが、インストール先は FSx for Luster となっており、ComputeNode からアクセスができるようになります。
Spack を git clone でダウンロードしています。
sudo su
export SPACK_ROOT=/shared/spack
mkdir -p $SPACK_ROOT
git clone -c feature.manyFiles=true https://github.com/spack/spack $SPACK_ROOT
root から ec2-user にもどります。
exit
Spack を利用するための bashrc の設定や、スクリプトの設定をします。
echo "export SPACK_ROOT=/shared/spack" >> $HOME/.bashrc
echo "source \$SPACK_ROOT/share/spack/setup-env.sh" >> $HOME/.bashrc
source $HOME/.bashrc
sudo chown -R $USER:$USER $SPACK_ROOT
Spack Binary Cache をビルドのスピードアップのために利用します。
spack mirror add binary_mirror https://binaries.spack.io/releases/v0.18
spack buildcache keys --install --trust
Intel Compiler のインストール
Spack を使って、Intel Compiler をインストールします。10 分くらいかかります。
spack install intel-oneapi-compilers@2022.0.2
compiler の一覧を表示します。
[ec2-user@ip-10-6-13-4 ~]$ spack compilers
==> Available compilers
-- gcc amzn2-x86_64 ---------------------------------------------
gcc@7.3.1
Spack に新しいコンパイラを認識させます
spack load intel-oneapi-compilers
spack compiler find
spack unload
再度、compiler の一覧を表示し、intel や oneapi が追加されているのがわかります。
[ec2-user@ip-10-6-13-4 ~]$ spack compilers
==> Available compilers
-- dpcpp amzn2-x86_64 -------------------------------------------
dpcpp@2022.0.0
-- gcc amzn2-x86_64 ---------------------------------------------
gcc@7.3.1
-- intel amzn2-x86_64 -------------------------------------------
intel@2021.5.0
-- oneapi amzn2-x86_64 ------------------------------------------
oneapi@2022.0.0
GROMACS のインストール
以下のコマンドで最適化された GROMACS をインストールします。時間がかかるらしいので、
spack install -j 8 gromacs@2022.2 +blas +lapack %intel ^intel-oneapi-mpi
次の最適化しない (?) コマンドでインストールを行います。(といってもこれでも 45 分くらかかりました・・・)
spack install -v -j 8 gromacs@2022.2
spack find でインストールされているパッケージ一覧を確認できます。
[ec2-user@ip-10-6-13-4 ~]$ spack find
-- linux-amzn2-zen / gcc@7.3.1 ----------------------------------
autoconf@2.72 cmake@3.27.9 gdbm@1.23 krb5@1.20.1 libtool@2.4.7 numactl@2.0.14 perl@5.38.0 util-macros@1.19.3
automake@1.16.5 curl@8.4.0 gettext@0.22.4 libedit@3.1-20210216 libxcrypt@4.4.35 openblas@0.3.26 pigz@2.8 xz@5.4.1
berkeley-db@18.1.40 diffutils@3.9 gmake@4.4.1 libevent@2.1.12 libxml2@2.10.3 openmpi@5.0.1 pkgconf@1.9.5 zlib-ng@2.1.5
bison@3.8.2 fftw@3.3.10 gromacs@2022.2 libiconv@1.17 m4@1.4.19 openssh@9.5p1 pmix@5.0.1 zstd@1.5.5
bzip2@1.0.8 findutils@4.9.0 hwloc@2.9.1 libpciaccess@0.17 ncurses@6.4 openssl@3.1.3 readline@8.2
ca-certificates-mozilla@2023-05-30 gcc-runtime@7.3.1 intel-oneapi-compilers@2022.0.2 libsigsegv@2.14 nghttp2@1.57.0 patchelf@0.17.2 tar@1.34
==> 46 installed packages
spack コマンドを使って、gromacs をロードして実行できます。
ロードする前では、次のように GROMACS のコマンド実行がエラーになります。
$ gmx_mpi
bash: gmx_mpi: command not found
Spack コマンドでロードします。
spack load gromacs
コマンドが実行できます。バージョン 2022.2 が動いていることがわかります。
$ gmx_mpi
:-) GROMACS - gmx_mpi, 2022.2-spack (-:
Executable: /shared/spack/opt/spack/linux-amzn2-zen/gcc-7.3.1/gromacs-2022.2-t7uvycqtxmmeevzv2v3bwan26exqhgin/bin/gmx_mpi
Data prefix: /shared/spack/opt/spack/linux-amzn2-zen/gcc-7.3.1/gromacs-2022.2-t7uvycqtxmmeevzv2v3bwan26exqhgin
Working dir: /home/ec2-user
Command line:
gmx_mpi
サンプルデータセットのダウンロード
/shared
ディレクトリにサンプルデータセットをダウンロードします。このディレクトリは FSx for Luster なので、すべての ComputeNode から同一のデータセットにアクセスができるようになります。
mkdir -p /shared/input/gromacs
mkdir -p /shared/logs
mkdir -p /shared/jobs
cd /shared/input/gromacs
wget https://www.mpinat.mpg.de/benchMEM.zip
wget https://www.mpinat.mpg.de/benchPEP.zip
wget https://www.mpinat.mpg.de/benchPEP-h.zip
wget https://www.mpinat.mpg.de/benchRIB.zip
# unzip
unzip benchMEM.zip
unzip benchPEP.zip
unzip benchPEP-h.zip
unzip benchRIB.zip
Run Multi-Node MPI
Custer の詳細を確認する
クラスターの詳細を確認してきます。
200 万分子のシミュレーションを行うベンチマークの benchRIB を利用します。slurm の使い方は、以下の Document のサイトを参照してください。
sinfo を実行すると、現在稼動しているインスタンスと稼動していないインスタンスの両方が表示されます (これはキュー制限のようなもの)。初期状態では、全てのノードが idle~ の状態にあり、インスタンスが稼働していないことを意味しています。
ジョブを投入すると、いくつかのインスタンスが alloc の状態になります。ジョブが完了すると、インスタンスは数分間 (デフォルトのクールダウンは10分) idle% 状態になります。これは混乱しやすいので、下の表で単純化してみました:
State | Description |
---|---|
idle~ |
インスタンスは起動されていないが、ジョブが投入されると起動できる。 |
idle% |
インスタンスは起動されており ScaledownIdletime (default 10 mins) が経過されると自動シャットダウンされる。 |
mix |
インスタンスが部分的に割り当てられている |
alloc |
インスタンスが完全に割り当てられている |
sinfo で Node の状態を確認します。hpc6a と c6i の node 定義が見えます。100 node を新たに立ち上げられるようになっていますが、いまは node は存在していません。
$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
hpc6a* up infinite 100 idle~ hpc6a-dy-compute-[1-100]
c6i up infinite 100 idle~ c6i-dy-spot-[1-100]
module は、環境変数(PATH、LD_LIBRARY_PATHなど)を動的に変更するために使用される、HPCではかなり標準的なツールです。
以下のコマンドで利用可能なモジュールの一覧を表示しています。 すべてのクラスタには intelmpi と openmpi がプリインストールされています。これらのMPIバージョンは高速インターコネクトEFAをサポートしてコンパイルされています。
$ module av
--------------------------------------------------------------------------- /usr/share/Modules/modulefiles ----------------------------------------------------------------------------
dot module-git modules openmpi/4.1.6
libfabric-aws/1.19.0amzn4.0 module-info null use.own
------------------------------------------------------------------------ /opt/intel/mpi/2021.9.0/modulefiles/ -------------------------------------------------------------------------
intelmpi
特定のモジュールをロードします。この場合、このコマンドは IntelMPI を環境にロードし、mpirun のパスをチェックします。
module load intelmpi
mpirun -V
実行例
$ module load intelmpi
Loading intelmpi version 2021.9.0
$ mpirun -V
Intel(R) MPI Library for Linux* OS, Version 2021.9 Build 20230307 (id: d82b3071db)
Copyright 2003-2023, Intel Corporation.
いくつかのボリュームはヘッドノードで共有され、起動時にコンピュートインスタンスにマウントされる。sharedと/homeは全ノードからアクセス可能です。
$ showmount -e localhost
Export list for localhost:
/opt/slurm 10.6.0.0/16
/opt/intel 10.6.0.0/16
/opt/parallelcluster/shared_login_nodes 10.6.0.0/16
/opt/parallelcluster/shared 10.6.0.0/16
/home 10.6.0.0/16
FSx for Luster をマウントしていることがわかります。1.2T の Size の '/shared' を確認できます。
$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs 3.9G 72K 3.9G 1% /dev/shm
tmpfs 3.9G 1.2M 3.9G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/nvme0n1p1 200G 20G 181G 10% /
tmpfs 784M 12K 784M 1% /run/user/42
tmpfs 784M 40K 784M 1% /run/user/1000
10.6.3.36@tcp:/wtkr5bev 1.2T 7.6G 1.2T 1% /shared
Submit Job
シミュレーションジョブを実行します。gromacs.sbatch
のファイルを作成します。
-
#SBATCH --job-name=gromacs-threadmpi
: ジョブの識別名を指定 -
#SBATCH --exclusive
: このジョブが実行される時、割り当てられたノードを他のジョブと共有しないようにします。ジョブがノードのリソースを独占的に使用します。 -
#SBATCH --output=/shared/logs/%x_%j.out
: ジョブの標準出力と標準エラー出力を指定したパスにリダイレクトします。%x
はジョブ名、%j
はジョブIDに展開されます。 -
#SBATCH -N 2
: ジョブを 2 つの ComputeNode に割り振ります -
#SBATCH -n 96
: 層タスク数 (MPI プロセス数) を 96 に指定します -
NTOMP=1
: OpenMPスレッドの数を1に設定します。これは、各MPIプロセスが使用するスレッドの数を指します。
cd /home/ec2-user
cat <<'EOF' > gromacs.sbatch
#!/bin/bash
#SBATCH --job-name=gromacs-threadmpi
#SBATCH --exclusive
#SBATCH --output=/shared/logs/%x_%j.out
#SBATCH -N 2
#SBATCH -n 96
NTOMP=1
# ジョブの実行に必要なディレクトリを作成し、そこに移動します。${SLURM_JOBID}はSLURMによって割り当てられたジョブIDです。
mkdir -p /shared/jobs/${SLURM_JOBID}
cd /shared/jobs/${SLURM_JOBID}
# Spackパッケージマネージャを使用してGROMACSをロードし、OpenMPIモジュールをロードします。これにより、GROMACSとMPIが利用可能になります。
spack load gromacs
module load openmpi
# mpirunを使用して、指定されたタスク数(SLURM_NTASKSで設定)でGROMACSのmdrunコマンドを実行します。
# -ntompオプションで各MPIプロセスのOpenMPスレッド数を設定し、-sオプションで入力ファイルを指定します。
set -x
time mpirun -np ${SLURM_NTASKS} gmx_mpi mdrun -ntomp ${NTOMP} -s /shared/input/gromacs/benchRIB.tpr -resethway
EOF
sbatch コマンドでジョブを実行します。
sbatch gromacs.sbatch
実行例 : ジョブ番号 1 で実行されました
$ sbatch gromacs.sbatch
Submitted batch job 1
Monitor Job
以下のコマンドを実行すると、
squeue -i 1
1 秒ごとに Queue の状況を確認できます。ST が CF となっており、これは インスタンスが立ち上がるのを待機している状態です。
Sat Feb 03 00:38:35 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
1 hpc6a gromacs- ec2-user CF 0:28 2 hpc6a-dy-compute-[1-2]
Sat Feb 03 00:38:36 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
1 hpc6a gromacs- ec2-user CF 0:29 2 hpc6a-dy-compute-[1-2]
Sat Feb 03 00:38:37 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
1 hpc6a gromacs- ec2-user CF 0:30 2 hpc6a-dy-compute-[1-2]
sinfo コマンドで、Node の状況も確認できます。2 台の Node が新たに立ち上がろうとしています。
$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
hpc6a* up infinite 2 alloc# hpc6a-dy-compute-[1-2]
hpc6a* up infinite 98 idle~ hpc6a-dy-compute-[3-100]
c6i up infinite 100 idle~ c6i-dy-spot-[1-100]
EC2 のマネジメントコンソール画面でも、新たに hpc6a.46xlarge
が立ち上がってくる様子が確認できます。
一定時間後、Running となっています。
Sat Feb 03 00:42:59 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
1 hpc6a gromacs- ec2-user R 2:22 2 hpc6a-dy-compute-[1-2]
Sat Feb 03 00:43:00 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
1 hpc6a gromacs- ec2-user R 2:23 2 hpc6a-dy-compute-[1-2]
Sat Feb 03 00:43:01 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
1 hpc6a gromacs- ec2-user R 2:24 2 hpc6a-dy-compute-[1-2]
次のコマンドで SSH もできます。
$ ssh hpc6a-dy-compute-1
FSx for Luster を /shared
にマウントしている様子が確認できます。同様に、HeadNode の NFS 領域もマウントしています。
$ df -hT
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 185G 0 185G 0% /dev
tmpfs tmpfs 185G 56M 185G 1% /dev/shm
tmpfs tmpfs 185G 1.2M 185G 1% /run
tmpfs tmpfs 185G 0 185G 0% /sys/fs/cgroup
/dev/nvme0n1p1 xfs 40G 20G 21G 50% /
10.6.29.198:/opt/parallelcluster/shared nfs4 200G 20G 181G 10% /opt/parallelcluster/shared
10.6.29.198:/home nfs4 200G 20G 181G 10% /home
10.6.29.198:/opt/intel nfs4 200G 20G 181G 10% /opt/intel
10.6.16.198@tcp:/5urb7bev lustre 1.2T 7.7G 1.2T 1% /shared
10.6.29.198:/opt/slurm nfs4 200G 20G 181G 10% /opt/slurm
tmpfs tmpfs 37G 0 37G 0% /run/user/1000
負荷状況を確認するため htop をインストールし実行します。
sudo yum install -y htop && htop
このような結果が確認できます。
HeadNode に戻ります。
exit
GROMACS コマンドを実行したときの標準出力のログは、以下のディレクトリに出力されています。
/shared/logs/gromacs-threadmpi_1.out
内容を確認します。この出力はGROMACSシミュレーションのパフォーマンス状況などを示しています。主なポイントは以下の通りのようです。
- 96個のMPIプロセスを用いてシミュレーションが実行されました。
- 1つのOpenMPスレッドが各MPIプロセスに割り当てられました。
- シミュレーションは10000ステップ、40ピコ秒実行されました。
- 平均の負荷不均衡は2.8%でした。
- 負荷不均衡による待ち時間はシミュレーション時間の2.1%でした。
- 1ステップ当たりの計算時間はコア時間で17945.160秒、ウォールクロック時間で186.929秒でした。
- シミュレーションのパフォーマンスは9.246 ns/dayでした。
$ cat /shared/logs/gromacs-threadmpi_1.out
+ mpirun -np 96 gmx_mpi mdrun -ntomp 1 -s /shared/input/gromacs/benchRIB.tpr -resethway
:-) GROMACS - gmx mdrun, 2022.2-spack (-:
Executable: /shared/spack/opt/spack/linux-amzn2-zen/gcc-7.3.1/gromacs-2022.2-t7uvycqtxmmeevzv2v3bwan26exqhgin/bin/gmx_mpi
Data prefix: /shared/spack/opt/spack/linux-amzn2-zen/gcc-7.3.1/gromacs-2022.2-t7uvycqtxmmeevzv2v3bwan26exqhgin
Working dir: /shared/jobs/1
Command line:
gmx_mpi mdrun -ntomp 1 -s /shared/input/gromacs/benchRIB.tpr -resethway
Highest SIMD level supported by all nodes in run: AVX2_256
SIMD instructions selected at compile time: AVX2_128
Compiled SIMD newer than supported; program might crash.
Reading file /shared/input/gromacs/benchRIB.tpr, VERSION 4.6.2-dev-20130529-36d170c (single precision)
Note: file tpx version 83, software tpx version 127
Changing nstlist from 25 to 80, rlist from 1 to 1.096
Using 96 MPI processes
Non-default thread affinity set, disabling internal thread affinity
Using 1 OpenMP thread per MPI process
starting mdrun 'Protein'
10000 steps, 40.0 ps.
step 5000: resetting all time and cycle counters
Writing final coordinates.
Dynamic load balancing report:
DLB was turned on during the run due to measured imbalance.
Average load imbalance: 2.8%.
The balanceable part of the MD step is 76%, load imbalance is computed from this.
Part of the total run time spent waiting due to load imbalance: 2.1%.
Steps where the load balancing was limited by -rdd, -rcon and/or -dds: X 0 % Y 0 % Z 0 %
Average PME mesh/force load: 0.872
Part of the total run time spent waiting due to PP/PME imbalance: 2.6 %
Core t (s) Wall t (s) (%)
Time: 17945.160 186.929 9600.0
(ns/day) (hour/ns)
Performance: 9.246 2.596
GROMACS reminds you: "If it weren't for C, we'd all be programming in BASI and OBOL." (Anonymous)
real 6m26.474s
user 609m28.690s
sys 4m7.930s
実際のシミュレーション結果についてです。今回のスクリプトでは、以下の指定があります。
GROMACS では、実行コマンドを実行したカレントディレクトリに出力されています。
# ジョブの実行に必要なディレクトリを作成し、そこに移動します。${SLURM_JOBID}はSLURMによって割り当てられたジョブIDです。
mkdir -p /shared/jobs/${SLURM_JOBID}
cd /shared/jobs/${SLURM_JOBID}
今回は jobid が 1 なので、以下のディレクトリにシミュレーション結果が出力されています。
$ ls -la /shared/jobs/1
total 137768
drwxrwxr-x 2 ec2-user ec2-user 33280 Feb 3 00:47 .
drwxrwxr-x 3 ec2-user ec2-user 33280 Feb 3 00:40 ..
-rw-rw-r-- 1 ec2-user ec2-user 147412535 Feb 3 00:47 confout.gro
-rw-rw-r-- 1 ec2-user ec2-user 13832 Feb 3 00:47 ener.edr
-rw-rw-r-- 1 ec2-user ec2-user 29663 Feb 3 00:47 md.log
-rw-rw-r-- 1 ec2-user ec2-user 51275984 Feb 3 00:47 state.cpt
md.log には難しい内容が出力されています。一部抜粋しつつ、以下のような意味の内容らしいですが、なにもわかりません。
- ポテンシャルエネルギー: -3.80x10^7 kJ/mol の範囲
- 運動エネルギー: 約5.07x10^6 kJ/mol
- 全エネルギー: -3.30x10^7 kJ/mol の範囲
- 温度: 300 K前後
- 圧力: 作用する圧力に関する詳細なデータが提供されていますが、平均圧力は-16.08 bar前後
<省略>
Energy conservation over simulation part #1 of length 40 ps, time 0 to 40 ps
Conserved energy drift: -8.07e-04 kJ/mol/ps per atom
<====== ############### ==>
<==== A V E R A G E S ====>
<== ############### ======>
Statistics over 10001 steps using 101 frames
Energies (kJ/mol)
Connect Bonds Angle Proper Dih. Ryckaert-Bell. LJ-14
0.00000e+00 3.47717e+05 1.19011e+04 7.61049e+05 2.87457e+05
Coulomb-14 LJ (SR) Coulomb (SR) Coul. recip. Potential
-1.18734e+06 5.15936e+06 -4.37575e+07 3.53117e+05 -3.80242e+07
Kinetic En. Total Energy Conserved En. Temperature Pressure (bar)
5.06755e+06 -3.29567e+07 -3.25538e+07 3.00145e+02 -1.60770e+01
Constr. rmsd
0.00000e+00
<省略>
Run on SPOT Instances
hpc6a をサポートしていないリージョンといったように、hpc6a インスタンスを使用できない場合は、Amazon EC2 Spot Instances インスタンスを使用するオプションも検討できます。このインスタンスでは、GROMACS シミュレーションをコスト効率よく実行でき、オンデマンドの価格から最大 90% の割引が適用されるため、HPC インスタンスと同様の価格帯で利用できます。スポットインスタンスのトレードオフは、2 分前の警告はありつつ、いつでも仮想マシンが停止される点にあります。
複雑なシミュレーションの実行時間は数時間から数日に及ぶこともあり、シミュレーションの実行時間が長くなればなるほど、中断リスクの可能性が高まるため、これが問題になる場合があります。そのため、シミュレーションの進行状況を維持しながら実行することが重要になります。シミュレーションのチェックポイントは、これを実現する方法です。GROMACSネイティブのチェックポイントとスポットインスタンスを組み合わせることで、シミュレーションを再開することができ、中断が発生しても進捗を最小限に抑えることができます。
このセクションでは、GromacsのチェックポイントとSpot pricing、Slurmのスケジューリングを組み合わせることで、Gromacsシミュレーションを実行するための費用対効果の高いソリューションを作成していきます
Configure Checkpointing
Amazon EC2のスポットインスタンスで、シミュレーションを中断が発生した場合、途中から再開する仕組みがあります。中断時の作業ロスを最小限に抑えるには、GROMACSでチェックポイントを行い、シミュレーションの実行状態を保存します。一度保存したら、中断したインスタンスを置き換えてSlurmジョブを再投入し、シミュレーションを終了します。
GROMACSは、ユーザーが定義した間隔でシミュレーションのチェックポイントをサポートします。GROMACSの主要な計算化学エンジンであるMdrunのコマンドラインフラグを使ってチェックポイントを設定可能です。次の表は、選択したフラグを説明するものです。
Flag and value | Explanation |
---|---|
- cpt 1 |
ユーザー定義のチェックポイント間隔 (分) |
- cpi spot-cpu.cpt |
保存状態を読み込むためのユーザー定義ファイル |
- cpo spot-cpu-output.cpt |
状態を書き込むためのユーザー定義ファイル |
cpt フラグをオンにすると、ノードの中断時に GROMACS シミュレーションを継続するために必要なデータを保存します。インスタンスが中断された場合、AWS ParallelClusterは自動的に新しいインスタンスをデプロイし、新しいインスタンスにSlurmジョブを再キューします。
デフォルトのチェックポイント時間は15分毎です。
Submit Job
HeadNode で gromacs-spot.sbatch
ファイルを作成します。
-
--partition=spot
: これは、ジョブがスポット・パーティション(キュー)に投入され、スポット・インスタンスで実行されることを保証します。 -
-cpt 1 -cpi spot-cpu-${SLURM_JOBID}.cpt -cpo spot-cpu-${SLURM_JOBID}.cpt
: この指定で、チェックポイントを 1 分ごとに書き出す設定を入れています。
cd /home/ec2-user
cat <<'EOF' > gromacs-spot.sbatch
#!/bin/bash
#SBATCH --job-name=spot-gromacs-demo
#SBATCH --exclusive
#SBATCH --output=/shared/logs/%x_%j.out
#SBATCH --partition=spot
NTOMP=2
mkdir -p /shared/jobs/${SLURM_JOBID}
cd /shared/jobs/${SLURM_JOBID}
echo ">>> loading gromacs module "
spack load gromacs
module load intelmpi
set -x
mpirun gmx_mpi mdrun -nsteps 500000 -pme cpu -ntomp ${NTOMP} -s /shared/input/gromacs/benchMEM.tpr -resethway -cpt 1 -cpi spot-cpu-${SLURM_JOBID}.cpt -cpo spot-cpu-${SLURM_JOBID}.cpt -e spot-cpu-${SLURM_JOBID}.edr -g spot-cpu-${SLURM_JOBID}.log
EOF
sinfo コマンドで、SpotInstance 用の PARTITION 名である c6i
を確認します。
$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
hpc6a* up infinite 100 idle~ hpc6a-dy-compute-[1-100]
c6i up infinite 100 idle% c6i-dy-spot-[1-100]
パーティション c6i
を指定して、ジョブを実行します。
sbatch -p c6i gromacs-spot.sbatch
実行例
$ sbatch -p c6i gromacs-spot.sbatch
Submitted batch job 3
queue の確認
$ squeue
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
3 c6i spot-gro ec2-user CF 0:10 1 c6i-dy-spot-1
sinfo
$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
hpc6a* up infinite 1 idle% hpc6a-dy-compute-1
hpc6a* up infinite 98 idle~ hpc6a-dy-compute-[2-5,7-100]
hpc6a* up infinite 1 idle hpc6a-dy-compute-6
c6i up infinite 1 down# c6i-dy-spot-1
c6i up infinite 99 idle~ c6i-dy-spot-[2-100]
デバッグ : Spot Instance が立ち上がらないエラー
立ち上がらない・・・容量エラーのように見えます。
$ sinfo -R
REASON USER TIMESTAMP NODELIST
(Code:InsufficientIn root 2024-02-03T01:57:14 c6i-dy-spot-1
ログ
less /var/log/parallelcluster/slurm_resume.log
対象の IAM Role が権限がないように見える。
2024-02-03 01:57:10,035 - 18082 - [botocore.credentials:load] - INFO - Found credentials from IAM Role: gromacs-workshop-RoleHeadNode-aZVxChHBAO57
2024-02-03 01:57:14,889 - 18082 - [slurm_plugin.fleet_manager:_launch_instances] - ERROR - JobID 4 - Error in CreateFleet request (10f11dc8-7cbc-4695-995a-53006a46163d): AuthFailure.ServiceLinkedRoleCreationNotPermitted - The provided credentials do not have permission to create the service-linked role for EC2 Spot Instances.
こっちのログもきになる
less /var/log/parallelcluster/clustermgtd
2024-02-03 02:04:07,242 - [slurm_plugin.clustermgtd:_reset_timeout_expired_compute_resources] - INFO - The following compute resources are in down state due to insufficient capacity: {'c6i': {'spot': ComputeResourceFailureEvent(timestamp=datetime.datetime(2024, 2, 3, 1, 58, 1, 448839, tzinfo=datetime.timezone.utc), error_code='InsufficientInstanceCapacity')}}, compute resources will be reset after insufficient capacity timeout (600.0 seconds) expired
以下のドキュメントを確認すると、以下の Role を作成する必要がありました。
Role の作成
aws iam create-service-linked-role --aws-service-name spot.amazonaws.com
実行例
> aws iam create-service-linked-role --aws-service-name spot.amazonaws.com
{
"Role": {
"Path": "/aws-service-role/spot.amazonaws.com/",
"RoleName": "AWSServiceRoleForEC2Spot",
"RoleId": "AROAVNVNXMHCKHV6DG7TC",
"Arn": "arn:aws:iam::xxxxxxxxxxx:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot",
"CreateDate": "2024-02-03T02:18:21+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"spot.amazonaws.com"
]
}
}
]
}
}
}
再度 Submit Job
cd /home/ec2-user
sbatch -p c6i gromacs-spot.sbatch
これで対象のスポットインスタンスが立ち上がるようになりました。
一定時間後、実行されている様子が確認できます。
$ ls -la /shared/logs/spot-gromacs-demo_8.out
-rw-rw-r-- 1 ec2-user ec2-user 4915 Feb 3 02:27 /shared/logs/spot-gromacs-demo_8.out
Simulate SPOT Interruption
このセクションでは、スポットの中断をシミュレートする方法を確認します。これは、チェックポイントと再起動の機能が正しく動作することをテストするのに役立ちます。この例ではEC2 Spotコンソールを使用しますが、Fault Injection Simulator(FIS)を使用しても同じ結果です。
再度 Job を Submit します。
cd /home/ec2-user
sbatch -p c6i gromacs-spot.sbatch
queue が実行されています。
$ squeue
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
9 c6i spot-gro ec2-user CF 0:16 1 c6i-dy-spot-1
実行状態
Sat Feb 03 03:06:34 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
10 c6i spot-gro ec2-user R 0:25 1 c6i-dy-spot-1
EC2 Spot の画面を開き、対象のインスタンス選択したあと、Initiate interruption を選択して中断させます。
実行
R から CG
Sat Feb 03 03:10:08 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
10 c6i spot-gro ec2-user R 3:59 1 c6i-dy-spot-1
Sat Feb 03 03:10:09 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
10 c6i spot-gro ec2-user R 4:00 1 c6i-dy-spot-1
Sat Feb 03 03:10:10 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
10 c6i spot-gro ec2-user CG 0:00 1 c6i-dy-spot-1
Sat Feb 03 03:10:11 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
10 c6i spot-gro ec2-user CG 0:00 1 c6i-dy-spot-1
対象のインスタンスがシャットダウンされました。
この手順では、新しいインスタンスが立ち上がるわけではありませんでした。
Sat Feb 03 03:19:16 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
10 c6i spot-gro ec2-user PD 0:00 1 (BadConstraints)
新しいインスタンスを立ち上げるために、以下の内容に従って、コマンドを実行してみます。
scontrol update jobid=10 NumNodes=1-1
すると新たな ComputeNode が立ち上がりました。
Status が Running に代わり、ジョブが再開されます。
Sat Feb 03 03:22:38 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
10 c6i spot-gro ec2-user CF 2:49 1 c6i-dy-spot-1
Sat Feb 03 03:22:39 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
10 c6i spot-gro ec2-user CF 2:50 1 c6i-dy-spot-1
Sat Feb 03 03:22:40 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
10 c6i spot-gro ec2-user R 0:01 1 c6i-dy-spot-1
Sat Feb 03 03:22:41 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
10 c6i spot-gro ec2-user R 0:02 1 c6i-dy-spot-1
Sat Feb 03 03:22:42 2024
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
ジョブが完了しました
[ec2-user@ip-10-6-29-198 10]$ ls -la /shared/jobs/10/
total 87896
drwxrwxr-x 2 ec2-user ec2-user 41472 Feb 3 03:09 .
drwxrwxr-x 8 ec2-user ec2-user 33280 Feb 3 03:06 ..
-rw-rw-r-- 1 ec2-user ec2-user 1963788 Feb 3 03:09 spot-cpu-10.cpt
-rw-rw-r-- 1 ec2-user ec2-user 1056 Feb 3 03:07 spot-cpu-10.edr
-rw-rw-r-- 1 ec2-user ec2-user 1056 Feb 3 03:07 #spot-cpu-10.edr.1#
-rw-rw-r-- 1 ec2-user ec2-user 1056 Feb 3 03:07 #spot-cpu-10.edr.10#
-rw-rw-r-- 1 ec2-user ec2-user 1056 Feb 3 03:07 #spot-cpu-10.edr.11#
-rw-rw-r-- 1 ec2-user ec2-user 1056 Feb 3 03:07 #spot-cpu-10.edr.12#
-rw-rw-r-- 1 ec2-user ec2-user 1056 Feb 3 03:07 #spot-cpu-10.edr.13#
-rw-rw-r-- 1 ec2-user ec2-user 1056 Feb 3 03:07 #spot-cpu-10.edr.14#
-rw-rw-r-- 1 ec2-user ec2-user 1056 Feb 3 03:07 #spot-cpu-10.edr.15#
-rw-rw-r-- 1 ec2-user ec2-user 1056 Feb 3 03:07 #spot-cpu-10.edr.16#
-rw-rw-r-- 1 ec2-user ec2-user 1056 Feb 3 03:07 #spot-cpu-10.edr.17#
-rw-rw-r-- 1 ec2-user ec2-user 1056 Feb 3 03:07 #spot-cpu-10.edr.18#
-rw-rw-r-- 1 ec2-user ec2-user 1056 Feb 3 03:07 #spot-cpu-10.edr.19#
検証を通じてわかったこと
- Slurm の sbatch といったコマンドに関する Document は、AWS ではなく以下のサイトで参照する。
- デフォルトでは、ジョブを実行したあとに ComputeNode がシャットダウンされるまで、10 分間の待機時間が発生する。これは、設定変更で変更が可能。1 に指定すると、すぐに ComputeNode がシャットダウンされる。再利用性が低くなるデメリットもある。
- ParallelCluster に複数のインスタンスタイプを指定可能
- スポットインスタンスとオンデマンドインスタンスを、それぞれの Queue として定義可能
- FSx for Luster は必須ではない。多くの ComputeNode を立ち上げるときに高性能なパフォーマンスを求める場合に利用可能。
- FSx for Luster や HeadNode の NFS 公開領域に GROMACS をインストールすることで、すべての ComputeNode から GROMASC を実行可能になる。
- HeadNode は 1 台構成となる。可用性を気にする場合は、複数の ParallelCluster を立ち上げる方法が考えられる。
- ベストプラクティス
- ジョブの実行履歴の保存に関して
- デフォルトの ParallelCluster が Slurm のジョブ実行履歴を管理しません。あとから「このジョブどれくらい時間かかったんだっけ?」を確認したいと思っても、確認ができないのがデフォルトの構成です。
- 考えられる 2 つの方法があります。
- 1 : ParallellCluster の構築で Slurm アカウンティングを有効にする方法
- MySQL や MariaDB のサーバーを構成して、データベースにジョブ実行履歴を保存する方法。RDS などの場合はある程度の費用が発生する。
- https://docs.aws.amazon.com/ja_jp/parallelcluster/latest/ug/tutorials_07_slurm-accounting-v3.html
- https://dev.classmethod.jp/articles/exploring-database-services-for-slurm-accounting/
- 2 : 簡易的に HeadNode のジョブ実行時に、ジョブの実行状態を監視して時間を計測するような Shell Script を仕込む
- HeadNode ないにファイルを出力する形になり、あとから統計的に確認などはできないが、まず費用が掛からないリーズナブルな方法。軽量な Shell Script を作る必要はあるのが、たまにきず。