Krok po kroku: MPI na halo
From Centrum Komputerów Dużej Mocy, ICM Uniwersytet Warszawski
| 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
