slurm: Simple Linux Utility for Resource Management
本家様 https://slurm.schedmd.com/
ジョブスケジューラ。SunGridEngineをいろいろ調整していたのだが、、、、良く分からん。
結局TORQUEを作ってみたが、ノード指定があるのに躊躇う。必要なコア数とメモリー量だけでノードが決まる代物が欲しくて調べてみた。
Torque:
queue名称 + node(マシン数) + ppn(processors per node)
Slurm:
queue名称 + ntasks(MPI数)
計算ノード/queue設定slurm/slurm.conf
参照先https://wiki.fysik.dtu.dk/niflheim/SLURM
TORQUEと同じようにsamba AD or NIS, LDAP/NFS環境で/home,/Applが共有され、計算ノードはn1,n2,n3の3台で、ジョブを投入するサイトが1台。
ジョブを管理するslurm管理ノードが1台とする。
各ノードはsamba(or nis, ldap)に登録されてホスト情報は共有する. アカウント情報も共有します. 登録方法はsamba/Linux参加とか参照
各マシンの時計は chrony or ntp とかで同期されている
役目 | ホスト名 | IPアドレス | core数 | GPU | OS | cgroup | 備考 |
管理ノード | slurm | 192.168.0.69 | 1 | - | RockyLinux 9.4 | v1 | slurmctldが起動 |
計算ノード | n1 | 192.168.0.14 | 1 | A2000 | Ubuntu 20.04 | v1,v2(unified) | slurmdが起動 |
n2 | 192.168.0.15 | 2 | T600 | RockyLinux 9.1 | v2 | ||
n3 | 192.168.0.16 | 4 | - | ubuntu 22.04 | v2 | ||
s | 192.168.0.7 | 4 | GT710*2 | RockyLinux 9.1 | v2 | ||
ジョブ発行ノード | slurm-client | 192.168.0.20 | 1 | - | RockyLinux 9.1 | srun,sbatchの 他TORQUEコマンドも使用可能 |
cgroup v1 or v2 は「mount -l | grep cgroup」で見分けられる
queue構成
queue名 | 対象ノード | 備考 |
workq | n1,n2 | |
gpu | n3 | GPUカード2枚 |
共通アカウントslurmを用意します。samba/ユーザ登録とかNIS#df5a057bとかLDAP/dataとかで
ユーザ名 | UID | GID | ホームディレクトリ | login shell | コマンド(nisの場合) | 備考 |
slurm | 5000 | 5000 | /var/lib/slurm | /sbin/nologin | groupadd -g 5000 slurm useradd -M -d /var/lib/slurm -s /sbin/nologin -u 5000 -g slurm slurm |
mungeを使って管理ノードと計算ノードの信頼関係を結んでましたが、slurm内の機能でそれが代用可能になりましたので、mungeは使いません
クラスターが単一のOSであるなら別途パッケージを製作してslurmの起点を「/opt/slurm」に集約させ共有するのもいいかなと思うが、
クラスターの各ノードのOSがまちまちであるならOS提供のパッケージをそのまま利用した方がいいかな
パッケージを作成するなら slurm/rpmbuild ubuntuでソースから作るslurm/ubuntu
各ノードでインストールするパッケージ(RHEL系)
パッケージ名称(RHEL系) | Summary | 備考 | 管理ノード | 計算ノード | ジョブ投入ノード | Slurmdbdノード | 備考 |
slurm | Slurm Workload Manager | 基本キット | ○ | ○ | ○ | ○ | ubuntuでは「slurm-client」かな |
slurm-slurmctld | Slurm controller daemon | 管理デーモン slurmctld.service | ○ | - | - | - | ubuntuでは「slurmctld」 |
slurm-slurmd | Slurm compute node daemon | 計算ノードデーモン slurmd.service | - | ○ | - | - | ubuntuでは「slurmd」 |
slurm-pam_slurm | PAM module for restricting access to compute nodes via Slurm | pam_slurm.so pam_slurm_adopt.so | - | △ | - | - | |
slurm-torque | Torque/PBS wrappers for transitition from Torque/PBS to Slurm | ラッパープログラム qsub,qstatとか slurm-perlapiが必須 | - | - | △ | - | ubuntuでは「slurm-wlm-torque」 |
slurm-openlava | openlava/LSF wrappers for transitition from OpenLava/LSF to Slurm | ラッパープログラム slurm-perlapiが必須 | - | - | △ | - | |
slurm-slurmdbd | Slurm database daemon | systemctl対応 slurmdbd | - | - | - | ○ | ubuntuでは「slurmdbd」 |
slurm-sql | Slurm SQL support | - | - | - | - | ○ |
ほかslurm-APIパッケージの「slurm-perlapi(libslurmdb-perl)」、開発環境向けの「slurm-devel(slurm-wlm-basic-plugins-dev)」、ツール類「slurm-contribs」がある.
恐らく複数台になると思うので ansible を作ってみた slurm/ansible
gpu対応slurm/gpu
アカウンティング対応slurm/accounting
torqueラッパーslurm/Torque
Prolog/epilog slurm/prolog
x11 slurm/x11
Slurm-web slurm/web
[illya@slurm-client ~]$ sinfo -N -l
Sun Dec 25 20:56:52 2022
NODELIST NODES PARTITION STATE CPUS S:C:T MEMORY TMP_DISK WEIGHT AVAIL_FE REASON
n1 1 workq* idle 1 1:1:1 16001 0 1 (null) none
n2 1 workq* idle 2 1:2:1 15732 0 1 (null) none
n3 1 workq* idle 4 1:4:1 16000 0 1 (null) none
[illya@slurm-client ~]$
各ノードは 1CPU ソケットで、1core、2core、4core構成です
STATEがdownとかなっていたら「scontrol update nodename=node_name state=idle」でidleに変更できる
STATEがdown/draindedになった理由は「sinfo -R」で確認できます
簡単なテストを行ってみます。
job queuing systemなのでバッチファイルを作ってジョブを流してみます. 使うコマンドは「sbatch」です
[illya@slurm-client ~]$ vi a.sh
#!/bin/bash
hostname
echo "sleeping..."
sleep 10
echo "done!"
[illya@slurm-client ~]$ sbatch a.sh <-- ジョブファイル「a.sh」を投入
Submitted batch job 41
[illya@slurm-client ~]$ squeue <-- 確認
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
41 workq a.sh illya R 0:01 1 n1
(結果確認)
[illya@slurm-client ~]$ cat slurm-41.out
n1
sleeping...
done!
[illya@slurm-client ~]$
な感じで動いている. 実際には「a.sh」の中に「#SBATCH」で始まるディレクティブを加えますが、ここは簡単に.
次にインターラクティヴでジョブを投げたいと思います. slurmは「srun」コマンドで
[illya@slurm-client ~]$ srun --pty bash
illya@n1:~$
illya@n1:~$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
workq* up infinite 1 alloc n1
workq* up infinite 2 idle n[2-3]
illya@n1:~$ exit
(n3を指定して)
[illya@slurm-client ~]$ srun --nodelist=n3 --pty bash
illya@n3:~$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
workq* up infinite 1 mix n3 <-- mixなのでまだ余裕がある
workq* up infinite 2 idle n[1-2]
illya@n3:~$ exit
(4coreを使うと宣言)
[illya@slurm-client ~]$ srun --ntasks=4 --pty bash
illya@n3:~$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
workq* up infinite 1 alloc n3 <-- allocとなって全て払い下げられた.
workq* up infinite 2 idle n[1-2]
illya@n3:~$ exit
[illya@slurm-client ~]$
バッチジョブファイルを作ってみます。
http://www.ceci-hpc.be/slurm_tutorial.htmlこのサイトが非常に分かりやすかったです。
slurmでの[task]はプロセスと読み替えて、1つのジョブを2MPIプロセスで処理させるのなら-ntasks=2。1つのジョブを2スレッドで処理させるのなら--cpus-per-task=2と定義する。
[illya@client ~]$ vi a.sh
#SBATCH -J test_run # --job-name=test_run
#SBATCH -o output_%j.txt # --output=output_test_run.txt
#SBATCH -e errors_%j.txt # --error=errors_test_run.txt
#SBATCH -p batch # いわゆる使用するキュー名
#SBATCH -n 4 # --ntasks=4 このジョブで4プロセスを実行する
#SBATCH -c 2 # --cpus-per-task=2 1プロセス当たり2core使用する
mpirun mpirun.exe
[illya@client ~]$
[illya@client ~]$ sbatch a.sh #これで実行される
[illya@slurm-client ~]$ sinfo -N -o "%N %G"
NODELIST GRES
n1 gpu:1(S:0)
n2 gpu:1(S:0)
n3 (null)
[illya@slurm-client ~]$
[illya@slurm-client ~]$ srun --gres=gpu:1 --pty nvidia-smi -L
GPU 0: NVIDIA RTX A2000 (UUID: GPU-23cc3ee7-31d3-a068-2f61-5aa00052d084)
[illya@slurm-client ~]$ srun --gres=gpu:1 -w n1 --pty bash
illya@n1:~$ nvidia-smi -L
GPU 0: NVIDIA RTX A2000 (UUID: GPU-23cc3ee7-31d3-a068-2f61-5aa00052d084)
illya@n1:~$ exit
exit
[illya@slurm-client ~]$ srun --gres=gpu:1 -w n2 --pty bash
[illya@n2 ~]$ nvidia-smi -L
GPU 0: NVIDIA T600 (UUID: GPU-01226552-df75-5989-c2f3-3550cdc3427d)
[illya@n2 ~]$ exit
exit
[illya@slurm-client ~]$
複数のGPUを持っているノードへのテスト
[illya@slurm-client ~]$ srun --gres=gpu:1 -w s --pty bash
[illya@s ~]$ nvidia-smi -L
GPU 0: NVIDIA GeForce GT 710 (UUID: GPU-f0753e20-06f7-695a-f325-b5b6342393ba)
[illya@s ~]$ exit
exit
[illya@slurm-client ~]$
[illya@slurm-client ~]$ srun --gres=gpu:2 -w s --pty bash
[illya@s ~]$ nvidia-smi -L
GPU 0: NVIDIA GeForce GT 710 (UUID: GPU-f0753e20-06f7-695a-f325-b5b6342393ba)
GPU 1: NVIDIA GeForce GT 710 (UUID: GPU-34c49ab7-b79d-e341-93e2-1659e9bd9e57)
[illya@s ~]$ exit
exit
[illya@slurm-client ~]$
と1枚指定したら1枚のみ。2枚指定したら2枚確保できた. そして2枚確保中に別のターミナルから再度GPUを確保するジョブを投げると待機状態になった.
[illya@slurm-client ~]$ srun --gres=gpu:1 --pty nvidia-smi -L
slurmstepd: error: no gpu utilization TRES! This should never happen
GPU 0: NVIDIA GeForce GT 710 (UUID: GPU-f0753e20-06f7-695a-f325-b5b6342393ba)
[illya@slurm-client ~]$
と「slurmstepd: error: no gpu utilization TRES! This should never happen」が表示されるのはslurm.confで
「JobAcctGatherType=jobacct_gather/cgroup」とかを「JobAcctGatherType=jobacct_gather/none」にする
「STATE」が「completing」になる場合はslurmのuid/gidが異なる場合とか。同じに変更しましょう