HPCといえばSlurmだよね

ラズパイが腐るほどあるので、Slurmクラスタを作る。流れとしては、Slurmの全体像を理解してから、実際にSlurmをインストールして、クラスタを構築。んで、MPIジョブを投入できたら最高ですね。

参考文献

slurm公式

Slurmの全体像

クラスタを使って並列分散処理をしたいとき、どうするか?例えばMPIを使ってなにかを計算したいとき、どうするか?直接mpirunをすればいいよね?簡単だ。うん。ユーザがおれ一人で他の人がクラスタを使わない前提であれば直接実行していいよね。しかし、HPCシステムってのは基本的にはいろんな人に使われるんですよ。そんな時にいろんな人が同時にMPIのジョブを実行すると何が起こるか? まあ、これは予想だけど、基本的に1つのMPIプロセスに対して1つのコアが割り当てられるので、コア数を超えるプロセスが割り当てられそうなときは、mpirunの実行が失敗すると思うんですよ。

このようなリソース競合によるジョブの実行失敗などを防いだり、その他、リソースのマネジメントをするのがリソースマネジメントシステム(RMS)だよね。SlurmもRMSなわけだ。いろいろなRMSがあるわけで、その中でもSlurmの特徴が三つある。

  1. ある一定期間、ユーザが計算資源(ノード)を占有することを許す
  2. 各ノードに対して、ジョブのスタート、実行、監視を可能にする
  3. 待ち行列内のpending jobに対して、恣意的な実行を可能にする

slurmのアーキテクチャ

各ノードでslurmdデーモンが動いている。そして、マネジメントノード(マスターノード)ではslurmctldデーモンが動いている。ユーザはクライアントアプリを使って、slurmctldにアクセスし、ジョブのサブミットや、状態の確認ができる。

Slurmのインストール

参考文献

文献1 文献2(一番参考になった資料)

前提

  1. ノード間でuidが同じユーザが作られていること これは、最初にラズパイの設定をするときにユーザ名を一律に決めておくことで解決できる。
  2. ノード間でシステムの時刻が一致している事 これは、raspi-configのロケール設定でAsia/Tokyoを選ぶことで解決できる

マスターノードのあるディレクトリをnfsとして外部にエクスポートしておくといろいろとらく

マスターノード、スレーブノードのホスト名を決めておく

/etc/hosts

マスターノードの設定

リポジトリからのインストール

sudo apt install slurm-wlm -y

Slurmの設定

設定ファイルの場所は

/etc/slurm/slurm.conf

この場所に、デフォルトの設定ファイルを持ってくる

cp /usr/share/doc/slurm-client/examples/slurm.conf.simple.gz .
gzip -d slurm.conf.simple.gz
mv slurm.conf.simple slurm.conf

設定ファイル(slurm.conf)の内容は厳密にかかないとだめ

SlurmctldHost=node01(<ip addr of node01>)
# e.g.: node01(192.168.1.14)
# actual : zeta(172.20.2.1)
SelectType=select/cons_res
SelectTypeParameters=CR_Core
...
...
ClusterName=glmdev
...
...
NodeName=zeta NodeAddr=172.20.2.1 CPUs=4 Sockets=1 CoresPerSocket=4 State=UNKNOWN
NodeName=slave1 NodeAddr=172.20.2.3 CPUs=4 Sockets=1 CoresPerSocket=4
State=UNKNOWN
NodeName=slave2 NodeAddr=172.20.2.4 CPUs=4 Sockets=1 CoresPerSocket=4
State=UNKNOWN
NodeName=slave3 NodeAddr=172.20.2.5 CPUs=4 Sockets=1 CoresPerSocket=4
State=UNKNOWN
NodeName=slave4 NodeAddr=172.20.2.6 CPUs=4 Sockets=1 CoresPerSocket=4
State=UNKNOWN
PartitionName=mycluster Nodes=slave[1-4] Default=YES MaxTime=INFINITE
State=UP

cgroup関係の設定ファイルをつくる

/etc/slurm/cgroup.confに

CgroupMountpoint="/sys/fs/cgroup"
CgroupAutomount=yes
CgroupReleaseAgentDir="/etc/slurm-llnl/cgroup"
AllowedDevicesFile="/etc/slurm-llnl/cgroup_allowed_devices_file.conf"
ConstrainCores=no
TaskAffinity=no
ConstrainRAMSpace=yes
ConstrainSwapSpace=no
ConstrainDevices=no
AllowedRamSpace=100
AllowedSwapSpace=0
MaxRAMPercent=100
MaxSwapPercent=100
MinRAMSpace=30

そして、 /etc/slurm/cgroup_allowed_devices_file.conf に

