Views

Krok po kroku: MPI na halo

From Centrum Komputerów Dużej Mocy, ICM Uniwersytet Warszawski

Jump to: navigation, search
Poradnik
Konto użytkownika  • Poczta elektroniczna  • Korzystanie z SSH  • Systemy kolejkowe: PBS (Klaster halo2), LoadLeveler (BlueGene/P notos)
Programowanie
Kompilatory: C/C++, Fortran  • Programowanie równoległe: OpenMP, MPI, UPC, CAF, SHMEM, pthreads  • Biblioteki numeryczne: BLAS, LAPACK, FFTW
Optymalizacja
Uruchamianie i optymalizacja kodów na architekturze Blue Gene/P  • Uruchamianie i optymalizacja kodów na halo2
Krok po kroku
Logowanie do ICM (Windows)  • Logowanie do ICM (UNIX)  • MPI (Klaster halo2)  • MPI (BlueGene/P notos)
Wszystkie "Krok po kroku"
Dokumentacja

Zadanie

Zalogowaliśmy się na klaster halo2. Chcemy napisać, skompilować i uruchomić prosty program wykorzystujący bibliotekę MPI.

Rozwiązanie krok po kroku

1. Tworzymy katalog roboczy:

 mkdir -p work/mpiex
 cd work/mpiex

2. Tworzymy plik mpisum.c przy pomocy edytora tekstowego nano (zapis: Ctrl-O, wyjście: Ctrl-X):

 nano -w mpisum.c

3. Plik mpisum.c powinien mieć następującą treść:

 #include <mpi.h>
 
 int main(int argc, char **argv) {
    int nprocs, myproc;
    int i, sum, val;
    MPI_Status status;
 
    /* inicjalizacja MPI */
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &myproc);
 
    if (myproc == 0) {
 
       /* procesor 0 zbiera wyniki od pozostałych procesorów i sumuje */
       sum = 0;
       for (i = 1; i < nprocs; i++) {
          MPI_Recv(&val, 1, MPI_INTEGER, i, 0, MPI_COMM_WORLD, &status);
          sum += val;
       }
 
    } else {
 
       /* każdy pozostały procesor oblicza wynik i wysyła do procesora 0 */
       val = myproc*myproc;
       MPI_Send(&val, 1, MPI_INTEGER, 0, 0, MPI_COMM_WORLD);
 
    }
 
    if (myproc == 0 && nprocs > 1) {
       /* procesor 0 wypisuje wynik */
       printf("Sum(n^2, n = 1...%d) = %d\n", nprocs-1, sum);
    }
 
    /* zakończenie MPI */
    MPI_Finalize();
    return 0;
 }

4. Ustawiamy środowisko kompilacji - kompilatory Portland Group oraz bibliotekę MPI dla takich kompilatorów, za pomocą narzędzia Modules:

 module load pgi
 module load openmpi

5. Kompilujemy napisany program:

 mpicc mpisum.c -o mpisum.exe

6. Tworzymy plik o nazwie mpisum.pbs z opisem zadania dla systemu PBS (poleceniem nano -w mpisum.pbs) o następującej treści:

 #!/bin/csh
 #PBS -q test
 #PBS -N mpi_sum
 #PBS -S /bin/csh
 #PBS -l nodes=1:ppn=4
 #PBS -l walltime=00:05:00
 #PBS -A nr grantu
 module load pgi
 module load openmpi
 
 cd ~/work/mpiex
 mpiexec ./mpisum.exe > wynik.txt

7. Wstawiamy zadanie do kolejki:

 qsub mpisum.pbs

8. W odpowiedzi powinniśmy otrzymać na ekranie identyfikator zadania, np.:

 118740.halo2

9. Sprawdzamy stan zadania poleceniem (zastępując użytkownik nazwą użytkownika)

 qstat -u użytkownik

10. W odpowiedzi otrzymujemy stan wszystkich naszych zadań znajdujących się obecnie w systemie kolejkowym. Kolumna S oznacza stan. W szczególności wartość Q oznacza "oczekujące w kolejce" (ang. queued), wartość R oznacza uruchomione (ang. running).

 halo2:
                                                                    Req'd  Req'd   Elap
 Job ID               Username Queue    Jobname    SessID NDS   TSK Memory Time  S Time
 -------------------- -------- -------- ---------- ------ ----- --- ------ ----- - -----
 118740.halo2         mszpindl test     mpi_sum       --      1  --    8gb 00:05 Q   --

11. Po zakończeniu zadania znika ono z listy. W katalogu ~/work/mpiex powinien pojawić się plik wynik.txt o zawartości:

 Sum(n^2, n = 1...3) = 14

Potencjalne problemy