#author("2026-10-02T08:02:08+00:00","default:sysosa","sysosa") #author("2026-10-07T15:00:25+00:00","default:sysosa","sysosa") slurmで流すときの「&color(orangered){''Standard submission script''};」を作ってみた. &size(10){ファイル名は「sbatch.sh」としています}; 2026.08.31 改定. 複数計算ノード対応へ. NVIDIA MPS(Multi-Process Service)対応版 [[Relion/slurm/mps]] #code(nonumber){{ #!/bin/bash #SBATCH --ntasks=XXXmpinodesXXX # Number of MPI procs #SBATCH --cpus-per-task=XXXthreadsXXX # Number of threads #SBATCH --partition=XXXqueueXXX # Queue name #SBATCH --nodes=XXXnodesXXX # CEIL( XXXcoresXXX / XXXdedicatedXXX ) 必要なcore数を1台当たりのcore数で割って切り上げ. ノード数 #SBATCH --error=XXXerrfileXXX #SBATCH --output=XXXoutfileXXX #SBATCH --job-name=XXXnameXXX cd $SLURM_SUBMIT_DIR ### Environment Modules . /etc/profile.d/modules.sh module load mpi/openmpi-x86_64 module load relion ### requested resources cat <<_EOF_>XXXoutfileXXX ---------------------------------------------- start `date` ---------------------------------------------- Queue name XXXqueueXXX required cores XXXcoresXXX :( XXXmpinodesXXX[mpi] * XXXthreadsXXX[threads] ) nodes XXXnodesXXX :CEIL( XXXcoresXXX / XXXdedicatedXXX ) :( ${SLURM_JOB_NODELIST} ) _EOF_ ### check command cmd_=$(/bin/cat <<_EOF_ XXXcommandXXX _EOF_ ) cmd=$(echo "$cmd_" | sed -z 's/\n/\&\&/g') run=$(echo $cmd|awk '{print $1}') ### Run export OMPI_MCA_pml=ob1 export OMPI_MCA_btl=self,vader,tcp SECONDS=0 command="{ { srun --mpi=pmix_v3 ${cmd:0:-2} | tee -a XXXoutfileXXX ; } 3>&2 2>&1 1>&3 | tee -a XXXerrfileXXX ; } 3>&2 2>&1 1>&3" eval $command cat <<_EOF_>>XXXoutfileXXX ---------------------------------------------- use relion: `readlink -f $run` end time: `date '+%y%m%d %H:%M:%S'` (spend `printf "%02d:%02d:%02d\n" $(($SECONDS/3600)) $((($SECONDS%3600)/60)) $(($SECONDS%60))`) ---------------------------------------------- done _EOF_ }} 「srun」で投げてますが、以前この部分をmpirunで以前は作ってました. mpirunなので「--oversubscribe」とかでrelion_refine_mpiの時の親mpi対処ができたのですが、、それよりもsrunの方が計算が早いみたい. ただそうなると「--oversubscribe」が使えないので「Number of MPI procs」「Number of threads」「Minimum dedicated cores per node」らの値の算出が結構面倒... ***Runningパネル [#p4ffefa9] Class2DやClass3DはGPUを使っての計算が可能ですが、複数のMPIを使って計算する場合、親MPIを考慮する必要がある。でも親MPIはGPU計算を行わない。子MPIのみGPU計算が可能 例えば、4枚GPUマシンが2台あってそれを全て使って計算したいとなると、 #code(nonumber){{ 1つのGPUに1つのMPI(子MPI)プロセスを割り当てるなら、8MPIが必要 加えて、親MPIを1つ加えての合計9MPIが必要となる 加えて、親MPIを1つ加えての合計9MPIが必要となる --> Number of MPI procs : 9 次に、1つのノードに幾つのMPIを乗せるか。9MPIの計算になるので、1つのノードには 9÷2 = 4.5 なので、5MPI割り当てる 次に、1つのノードに幾つのMPIを乗せるか。9MPIの計算になるので、1つのノードには 9(mpi)÷2(ノード) = 4.5 なので、1ノードに5MPI割り当てる --> Queue submit command: sbatch --ntasks-per-node=5 --gres=gpu:2 もし 32core/4GPUと64core/4GPUなら、少ない32coreに合わせて、32÷5 = 6.4 で、1MPI当たり6core割り当てることになる もし 32core/4GPUと64core/4GPUなら、少ない32coreに合わせて、32÷5 = 6.4 で、1MPI当たり6core割り当てることになる --> Number of threads: 6 9MPIを6coreで計算するので、全体では9 x 6 = 54 core必要として、1ノードでは54÷2 = 27 なので1ノードの最低coreを27 coreと定義します 9MPIを6coreで計算するので、全体では9 x 6 = 54 core必要として、1ノードでは54÷2 = 27 なので1ノードの最低coreを27 coreと定義します--> Minimum dedicated cores per node: 27 }} これでパネルは下記のようにします &ref(2026y09m01d_105627163.png,nolink); &color(red){*};「Compute」タグでは「Use GPU acceleration?」を有効にして「Which GPUs to use」は無記載でもok 見切れてますが「&color(magenta){Queue submit command};」は「sbatch --ntasks-per-node=5 --gres=gpu:4」です。1ノードあたり5mpiを消費して、4GPUを使用する意図です。 ログ(run.out)には #code(nonumber){{ : Queue name g required cores 54 :( 9[mpi] * 6[threads] ) nodes 2 :CEIL( 54 / 27 ) :( g[01-02] ) : }} と記載されます slurm側では、それぞれ30coreを確保して計算されることになります. (5mpi * 6 threads) #code(nonumber){{ (sloadから) Queue Run wait Host CPU usage GPU g01 30/64 **********---------- 4/4 **** pro4000 mix g02 30/32 *******************- 4/4 **** pro4000 mix }} ***Runningパネル その2 [#s6b23ccf] 2枚のGPUを持つマシンが3台あって、それぞれ32core持っている. 1つのGPUに1つのMPIで計算させる #code(nonumber){{ 2(GPU) x 3(ノード) なので6MPIとなるが、親MPIを加えるので 7MPI となる --> Number of MPI procs : 7 7MPIを3台で計算するので、7(MPI)÷3(ノード) = 2.33 なので1ノード当たり3MPI割り当てる --> Queue submit command: sbatch --ntasks-per-node=3 --gres=gpu:2 全ノードいずれも32coreなので、1ノードでは 32(core)÷3(MPI) = 10.66 となり、1MPI当たり10(core)を割り当てる --> Number of threads: 10 7MPIを1MPI当たり10coreで計算するので、全体では7(MPI) x 10(core) = 70 (core)必要で、1ノードでは、70(core)÷3(ノード) = 23.33なので、1ノード当たり 24core必要 --> Minimum dedicated cores per node: 24 }} ***Runningパネル その3 [#ga8f94f6] 2枚のGPUを持つマシンが5台あって、TH有効で1ノードに 128 core(HT)もっている. 1つのGPUに1つのMPIで計算してみる #code(nonumber){{ 2(GPU) x 5(ノード) なので10MPIとなるが、親MPIを加えるので 11MPI となる --> Number of MPI procs : 11 次に1つのノードに幾つのMPIを乗せるか。11MPIの計算を5台で計算するので、11÷5 = 2.2 なので、3MPI割り当てる --> Queue submit command: sbatch --ntasks-per-node=3 --gres=gpu:2 全部の計算ノードが(HTレベルで)128coreなので、128(HT)÷3(MPI) = 42.6 なので、切り捨てて1MPI当たりに 42core(HT)を割り当てる --> Number of threads: 42 11MPIを42core(HT)で計算するので、全体では 11x42 = 462 core(HT)必要として、1ノードでは 462÷5(ノード) = 92.4なので、切り上げて1ノード当たり 93core必要 --> Minimum dedicated cores per node: 93 }} &ref(2026y10m02d_170125673.png,nolink); #code(nonumber){{ (sloadから) Queue Run wait Host CPU usage GPU g31 126/128 ******************** 2/2 ** a6000 mix g32 126/128 ******************** 2/2 ** a6000 mix g33 126/128 ******************** 2/2 ** a6000 mix g34 126/128 ******************** 2/2 ** a6000 mix g35 126/128 ******************** 2/2 ** a6000 mix }} ***Runningパネル その4 [#p526c1a3] 2枚のGPUを持つマシンが5台あって、TH有効で1ノードに 128 core(HT)もっている. 1つのGPUを2つのMPIで計算してみる #code(nonumber){{ 2x5で 10MPI 作成可能だが、Class2Dを行うので各GPUに2MPI載せたい。なので 20MPI で実行する。なら親MPIを加えて、合計 21MPIを要する --> Number of MPI procs : 21 次に1つのノードに幾つのMPIを乗せるか。21MPIの計算を5台で計算するので、21÷5 = 4.2 なので、5MPI割り当てる --> Queue submit command: sbatch --ntasks-per-node=5 --gres=gpu:2 全部の計算ノードが(HTレベルで)128coreなので、128(HT)÷5(MPI) = 25.6 なので、1MPI当たりに 25core(HT)を割り当てる --> Number of threads: 25 21MPIを25core(HT)で計算するので、全体では 21x25 = 525 core(HT)必要として、1ノードでは 525÷5(ノード) = 105なので、1ノード当たり 105core必要 --> Minimum dedicated cores per node: 105 }} なので &ref(2026y10m02d_165704793.png,nolink); #code(nonumber){{ (sloadから) Queue Run wait Host CPU usage GPU g31 125/128 ******************** 2/2 ** a6000 mix g32 125/128 ******************** 2/2 ** a6000 mix g33 125/128 ******************** 2/2 ** a6000 mix g34 125/128 ******************** 2/2 ** a6000 mix g35 125/128 ******************** 2/2 ** a6000 mix }} ***Runningパネル その5 [#bfd78ef0] 2枚のGPUを持つマシンが5台あって、TH有効で1ノードに 128 core(HT)もっている. 1つのGPUを2つのMPIで計算してみる。っが1MPI当たり4threadsで計算したい #code(nonumber){{ 2x5で 10MPI 作成可能だが、各GPUに2MPI載せたい。なので 20MPI となるが、親MPIを加えて、合計 21MPIを要する --> Number of MPI procs : 21 1つのノードに幾つのMPIを乗せるか。21MPIの計算を5台で計算するので、21÷5 = 4.2 なので、5MPI割り当てる --> Queue submit command: sbatch --ntasks-per-node=5 --gres=gpu:2 1MPI当たり4threadsで計算したい --> Number of threads: 4 21MPIを4core(HT)で計算するので、21x4 = 84core(HT)を必要として、1ノードでは84÷5(ノード)=16.8なので、1ノード当たり 17core必要 --> Minimum dedicated cores per node: 17 }} &ref(2026y10m02d_165426386.png,nolink); #code(nonumber){{ (sloadから) Queue Run wait Host CPU usage GPU g31 20/128 ****---------------- 2/2 ** a6000 mix g32 20/128 ****---------------- 2/2 ** a6000 mix g33 20/128 ****---------------- 2/2 ** a6000 mix g34 20/128 ****---------------- 2/2 ** a6000 mix g35 20/128 ****---------------- 2/2 ** a6000 mix }} ***Runningパネル(CPUを使い切りたい) [#i1443692] GPUを使わず、全CPU coreを使って計算したいなら. MotionCorrectionとかでしょうか #code(nonumber){{ 32coreマシンと64coreマシンなら、1MPI1threadsとして、96MPIを用意できる。この96MPIの中に親MPIを入れる。 core数が違うので、--ntasks-per-nodeで均等割りはしない 96÷2 = 48 なので、1ノードの最低coreを48 coreと定義します }} パネルにすれば &ref(2026y09m01d_112508834.png,nolink); &color(red){*};「Compute」タグでは「Use GPU acceleration?」は無効にします ログ(run.out)には #code(nonumber){{ : Queue name g required cores 96 :( 96[mpi] * 1[threads] ) nodes 2 :CEIL( 96 / 48 ) :( g[01-02] ) : }} と記載されます slurm側では、それぞれ全core確保して計算されることになります. #code(nonumber){{ (sloadから) Queue Run wait Host CPU usage GPU g01 64/64 ******************** 0/4 ---- pro4000alloc g02 32/32 ******************** 0/4 ---- pro4000alloc }} となります ***Runningパネル (4ノードGPUマシン) [#p9addeb8] 1台の2基のGPUがあって、それぞれが32coreなら #code(nonumber){{ 1つのGPUに1つのMPI(子MPI)プロセスを乗せるので、4 x 2 = 8MPI 加えて、親MPIがあるので合計9MPIが必要となる 次に1つのノードには 9(MPI)÷4(台) = 2.25なので、3MPIを割り当てる そして32coreマシンなので、32÷3 = 10.67で、1MPI当たり10core割り当てる 9MPIをそれぞれ10coreで計算するので、全体では9 x 10 = 90 coreが必要で、1ノードでは 90 ÷ 4 = 22.5、1ノードの最低コアは23とします }} パネルでは下記のようになります &ref(2026y09m05d_012429295.png,nolink); 見切れてますが「&color(magenta){Queue submit command};」は「sbatch --ntasks-per-node=3 --gres=gpu:2」です。1ノードあたり3mpiを消費して、2GPUを使用する意図です。 run.outは下記のようになり #code(nonumber){{ Queue name g2 required cores 90 :( 9[mpi] * 10[threads] ) nodes 4 :CEIL( 90 / 23 ) :( g[21-24] ) }} 計算途中の sload を見ると、各ノードは 3MPI確保されるので、30coreが確保されるのですが、親MPIを運営する1台を除き他は用意された3MPIをすべて使わない。 #code(nonumber){{ Queue Run wait Host CPU usage GPU g21 30/32 *******************- 2/2 ** rtx3090 mix g22 30/32 *******************- 2/2 ** rtx3090 mix g23 30/32 *******************- 2/2 ** rtx3090 mix g24 30/32 *******************- 2/2 ** rtx3090 mix }} ***メモ [#d9a6053d] 使用可能な変数とパネルの位置 #code(nonumber){{ Number of MPI procs: => XXXmpinodesXXX Number of threads; => XXXthreadsXXX Submit to queue?: => XXXqueueXXX Minimum dedicated cores per node: => XXXdedicatedXXX }} 他「Standard submisstion script」で使える変数 #code(nonumber){{ XXXmpinodesXXX * XXXthreadsXXX => XXXcoresXXX XXXnodesXXX = CEIL( XXXcoresXXX / XXXdedicatedXXX ) }} slurmでは、 「Number of MPI procs」はtaskとして扱い「--ntask(-n)」に該当かと。 「Number of threasds」は「--cpus-per-task(-c)」に該当かなと。 XXXnodesXXX は「--nodes(-N)」に該当かな 計算ノード間でMPIの数を均等にしたいなら「&color(magenta){Queue submit command};」に「sbatch --ntasks-per-node=X」とか入れて、計算ノード間に割り振られるtaskの値を同じにする もし同じqueueの中で、計算機を指定したいなら「&color(magenta){Queue submit command};」には「sbatch --nodes=2 --nodelist=a,c」と「--nodelist」を使って指定する