Slurmことはじめ

# Slurm
[Slurm Workload Manager - Documentation](https://slurm.schedmd.com/documentation.html): OpenPBS等と同じジョブスケジューラ

度々見かけるし、OpenPBSよりも設定が単純で良いなどの情報も見かけたので、試してみる。

公式: [Slurm Workload Manager - Quick Start Administrator Guide](https://slurm.schedmd.com/quickstart_admin.html)
# インストール
Kubuntu22.04に`apt`でインストールする
```console:/etc/os-relase
RETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
```

## 必要パッケージのインストール
```bash
sudo apt update
sudo apt install -y slurm-wlm munge
```
でslurmのインストール完了。

```bash
sudo create-munge-key
sudo systemctl enable --now munge
```
でMUNGE認証の初期化と起動。

`systemctl status munge`で
```console
● munge.service - MUNGE authentication service
     Loaded: loaded (/lib/systemd/system/munge.service; enabled; vendor preset: >
     Active: active (running) since Thu 2025-03-27 01:29:46 JST; 9h ago
       Docs: man:munged(8)
   Main PID: 510396 (munged)
      Tasks: 4 (limit: 38223)
     Memory: 632.0K
        CPU: 116ms
     CGroup: /system.slice/munge.service
             └─510396 /usr/sbin/munged

 3月 27 01:29:46 shinohara-kubuntu systemd[1]: Starting MUNGE authentication s>
 3月 27 01:29:46 shinohara-kubuntu systemd[1]: Started MUNGE authentication s
 ```
 でmungeが起動していることが確認できる。

 ## 設定ファイルの記載と起動
 `sudo mkdir -p /etc/slurm-llnl/`で設定ファイルを置くディレクトリを作成。ホスト名を`shinohara-kubuntu`として、CPU数が4のとき、以下のようにconfファイルを記載
```conf:/etc/slurm-llnl/slurm.conf
ClusterName=single_node_cluster #好きな名前を付ける
ControlMachine=shinohara-kubuntu #slurmctldを立ち上げるホスト名

SlurmUser=slurm
SlurmdUser=root #ここをrootにしないとslurmdが立ち上がらなかった
StateSaveLocation=/var/spool/slurm-llnl
SlurmdSpoolDir=/var/spool/slurmd
SlurmctldPidFile=/var/run/slurmctld.pid
SlurmdPidFile=/var/run/slurmd.pid
AuthType=auth/munge

ProctrackType=proctrack/pgid

SlurmctldTimeout=120
SlurmdTimeout=300
SchedulerType=sched/backfill
SelectType=select/cons_res
SelectTypeParameters=CR_Core

NodeName=shinohara-kubuntu CPUs=8 Sockets=1 CoresPerSocket=4 ThreadsPerCore=2 State=UNKNOWN #ソケット数1、ソケット当たりコア数4、コア当たりスレッド数2の合計8cpuであることを宣言
PartitionName=debug Nodes=shinohara-kubuntu Default=YES MaxTime=INFINITE State=UP #debugパーティションの指定ノード、デフォルトパーティション、実行可能時間無制限の指定
```

`slurmd`はconfファイルのpathとして`/etc/slurm/slurm.conf`を探しに行くが、上記のファイルはこのpathにはない。そこで、`ln -s /etc/slurm-llnl/slurm.conf /etc/slurm/slurm.conf`としてシンボリックリンクを張ることで、元ファイルの設定が読み込まれる。

```bash
sudo systemctl enable --now slurmctld
sudo systemctl enable --now slurmd
```
で、デーモンを起動。

```console
● slurmd.service - Slurm node daemon
     Loaded: loaded (/lib/systemd/system/slurmd.service; enabled; vendor preset:>
     Active: active (running) since Thu 2025-03-27 14:36:30 JST; 11min ago
       Docs: man:slurmd(8)
   Main PID: 518082 (slurmd)
      Tasks: 1
     Memory: 1.4M
        CPU: 123ms
     CGroup: /system.slice/slurmd.service
             └─518082 /usr/sbin/slurmd -D -s

(略)

 ● slurmctld.service - Slurm controller daemon
     Loaded: loaded (/lib/systemd/system/slurmctld.service; enabled; vendor pres>
     Active: active (running) since Thu 2025-03-27 14:36:30 JST; 11min ago
       Docs: man:slurmctld(8)
   Main PID: 518091 (slurmctld)
      Tasks: 10
     Memory: 4.2M
        CPU: 430ms
     CGroup: /system.slice/slurmctld.service
             ├─518091 /usr/sbin/slurmctld -D -s
             └─518093 "slurmctld: slurmscriptd" "" ""

(略)
 ```
 として起動していることがわかる。

 ```console:sinfo
 PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
debug*       up   infinite      1   idle shinohara-kubuntu
 ```
 ```console:scontrol show node
 NodeName=shinohara-kubuntu Arch=x86_64 CoresPerSocket=4
   CPUAlloc=0 CPUTot=8 CPULoad=0.02
   AvailableFeatures=(null)
   ActiveFeatures=(null)
   Gres=(null)
   NodeAddr=shinohara-kubuntu NodeHostName=shinohara-kubuntu Version=21.08.5
   OS=Linux 5.15.0-131-generic #141-Ubuntu SMP Fri Jan 10 21:18:28 UTC 2025
   RealMemory=1 AllocMem=0 FreeMem=18479 Sockets=1 Boards=1
   State=IDLE ThreadsPerCore=2 TmpDisk=0 Weight=1 Owner=N/A MCS_label=N/A
   Partitions=debug
   BootTime=2025-02-15T23:30:03 SlurmdStartTime=2025-03-27T14:36:30
   LastBusyTime=2025-03-27T14:44:37
   CfgTRES=cpu=8,mem=1M,billing=8
   AllocTRES=
   CapWatts=n/a
   CurrentWatts=0 AveWatts=0
   ExtSensorsJoules=n/s ExtSensorsWatts=0 ExtSensorsTemp=n/s
 ```

# Kubuntu24.04にslurm-wlm 23.11.4を入れる場合
Ubuntu24.04に`apt`で`slurm-wlm`を入れると、バージョンが23.11.4。
[Slurmの認証にmungeが不要になった件 #SLURM - Qiita](https://qiita.com/masamokkulu/items/53a651db9026511c5b90)に記載がある通り、23.11以降はmungeは必ずしも要さない。(つまり`create-munge-key`コマンドでkeyを作成しない)
公式情報([Slurm Workload Manager - ](https://slurm.schedmd.com/authentication.html#slurm))によると、
```bash
dd if=/dev/random of=/etc/slurm/slurm.key bs=1024 count=1
```
でkeyを作成して、`/etc/slurm/`に置く。
```bash
chown slurm:slurm /etc/slurm/slurm.key
chmod 600 /etc/slurm/slurm.key
```
でユーザーとパーミションを設定する。
`slurm.key`を使うことに対応して、
```conf:slurm.conf(抜粋)
AuthType = auth/slurm
CredType = cred/slurm
```
と記載する。
上のKubuntu22.04のケースではchatGPTに教えてもらった通りに`/etc/slurm-llnl`に`slurm.conf`を置いて、`/etc/slurm/slurm.conf`からシンボリックリンクを貼ったが、そもそも`/etc/slurm/`に置けば良いだろうということでそうした。以下が、`slurm.conf`の一例

```conf:/etc/slurm/slurm.conf
ClusterName=single_node_cluster
ControlMachine=shinohara-desk001

SlurmUser=slurm
SlurmdUser=root #出来ればここもslurmにしたかったが色々試みた末諦めた
StateSaveLocation=/var/spool/slurmctld
SlurmdSpoolDir=/var/spool/slurmd
SlurmctldPidFile=/var/run/slurmctld.pid
SlurmdPidFile=/var/run/slurmd.pid
AuthType=auth/slurm
CredType=cred/slurm

ProctrackType=proctrack/pgid

SlurmctldTimeout=120
SlurmdTimeout=300
SchedulerType=sched/backfill

NodeName=shinohara-desk001 Sockets=1 CoresPerSocket=6 ThreadsPerCore=2 RealMemory=60000 State=UNKNOWN
PartitionName=workq Nodes=shinohara-desk001 Default=YES MaxTime=INFINITE State=UP
```
これで
```bash
sudo systemctl start slurmctld
sudo systemctl start slurmd
```
で起動させればOK。

# トラブルシューティング
## `State=IDLE+DRAIN`等でノードで計算可能にならない
`scontrol show nodes`とすると認識されているノード情報が得られる。例えば
```console:scontrol show nodes
(略)
State=IDLE+DRAIN
(略)
Reason=Low socket*core*thread count, Low CPUs [slurm@2025-03-27T11:58:12]
```
という表示があると、うまく動かない。原因は、`slurmd`が取得したハードウェア情報と`slurm.conf`の情報が整合していないことを意味している。基本的にはこれが整合しないと動かない。
**<font color="red">だったら、それを`slurm.conf`にユーザーに記入させる意味がわからない。しかも、`slurmd`が取得したハードウェアの情報は簡単に見えるところにはない。しかも、その情報は結構雑であんまり正しくないケースがある。(私が直面したケースでは最近流行りの非対称構成のコアでは20CPUsのはずなのに、`slurmd`に言わせると12CPUsだった。)ﾌﾞﾂﾌﾞﾂﾌﾞﾂﾌﾞﾂ...</font>** んで、どうすれば`slurmd`が取得したハードウェア情報を見れば良いかというと、`slurmd`のログファイルを見るしかないのである！(ｽﾞｺｰ)
というわけで、`journalctl -u slurmd`でログをみると
```console
M月 DD 22:30:58 shinohara-desk001 slurmd[1141375]: slurmd-shinohara-desk001: error: Node configuration differs from hardware: CPUs=1:12(hw) Boards=1:1(hw) SocketsPerBoard=1:1(hw) CoresPerSocket=1:6(hw) ThreadsPerCore=1:2(hw)
```
みたいな感じで、はんなりと教えてくれていることがわかる。(右が`slurmd`が取得したハードウェアの値)

というわけでこの数字を頼りに
```conf:slurm.conf(抜粋)
NodeName=shinohara-desk001 Sockets=1 CoresPerSocket=6 ThreadsPerCore=2 State=UNKNOWN #CPUs=12は独立な変数ではないのでここでは端折った
```
と書き直して
```bash
sudo systemctl stop slurmd slurmctld
```
でデーモン止めて
```bash
sudo rm /var/spool/slurmd/*
sudo rm /var/spool/slurmctld/* #slurm-llnlとかになっているかも
```
でデーモンが書き込んだ設定ファイルを一度消して(なんでかわからないけれど、デーモン起動時に設定が間違っていると、その認識を設定ファイル群のどこかに書き込んでいて、`slurm.conf`を更新してデーモン再起動するだけでは問題が解決しなかった。このファイル群を一掃すれば、起動時にフレッシュな状況になる。)
```bash
sudo systemctl start slurmd slurmctld
```
でデーモン起動して、`scontrol show nodes`で確認。
```console:(抜粋)
   State=IDLE ThreadsPerCore=2 TmpDisk=0 Weight=1 Owner=N/A MCS_label=N/A
```
の`State=IDLE`が確認できれば完了。

多分一生分`sudo systemctl stop slurmd slurmctld``sudo systemctl start slurmd slurmctld
`のコマンドを入力したと思う。

# よく使うコマンド
```bash
sinfo
scontrol show node
squeue #状況の確認
scancel $JOB_ID #投入済みのジョブのキャンセル
sbatch calc.sh #ジョブ投入
```

# サンプルスクリプト
```bash
#!/bin/bash
#SBATCH --job-name=jobs_name
#SBATCH --time=24:00:00
#SBATCH --partition=debug
#SBATCH --ntasks=1 
#SBATCH --cpus-per-task=4

module load /to/be/loaded

export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK

EXE=/home/shinohara/opt/elk/10.4.9/oneapi-2025.1/src/elk
MPIEXE=mpirun
MPINP=$SLURM_NTASKS

$MPIEXE -np $MPINP $EXE > log.log
```
多分最近のMPIなら、並列数を指定せず`$MPIEXE $EXE > log.log`で動くはずで、私の環境では正しくプロセス数が設定された。一方で、`OMP_NUM_THREADS`は私の環境では自動で設定されることはなかった。

## 関連設定キーワード
```bash
# ジョブ名
#SBATCH --job-name=jobs_name
#SBATCH -J jobs_name
# 標準出力ファイル名
#SBATCH --output=output_%j.out
#SBATCH -o output_%j.out
# 標準エラーファイル名
#SBATCH --error=error_%j.err
#SBATCH -e error_%j.err
# MPIの総プロセス数
#SBATCH --ntasks=1 
#SBATCH -n 1 
# 利用ノード数
#SBATCH --nodes=1 
#SBATCH -N 1 
# スレッド並列数
#SBATCH --cpus-per-task=4
#SBATCH -c 4
# 実行時間
#SBATCH --time=24:00:00
#SBATCH -t 24:00:00
# 利用パーティション
#SBATCH --partition=debug
#SBATCH -p debug
```