Slurm sbatch Job投入 チートシート

sbatchによるジョブ投入
================================

事前準備
-----------

事前準備として、

- `sinfo -s` を使ってどのようなPartitionがあるか
- `scontrol show nodes` や `scontrol show partitions` を使って、利用するノードの1ノードあたりのコア数を把握しておきましょう

Basic
-----------

単一ノードで4コア

```bash
#!/bin/bash
#SBATCH --partition sambanova
#SBATCH --job-name=handson
#SBATCH --ntasks=4

echo "---- machinefile ----"
srun -n ${SLURM_NTASKS} hostname | sort

echo "---- Slurm Environment Variables ----"
cat <<ETX
JOB_ID="${SLURM_JOB_ID}"
JOB_NAME="${SLURM_JOB_NAME}"
PARTITION_NAME="${SLURM_JOB_PARTITION}"
NODE_LIST="${SLURM_JOB_NODELIST}"
NTASKS="${SLURM_NTASKS}"
ETX
```

```bash
sbatch run.sh
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73207/ca249812-e91c-ddcd-c535-e29addd636c7.png)

```terminal
---- machinefile ----
host1
host1
host1
host1
---- Slurm Environment Variables ----
JOB_ID="39"
JOB_NAME="handson"
PARTITION_NAME="sambanova"
NODE_LIST="host1"
NTASKS="4"
```


標準出力、標準エラー出力の指定
--------------------------

次に以下の2行を追加します。

- `#SBATCH -o %x.%J.out`
- `#SBATCH -e %x.%J.err`

```bash
#!/bin/bash
#SBATCH -p sambanova
#SBATCH --job-name=handson
#SBATCH --ntasks=4
#SBATCH -o %x.%J.out
#SBATCH -e %x.%J.err

echo "---- machinefile ----"
srun -n ${SLURM_NTASKS} hostname | sort

echo "---- Slurm Environment Variables ----"
cat <<ETX

JOB_ID="${SLURM_JOB_ID}"
JOB_NAME="${SLURM_JOB_NAME}"
PARTITION_NAME="${SLURM_JOB_PARTITION}"
NODE_LIST="${SLURM_JOB_NODELIST}"
NTASKS="${SLURM_NTASKS}"

ETX
```

ジョブ実行後、以下の２つのファイルが作成されていることが確認できます

- `handson.<JobID>.out`: 標準出力
- `handson.<JobID>.err`: 標準エラー出力

```
sbatch run.sh
```

`handson.<JobID>.out`を開くと以下のような結果が得られます。

```terminal
---- machinefile ----
host1
host1
host1
host1
---- Slurm Environment Variables ----
JOB_ID="40"
JOB_NAME="handson"
PARTITION_NAME="sambanova"
NODE_LIST="host1"
NTASKS="4"
```

複数ノードまたがり, コア開け (確認必要)
--------------------------

2ノードを使い1ノードあたり16コア(トータル32コア)を確保し、1ノードあたり3コア利用したいとき、いわゆるコアあけの使い方について説明します。1プロセスあたりのメモリー量を確保したいときに、よくこの使い方を行います

ポイントは

- `#SBATCH --nodes=2`: 2ノード確保します
- `#SBATCH --tasks-per-node=16`: CPUコアとしてノードあたり16コア確保します
- `#SBATCH --ntasks=6`: 2ノードで合計6コア使います


```bash:run.sh
#!/bin/bash
#SBATCH -p sambanova
#SBATCH --job-name handson
#SBATCH --nodes=2
#SBATCH --tasks-per-node=16
#SBATCH --ntasks=6
#SBATCH -o %x.%J.out
#SBATCH -e %x.%J.err

echo "---- machinefile ----"
srun -n ${SLURM_NTASKS} hostname | sort

echo "---- Slurm Environment Variables ----"
cat <<ETX

JOB_ID="${SLURM_JOB_ID}"
JOB_NAME="${SLURM_JOB_NAME}"
PARTITION_NAME="${SLURM_JOB_PARTITION}"
NODE_LIST="${SLURM_JOB_NODELIST}"
NTASKS="${SLURM_NTASKS}"
CORES_PER_NODE="${SLURM_JOB_CPUS_PER_NODE}"
NTASKS_PER_NODE="${SLURM_NTASKS_PER_NODE}"

ETX
```

```bash
sbatch run.sh
```

```terminal
---- machinefile ----
host1
host1
host1
host2
host2
host2
---- Slurm Environment Variables ----

JOB_ID="42"
JOB_NAME="handson"
PARTITION_NAME="sambanova"
NODE_LIST="host[1-2]"
NTASKS="6"
CORES_PER_NODE="16(x2)"
NTASKS_PER_NODE="16"
```

このケースだと26コア分無駄になり、ここまで無駄にするケースは現実ではあまりないかもしれません。しかしMPIを利用する場合、キャッシュやメモリアクセス等により、ノードを確保して数コア分、コア開けしたほうがアプリとして早くなることも多々あるので、この使い方を覚えて起きましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73207/b69be1ad-cfe4-d0ca-a465-03384f073e09.png)

業務番号、コメントを挿入する
----------------

- `#SBATCH --comment`: <任意のコメント>
- `#SBATCH --account`: <任意のグループ名やプロジェクト名>

