#author("2025-11-30T14:24:19+00:00","default:sysosa","sysosa")
#author("2025-11-30T14:26:16+00:00","default:sysosa","sysosa")
ジョブ管理システム slurm にてジョブを発行してみる
参照先 [[https://slurm.schedmd.com/sbatch.html>+https://slurm.schedmd.com/sbatch.html]]


***ジョブの分散が上手く行っているか [#sbb355fb]

ここでは計算ノードが3つあって、それぞれ4coreを持っている。
どれかのノードに1coreなジョブを流したければ
#code(nonumber){{
#!/bin/bash
#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 workq            # いわゆる使用するキュー名
#SBATCH -n 3                # --ntasks=           このジョブで3タスク(プロセス)を実行する
#SBATCH -c 1                # --cpus-per-task=   1プロセス当たり1core使用する

echo "===== SLURM NODELIST ====="
echo $SLURM_NODELIST

echo "===== srun hostname ====="
srun hostname
}}

結果ファイル「errors_%j.txt」の中身は
#code(nonumber){{
===== SLURM NODELIST =====
n1
===== srun hostname =====
n1
n1
n1
}}
と表示されます. 1つのノードに3つのプロセスが入りました。

次に同じく3つのプロセスを動かすのですが、1つのプロセスあたり3つのcoreを使用したいとなると「-c 1」を「-c 3」に変更じて実行すると
#code(nonumber){{
===== SLURM NODELIST =====
n[1-3]
===== srun hostname =====
n1
n3
n2
}}
となります。1つのノードで3core使用するので、3ノードで計算するって事になります。

relionのようなハイブリッドmpiの場合では、この「-c」がthreadsになって、「-n」がmpi数って感じでしょうか.

ただslurmの場合、リソース要求した後に mpi masterの数を加えたいとかで「mpirun -np (XX + 1)」とするとエラーになります。その際は mpirun のオプション「--oversubscribe」で誤魔化すことが必要かな.
openpbsはその辺見逃してくれる.

***mpiプログラム [#m7ca272d]

サンプルジョブはmpiプログラムで1台もしくは複数台にまたがって実行させたく、そのサンプルmpiプログラムを chatgpt君に作ってもらった
#code(c,nonumber,nooutline){{
#include <mpi.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char** argv) {
    MPI_Init(&argc, &argv);

    int world_size, world_rank, name_len;
    char processor_name[MPI_MAX_PROCESSOR_NAME];

    MPI_Comm_size(MPI_COMM_WORLD, &world_size);
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    MPI_Get_processor_name(processor_name, &name_len);

    printf("Hello from rank %d of %d on host %s (PID %d)\n",
           world_rank, world_size, processor_name, getpid());

    MPI_Finalize();
    return 0;
}
}}
ファイル名を mpi_hello.c として保存して下記のようにしてコンパイル
#code(nonumber){{
mpicc -o mpi_hello mpi_hello.c
}}
作られたプログラム「mpi_hello」を使って各種テストを行ってみた

#code(nonumber){{
#!/bin/bash
#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 workq            # いわゆる使用するキュー名
#SBATCH -n 3                # --ntasks         このジョブで3タスク(プロセス)を実行する
#SBATCH -c 3                # --cpus-per-task 1プロセス当たり3core使用する

NODEFILE=$(mktemp)
scontrol show hostname $SLURM_NODELIST > $NODEFILE    # mpi向けのnodefileを作る

module load mpi
opt="--display-map --bind-to none --map-by node --oversubscribe"   # mpirunのオプション

mpirun -np 4 -machinefile $NODEFILE $opt  ./mpi_hello

echo "-----"
hostname
ls -l $NODEFILE
cat $NODEFILE

echo "-----"
rm $NODEFILE   # 終わったら削除
}}
っで結果は下記になります
#code(nonumber){{
 Data for JOB [41586,1] offset 0 Total slots allocated 3

 ========================   JOB MAP   ========================

 Data for node: n1      Num slots: 1    Max slots: 0    Num procs: 2
        Process OMPI jobid: [41586,1] App: 0 Process rank: 0 Bound: N/A
        Process OMPI jobid: [41586,1] App: 0 Process rank: 3 Bound: N/A

 Data for node: n2      Num slots: 1    Max slots: 0    Num procs: 1
        Process OMPI jobid: [41586,1] App: 0 Process rank: 1 Bound: N/A

 Data for node: n3      Num slots: 1    Max slots: 0    Num procs: 1
        Process OMPI jobid: [41586,1] App: 0 Process rank: 2 Bound: N/A

 =============================================================
Hello from rank 3 of 4 on host n1 (PID 47993)
Hello from rank 0 of 4 on host n1 (PID 47992)
Hello from rank 2 of 4 on host n3 (PID 15761)
Hello from rank 1 of 4 on host n2 (PID 50866)
-----
n1
-rw-------. 1 saber em 9 Nov 30 23:00 /tmp/tmp.IaLCtkTerX
n1
n2
n3
-----
}}

rank 0が n1、rank 1が n2, rank2が n3, rank3 が n1 と「--map-by node」が効いてrank毎にマシンを変えてます。加えて「--oversubscribe」の効果で「mpirun -np 4」が流れました。本来ならリソースが足らないとして怒られます.

***srunを使う方法 [#j8d652a8]
本来はこちらが望ましいみたい。mpirunでのnodefileとか不要で、srunで動かすみたい

#code(nonumber){{
#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 workq            # いわゆる使用するキュー名
#SBATCH -n 3                # --ntasks         このジョブで3タスク(プロセス)を実行する
#SBATCH -c 3                # --cpus-per-task 1プロセス当たり3core使用する

module load mpi
opt="--display-map --bind-to none --map-by node --oversubscribe"
mpirun --mca orte_rsh_agent "srun" -np 7 $opt ./mpi_hello
mpirun --mca orte_rsh_agent "srun" -np 4 $opt ./mpi_hello         # すべては srun が処理してくれます.

echo "-----"
hostname
echo "-----"
}}

っで結果は下記のようになります. 「--map-by node」「--oversubscribe」も効いてます.

#code(nonumber){{
 Data for JOB [42060,1] offset 0 Total slots allocated 3

 ========================   JOB MAP   ========================

 Data for node: n1      Num slots: 1    Max slots: 0    Num procs: 2
        Process OMPI jobid: [42060,1] App: 0 Process rank: 0 Bound: N/A
        Process OMPI jobid: [42060,1] App: 0 Process rank: 3 Bound: N/A

 Data for node: n2      Num slots: 1    Max slots: 0    Num procs: 1
        Process OMPI jobid: [42060,1] App: 0 Process rank: 1 Bound: N/A

 Data for node: n3      Num slots: 1    Max slots: 0    Num procs: 1
        Process OMPI jobid: [42060,1] App: 0 Process rank: 2 Bound: N/A

 =============================================================
Hello from rank 0 of 4 on host n1 (PID 48478)
Hello from rank 3 of 4 on host n1 (PID 48479)
Hello from rank 2 of 4 on host n3 (PID 16093)
Hello from rank 1 of 4 on host n2 (PID 51200)
-----
n1
-----
}}

srunを使うには firewall での特定ポートを解除する必要がありますので firewall 内で行うときはこの辺が注意.
1

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS