MPI - Przedmiot: Techniki Programowania Równoległego
Transkrypt
MPI - Przedmiot: Techniki Programowania Równoległego
MPI
MPI
Plan prezentacji
MPI
Wstęp
Przedmiot: Techniki Programowania Równoległego
Komunikacja punkt-punkt
Dr inż. Stanisław Polak
Akademia Górniczo - Hutnicza w Krakowie, Katedra Informatyki
Komunikacja kolektywna
http://www.icsr.agh.edu.pl/~polak/
Pochodne typy danych
MPE
Dr inż. Stanisław Polak
1
Przedmiot: Techniki Programowania Równoległego
Wstęp
2
MPI
Ogólna charakterystyka MPI
Przedmiot: Techniki Programowania Równoległego
Wstęp
MPI
Główne założenia MPI
I
Próba połączenia zalet istniejących
systemów „message passingu”.
I
Twórcy standardu: większość producentów
maszyn współbieżnych, naukowcy
uniwersyteccy, przedstawiciele ośrodków
rządowych.
I
Przenośność.
I
Udostępnia zbiór precyzyjnie
zdefiniowanych metod, które mogą być
efektywnie zaimplementowane. Punkt
wyjściowy do stworzenia praktycznego,
przenośnego, elastycznego i efektywnego
narzędzia dla „message passingu”.
Dr inż. Stanisław Polak
Dr inż. Stanisław Polak
3
Przedmiot: Techniki Programowania Równoległego
I
Efektywna komunikacja
I
Niska szczegółowość
I
„Znajomy” interfejs
I
Komunikacja P-P oraz zbiorowa
I
Działanie na wielu platformach
I
Semantyka niezależna od języka
I
„Thread-safe”
Dr inż. Stanisław Polak
4
Przedmiot: Techniki Programowania Równoległego
Wstęp
MPI
Dalsze informacje
MIMD
I
Własna przestrzeń adresowa.
I
I
I
Wielowątkowość
Rozłożenie obciążenia
Nr ∈ [0 .. Rozmiar grupy – 1]
I
Deklaracje: ISO C
I
Implementacje mogą oferować obsługę MPI za pomocą obiektów
I
MPI Xxxx xxx()
I
MPI XXXXX
I
MPI SUCCESS
≈ 400 funkcji
Dr inż. Stanisław Polak
MPI
Integracja MPI z językiem C
I
I
Wstęp
5
Przedmiot: Techniki Programowania Równoległego
Wstęp
Dr inż. Stanisław Polak
6
MPI
Pierwszy program w MPI
Przedmiot: Techniki Programowania Równoległego
Wstęp
MPI
Kompilacja programu równoległego
Implementacja „MPICH2”
1
2
3
4
5
6
7
8
9
Kompilacja
I Program w C
# include "mpi.h"
# include <s t d i o . h>
int main ( int argc , char ∗∗argv )
{
MPI Init ( &argc , &argv ) ;
printf ( " Hello world \ n " ) ;
MPI Finalize ( ) ;
return 0 ;
}
Dr inż. Stanisław Polak
7
I
I
mpicc -o program program.c
Program w C++
I
mpic++ -o program program.cpp
Wybrane opcje kompilatora
Przedmiot: Techniki Programowania Równoległego
I
-profile=mpe mpilog
I
-cc=nazwa
Dr inż. Stanisław Polak
8
Przedmiot: Techniki Programowania Równoległego
Wstęp
MPI
Uruchomienie programu równoległego
Wstęp
MPI
Program „Jumpshot”
Implementacja „MPICH2”
1
2
3
4
#U r u c h o m i e n i e j e d n a k o w e g o z e s t a w u p r o c e s ów
mpiexec −n <liczba uruchamianych proces ów> . / program
#U r u c h o m i e n i e r ó ż nego z e s t a w u p r o c e s ów − obydwa p r o g r a m y d z i e l ą wsp ó l n y
k o m u n i k a t o r MPI COMM WORLD
mpiexec −n 1 −host vnode −01 . / master : −n 2 −host vnode −02 . / slave
Przydatne opcje
I
-machinefile
I
-configfile
I
-l
Dr inż. Stanisław Polak
9
Przedmiot: Techniki Programowania Równoległego
Wstęp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
10
MPI
Mierzenie czasu
I
Dr inż. Stanisław Polak
Przedmiot: Techniki Programowania Równoległego
Wstęp
MPI
Komunikator
double MPI Wtime()
# include " mpi . h "
# include <s t d i o . h>
int main ( int argc , char ∗argv [ ] )
{
double t1 , t2 ;
MPI_Init ( 0 , 0 ) ;
t1 = MPI Wtime ( ) ;
sleep ( 1 ) ;
t2 = MPI Wtime ;
printf ( " MPI_Wtime measured a 1 second sleep to be : %1.2 f \ n " , t2−t1 ) ;
fflush ( stdout ) ;
MPI_Finalize ( ) ;
return 0 ;
I
MPI COMM WORLD
I
Specyfikuje grupę procesów
I
Brak interferencji pomiędzy komunikatami należącymi do różnych
komunikatorów
I
Jeden proces ∈ kilka komunikatorów?
I
Komunikator = grupa + kontekst
}
Na wyjściu
MPI_Wtime measured a 1 second sleep to be: 1.00
Dr inż. Stanisław Polak
11
Przedmiot: Techniki Programowania Równoległego
Dr inż. Stanisław Polak
12
Przedmiot: Techniki Programowania Równoległego
Wstęp
MPI
Informacje o komunikatorze
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
MPI_Init (&argc ,& argv ) ;
MPI Comm size ( MPI_COMM_WORLD ,& numprocs ) ;
MPI Comm rank ( MPI_COMM_WORLD ,& rank ) ;
if ( rank == 0 ) /∗ c o d e f o r p r o c e s s z e r o ∗/
printf ( " Proces master \ n " ) ;
else
printf ( " Hello , world . I am % d of % d \ n " , rank , numprocs ) ;
fflush ( stdout ) ;
MPI_Finalize ( ) ;
return 0 ;
11
12
13
14
15
16
17
18
19
20
21
}
hello.c
Na wyjściu
mpiexec -n 4 ./hello
Proces master
Hello, world. I am 1 of 4
Hello, world. I am 2 of 4
Hello, world. I am 3 of 4
13
Przedmiot: Techniki Programowania Równoległego
MPI Init(&argc ,& argv ) ;
// Z a s t ą p domy ś l n y h a n d l e r o b s ł u g i b ł ę dów ’ MPI ERRORS ARE FATAL ’ , h a n d l e r e m ’
MPI ERRORS RETURN ’
MPI Comm set errhandler ( MPI_COMM_WORLD , M P I_E R RO RS _R E TU R N ) ;
rc=MPI_Comm_size ( MPI_COMM_WORLD ,& numtasks ) ;
if ( rc != MPI_SUCCESS ) {
perror ( " Problem with communicator . Terminating .\ n " ) ;
MPI Abort ( MPI_COMM_WORLD , rc ) ;
/∗ No f u r t h e r c o d e w i l l e x e c u t e ∗/
}
MPI Finalize ( ) ;
}
Dr inż. Stanisław Polak
14
Przedmiot: Techniki Programowania Równoległego
Wstęp
MPI
Komunikaty MPI
...
MPI Info create ( &info1 ) ;
MPI Info set ( info1 , " host " , " myhost . myorg . org " ) ;
MPI Info set ( info1 , " file " , " runfile . txt " ) ;
MPI Info set ( info1 , " soft " , " 2:1000:4 ,3:1000:7 " ) ;
MPI Info dup ( info1 , &info2 ) ;
MPI Info get nkeys ( info2 , &nkeys2 ) ;
MPI Info get nkeys ( info1 , &nkeys1 ) ;
if ( nkeys1 != nkeys2 ) {
printf ( " Dup ’ ed info has a different number of keys ; is % d should be % d \ n " ,
nkeys2 , nkeys1 ) ;
fflush ( stdout ) ;
}
for ( i =0; i<nkeys1 ; i++) {
/∗ MPI r e q u i r e s t h a t t h e k e y s a r e i n t h e same o r d e r a f t e r t h e dup ∗/
MPI Info get nthkey ( info1 , i , key1 ) ;
MPI Info get nthkey ( info2 , i , key2 ) ;
if ( strcmp ( key1 , key2 ) ) {
printf ( " keys do not match : % s should be % s \ n " , key2 , key1 ) ;
fflush ( stdout ) ;
}
}
...
MPI Info free ( &info1 ) ;
MPI Info free ( &info2 ) ;
...
Dr inż. Stanisław Polak
int main ( int argc , char ∗argv [ ] )
{
int numtasks , rank , rc ;
MPI
Obiekt info
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# include " mpi . h "
# include <s t d i o . h>
Rank ∈ [0..Rozmiarkomunikator − 1]
Wstęp
1
2
3
4
5
6
7
8
9
10
MPI
Obsługa środowiska MPI
# include " mpi . h "
# include <s t d i o . h>
int main ( int argc , char ∗argv [ ] )
{
int rank , numprocs ;
Dr inż. Stanisław Polak
Wstęp
15
Przedmiot: Techniki Programowania Równoległego
I
Typy niezależne:
I
I
I
I
I
I
I
I
I
I
I
I
I
MPI
MPI
MPI
MPI
MPI
MPI
MPI
MPI
MPI
MPI
MPI
MPI
CHAR,
SHORT,
INT,
LONG,
UNSIGNED CHAR,
UNSIGNED SHORT,
UNSIGNED,
UNSIGNED LONG,
FLOAT,
LONG DOUBLE,
BYTE,
PACKED
Zgodność typów
Dr inż. Stanisław Polak
16
Przedmiot: Techniki Programowania Równoległego
Komunikacja punkt-punkt
MPI
Komunikacja „punkt-punkt”
Komunikacja punkt-punkt
MPI
Reguły komunikacji punkt-punkt
3
odbierz(0,. . . )
wyślij(3,. . . )
wyślij(1,. . . )
2
odbierz(0,. . . )
wyślij(2,. . . )
0
odbierz(0,. . . )
1
I
Zachowanie kolejności
I
Postęp
I
Brak uczciwości
wyślij(4,. . . )
odbierz(0,. . . )
4
Dr inż. Stanisław Polak
17
Komunikacja punkt-punkt
Przedmiot: Techniki Programowania Równoległego
MPI
Tryby nadawania i odbierania
I
I
I
tryb blokujący
tryb nieblokujący
Odbieranie
I
I
Dr inż. Stanisław Polak
18
Komunikacja punkt-punkt
Przedmiot: Techniki Programowania Równoległego
MPI
Tryby komunikacji
Nadawanie
I
Dr inż. Stanisław Polak
tryb blokujący
tryb nieblokujący
19
Przedmiot: Techniki Programowania Równoległego
I
Synchroniczny
I
Buforowany
I
Przygotowany
I
Standardowy
Dr inż. Stanisław Polak
20
Przedmiot: Techniki Programowania Równoległego
Blokująca
Komunikacja punkt-punkt
MPI
Nazwy procedur do wysyłki / odbierania danych
Blokująca
Komunikacja punkt-punkt
Nadawanie w trybie synchronicznym
I
Nadawnie
Tryb
Standardowy
Przygotowany
Synchroniczny
Buforowany
MPI
int MPI Ssend(void *buf, int count, MPI Datatype datatype, int dest, int
tag, MPI Comm comm)
Wywołanie MPI
MPI Send()
MPI Rsend()
MPI Ssend()
MPI Bsend()
Odbieranie
Tryb
Standardowy
Dr inż. Stanisław Polak
Wywołanie MPI
MPI Recv()
21
Blokująca
Przedmiot: Techniki Programowania Równoległego
Komunikacja punkt-punkt
MPI
Nadawanie w trybie buforowanym
int MPI Buffer attach(void *buffer, int size)
I
int MPI Pack size(int incount,MPI Datatype datatype, MPI Comm comm,
int *size)
int MPI Buffer detach(void *buffer, int *size)
Dr inż. Stanisław Polak
23
22
Blokująca
Przedmiot: Techniki Programowania Równoległego
Komunikacja punkt-punkt
MPI
Nadawanie w trybie przygotowanym
I
I
Dr inż. Stanisław Polak
Przedmiot: Techniki Programowania Równoległego
1
2
3
4
5
6
7
8
...
if ( rank == 0 ) {
for ( i =0; i <10; i++)
buffer [ i ] = i ;
MPI Rsend ( buffer , 1 0 , MPI_INT , 1 , 1 2 3 , MPI_COMM_WORL D ) ;
}
...
Dr inż. Stanisław Polak
24
Przedmiot: Techniki Programowania Równoległego
Blokująca
Komunikacja punkt-punkt
MPI
Nadawanie w trybie standardowym
Blokująca
Komunikacja punkt-punkt
Standardowe blokujące odbieranie danych
I
1
2
3
4
5
6
7
8
...
if ( rank == 0 ) {
for ( i =0; i <10; i++)
buffer [ i ] = i ;
int MPI Recv(void *buf, int count, MPI Datatype datatype, int source, int
tag, MPI Comm comm, MPI Status *status)
I
I
I
I
MPI Send ( buffer , 1 0 , MPI_INT , 1 , 1 2 3 , MPI_COMM_WORLD ) ;
I
}
...
1
2
3
4
5
6
7
8
9
10
Dr inż. Stanisław Polak
25
Blokująca
MPI
Przedmiot: Techniki Programowania Równoległego
Komunikacja punkt-punkt
MPI
Wymiana komunikatów bez zakleszczania
MPI ANY SOURCE
MPI PROC NULL
MPI ANY TAG
status.MPI SOURCE
status.MPI TAG
I
int MPI Probe(int source, int tag, MPI Comm comm, MPI Status *status)
I
int MPI Get count( MPI Status *status, MPI Datatype datatype, int
*count)
...
for ( i =0; i <3; i++) {
tag = i ;
...
MPI Probe ( MPI_ANY_SOURCE , tag , MPI_COMM_WORLD , &status ) ;
MPI Get count(&status , MPI_INT , &count ) ;
buf=(int ∗) calloc ( count , sizeof ( int ) ) ;
MPI Recv ( buf, count, MPI INT, src, tag, comm, &status ) ;
}
...
Dr inż. Stanisław Polak
26
Nieblokująca
Przedmiot: Techniki Programowania Równoległego
Komunikacja punkt-punkt
MPI
Nazwy procedur do wysyłki / odbierania danych
Nadawnie
I
1
2
3
4
5
6
7
Tryb
Standardowy
Przygotowany
Synchroniczny
Buforowany
int MPI Sendrecv( void *sendbuf, int sendcount, MPI Datatype sendtype,
int dest, int sendtag, void *recvbuf, int recvcount, MPI Datatype recvtype,
int source, int recvtag, MPI Comm comm, MPI Status *status )
...
right = ( rank + 1 ) % numprocs ;
left = rank − 1 ;
if ( left < 0 )
left = numprocs − 1 ;
MPI_Sendrecv ( buffer , 1 0 , MPI_INT , left , 1 2 3 , buffer2 , 1 0 , MPI_INT , right , 1 2 3 ,
MPI_COMM_WORLD , &status ) ;
...
I
27
Przedmiot: Techniki Programowania Równoległego
int MPI I[rsb]?send(void *buf, int count, MPI Datatype datatype, int dest,
int tag, MPI Comm comm, MPI Request *request)
Odbieranie
Tryb
Standardowy
I
Dr inż. Stanisław Polak
Wywołanie MPI
MPI Isend()
MPI Irsend()
MPI Issend()
MPI Ibsend()
Wywołanie MPI
MPI Irecv()
int MPI Irecv(void *buf, int count, MPI Datatype datatype, int source, int
tag, MPI Comm comm, MPI Request *request)
Dr inż. Stanisław Polak
28
Przedmiot: Techniki Programowania Równoległego
Nieblokująca
Komunikacja punkt-punkt
MPI
Wysyłanie i odbieranie danych
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
„Czekaj”
MPI Wait()
MPI Waitany()
MPI Waitall()
MPI Waitsome()
MPI Iprobe ( MPI_ANY_SOURCE , MPI_ANY_TAG , MPI_COMM_WORLD , &flag , &status ) ;
if ( flag )
printf ( " Przyby ł komunikat od procesu o ranku % d \ n " , status . MPI_SOURCE ) ;
MPI Irecv ( buffer , 1 0 , MPI_INT , left , 1 2 3 , MPI_COMM_WORLD , &request ) ;
...
MPI_Wait (& request , &status ) ;
MPI Isend ( buffer2 , 1 0 , MPI_INT , right , 1 2 3 , MPI_COMM_WORLD , &request2 ) ;
...
MPI_Wait (& request2 , &status ) ;
...
29
Nieblokująca
Przedmiot: Techniki Programowania Równoległego
Komunikacja punkt-punkt
MPI
Przykład użycia funkcji typu „Czekaj”
18
19
MPI
Dr inż. Stanisław Polak
„Test”
MPI Test()
MPI Testany()
MPI Testall()
MPI Testsome()
30
Nieblokująca
Przedmiot: Techniki Programowania Równoległego
Komunikacja punkt-punkt
MPI
Przykład użycia funkcji typu „Test”
...
int index ;
MPI_Request request [ 2 ] ;
MPI_Status status [ 2 ] ;
...
if ( rank == 1 )
MPI_Send ( buffer1 , 4 , MPI_INT , 0 , 1 2 3 , MPI_COMM_WORLD ) ;
if ( rank == 2 )
MPI_Send ( buffer2 , 4 , MPI_FLOAT , 0 , 1 2 3 , MPI_COMM_WORLD ) ;
if ( rank == 0 )
{
MPI_Irecv ( buffer1 , 4 , MPI_INT , MPI_ANY_SOURCE , 1 2 3 , MPI_COMM_WORLD , &request [ 0 ] ) ;
MPI_Irecv ( buffer2 , 4 , MPI_FLOAT , MPI_ANY_SOURCE , 1 2 3 , MPI_COMM_WORLD , &request [ 1 ] ) ;
printf ( " Czekam na zako ń czenie jednej z dw ó ch komunikacji \ n " ) ;
MPI Waitany ( 2 , request , &index , status ) ;
printf ( " Zako ń czy ł a si ę komunikacja o indeksie %d , kt ó rej nadawc ą jest proces o ranku % d \ n " ,
index , status [ index ] . MPI_SOURCE ) ;
}
...
Na wyjściu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
MPI_Request request [ 4 ] ;
MPI_Status status [ 4 ] ;
int index [ 4 ] ;
...
if ( rank == 0 ) {
int remaining = 3 ;
for ( i =1; i < numprocs ; i++)
MPI_Irecv (& buffer [ i ] , 1 , MPI_INT , MPI_ANY_SOURCE , 1 2 3 , MPI_COMM_WORLD , &request [ i −1]) ;
while ( remaining > 0 ) {
printf ( " Sprawdzam czy zako ń czy ł a si ę , co najmniej , jedna z komunikacji \ n " ) ;
MPI Testsome ( numprocs −1, request , &count , index , status ) ;
if ( count > 0 ) {
for ( i =0; i<count ; i++)
printf ( " Zako ń czy ł a si ę komunikacja nr % d \ n " , index [ i ] ) ;
remaining −= count ;
}
else
sleep ( 1 ) ;
}
}
else
MPI_Send ( buffer , 1 , MPI_INT , 0 , 1 2 3 , MPI_COMM_WORLD ) ;
...
testsome.c
Na wyjściu
Czekam na zakończenie jednej z dwóch komunikacji
Zakończyła się komunikacja o indeksie 0, której nadawcą jest proces o ranku 1
Dr inż. Stanisław Polak
Komunikacja punkt-punkt
Testowanie zakończenia komunikacji
...
right = ( rank + 1 ) % numprocs ;
left = rank − 1 ;
if ( left < 0 )
left = numprocs − 1 ;
Dr inż. Stanisław Polak
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Nieblokująca
31
mpiexec -n 4 ./testsome
Sprawdzam czy zakończyła się, co
Zakończyła się komunikacja nr
Sprawdzam czy zakończyła się, co
Zakończyła się komunikacja nr
Sprawdzam czy zakończyła się, co
Zakończyła się komunikacja nr
Przedmiot: Techniki Programowania Równoległego
Dr inż. Stanisław Polak
najmniej, jedna z komunikacji
0
najmniej, jedna z komunikacji
1
najmniej, jedna z komunikacji
2
32
Przedmiot: Techniki Programowania Równoległego
Nieblokująca
Komunikacja punkt-punkt
MPI
Obsługa żądań trwałych
Komunikacja bez użycia żądań trwałych
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
MPI_Request request ;
MPI_Status status ;
...
if ( rank == 0 ){
for ( i=0 ; i< 100 ; i++) {
MPI_Isend ( buf , 1 0 , MPI_INT , 1 , 1 2 3 ,
MPI_COMM_WORLD , &request ) ;
...
MPI_Wait (& request , &status ) ;
...
}
...
}
if ( rank == 1 ){
for ( i=0 ; i< 100 ; i++) {
MPI_Irecv ( rbuf , 1 0 , MPI_INT , MPI_ANY_SOURCE
, 1 2 3 , MPI_COMM_WORLD , &request ) ;
...
do {
MPI_Test (& request , &flag , &status ) ;
...
} while ( flag == 0 ) ;
...
}
...
}
...
Dr inż. Stanisław Polak
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Przykład zastosowania
...
MPI_Request request ;
MPI_Status status ;
...
if ( rank == 0 ){
/∗ Utwó r z t r w a ł e ż ą d a n i a wys ł a n i a d a n y c h ∗/
MPI Send init ( buf , 1 0 , MPI_INT , 1 , 1 2 3 ,
MPI_COMM_WORLD , &request ) ;
for ( i=0 ; i< 100 ; i++) {
MPI Start(& request ) ; /∗ Uż y j t e g o ż ą d a n i a ∗/
...
MPI_Wait (& request , &status ) ;
...
}
MPI Request free(& request ) ;
...
}
if ( rank == 1 ){
/∗ Utwó r z t r w a ł e ż ą d a n i a o d b i o r u d a n y c h ∗/
MPI Recv init ( rbuf , 1 0 , MPI_INT , MPI_ANY_SOURCE ,
1 2 3 , MPI_COMM_WORLD , &request ) ;
for ( i=0 ; i< 100 ; i++) {
MPI Start(& request ) ;
...
do {
MPI_Test (& request , &flag , &status ) ;
...
} while ( flag == 0 ) ;
...
}
MPI Request free(& request ) ;
...
}
...
33
Iloczyn skalarny
x ·y =
’x’:
xi yi
x1
...
xN/2
xN/2+1
...
xN
y1
’y’:
...
yN/2
Proces ’1’
P
yN/2+1
...
yN
Proces ’2’
x1
...
xN/2
*
*
*
y1
...
yN/2
P
xN/2+1
...
*
*
*
yN/2+1
...
yN
=
=
il1
il2
+
xN
=
il
Dr inż. Stanisław Polak
MPI
Komunikacja kolektywna
34
Przedmiot: Techniki Programowania Równoległego
Komunikacja kolektywna
MPI
Synchronizacja
Wstęp
I
Wszystkie procesy biorą udział w komunikacji
I
Substytut P-P
I
Synchronizacja nadawcy z odbiorcą — zależy od implementacji
I
Rozłączność (P-P)
Podobieństwa
Różnice
Komunikat jest tablicą zawierającą
dane określonego typu
I
Zgodność typów po stronie
nadawcy i odbiorcy
I
Występuje w formie blokującej i
nieblokującej
Dr inż. Stanisław Polak
N
X
i=1
Przedmiot: Techniki Programowania Równoległego
Komunikacja kolektywna
I
MPI
Komunikacja kolektywna
Komunikacja z użyciem żądań trwałych
1
2
3
4
5
6
7
Komunikacja kolektywna
35
I
Brak „etykiet”
I
Wysłana wiadomość musi wypełnić
wyspecyfikowany bufor odbiorczy
I
Rozłączność komunikacji
blokującej i nieblokującej
Przedmiot: Techniki Programowania Równoległego
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
I
int MPI Barrier( MPI Comm
comm )
I
int MPI Ibarrier( MPI Comm
comm, MPI Request *request )
...
if ( rank == 1 ){
printf ( " % d : Wykonuje sleep (1) \ n " , rank ) ;
fflush ( stdout ) ;
sleep ( 1 ) ;
}
printf ( " % d : Przed MPI_Barrier \ n " , rank ) ;
fflush ( stdout ) ;
MPI Barrier ( MPI_ COMM_WOR LD ) ;
printf ( " % d : Po MPI_Barrier \ n " , rank ) ;
fflush ( stdout ) ;
if ( rank == 0 ){
printf ( " % d : Wykonuje sleep (1) \ n " , rank ) ;
fflush ( stdout ) ;
sleep ( 1 ) ;
}
printf ( " % d : Przed MPI_Ibarrier \ n " , rank ) ;
fflush ( stdout ) ;
MPI Ibarrier ( MPI_COMM_WORLD ,& request ) ;
printf ( " % d : Po MPI_Ibarrier \ n " , rank ) ;
fflush ( stdout ) ;
printf ( " % d : Przed MPI_Wait \ n " , rank ) ;
fflush ( stdout ) ;
MPI_Wait (& request ,& status ) ;
printf ( " % d : Po MPI_Wait \ n " , rank ) ;
fflush ( stdout ) ;
...
Dr inż. Stanisław Polak
36
Na wyjściu
1:
0:
2:
1:
0:
0:
1:
1:
1:
1:
2:
2:
2:
2:
0:
0:
0:
2:
0:
1:
Wykonuje sleep(1)
Przed MPI_Barrier
Przed MPI_Barrier
Przed MPI_Barrier
Po MPI_Barrier
Wykonuje sleep(1)
Po MPI_Barrier
Przed MPI_Ibarrier
Po MPI_Ibarrier
Przed MPI_Wait
Po MPI_Barrier
Przed MPI_Ibarrier
Po MPI_Ibarrier
Przed MPI_Wait
Przed MPI_Ibarrier
Po MPI_Ibarrier
Przed MPI_Wait
Po MPI_Wait
Po MPI_Wait
Po MPI_Wait
Przedmiot: Techniki Programowania Równoległego
Komunikacja kolektywna
MPI
Rozgłaszanie
1
2
3
4
5
6
7
8
9
10
Komunikacja kolektywna
Rozsiewanie
I
I
int MPI Bcast( void *buffer, int count, MPI Datatype
datatype, int root, MPI Comm comm )
I
int MPI Ibcast( void *buffer, int count, MPI Datatype
datatype, int root, MPI Comm comm, MPI Request *request )
I
1
2
3
4
5
6
7
8
9
10
11
...
int buf [6]={−1,−1,−1,−1,−1,−1};
...
if ( rank == 1 )
for ( i=0 ; i<6 ; i++)
buf [ i]=i +1;
MPI Bcast ( buf , 6 , MPI_INT , 1 , MPI_ COMM_WOR LD ) ;
for ( i=0 ; i<6 ; i++)
printf ( " % d : buf [% d ]=% d \ n " , rank , i , buf [ i ] ) ;
...
rank=0
Zawartość ’buf’ przed
rank=1
-1 -1 -1 -1 -1 -1
int MPI Scatter( void *sendbuf, int sendcnt, MPI Datatype
sendtype, void *recvbuf, int recvcnt, MPI Datatype recvtype,
int root, MPI Comm comm )
int MPI Iscatter( ..., MPI Request *request )
...
int sendbuf [6]={−1,−1,−1,−1,−1,−1};
int recvbuf [2]={ −1 , −1};
...
if ( rank == 1 )
for ( i=0 ; i<6 ; i++)
in [ i]=i +1;
MPI Scatter ( sendbuf , 2 , MPI_INT , recvbuf , 2 , MPI_INT , 1 , MPI_COMM_WORLD ) ;
for ( i=0 ; i<2 ; i++)
printf ( " % d : recvbuf [% d ]=% d \ n " , rank , i , recvbuf [ i ] ) ;
...
rank=2
1 2 3 4 5 6
rank=0
-1 -1 -1 -1 -1 -1
Zawartość ’recvbuf’ przed
Zawartość ’sendbuf’ przed i po
Zawartość ’buf’ po
1 2 3 4 5 6
Dr inż. Stanisław Polak
1 2 3 4 5 6
37
1 2 3 4 5 6
rank=2
-1 -1
-1 -1
-1 -1 -1 -1 -1 -1
1 2 3 4 5 6
-1 -1 -1 -1 -1 -1
3 4
5 6
1 2
Dr inż. Stanisław Polak
38
MPI
Rozsiewanie w częściach
rank=1
-1 -1
Zawartość ’recvbuf’ po
Przedmiot: Techniki Programowania Równoległego
Komunikacja kolektywna
1
2
3
4
5
6
7
8
9
10
11
12
MPI
Przedmiot: Techniki Programowania Równoległego
Komunikacja kolektywna
MPI
Zbieranie przez pojedynczy proces
I
int MPI Scatterv(const void *sendbuf, const int *sendcounts,
const int *displs, MPI Datatype sendtype, void *recvbuf, int
recvcount, MPI Datatype recvtype, int root, MPI Comm comm)
I
int MPI Gather(void *sendbuf, int sendcnt, MPI Datatype
sendtype, void *recvbuf, int recvcnt, MPI Datatype recvtype,
int root, MPI Comm comm)
I
int MPI Iscatterv( ..., MPI Request *request)
I
int MPI Igather( ..., MPI Request *request)
1
2
3
4
5
6
7
8
9
10
11
int sendbuf [7]={−1,−1,−1,−1,−1,−1,−1};
int recvbuf [2]={−1,−1};
int sendcounts [3]={2 , 2 , 2};
int displs [3]={ 0 , 4 , 2 };
...
if ( rank == 1 )
for ( i=0 ; i<7 ; i++)
in [ i]= i +1;
MPI Scatterv ( sendbuf , sendcounts , displs , MPI_INT , recvbuf , 2 , MPI_INT , 1 , MPI_C OMM_WOR LD ) ;
for ( i=0 ; i<2 ; i++)
printf ( " % d : recvbuf [% d ]=% d \ n " , rank , i , recvbuf [ i ] ) ;
...
rank=0
Zawartość ’recvbuf’ przed
Zawartość ’sendbuf’ przed i po
rank=2
-1 -1
-1 -1
-1 -1
-1 -1 -1 -1 -1 -1
1 2 3 4 5 6
-1 -1 -1 -1 -1 -1
5 6
3 4
Zawartość ’recvbuf’ po
Dr inż. Stanisław Polak
rank=1
1 2
39
...
int sendbuf [2]={ −1 , −1};
int recvbuf [6]={−1,−1,−1,−1,−1,−1};
...
for ( i=0 ; i<2 ; i++)
sendbuf [ i]= rank ;
MPI Gather ( sendbuf , 2 , MPI_INT , recvbuf , 2 , MPI_INT , 1 , MPI_COMM_WORLD ) ;
if ( rank == 1 )
for ( i=0 ; i<6 ; i++)
printf ( " recvbuf [% d ]=% d \ n " , i , recvbuf [ i ] ) ;
...
Przedmiot: Techniki Programowania Równoległego
Zawartość ’recvbuf’ przed
-1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1
0 0
1 1
2 2
-1 -1 -1 -1 -1 -1
0 0 1 1 2 2
-1 -1 -1 -1 -1 -1
Zawartość ’sendbuf’ przed i po
Zawartość ’recvbuf’ po
Dr inż. Stanisław Polak
40
Przedmiot: Techniki Programowania Równoległego
Komunikacja kolektywna
MPI
Zbieranie przez pojedynczy proces do określonych lokalizacji
1
2
3
4
5
6
7
8
9
10
11
12
int MPI Gatherv(void *sendbuf, int sendcount, MPI Datatype
sendtype, void *recvbuf, int recvcounts, int *displs,
MPI Datatype recvtype, int root, MPI Comm comm)
I
int MPI Igatherv( ..., MPI Request *request)
I
I
...
int sendbuf [2]={−1,−1};
int recvbuf [7]={−1,−1,−1,−1,−1,−1,−1};
int recvcounts [3]={2 , 2 , 2};
int displs [3]={ 0 , 3 , 5 };
...
for ( i=0 ; i<2 ; i++)
sendbuf [ i]= rank ;
MPI Gatherv ( sendbuf , 2 , MPI_INT , recvbuf , recvcounts , displs , MPI_INT , 1 , MPI_ COMM_WORLD ) ;
if ( rank == 1 )
for ( i=0 ; i<7 ; i++)
printf ( " recvbuf [% d ]=% d \ n " , i , recvbuf [ i ] ) ;
-1 -1 -1 -1 -1 -1 -1
1
2
3
4
5
6
7
8
9
10
11
-1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1
0 0
1 1
2 2
-1 -1 -1 -1 -1 -1 -1
0 0 -1 1 1 2 2
-1 -1 -1 -1 -1 -1 -1
int MPI Allgather ( void *sendbuf, int sendcount,
MPI Datatype sendtype, void *recvbuf, int recvcount,
MPI Datatype recvtype, MPI Comm comm)
int MPI Allgatherv ( void *sendbuf, int sendcount,
MPI Datatype sendtype, void *recvbuf, int *recvcounts, int
*displs, MPI Datatype recvtype, MPI Comm comm)
...
int sendbuf [2]={ −1 , −1};
int recvbuf [6]={−1,−1,−1,−1,−1,−1};
...
for ( i=0 ; i<2 ; i++)
sendbuf [ i]= rank ;
MPI Allgather ( sendbuf , 2 , MPI_INT , recvbuf , 2 , MPI_INT , MPI_COMM_WORLD ) ;
if ( rank == 1 )
for ( i=0 ; i<6 ; i++)
printf ( " recvbuf [% d ]=% d \ n " , i , recvbuf [ i ] ) ;
...
Zawartość ’recvbuf’ przed
Zawartość ’sendbuf’ przed i po
-1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1
0 0
1 1
2 2
0 0 1 1 2 2
0 0 1 1 2 2
0 0 1 1 2 2
Zawartość ’sendbuf’ przed i po
Zawartość ’recvbuf’ po
Zawartość ’recvbuf’ po
Dr inż. Stanisław Polak
41
Przedmiot: Techniki Programowania Równoległego
Komunikacja kolektywna
MPI
Rozsiewanie i zbieranie przez wszystkie procesy
I
I
1
2
3
4
5
6
7
8
...
int sendbuf [ 3 ] [ 2 ] = { 1 , 2 , 3 , 4 , 5 , 6 } ;
int recvbuf [2]={ −1 , −1};
...
MPI Alltoall ( sendbuf , 2 , MPI_INT , recvbuf , 2 , MPI_INT , MPI_COMM_WOR LD ) ;
for ( i=0 ; i<2 ; i++)
printf ( " % d : recvbuf [% d ]=% d \ n " , rank , i , recvbuf [ i ] ) ;
...
43
Dr inż. Stanisław Polak
42
Obliczenia globalne
Przedmiot: Techniki Programowania Równoległego
Komunikacja kolektywna
MPI
Obliczenia globalne
int MPI Alltoall( void *sendbuf, int sendcount, MPI Datatype
sendtype, void *recvbuf, int recvcnt, MPI Datatype recvtype,
MPI Comm comm )
int MPI Alltoallv(const void *sendbuf, const int
*sendcounts,const int *sdispls, MPI Datatype sendtype, void
*recvbuf,const int *recvcounts, const int *rdispls,
MPI Datatype recvtype, MPI Comm comm)
Dr inż. Stanisław Polak
MPI
Zbieranie przez wszystkie procesy
I
Zawartość ’recvbuf’ przed
Komunikacja kolektywna
Wstęp
I
Suma, maksimum, itp.
I
Operacje — predefiniowane lub własne
I
Wyniki — jeden lub wszystkie procesy
Na wyjściu
2:
2:
0:
0:
1:
1:
recvbuf[0]=5
recvbuf[1]=6
recvbuf[0]=1
recvbuf[1]=2
recvbuf[0]=3
recvbuf[1]=4
Przedmiot: Techniki Programowania Równoległego
Dr inż. Stanisław Polak
44
Przedmiot: Techniki Programowania Równoległego
Obliczenia globalne
Komunikacja kolektywna
MPI
Redukcja
I
Obliczenia globalne
Komunikacja kolektywna
MPI
Wybrane warianty operacji redukcji
int MPI Reduce(void *sendbuf, void *recvbuf, int count,
MPI Datatype data type, MPI Op op, int root, MPI Comm comm)
I
int MPI Ireduce(..., MPI Request *request)
Dr inż. Stanisław Polak
45
Obliczenia globalne
Przedmiot: Techniki Programowania Równoległego
Komunikacja kolektywna
MPI
Predefiniowane operatory
Operator
MPI MAX
MPI PROD
MPI LOR
MPI BXOR
Dr inż. Stanisław Polak
I
int MPI Allreduce (void *sendbuf, void *recvbuf, int count,
MPI Datatype datatype, MPI Op op, MPI Comm comm)
I
int MPI Reduce scatter (void *sendbuf, void *recvbuf, int
*recvcnts, MPI Datatype datatype, MPI Op op, MPI Comm comm)
I
int MPI Scan (void *sendbuf, void *recvbuf, int count,
MPI Datatype datatype, MPI Op op, MPI Comm comm)
Dr inż. Stanisław Polak
46
Obliczenia globalne
Przedmiot: Techniki Programowania Równoległego
Komunikacja kolektywna
MPI
Definiowanie własnych operatorów
Operator
MPI MIN
MPI LAND
MPI BOR
MPI MAXLOC
47
Operator
MPI SUM
MPI BAND
MPI LXOR
MPI MINLOC
Przedmiot: Techniki Programowania Równoległego
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
typedef struct {
double real , imag ;
} Complex ;
void myAdd ( Complex ∗in , Complex ∗inout , int ∗len , MPI_Datatype ∗dtype ){
...
for ( i =0; i< ∗len ; ++i ) { // O b l i c z a n i e sumy l i c z b z e s p o l o n y c h
z . real = in−>real + inout−>real ;
z . imag = in−>imag + inout−>imag ;
∗inout = z ;
in++; inout++;
}
}
int main ( int argc , char ∗∗argv ){
...
Complex a [ 2 ] , answer [ 2 ] , complex ;
...
complex . real =0;
complex . imag =2;
a [ 0 ] = complex ;
complex . real =0;
complex . imag =3;
a [ 1 ] = complex ;
M P I _ T yp e _ c o n t i g u o u s ( 2 , MPI_DOUBLE , &ctype ) ;
MPI _T ype _c omm it ( &ctype ) ;
MPI Op create ( ( M P I _ U s e r _ f u n c t i o n ∗) myAdd , 1 , &myOp ) ;
MPI_Reduce ( a , answer , 2 , ctype , myOp , 1 , MPI_ COMM_WORLD ) ;
if ( rank==1)
for ( i =0; i<2;i++)
printf ( " %.1 lf %.1 lf \ n " , answer [ i ] . real , answer [ i ] . imag ) ;
...
}
Dr inż. Stanisław Polak
48
Dla trzech
procesów
Na wyjściu
0.0 6.0
0.0 9.0
Przedmiot: Techniki Programowania Równoległego
Obliczenia globalne
Komunikacja kolektywna
MPI
Pochodne typy danych
Obliczanie iloczynu skalarnego
Pochodne typy danych
Wersja równoległa
Wstęp
15
16
17
18
19
20
21
22
23
24
25
Dr inż. Stanisław Polak
49
Pochodne typy danych
1
2
...
...
...
Elementy do wysłania
...
...
P
P
...
I
I
I
I
I
I
I
I
I
I
I
=
...
1
2
3
4
Type
Type
Type
Type
Type
Type
Type
Type
Type
Type
Type
Przedmiot: Techniki Programowania Równoległego
Dr inż. Stanisław Polak
MPI
Przedmiot: Techniki Programowania Równoległego
Pochodne typy danych
MPI
int MPI Type contiguous(int count, MPI Datatype oldtype,
MPI Datatype *newtype)
contiguous()
vector()
create hvector()
create indexed block()
create hindexed block()
indexed()
create hindexed()
create struct()
create subarray()
create darray()
create resized()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
MPI Type commit()
...
MPI_Status status ;
MPI_Datatype type ;
int buffer [ 1 0 ] ;
...
MPI Type contiguous ( 5 , MPI_INT , &type ) ;
M PI_T yp e _c om mi t (& type ) ;
if ( rank == 0 ){
for ( i =0; i<10; i++)
buffer [ i ] = i ;
MPI_Send ( buffer , 1 , type , 1 , 1 2 3 , MPI_C OMM_WOR LD ) ;
}
if ( rank == 1 ){
for ( i =0; i<10; i++)
buffer [ i ] = −1;
MPI_Recv ( buffer , 1 0 , MPI_INT , 0 , 1 2 3 , MPI_COMM_WORLD , &status ) ;
for ( i =0; i<10; i++)
printf ( " buffer [% d ] = % d \ n " , i , buffer [ i ] ) ;
fflush ( stdout ) ;
}
...
Na wyjściu
buffer[0]
buffer[1]
buffer[2]
buffer[3]
buffer[4]
buffer[5]
buffer[6]
buffer[7]
buffer[8]
buffer[9]
=
=
=
=
=
=
=
=
=
=
0
1
2
3
4
-1
-1
-1
-1
-1
MPI Type free()
count=5
Dr inż. Stanisław Polak
50
Typ przyległy
Zwolnienie typu danych
I
struct{
int nWynikow ;
double wyniki [ RMAX ] ;
} spakowanyWynik ;
Chcemy wysłać dane różnych typów
Zatwierdzenie nowego typu
I
I
MPI
MPI
MPI
MPI
MPI
MPI
MPI
MPI
MPI
MPI
MPI
Ich umiejscowienie w pamięci
...
+
Utworzenie nowego typu
I
. . . , t a b [ IMAX− 1 ] [ 5 ] ∗/
Chcemy wysłać fragment macierzy
...
Kreowanie typów pochodnych
I
double tab [ IMAX ] [ JMAX ] ;
/∗ Chcemy wys ł a ć : t a b [ 0 ] [ 5 ] , t a b [ 1 ] [ 5 ] ,
*
14
...
if ( rank == 1 ) {
printf ( " Podaj rozmiar wektor ó w : " ) ;
scanf ( " % d " ,&n ) ;
x = ( double ∗) calloc ( n , sizeof ( double ) ) ;
y = ( double ∗) calloc ( n , sizeof ( double ) ) ;
for ( i =0; i<n ; i++) {x [ i ] = 1 . 0 ;
y [ i ] = 1.0;}
n_bar = n / numprocs ; // ’ numprocs ’ − l i c z b a p r o c e s ów ( r o z m i a r k o m u n i k a t o r a )
}
MPI_Bcast (&n_bar , 1 , MPI_INT , 1 , MPI_COMM_WORLD ) ;
local_x = ( double ∗) calloc ( n_bar , sizeof ( double ) ) ;
local_y = ( double ∗) calloc ( n_bar , sizeof ( double ) ) ;
MPI_Scatter ( x , n_bar , MPI_DOUBLE , local_x , n_bar , MPI_DOUBLE , 1 ,
MPI_ COMM_WOR LD ) ;
MPI_Scatter ( y , n_bar , MPI_DOUBLE , local_y , n_bar , MPI_DOUBLE , 1 ,
MPI_ COMM_WOR LD ) ;
/∗∗∗∗∗∗∗ o b l i c z a n i e l o k a l n e g o i l o c z y n u s k a l a r n e g o ∗/
local_dot = 0 . 0 ;
for ( i = 0 ; i < n_bar ; i++)
local_dot += local_x [ i ] ∗ local_y [ i ] ;
...
/∗∗∗∗∗∗∗ o b l i c z a n i e ca ł k o w i t e g o i l o c z y n u s k a l a r n e g o ∗/
MPI_Reduce (& local_dot , &dot , 1 , MPI_DOUBLE , MPI_SUM , 1 , MPI_ COMM_WORLD ) ;
if ( rank == 1 )
// Zak ł adam , ż e z k l a w i a t u r y , j a k o w a r t o ś ć ’ n ’ wprowadzono 6
printf ( " Iloczyn skalarny wynosi % f \ n " , dot ) ; // W y p i s z e : I l o c z y n s k a l a r n y
wynosi 6
...
*
1
2
3
4
5
6
7
8
9
10
11
12
13
MPI
51
Przedmiot: Techniki Programowania Równoległego
Dr inż. Stanisław Polak
0 1 2 3 4 5 6 7 8 9
52
Przedmiot: Techniki Programowania Równoległego
Pochodne typy danych
MPI
Typ wektorowy
I
I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.
int MPI Type vector(int count, int blocklength, int stride,
MPI Datatype old type, MPI Datatype *newtype p)
int MPI Type create hvector(int count, int blocklength,
MPI Aint stride, MPI Datatype old type, MPI Datatype
*newtype p)
if ( rank == 0 ){
for ( i =0; i<10; i++)
buffer [ i ] = i ;
MPI_Send ( buffer , 1 , type , 1 , 1 2 3 , MPI_C OMM_WOR LD ) ;
}
if ( rank == 1 ){
for ( i =0; i<10; i++)
buffer [ i ] = −1;
MPI_Recv ( buffer , 1 0 , MPI_INT , 0 , 1 2 3 , MPI_COMM_WORLD , &status ) ;
for ( i =0; i<10; i++)
printf ( " buffer [% d ] = % d \ n " , i , buffer [ i ] ) ;
fflush ( stdout ) ;
}
...
count=2
I
I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Na wyjściu
buffer[0]
buffer[1]
buffer[2]
buffer[3]
buffer[4]
buffer[5]
buffer[6]
buffer[7]
buffer[8]
buffer[9]
=
=
=
=
=
=
=
=
=
=
0
1
2
5
6
7
-1
-1
-1
-1
stride = 5 blocklength = 3
0 1 2 3 4 5 6 7 8 9
Dr inż. Stanisław Polak
53
Przedmiot: Techniki Programowania Równoległego
count=2
Na wyjściu
buffer[0]
buffer[1]
buffer[2]
buffer[3]
buffer[4]
buffer[5]
buffer[6]
buffer[7]
buffer[8]
buffer[9]
=
=
=
=
=
=
=
=
=
=
0
1
3
4
-1
-1
-1
-1
-1
-1
0 1 2 3 4 5 6 7 8 9
blocklength = 2
Dr inż. Stanisław Polak
54
Przedmiot: Techniki Programowania Równoległego
Pochodne typy danych
MPI
Typ strukturalny
int MPI Type indexed(int count, int blocklens[], int
array of displacements[], MPI Datatype old type, MPI Datatype
*newtype)
int MPI Type create hindexed(int count, int blocklens[],
MPI Aint array of displacements[], MPI Datatype old type,
MPI Datatype *newtype)
...
int blocklens [2]={ 1 , 2 };
int displacement [ 2 ] = { 0 , 3 };
...
MPI Type indexed ( 2 , blocklens , displacement , MPI_INT , &type ) ;
MPI_T ype _c om m it (& type ) ;
if ( rank == 0 ){
for ( i =0; i<10; i++)
buffer [ i ] = i ;
MPI_Send ( buffer , 1 , type , 1 , 1 2 3 , MPI_COMM_WORLD ) ;
}
if ( rank == 1 ){
for ( i =0; i<10; i++)
buffer [ i ] = −1;
MPI_Recv ( buffer , 1 0 , MPI_INT , 0 , 1 2 3 , MPI_COMM_WORLD , &status ) ;
for ( i =0; i<10; i++)
printf ( " buffer [% d ] = % d \ n " , i , buffer [ i ] ) ;
fflush ( stdout ) ;
}
...
...
int displacement [ 2 ] = { 0 , 3 };
...
MPI Type create indexed block ( 2 , 2 , displacement , MPI_INT , &type ) ;
M PI _T yp e _c om m it (& type ) ;
if ( rank == 0 ){
for ( i =0; i<10; i++)
buffer [ i ] = i ;
MPI_Send ( buffer , 1 , type , 1 , 1 2 3 , MPI_COMM_WORLD ) ;
}
if ( rank == 1 ){
for ( i =0; i<10; i++)
buffer [ i ] = −1;
MPI_Recv ( buffer , 1 0 , MPI_INT , 0 , 1 2 3 , MPI_COMM_WORLD , &status ) ;
for ( i =0; i<10; i++)
printf ( " buffer [% d ] = % d \ n " , i , buffer [ i ] ) ;
fflush ( stdout ) ;
}
...
MPI
Typ indeksowany z blokami różnego rozmiaru
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int MPI Type create indexed block(int count, int blocklength, const
int array of displacements[], MPI Datatype oldtype, MPI Datatype
*newtype)
int MPI Type create hindexed block(int count, int blocklength, const
MPI Aint array of displacements [], MPI Datatype oldtype,
MPI Datatype * newtype)
count=2
Pochodne typy danych
I
MPI
Typ indeksowany z blokami stałego rozmiaru
...
MPI Type vector ( 2 , 3 , 5 , MPI_INT , &type ) ;
M PI_T yp e_com mit (& type ) ;
I
Pochodne typy danych
Na wyjściu
buffer[0]
buffer[1]
buffer[2]
buffer[3]
buffer[4]
buffer[5]
buffer[6]
buffer[7]
buffer[8]
buffer[9]
=
=
=
=
=
=
=
=
=
=
0
3
4
-1
-1
-1
-1
-1
-1
-1
int MPI Type create struct(int count, int blocklens[], MPI Aint
array of displacements[], MPI Datatype old types[], MPI Datatype
*newtype)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
int blocklen [ 2 ] = { 1 , 2 } ;
MPI_Aint displacement [ 2 ] = { 0 , 3∗4 }; // 3∗4 , bo p r z e s u n i ę c i e wyra ż amy w
b a j t a c h , a n i e w e l e m e n t a c h danego typu , a MPI INT ma 4 b a j t y
int oldtypes [2]={ MPI_INT , MPI_INT };
...
MPI Type create struct ( 2 , blocklen , displacement , oldtypes , &type ) ;
MPI _T ype _c omm it (& type ) ;
if ( rank == 0 ){
for ( i =0; i<10; i++)
buffer [ i ] = i ;
MPI_Send ( buffer , 1 , type , 1 , 1 2 3 , MPI_COMM_WORLD ) ;
}
if ( rank == 1 ){
for ( i =0; i<10; i++)
buffer [ i ] = −1;
MPI_Recv ( buffer , 1 0 , MPI_INT , 0 , 1 2 3 , MPI_COMM_WORLD , &status ) ;
for ( i =0; i<10; i++)
printf ( " buffer [% d ] = % d \ n " , i , buffer [ i ] ) ;
fflush ( stdout ) ;
}
...
Na wyjściu
buffer[0]
buffer[1]
buffer[2]
buffer[3]
buffer[4]
buffer[5]
buffer[6]
buffer[7]
buffer[8]
buffer[9]
=
=
=
=
=
=
=
=
=
=
0
3
4
-1
-1
-1
-1
-1
-1
-1
0 1 2 3 4 5 6 7 8 9
Dr inż. Stanisław Polak
55
Przedmiot: Techniki Programowania Równoległego
Dr inż. Stanisław Polak
56
Przedmiot: Techniki Programowania Równoległego
Pochodne typy danych
MPI
Tworzenie podtablicy
Pochodne typy danych
Rozpraszenie danych w stylu HPF
int MPI Type create subarray(int ndims, const int array of sizes[],
const int array of subsizes[], const int array of starts[], int
order, MPI Datatype oldtype, MPI Datatype *newtype)
1
2
3
4
5
6
...
int
int
int
...
MPI
int MPI Type create darray(int size, int rank, int ndims, const
int array of gsizes[], const int array of distribs[], const int
array of dargs[], const int array of psizes[], int order,
MPI Datatype oldtype, MPI Datatype *newtype)
array_of_sizes [ ] = {10};
a rr ay_ of _ s u b s i z e s [ ] = { 3 };
array _of_sta r ts [ ] = { 2 };
Type create subarray ( 1 , array_of_sizes , array_of_subsizes , array_of_starts ,
MPI_ORDER_C , MPI_INT , &type ) ;
M PI_T yp e_com mit (& type ) ;
if ( rank == 0 ){
for ( i =0; i<10; i++)
buffer [ i ] = i ;
MPI_Send ( buffer , 1 , type , 1 , 1 2 3 , MPI_C OMM_WOR LD ) ;
}
if ( rank == 1 ){
for ( i =0; i<10; i++)
buffer [ i ] = −1;
MPI_Recv ( buffer , 1 0 , MPI_INT , 0 , 1 2 3 , MPI_COMM_WORLD , &status ) ;
for ( i =0; i<10; i++)
printf ( " buffer [% d ] = % d \ n " , i , buffer [ i ] ) ;
fflush ( stdout ) ;
}
...
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Na wyjściu
buffer[0]
buffer[1]
buffer[2]
buffer[3]
buffer[4]
buffer[5]
buffer[6]
buffer[7]
buffer[8]
buffer[9]
=
=
=
=
=
=
=
=
=
=
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
-1
-1
-1
-1
-1
-1
-1
15
16
17
0 1 2 3 4 5 6 7 8 9
Dr inż. Stanisław Polak
18
19
57
Przedmiot: Techniki Programowania Równoległego
Pochodne typy danych
/∗<o l d t y p e> BUFFER ( 1 2 , 1 6 )
R e a l i z a c j a i n s t r u k c j i HPF
! HPF$ PROCESSORS PROCESSES ( 3 , 2 )
! HPF$ DISTRIBUTE BUFFER(BLOCK, BLOCK) ONTO PROCESSES ∗/
...
gsizes [ 0 ] = 1 2 ;
gsizes [ 1 ] = 1 6 ;
gdistr [ 0 ] = M P I _ D I S T R I B U T E _ B L O C K ;
gdistr [ 1 ] = M P I _ D I S T R I B U T E _ B L O C K ;
gdargs [ 0 ] = M P I _ D I S T R I B U T E _ D F L T _ D A R G ;
gdargs [ 1 ] = M P I _ D I S T R I B U T E _ D F L T _ D A R G ;
psizes [ 0 ] = 3 ;
psizes [ 1 ] = 2 ;
MPI Type create darray ( 6 , rank , 2 , gsizes , gdistr , gdargs ,
psizes , MPI_ORDER_C , MPI_INT , &type ) ;
M PI_T yp e _c om mi t (& type ) ;
MPI_File_open ( MPI_COMM_WORLD , fileName , MPI_MODE_RDONLY ,
MPI_INFO_NULL , &fh ) ;
M P I_ F i le _ se t _ v i e w ( fh , 0 , MPI_INT , type , " native " ,
MPI_INFO_NULL ) ;
MPI_File_read ( fh , buffer , 3 2 , MPI_INT , &status ) ;
...
Dr inż. Stanisław Polak
MPI
Przykład
Wysłanie kolumny macierzy
Wysłanie struktury języka C
...
# define IMAX 2
# define JMAX 6
...
double wyniki [ IMAX ] [ JMAX ] ;
MPI_Datatype nowytyp ;
/∗ IMAX b l o k ów , r o z m i a r ka ż dego z n i c h t o 1 ( e l e m e n t )
∗ Pocz ą t e k n a s t ę pnego j e s t p r z e s u n i ę t y o JMAX e l e m e n t ów
∗/
...
M PI _T yp e_vector ( IMAX , 1 , JMAX , MPI_DOUBLE , &nowytyp ) ;
MPI _T yp e _Com mit (& nowytyp ) ;
MPI_Ssend ( &wyniki[0][JMAX-1] , 1 , nowytyp , dest , tag , comm ) ;
...
JMAX-1
count=IMAX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
IMAX-1
blocklength = 1
... ... ... ... ... ... ... ... ... ... ... ...
58
Pochodne typy danych
Przykład
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MPI
20
Źródła: http://www.florian-rappl.de/
download/57/homework-set-7 oraz
http://www.mcs.anl.gov/~itf/dbpp/text/
node85.html
Przedmiot: Techniki Programowania Równoległego
MPI
...
# define RESULT PACKET NBLOCKS 2
struct{
int nWynikow ;
double wyniki [ RMAX ] ;
} spak owanyWyn ik ;
int a r r a y _ o f _ b l o c k l e n g t h s [ R E S U L T _ P A C K E T _ N B L O C K S ]
= {1 , RMAX };
MPI_Datatype ar ray_of_t ypes [
R E S U L T _ P A C K E T _ N B L O C K S ] = {MPI_INT ,
MPI_DOUBLE };
MPI_Aint a r r a y _ o f _ d i s p l a c e m e n t s [
RESULT_PACKET_NBLOCKS ] ;
MPI_Datatype r e s ul tP a c k e t T y p e ;
M P I _ T y p e _ g e t _ e x t e n t ( MPI_INT , &lb , &extent ) ;
array_of_displacements [ 0 ] = 0 ;
a r r a y _ o f _ d i s p l a c e m e n t s [ 1 ] = extent ;
M P I _ T y p e _ c r e a t e _ s t r u c t ( 2 , array_of_blocklengths
, array_of_displacements , array_of_types ,
&r e su l t P a c k e t Ty pe ) ;
M PI_T yp e _com mit (& r e s u l t P ac ke t T y p e ) ;
MPI_Ssend (& spakowanyWynik , 1 , resultPacketType ,
dest , tag , comm ) ;
...
stride = JMAX
Dr inż. Stanisław Polak
59
Przedmiot: Techniki Programowania Równoległego
Dr inż. Stanisław Polak
60
Przedmiot: Techniki Programowania Równoległego
Pochodne typy danych
MPI
Pochodne typy danych
Podstawowe pojęcia
MPI
Zmiana / odczyt granic oraz zasięgu
Mapa typów
Markery
I ub marker
Typemap = {(typ0 , przes0 ), . . . , (typn−1 , przesn−1 )}
I
Sygnatura
lb marker
Typesig = {typ0 , . . . , typn−1 }
Granica dolna
lb(Typemap) =
minj (przesj )
minj ({przesj takie, że typj = lb marker})
-4
gdy brak markera lb marker
w przeciwnym razie
maxj (przesj + sizeof (typj )) + )
maxj ({przesj takie, że typj = ub marker})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
extent(Typemap) = ub(Typemap) − lb(Typemap)
lb({(int, 0), (char , 4)}) = min(0, 4) = 0
ub({(int, 0), (char , 4)}) = max(0 + 4, 4 + 1) + = 5 + = 8
extent({(int, 0), (char , 4)}) = 8 − 0 = 8
61
Przedmiot: Techniki Programowania Równoległego
Pochodne typy danych
...
M P I _ T y p e _ c o n t i g u o u s ( 2 , MPI_INT , &contig ) ;
M PI _T ype _c om mit (& contig ) ;
lb
= −1 ∗ sizeof ( int ) ; // −4
extent = 7 ∗ sizeof ( int ) ; // 28
MPI Type create resized ( contig , lb , extent , &filetype ) ;
// l b = −4
// ub = l b + e x t e n t = −4 + 28 = 24
M PI _T ype _c om mit (& filetype ) ;
MPI Type get extent ( filetype , &lb , &extent ) ;
printf ( " % d % d \ n " , lb , extent ) ; // −4 28
MPI Type get true extent ( filetype , &lb , &extent ) ;
printf ( " % d % d \ n " , lb , extent ) ; // 0 8
...
Dr inż. Stanisław Polak
MPI
Przykład
Wysłanie kolumn macierzy — wersja niepoprawna
1
2
3
4
5
6
7
8
9
10
//Wys ł a n i e t r z e c h w i e r s z y
MPI_Send ( A , 3 , typ , 1 , 1 , MPI_COMM_WOR LD ) ;
...
MPI_Recv ( B , 9 , MPI_INT , 0 , 1 , MPI_COMM_WORLD ,& status ) ;
// o d e b r a n o B = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }
Typemap =
{(int, 0), (int, 4), (int, 8)}
extent(Typemap) =
0 + 8 + sizeof (int) = 12
Przedmiot: Techniki Programowania Równoległego
Pochodne typy danych
Wysłanie wierszy macierzy
int A [ 3 ] [ 3 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } ;
int B [ 9 ] ;
...
M P I _ T y p e _ c o n t i g u o u s ( 3 , MPI_INT ,& typ ) ;
Typemapcontig ={(int, 0), (int, 8)}
Typemapfiletype ={(int, 0), (int, 8), (lb marker , −4), (ub marker , 24)}
62
Przykład
1
2
3
4
5
6
7
8
9
10
24
gdy brak markera ub marker
w przeciwnym razie
Rozpiętość
Dr inż. Stanisław Polak
8
Rysunek: Typ — jedna dziura MPI INT + dwa elementy MPI INT + cztery dziury
MPI INT
Granica górna
ub(Typemap) =
0
MPI
int A [ 3 ] [ 3 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } ;
int B [ 9 ] ;
...
MPI _Typ e_vec tor ( 3 , 1 , 3 , MPI_INT ,& typ ) ;
//Wys ł a n i e t r z e c h kolumn
MPI_Send ( A , 3 , typ , 1 , 1 , MPI_COMM_WORLD ) ;
...
MPI_Recv ( B , 9 , MPI_INT , 0 , 1 , MPI_COMM_WORLD ,& status ) ;
//B = {1 , 4 ,7 , 8 , −10 73 859 432 ,6 79 115 6 ,2 , −1 073 8594 08 , 1}
Typemap =
extent(Typemap) =
1 2 3
28
4 5 6
{(int, 0), (int, 12), (int, 24)}
7 8 9
0 + 24 + sizeof (int) = 28
12 1 2 3
4 5 6
7 8 9
Dr inż. Stanisław Polak
63
Przedmiot: Techniki Programowania Równoległego
Dr inż. Stanisław Polak
64
Przedmiot: Techniki Programowania Równoległego
Pochodne typy danych
MPI
MPE
Przykład
MPE
Wysłanie kolumn macierzy — wersja poprawna
Wstęp
1
2
3
4
5
6
7
8
9
I
...
M PI _T yp e _vec tor ( 3 , 1 , 3 , MPI_INT ,& typ ) ;
...
M P I _ T y p e _ g e t _ e x t e n t ( MPI_INT , &lb , &extent ) ;
M P I _ T y p e _ c r e a t e _ r e s i z e d ( typ , 0 , extent , &nowy_typ ) ;
M PI _T yp e _com mit (& nowy_typ ) ;
...
MPI_Send ( A , 3 , nowy_typ , 1 , 1 , MPI_COMM_WORLD ) ;
...
lb(Typemap) =
ub(Typemap) =
n
minj (przesj )
minj ({przesj takie, że typj = lb marker})
n
maxj (przesj + sizeof (typj )) + )
maxj ({przesj takie, że typj = ub marker})
I
MPI
MPE — Multi-Processing Environment
Przebieg wykonania programu −→ generowanie dziennika zdarzeń
I
I
automatycznie
ręcznie
gdy brak markera lb marker
w przeciwnym razie
gdy brak markera ub marker
w przeciwnym razie
extent(Typemap) = ub(Typemap) − lb(Typemap)
4
Typemap = {(int, 0), (int, 12), (int, 24), (lb marker , 0), (ub marker , 4)} 1 2 3
extent(Typemap) = 0 + 4 = 4
4 5 6
7 8 9
Dr inż. Stanisław Polak
65
Rysunek: Główne okno programu „Jumpshot”
Przedmiot: Techniki Programowania Równoległego
MPE
Przedmiot: Techniki Programowania Równoległego
MPE
MPI
Ręczne generowanie dziennika zdarzeń
...
if ( rank == 0 ){
for ( i = 1 ; i <= 2 ; i++){
MPI_Send ( buffer , 1 , MPI_FLOAT , 1 , 1 0 0 , MPI_COMM_WORLD ) ;
MPI_Recv ( buffer , length_of_message , MPI_FLOAT , 1 , 1 0 1 , MPI_COMM_WORLD , &status ) ;
}
}
if ( rank == 1 ){
for ( i = 1 ; i <= 2 ; i++){
MPI_Recv ( buffer , length_of_message , MPI_FLOAT , 0 , 1 0 0 , MPI_COMM_WORLD , &status ) ;
MPI_Send ( buffer , 1 , MPI_FLOAT , 0 , 1 0 1 , MPI_COMM_WORLD ) ;
}
}
...
1. mpicc
-profile=mpe mpilog -o
program program.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int event1 , event2 ;
...
MPE Init log ( ) ;
MPE Log get state eventIDs ( &event1 , &event2 ) ;
MPE Describe state ( event1 , event2 , " Moj stan " , " green " ) ; "
...
if ( rank == 0) {
for ( i = 1; i <= 2; i ++) {
MPE Log event( event1 , 0 , " Iteracja start " ) ;
MPI_Send ( buffer , 1 , MPI_FLOAT , 1 , 100 , MPI _COMM_WORLD ) ;
MPI_Recv ( buffer , length_of_message , MPI_FLOAT ,1 , 101 , MPI_COMM_WORLD , & status ) ;
MPE Log event( event2 , 0 , " Iteracja stop " ) ;
}
}
...
MPE Finish log( " program−mpe " ) ;
...
1. mpicc -o program program.c -lmpe
2. mpiexec -n 2 ./program
2. mpiexec -n 2 ./program
3. jumpshot program-mpe.clog
3. jumpshot program.clog
Dr inż. Stanisław Polak
66
MPI
Automatyczne generowanie dziennika zdarzeń
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Dr inż. Stanisław Polak
67
Przedmiot: Techniki Programowania Równoległego
Dr inż. Stanisław Polak
68
Przedmiot: Techniki Programowania Równoległego
Grafika
MPE
MPI
Grafika MPE
Dostarcza biblioteka MPE
I
Zawiera prosty interfejs do X
Nagłówek
I
I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <mpe.h>
Kompilacja
I
Dr inż. Stanisław Polak
MPE
MPI
Przykład
I
I
Grafika
mpicc -profile=mpe graphics program.c -o program
69
Przedmiot: Techniki Programowania Równoległego
Źródła
...
MPE_XGraph graph ;
MPE_Color my_color ;
char ckey ;
...
ierr = MPE Open graphics(&graph , MPI_COMM_WORLD , NULL , −1, −1, 4 0 0 , 4 0 0 , 0 ) ;
if (ierr != MPE SUCCESS) {
fprintf ( stderr , " % d : MP E_O p en _ gr ap h ics () fails \ n " , rank ) ;
MPI_Abort ( MPI_COMM_WORLD , 1 ) ;
}
my color = (MPE Color) (rank + 1) ;
if ( rank == 0 )
MPE Draw string ( graph , 1 8 7 , 2 0 5 , MPE_BLUE , " Hello " ) ;
MPE Draw circle ( graph , 2 0 0 , 2 0 0 , 20+rank ∗5 , my_color ) ;
MPE Update ( graph ) ;
if ( rank == 0 ) {
fprintf ( stdout , " Hit any key then return to continue " ) ;
fscanf ( stdin , " % s " , &ckey ) ;
fprintf ( stdout , " \ n " ) ;
}
MPI_Barrier ( MPI_C OMM_WORLD ) ;
MPE Close graphics(& graph ) ;
...
Dr inż. Stanisław Polak
70
MPI
Źródła I
Przedmiot: Techniki Programowania Równoległego
Źródła
MPI
Źródła II
Blaise Barney
Message Passing Interface (MPI)
https://computing.llnl.gov/tutorials/mpi/
Zdzislaw Meglicki
MPI Graphics and Process Visualization
http://beige.ucs.indiana.edu/I590/node111.html
Neil MacDonald, Elspeth Minty, Tim Harding, Simon Brown,
Writing Message-Passing Parallel Programs with MPI
http://www.math.tu-cottbus.de/~kd/parallel/mpi/mpi-course.
book_1.html
Rolf Rabenseifner
Introduction to the Message Passing Interface (MPI)
https://fs.hlrs.de/projects/par/par_prog_ws/pdf/mpi_1_rab.pdf
MPI Forum
MPI Documents
http://www.mpi-forum.org/docs/docs.html
Jacek Dziedzic
Algorytmy równoległe
http://www.mif.pg.gda.pl/homepages/jaca/AR_W/AR1bw.pdf
PDC
MPI
http://www.pdc.kth.se/publications/talks/mpi
Cnea
Introduction to MPI
http://www.ib.cnea.gov.ar/~ipc/ipd2007/htmlcourse/
Lans
Performance Visualization for Parallel Programs
http://www.mcs.anl.gov/research/projects/perfvis/
DeinoMPI
http://mpi.deino.net/
Dr inż. Stanisław Polak
71
Przedmiot: Techniki Programowania Równoległego
Dr inż. Stanisław Polak
72
Przedmiot: Techniki Programowania Równoległego
Źródła
MPI
Źródła III
Źródła
MPI
Źródła IV
Vagelis Harmandaris
Parallel Computing
http://www.tem.uoc.gr/~vagelis/Courses/EM361/em361.html
Jean-Pierre Prost
MPI-2 Overview
http:
//www.pdc.kth.se/training/Talks/SMP/maui98/jpprost/index.htm
EPCC
MPI-2: Extending the Message Passing Interface
ftp://ftp.epcc.ed.ac.uk/pub/personal/dsh/mpi2-report.ps.gz
MCS
MPI-2: Extensions to the Message-Passing Interface
http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/
mpi-report-2.0/mpi2-report.htm
William Gropp, Ewing Lusk, Rajeev Thakur
Using MPI-2: Advanced Features of the Message-Passing Interface
MIT Press, 1999; ISBN 0-262-57132-3
Michał Sajkowski
Dynamiczne zarządzanie procesami
http://szkolenia.man.poznan.pl/kdm/presentations/MPI-2/
dynamiczne_MPI2_22112006.pdf
Mirosław Kupczyk
Rozszerzenia standardu MPI: MPI-2
https://hpc.man.poznan.pl/modules/kdm_training/uploads/
rozszerzeniastandarduMPI-MPI-2.pdf
Dariusz Konieczny
http://www.ci.pwr.wroc.pl/~koniecz/ParAlg/Macierz.html
Dr inż. Stanisław Polak
73
Przedmiot: Techniki Programowania Równoległego
Dr inż. Stanisław Polak
74
Przedmiot: Techniki Programowania Równoległego