/dev/null
/dev/urandom
/dev/zero
/dev/sda*
/dev/cpu/*/*
/dev/pts/*
/clusterfs*

munge関係の設定

slurmはノード間の通信にmungeっていうソフトを使う。その辺の設定をしてください。割愛します。

スレーブノードの設定

必要なソフトのインストール

sudo apt install slurmd slurm-client -y

マスターノードの設定ファイル(slurm.conf)、mungeの鍵ファイル(/etc/munge/munge.key)をスレーブノードに配る

場所はオリジナルと同じ場所で。

sudo cp /cluster_common/munge.key /etc/munge/munge.key
sudo cp /cluster_common/slurm.conf /etc/slurm/slurm.conf
sudo cp /cluster_common/cgroup* /etc/slurm

mungeサーバの起動

sudo systemctl enable munge
sudo systemctl start munge

mungeを使った認証

ssh pi@node01 munge -n | unmunge

slurmdの起動

sudo systemctl enable slurmd
sudo systemctl start slurmd

その他、注意点

  1. マスターノードではslurmctldが稼働する
  2. スレーブノードではslurmdが稼働
  3. どちらのデーモンも/etc/slurm/slurm.confを使う
  4. slurmctldは6817ポートでslurmdと通信をするので開けておく 以下のコマンドでプロセスがどのポートを使っているのかを確認
sudo lsof -i TCP

エラーが発生時の対処方法

1. journalctlでログを見る

2. 直接ログファイルを見に行く

コントロールコマンドの基本

NQSVと同じ感じだね。qsub,qstat,など、やったよね。

  1. sinfo

ノードの状態を得る

  1. srun ジョブのサブミットに使われる

  2. sstat ジョブの実行状況とリソースの割り当て状況

  3. scancel 実行中のジョブのキャンセル、停止

その他にもいろいろあるので、適宜調べてください。

その他、起こったエラーと対処法

ノードのステートがdrainのままで変わらない

sinfoでノードの状態を見ると、次のようになる。

mycluster*    up   infinite      2  drain slave[3-4]
mycluster*    up   infinite      2   idle slave[1-2]

sinfo -R でdrainもしくはdropの原因を知ることが可能

REASON               USER      TIMESTAMP           NODELIST
Low socket*core*thre slurm     2023-01-17T08:50:28 slave[3-4]

これは、slurm.confの各ノードの資源量パラメータを設定する箇所が間違っているのが原因だとおもう。直して、

scontrol update nodename=YOURNODEHERE state=resume

でノードの状態をアップデートできる。が

scontrol update nodename=slave2 state=resume

をすると、

slurm_update error: Invalid user id

が出てくる。これはもしや、mungeでの認証うまくいていない?

いや、調べてみた結果、sudoで実行すればいいっぽい。んで、stateはresumeではなく、idleに変更するっぽい。次のコマンドで実行できた。

sudo scontrol update NodeName=slave4 state=idle

んで、だ。次の問題は

srun --nodes=2 hostname

が実行できないこと。

その前に、 squeueで ジョブキューがみられる。

JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                17 mycluster     bash      ray  R      47:57      1 slave1

んで、 scancel jobid でジョブを削除できる。 これをやると、 sinfoでmixだったノードのステートがidleにもどった。 ちなみに、sinfoでmix担っている奴は、稼働中って意味なのかな?わからん。

でもやっぱりだめなんですよね、srunが利かない。

うん、やっとsrunでマルチノードでできるようになった。まだ完ぺきではないんだけど。 なぜかわからないんだけど、特定のノードから出ないとsrunが効かないんだよね。 どういうことか? zeta,slave1,slave2からsrunをすると、なぜかわからないが、実行されない。

しかし、slave3-11のノード上だとsrunで何を起動してもうまくいくのよ。なぜや?なんか、最初に素ラームの設定をしたのがうまくいかない3ノードなんだよね。これ何か関係しているのではないか? なぞです。忘れる前にいろいろと書いておこう。

なんか役に立ちそうなメモ

  1. ノードを指定して実行
srun --nodelist=slave1 hostname
  1. ジョブキューの中身の見方
squeue

ジョブidとかが見られる。

  1. downやdrainになっているノードの復活方法
scontrol update NodeName=slave1 state=idle
  1. ジョブの削除方法
scancel job_id
  1. ジョブの投入方法
sbatch script.sh

なんと、sbatchはどこからでも提出できるっぽんだよね。 zetaでも、slave[1-11]でも。ダメなのは、srunだけだね。あとは完ぺき。

2/3追記

srunは、ufwを無効化したらどこからでも実行できるようになりました。完璧ですよ!

  1. ジョブの詳細情報確認方法
scontrol show job

あとは、MPIのジョブを投入するだけです~!

何をインストールすればインですかね?PMIxって何なんですかね?わからんです。

MPI関係のpackageインストールコマンド

sudo apt install openmpi-bin libopenmpi-dev openmpi-doc

スクリプトにかいた要求ノード数でmpiを実行できるようになります。以下にジョブスクリプトの例をのせておきます。

#!/bin/bash
#SBATCH -p mycluster
#SBATCH -n 16
#SBATCH -J test_openmpi
#SBATCH -o stdout.%J.log
#SBATCH -e stderr.%J.log
cd /cluster_common/mpi_file
time mpirun -np ${SLURM_NTASKS} ./pi_calc < input.txt
echo ${SLURM_NTASKS}
RETCODE=$?
exit ${RETCODE}

今後やりたい事

  • slurmのプラグインをいじって、独自のスケジューリングポリシーでジョブスケジューリングを実行したいよね。
  • それくらいですかね?