Slurm ile MPI kullanımı

Slurm ile MPI kullanımı#

MPI, HPC için çok önemli olan bir şeye izin verir - birden çok düğümün (sunucunun) aynı prosedür üzerinde çalışmasını sağlar. Sunucular arasındaki bu işbirliği oldukça sorunsuzdur ve TRUBA gibi bir sistemde çalışmak kolaydır. MPI içeren görevleri yürütmek için, iş adımlarını mpirun komutunu kullanarak başlatmamız gerekir (şimdiye kadar kullanılan srun komutu yerine). mpirun komutu kullanılarak oluşturulan iş adımları yine birden fazla görev oluşturacaktır, ancak bu görevler aynı MPI prosedürü üzerinde çalışacaktır. Öte yandan, srun komutu kullanılarak oluşturulan görevler birbirinden bağımsızdır.

OMP ile deney yapmak için aşağıdaki MPI programını kullanacağız (şimdilik bu programı anlamaya çalışmanıza gerek yok. İlerki bölümleri takip ettikten sonra geri dönüp anlamaya çalışmanızı tavsiye ederiz.

Örnek Betik (Tıklayınız)
#include <stdio.h>
#include <omp.h>
#include <limits.h>
#include <unistd.h>
static long long num_steps=1000000000;
double step;
char hostname[HOST_NAME_MAX];

int main(int argc, char** argv){
        gethostname(hostname, HOST_NAME_MAX);
        int i, myid, num_procs;
        double x, pi, remote_sum, sum=0, start=0, end=0;;
        MPI_Init(&argc, &argv);
        MPI_Barrier(MPI_COMM_WORLD);
        MPI_Comm_rank(MPI_COMM_WORLD, &myid);
        MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
        start = MPI_Wtime();
        step = 1.0/(double) num_steps;
        for (i = myid; i< num_steps; i=i+num_procs){
                x =(i+0.5)*step;
                sum +=4.0/(1.0+x*x);
        }
        printf("Process %d running on %s\n", myid, hostname);
        if (myid==0){
                for (i = 1; i< num_procs;i++){
                        MPI_Status status;
                        MPI_Recv(&remote_sum, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status);
                        sum +=remote_sum;
                }
                pi=sum*step;
        } else {
                MPI_Send(&sum, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
        }
        MPI_Finalize();

        if (myid ==0){
                end = MPI_Wtime();
                printf("Processes %d, took %f \n", num_procs, end-start);
        }
        return 0;
#!/bin/bash

#SBATCH --account=<my_account>
#SBATCH --job-name=my_job
#SBATCH --partition=short
#SBATCH --time=0-00:02:00
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=4
#SBATCH --workdir=/truba/home/my_account/
#SBATCH --output=output.txt
#SBATCH --error=error.txt

# Setup the environment
# 1. load the modules required for compilation
module purge # remove any modules that were loaded on the client server to start fresh
module lib/openmpi/5.0.4
# 2. compile code
mpicc mpi.c -o mpi

echo "Using four tasks"
mpirun -np 4 ./mpi
echo ""
echo ""
echo "Using six tasks"
mpirun -np 6 ./mpi
echo ""
echo ""
echo "Using eight tasks"
mpirun ./mpi
echo ""
echo ""
Using four tasks
Process 1 running on akya14.yonetim
Process 3 running on akya14.yonetim
Process 0 running on akya14.yonetim
Process 2 running on akya14.yonetim
Processes 4, took 3.254500

Using six tasks
Process 4 running on akya15.yonetim
Process 0 running on akya14.yonetim
Process 2 running on akya14.yonetim
Process 5 running on akya15.yonetim
Process 3 running on akya14.yonetim
Process 1 running on akya14.yonetim
Processes 6, took 2.209622

Using eight tasks
Process 1 running on akya14.yonetim
Process 6 running on akya15.yonetim
Process 0 running on akya14.yonetim
Process 3 running on akya14.yonetim
Process 4 running on akya15.yonetim
Process 5 running on akya15.yonetim
Process 2 running on akya14.yonetim
Process 7 running on akya15.yonetim
Processes 8, took 1.722208

<my_account>: TRUBA’daki hesap adı

<job_name>: iş kuyruğunda görünen gönderilen işin adı.

<part>: çalışmayı sıraya alacağınız bölümün adı.

<time>: Çalışmanızın çalışacağı maksimum süre. Bu girdinin biçimi d-hh: mm: ss``şeklindedir, burada`dgünü,hhsaati,mmdakikayı vess` saniyeyi temsil eder. Not: Yürütülebilir dosya belirtilen bu zaman aralığında sona ermezse, otomatik olarak sonlandırılacaktır.

<N>: bu komut dosyasındaki görevleri çalıştırmak için kullanılacak düğüm (sunucu) sayısı.

<n>: komut dosyası içinde paralel olarak çalışacak maksimum görev sayısı.

<n1>: ilgili MPI iş adımına katkıda bulunacak görev sayısı

<c>: her görevin yürütülmesi için ayrılmış CPU sayısı

<dir>: TRUBA’da komut dosyasının yürütüleceği yol. Burası genellikle girdi ve çıktı dosyalarının bulunduğu yerdir. Komut dosyasında tanımlanan tüm göreli yollar <out> ile göreli olacaktır.

<out>: bu işin stdout unun yazdırılacağı dosya. Bu, koddaki yürütmelerin ürettiği tüm çıktıları içerir.

<err>: bu işin stderr inin yazdırılacağı dosya.

Sbatch komutunu çağırdığımızda, işi TRUBA kuyruğuna kaydedeceğiz. Kaynaklar mevcut olduğunda ve işimiz sıranın en üstünde olduğunda, aşağıdakiler gerçekleşecektir:

  1. Talep edilen kaynaklar, talep edilen zaman aralığı için tahsis edilecektir ve bu durumda talep ettiklerimiz:

    1. <N> düğüm

    2. <npn> * <N> görev yürütme yetkisi

    3. her görev için <c> işemci, yani totalde <c> * (<npn> * <N>) işlemci

  2. the lines starting with mpirun will start job-steps that will run the program my_mpi_omp_program using <N> nodes. The first job-step will use <n1> tasks to run its procedure. The second will use <n> tasks. Both of these job-steps’ tasks will use <c> threads.

  3. mpirun ile başlayan satırlar, my_mpi_omp_program programını <N> düğüm kullanarak çalıştıracak iş adımlarını başlatacaktır. İlk iş adımı, prosedürünü çalıştırmak için <n1> görev kullanacaktır. İkincisi, <n> görev kullanacaktır. Bu iş adımlarının her iki görevi de <c> iş parçacığı kullanacaktır.