```bash:run.sh
#!/bin/bash
#SBATCH -p sambanova
#SBATCH --job-name handson
#SBATCH --nodes=2
#SBATCH --tasks-per-node=16
#SBATCH --ntasks=6
#SBATCH -o %x.%J.out
#SBATCH -e %x.%J.err
#SBATCH --comment "test"
#SBATCH --account "xdg-059"

echo "---- machinefile ----"
srun -n ${SLURM_NTASKS} hostname | sort

echo "---- Slurm Environment Variables ----"
cat <<ETX

JOB_ID="${SLURM_JOB_ID}"
JOB_NAME="${SLURM_JOB_NAME}"
PARTITION_NAME="${SLURM_JOB_PARTITION}"
NODE_LIST="${SLURM_JOB_NODELIST}"
NTASKS="${SLURM_NTASKS}"
CORES_PER_NODE="${SLURM_JOB_CPUS_PER_NODE}"
NTASKS_PER_NODE="${SLURM_NTASKS_PER_NODE}"
ACCOUNT="${SLURM_JOB_ACCOUNT}"

ETX
```

```bash
sbatch run.sh
```

```terminal
---- machinefile ----
host1
host1
host1
host2
host2
host2
---- Slurm Environment Variables ----

JOB_ID="43"
JOB_NAME="handson"
PARTITION_NAME="sambanova"
NODE_LIST="host[1-2]"
NTASKS="6"
CORES_PER_NODE="16(x2)"
NTASKS_PER_NODE="16"
ACCOUNT="xdg-059"
```

sacctコマンドにて、このジョブIDに対して業務番号とコメントが割り当てられていることを確認します。また、ジョブ名、計算時間等も合わせて表示してみます。 --starttime 2020-10-23 は今日の日付に変更してください。

```bash
sacct --starttime 2020-10-21 \
--format JobID%5,JobName%8,Partition,NCPU%5,ReqCPUS,Start,End,Elapsed%8,Account,Comment%10 -X
```

```
JobID  JobName  Partition NCPUS  ReqCPUS               Start                 End  Elapsed    Account    Comment
----- -------- ---------- ----- -------- ------------------- ------------------- -------- ---------- ----------
 1251  handson  sambanova    16        4 2020-10-21T12:21:38 2020-10-21T12:21:39 00:00:01
 1252  handson  sambanova    32        6 2020-10-21T12:32:49 2020-10-21T12:32:50 00:00:01
 1253  handson  sambanova    32        6 2020-10-21T12:35:46 2020-10-21T12:35:47 00:00:01
 1254  handson  sambanova    32        6 2020-10-21T12:42:27 2020-10-21T12:42:27 00:00:00    project1      test
 1255  handson  sambanova    32        6 2020-10-21T12:43:24 2020-10-21T12:43:24 00:00:00    project1      test
```


-------------------------


sacctによる履歴確認
================================

過去に実行したジョブに関して、ジョブのメタ情報を得ることができます。 JobIDや計算時間等は、かならずsacctで取得可能な情報ですが、sbatchのオプション指定を活用することで、そのオプションに関するメタ情報もsacctで取得可能なデータとして残すことができます。 例えば、#SBATCH --acount=<プロジェクト番号> でジョブを実行しておけば、sacctコマンドでプロジェクト毎のリソース使用時間を分析することができ、次年度の計算機の投資計画等の分析に役に立ちます。

基本的な使い方例
----------------------

代表的な使い方の例を以下に示します。
最初にサンプルジョブを実行します。

```bash:サンプルジョブ投入
sbatch <<EOF
#!/bin/bash
#SBATCH -p debug
#SBATCH --job-name sacct_test
#SBATCH --nodes=2
#SBATCH --tasks-per-node=3
#SBATCH --ntasks=6
srun hostname
EOF
```

```bash:command
sacct --starttime 2020-10-21 --endtime 2020-10-23 \
    --format JobID%5,JobName%16,Partition,NCPU%5,ReqCPUS,Start,End,Elapsed%8 -X
```

```
JobID          JobName  Partition NCPUS  ReqCPUS               Start                 End  Elapsed
----- ---------------- ---------- ----- -------- ------------------- ------------------- --------
 1264       my_project      debug    16        1 2020-10-21T14:39:48 2020-10-21T14:39:48 00:00:00
 1265       sacct_test      debug    32        6 2020-10-21T14:48:16 2020-10-21T14:48:16 00:00:00
 1266          handson      debug    16        4 2020-10-21T14:58:27 2020-10-21T14:58:28 00:00:01
 1267       sacct_test      debug    32        6 2020-10-21T16:05:14 2020-10-21T16:05:14 00:00:00
 ```

sacctで昨日終了したログを収集する
-----------------------------

フィルターとして、3ヶ月以内にジョブ投入し昨日終了したジョブを抽出している

```bash:command
sacct --starttime $(date -d '90 day ago' "+%Y-%m-%d") \
--format Cluster%20,start,end,uid%9,gid%9,partition%22,Ncpu%4,ReqCPUS,elapsed,cputime -X \
| sed '1,2d' | sort -k 3n | grep $(date -d 'yesterday' "+%Y-%m-%d")
```