Łagodne wprowadzenie do Message Passing Interface (MPI) Szymon Łukasik Zakład Automatyki PK szymonl@pk.edu.pl Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 1/48
Czym jest MPI? Własności MPI MPI-2 Implementacje MPI Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 2/48
Czym jest MPI? Czym jest MPI? Własności MPI MPI-2 Implementacje MPI MPI to standard przesyłania wiadomości (komunikatów) pomiędzy procesami programów równoległych działajacych na jednym lub więcej komputerach. Implementowany jest najczęściej w postaci bibliotek, do wykorzystania w programach tworzonych w Fortranie, C, C++, Ada. Pierwsza wersja standardu MPI: MPI-1, ukazała się w maju 1994 r., druga (i obecnie obowiazuj aca) MPI-2 w 1998 roku. Standard MPI ma status public-domain i jest dostępny w sieci Internet pod adresem www.mpi-forum.org Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 3/48
Własności MPI Czym jest MPI? Własności MPI MPI-2 Implementacje MPI architektura programu - niezależne procesy operujace na różnych danych (MIMD), zapewnia przenośność programów, możliwość stosowania zarówno dla multiprocesorów jak i multikomputerów, udostępnia mechanizmy komunikacji jeden - jeden oraz grupowej, pozwala na tworzenie (intra- i inter-) komunikatorów, zapewnia możliwość definiowania nowych typów danych, umożliwia wykonywanie obliczeń i operacji globalnych, pozwala na definiowanie topologii procesów Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 4/48
MPI-2 Czym jest MPI? Własności MPI MPI-2 Implementacje MPI Najnowszy standard umożliwia: równoległe operacje wejścia-wyjścia, zdalne operacje na pamięci, dynamiczne zarzadzanie struktura procesów bioracych udział w obliczeniach. Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 5/48
Implementacje MPI Czym jest MPI? Własności MPI MPI-2 Implementacje MPI MPICH2 wieloplatformowa (gridy: MPICH-G2), ogólnodostępna www: http://www-unix.mcs.anl.gov/mpi/mpich LAM/MPI projekt zawieszony, ogólnodostępna www: http://www.lam-mpi.org Open MPI kontynuacja LAM/MPI, ogólnodostępna www: http://www.open-mpi.org WMPI folklor - dla Windows, płatna www: http://www.criticalhpc.com/ HP-MPI, IBM-MPI, SGI-MPI implementacje specjalizowane Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 6/48
Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 7/48
Użyta notacja i uwagi ogólne Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa definicje podano w składni języka C, IN/OUT/INOUT przy argumencie oznacza parametr wejściowy, wyjściowy i modyfikowany przez funkcję, comm to komunikator, który odpowiada oddzielnej strukturze komunikacji, specyfikuje on grupę procesów, które do niego należa MPI_COMM_WORLD to specyficzny komunikator grupujacy wszystkie procesy, które właczyły się do systemu MPI od jego uruchomienia src,dest definiuja numery procesów źródłowych i docelowych komunikatu tag określa znacznik typu komunikatu gdy długość danych jest krótsza od bufora, pozostałe pola bufora nie sa nadpisywane. Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 8/48
Podstawowe funkcje Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa Inicjalizacja biblioteki: OUT int MPI_Init(IN int *argc, IN char ***argv); obliczeń: OUT int MPI_Finalize(void); Numer bież acego procesu w danym komunikatorze: OUT int MPI_Comm_rank(IN MPI_Comm comm, OUT int *rank); Ilość procesów w komunikatorze: OUT int MPI_Comm_size(IN MPI_Comm comm, OUT int *size); Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 9/48
Komunikacja blokujaca jeden do jednego Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa Wysyłanie danych: OUT int MPI_Send(IN void* buf, IN int count, IN MPI_Datatype datatype, IN int dest, IN int tag, IN MPI_Comm comm); Odbieranie: OUT int MPI_Recv(OUT void* buf, IN int count, IN MPI_Datatype datatype, IN int source, IN int tag, IN MPI_Comm comm, OUT MPI_Status *status); Uwagi: w odwołaniach można użyć stałych MPI_ANY_SOURCE i MPI_ANY_TAG MPI_STATUS jest struktura o polach MPI_SOURCE, MPI_TAG, MPI_ERROR ; sprawdzanie ilości odebranych danych realizuje MPI_Get_count testowanie czy wiadomość nie nadeszła - MPI_Probe Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 10/48
Przykład - kom. blokujaca Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa #include < s t d i o. h> #include <mpi. h> void main ( i n t argc, char argv ) { i n t myrank ; MPI_Status s t a t u s ; double a [ 1 0 0 ] ; MPI_Init (& argc, &argv ) ; MPI_Comm_rank (MPI_COMM_WORLD, &myrank ) ; i f ( myrank == 0) MPI_Send ( a, 100, MPI_DOUBLE, 1, 17, MPI_COMM_WORLD) ; else i f ( myrank == 1 ) MPI_Recv ( a, 100, MPI_DOUBLE, 0, 17, MPI_COMM_WORLD, &s t a t u s ) ; MPI_Finalize ( ) ; } Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 11/48
Typy danych MPI Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa Typ MPI MPI_CHAR MPI_SHORT MPI_INT MPI_LONG MPI_UNSIGNED_CHAR MPI_UNSIGNED_SHORT MPI_UNSIGNED MPI_UNSIGNED_LONG MPI_FLOAT MPI_DOUBLE MPI_LONG_DOUBLE MPI_BYTE MPI_PACKED Typ C signed char signed short int signed int signed long int unsigned char unsigned short int unsigned int unsigned long int float double long double brak brak Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 12/48
Pakowanie danych Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa Pakowanie danych do bufora: OUT int MPI_Pack(IN void* inbuf, IN int incount, IN MPI_Datatype datatype, OUT void *outbuf, IN int outsize, INOUT int *position, IN MPI_Comm comm); Rozpakowywanie: OUT int MPI_Unpack(IN void* inbuf, IN int insize, INOUT int *position, OUT void *outbuf, IN int outcount, IN MPI_Datatype datatype, IN MPI_Comm comm); Uwaga: position jest wskaźnikiem do bufora ci agłego (przy wysyłaniu - bufora nadawczego outbuf, przy odbieraniu - bufora odbiorczego inbuf) przesuwanym automatycznie przez funkcje. Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 13/48
Przykład - pakowanie Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa i n t p o s i t i o n, i, j, a [ 2 ] ; char b u f f [ 1 0 0 0 ] ;.... MPI_Comm_rank (MPI_COMM_WORLD, &myrank ) ; i f ( myrank == 0) { / /NADAWCA p o s i t i o n = 0 ; MPI_Pack(& i, 1, MPI_INT, b u ff, 1000, &p o s i t i o n, MPI_COMM_WORLD) ; MPI_Pack(& j, 1, MPI_INT, b u ff, 1000, &p o s i t i o n, MPI_COMM_WORLD) ; MPI_Send ( b u ff, p o s i t i o n, MPI_PACKED, 1, 0, MPI_COMM_WORLD) ; } else / / ODBIORCA MPI_Recv ( a, 2, MPI_INT, 0, 0, MPI_COMM_WORLD) Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 14/48
Typy użytkownika Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa Do definiowania własnych typów służy rodzina funkcji MPI_TYPE: OUT int MPI_Type_contiguous(IN int count, IN MPI_Datatype oldtype, OUT MPI_Datatype *newtype); OUT int MPI_Type_vector(IN int count, IN int blocklength, IN int stride, IN MPI_Datatype oldtype, OUT MPI_Datatype *newtype); OUT int MPI_Type_struct(IN int count, IN int *array_of_blocklengths, IN MPI_Aint *array_of_displacements, IN MPI_Datatype *array_of_types, OUT MPI_Datatype *newtype); Aby używać nowego typu danych należy dokonać operacji: OUT int MPI_Type_commit (INOUT MPI_datatype *datatype); Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 15/48
Przykład - typy użytkownika Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 16/48
Przykład - typy użytkownika Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa #include " mpi. h " # def ine SIZE 4 i n t main ( argc, argv ) i n t argc ; char argv [ ] ; { i n t numtasks, rank, source =0, dest, tag =1, i ; f l o a t a [ SIZE ] [ SIZE ] = { 1. 0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 1 6. 0 } ; f l o a t b [ SIZE ] ; MPI_Status s t a t ; MPI_Datatype columntype ; MPI_Init (& argc,& argv ) ; MPI_Comm_rank (MPI_COMM_WORLD, &rank ) ; MPI_Comm_size(MPI_COMM_WORLD, &numtasks ) ; Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 17/48
Przykład - typy użytkownika Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa MPI_Type_vector ( SIZE, 1, SIZE, MPI_FLOAT, &columntype ) ; MPI_Type_commit(& columntype ) ; i f ( numtasks == SIZE ) { i f ( rank == 0) { for ( i =0; i < numtasks ; i ++) MPI_Send(&a [ 0 ] [ i ], 1, columntype, i, tag, MPI_COMM_WORLD) ; } MPI_Recv ( b, SIZE, MPI_FLOAT, source, tag, MPI_COMM_WORLD, &s t a t ) ; p r i n t f ( " rank=%d b=%3.1 f %3.1 f %3.1 f %3.1 f \ n ", rank, b [ 0 ], b [ 1 ], b [ 2 ], b [ 3 ] ) ; } else p r i n t f ( " Must s p e c i f y %d processors. Terminating. \ n ", SIZE ) ; MPI_Finalize ( ) ; } Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 18/48
Tryby komunikacji Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa Polecenia MPI_Send i MPI_Recv realizuja tryb standardowy - wysyłanie MOŻE (ale nie musi) być buforowane (brak oczekiwania na odpowiednie MPI_Recv). Inne tryby to: Buforowany (MPI_Bsend i MPI_Brecv) - wysyłanie odbywa się niezależnie od tego czy została wywołana funkcja odbierajaca ; zwraca sterowanie natychmiast, niezależnie od wystapienia funkcji odbioru, Synchroniczny (prefix S) - wysyłanie niezależnie od tego czy została wywołana funkcja odbierajaca ; zwraca sterowanie po odebraniu wiadomości Przygotowany (prefix R) - wiadomość może być wysłana dopiero wtedy, gdy została wywołana funkcja odbierajaca, w przeciwnym wypadku funkcja wysyłajaca zwraca bład. Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 19/48
Tryby komunikacji Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 20/48
Komunikacja nieblokujaca Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa Funkcja zwraca sterowanie od razu nie czekajac na wykonanie operacji. OUT int MPI_IXsend(IN void *buf, IN int count, IN MPI_Datatype dtype, IN int dest, IN int tag, IN MPI_Comm comm, OUT MPI_Request *request); OUT int MPI_IXrecv(OUT void *buf, IN int count, IN MPI_Datatype dtype, IN int source, IN int tag, IN MPI_Comm comm, OUT MPI_Request *request); Uwaga: X={,B,S,R} Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 21/48
Komunikacja nieblokujaca Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa request jest wskaźnikiem realizacji żadania którego stan można sprawdzić funkcjami - blokujac a i nieblokujac a: OUT int MPI_Wait(INOUT MPI_Request *request, OUT MPI_Status *status); OUT int MPI_Test(INOUT MPI_Request *request, OUT int *flag, OUT MPI_Status *status); Uwaga: flag=true gdy opisywana wskaźnikiem request operacja została zakończona. Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 22/48
Przykład - kom. nieblokujaca Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa typedef struct { char data [ MAXSIZE ] ; i n t d a tasize ; MPI_Request req ; } B u f f e r ; B u f f e r b u f f e r [ ] ; MPI_Status s t a t u s ;... MPI_Comm_rank (comm, &rank ) ; MPI_Comm_size(comm, &size ) ; i f ( rank!= size 1) { / i n i c j a l i z a c j a producent a l o k u j e swój b u for / } b u f f e r = ( B u f f e r ) malloc ( sizeof ( B u f f e r ) ) ; while ( 1 ) { / main loop / / producent wypełnia b u for danych i zwraca i c h i l o ś ć / produce ( b u f f e r >data, &b u f f e r >d a tasize ) ; / po czym j e wysyła / MPI_Send ( b u f f e r >data, b u f f e r >datasize, MPI_CHAR, size 1,tag,comm) ; } Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 23/48
Przykład - kom. nieblokujaca Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa else { } } / rank == s i z e 1; kod konsumenta / / konsument a l o k u j e jeden b u for dla każdego producenta / b u f f e r = ( B u f f e r ) malloc ( sizeof ( B u f f e r ) ( size 1)); for ( i =0; i < size 1; i ++) / r o z p o c z n i j odbiór od każdego producenta / MPI_Irecv ( b u f f e r [ i ]. data, MAXSIZE, MPI_CHAR, i, tag, comm, &( b u f f e r [ i ]. req ) ) ; for ( i =0; ; i =( i +1)%( size 1)) { / główna p ę t l a oczekiwanie / } MPI_Wait (&( b u f f e r [ i ]. req ), &s t a t u s ) ; / sprawdź i l e danych d o t a r ł o / MPI_Get_count(& status, MPI_CHAR, &( b u f f e r [ i ]. d a tasize ) ) ; / o p r ó ż n i j b u for i r o z p o c z n i j nowy proces odbioru / consume ( b u f f e r [ i ]. data, b u f f e r [ i ]. d a tasize ) ; MPI_Irecv ( b u f f e r [ i ]. data, MAXSIZE, MPI_CHAR, i, tag, comm, &( b u f f e r [ i ]. req ) ) ; Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 24/48
Komunikacja grupowa Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa OUT int MPI_Bcast (INOUT void* buffer, IN int count, IN MPI_Datatype datatype, IN int rank, IN MPI_Comm comm); UWAGA: Synchronizacja w operacjach grupowych odbywa się za pomoca barier: OUT MPI_Barrier(IN MPI_Comm comm); Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 25/48
Komunikacja grupowa Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa OUT int MPI_Reduce (IN void* send_buffer, OUT void* recv_buffer, IN int count, IN MPI_Datatype datatype, IN MPI_Op operation, IN int rank, IN MPI_Comm comm); Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 26/48
Komunikacja grupowa Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa OUT int MPI_Gather (IN void* send_buffer, IN int send_count, IN MPI_datatype send_type, OUT void* recv_buffer, IN int recv_count, IN MPI_Datatype recv_type, IN int rank, IN MPI_Comm comm); Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 27/48
Komunikacja grupowa Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa OUT int MPI_Allgather (IN void *sendbuf, IN int sendcount, IN MPI_Datatype sendtype, OUT void *recvbuf, IN int recvcount, IN MPI_Datatype recvtype, MPI_Comm comm); Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 28/48
Komunikacja grupowa Użyta notacja i uwagi ogólne Podstawowe funkcje Komunikacja blokujaca jeden do jednego Przykład - kom. blokujaca Typy danych MPI Pakowanie danych Przykład - pakowanie Typy użytkownika Przykład - typy użytkownika Tryby komunikacji Komunikacja nieblokujaca Przykład - kom. nieblokujaca Komunikacja grupowa OUT int MPI_Scatter (IN void *sendbuf, IN int sendcnt, IN MPI_Datatype sendtype, OUT void *recvbuf, int recvcnt, IN MPI_Datatype recvtype, IN int root, IN MPI_Comm comm); Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 29/48
Równoległe we-wy Przykład równoległego zapisu Przykład równoległego odczytu Zdalne operacje na pamięci (RMA) Przykład: RMA Dynamiczna struktura obliczeniowa Przykład: dynamiczny model master-slave Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 30/48
Równoległe we-wy Równoległe we-wy Przykład równoległego zapisu Przykład równoległego odczytu Zdalne operacje na pamięci (RMA) Przykład: RMA Dynamiczna struktura obliczeniowa Przykład: dynamiczny model master-slave Realizacja: zapis do pliku jest analogia nadawania komunikatu do systemu plików odczyt z pliku jest analogia odbierania komunikatu z systemu plików MPI-2 zawiera analogie do operacji Uniksowych: open, close, seek, read i write. Funkcje: MPI_File_open(); MPI_File_write(); MPI_File_read(); MPI_File_set_view(); MPI_File_close(); MPI_File_seek(); MPI_File_write_shared(); Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 31/48
Przykład: równoległy zapis do pliku Równoległe we-wy Przykład równoległego zapisu Przykład równoległego odczytu Zdalne operacje na pamięci (RMA) Przykład: RMA Dynamiczna struktura obliczeniowa Przykład: dynamiczny model master-slave #include " mpi. h " #include < s t d i o. h> # def ine BUFSIZE 100 i n t main ( i n t argc, char argv [ ] ) { i n t i, myrank, buf [ BUFSIZE ] ; MPI_File t h e f i l e ; MPI_Init (& argc, &argv ) ; MPI_Comm_rank (MPI_COMM_WORLD, &myrank ) ; for ( i =0; i <BUFSIZE ; i ++) buf [ i ] = myrank BUFSIZE + i ; MPI_File_open (MPI_COMM_WORLD, " t e s t f i l e ", MPI_MODE_CREATE MPI_MODE_WRONLY, MPI_INFO_NULL, & t h e f i l e ) ; MPI_File_set_view ( t h e f i l e, myrank BUFSIZE sizeof ( i n t ), MPI_INT, MPI_INT, " n a t i v e ", MPI_INFO_NULL ) ; MPI_File_write ( t h e f i l e, buf, BUFSIZE, MPI_INT, MPI_STATUS_IGNORE ) ; MPI_File_close (& t h e f i l e ) ; MPI_Finalize ( ) ; return 0 ; } Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 32/48
Przykład: równoległy odczyt pliku Równoległe we-wy Przykład równoległego zapisu Przykład równoległego odczytu Zdalne operacje na pamięci (RMA) Przykład: RMA Dynamiczna struktura obliczeniowa Przykład: dynamiczny model master-slave #include mpi. h #include < s t d i o. h> i n t main ( i n t argc, char argv [ ] ) { i n t myrank, numprocs, bufsize, buf, count ; MPI_File t h e f i l e ; MPI_Status s t a t u s } MPI_Offset f i l e s i z e ; MPI_Init (& argc, &argv ) ; MPI_Comm_rank (MPI_COMM_WORLD, &myrank ) ; MPI_Comm_size (MPI_COMM_WORLD, &numprocs ) ; MPI_File_open (MPI_COMM_WORLD, " t e s t f i l e ", MPI_MODE_RDONLY, MPI_INFO_NULL, & t h e f i l e ) ; MPI_File_get_size ( t h e f i l e, & f i l e s i z e ) ; / w bajtach / f i l e s i z e = f i l e s i z e / size ( i n t ) ; / w l i c z b i e i n t s / b u f s i z e = f i l e s i z e / numprocs + 1; / l o k a l n a l i c z b a do odczytu / buf = ( i n t ) malloc ( b u f s i z e + sizeof ( i n t ) ) ; MPI_File_set_view ( t h e f i l e, myrank b u f s i z e sizeof ( i n t ) ), MPI_INT, MPI_INT, " n a t i v e ", MPI_INFO_NULL ) ; MPI_File_read ( t h e f i l e, buf, bufsize, MPI_INT, &s t a t u s ) ; MPI_Get_count (& status, MPI_INT, &count ) ; p r i n t f ( " process %d read %d i n t s \ n ", myrank, count ) ; MPI_File_close (& t h e f i l e ) ; MPI_Finalize ( ) ; return 0; Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 33/48
Zdalne operacje na pamięci (RMA) Równoległe we-wy Przykład równoległego zapisu Przykład równoległego odczytu Zdalne operacje na pamięci (RMA) Przykład: RMA Dynamiczna struktura obliczeniowa Przykład: dynamiczny model master-slave Zdalne operacje na pamięci pamięć dzielona: MPI-2: dane sa przesyłane z jednej przestrzeni adresowej do drugiej za pomoca pary operacji sendreceive Pamięć dzielona: procesy maja dostęp do wspólnej puli pamięci i moga wprost wykonywać operacje na pamięci Realizacja: oddzielenia synchronizacji od przesyłania danych w celu zwiększenia efektywności, powstałe rozwi azanie jest oparte na idei okien zdalnego dostępu do pamięci (okno - to porcja przestrzeni adresowej każdego procesu dostępna dla innych). Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 34/48
RMA Równoległe we-wy Przykład równoległego zapisu Przykład równoległego odczytu Zdalne operacje na pamięci (RMA) Przykład: RMA Dynamiczna struktura obliczeniowa Przykład: dynamiczny model master-slave Operacje na oknach: pobieranie zawartości okna MPI_Get zapisywanie do okna MPI_Put zmiana zawartości okna MPI_Accumulate A wszystko: synchronizowane przez MPI_Win_Fence Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 35/48
Przykład: RMA Równoległe we-wy Przykład równoległego zapisu Przykład równoległego odczytu Zdalne operacje na pamięci (RMA) Przykład: RMA Dynamiczna struktura obliczeniowa Przykład: dynamiczny model master-slave / o b l i c z a n i e p i za pomoca całkowania numerycznego, we r sj a RMA / #include " mpi. h " # include <math. h> i n t main ( i n t argc, char argv [ ] ) { i n t n, myid, numprocs, i ; double PI25DT = 3.141592653589793238462643; double mypi, pi, h, sum, x ; MPI_Win nwin, piwin ; MPI_Init (& argc, &argv ) ; MPI_Comm_size (MPI_COMM_WORLD,& numprocs ) ; MPI_Comm_rank (MPI_COMM_WORLD,& myid ) ; i f ( myid == 0) { MPI_Win_create(&n, sizeof ( i n t ), 1, MPI_INFO_NULL, MPI_COMM_WORLD, &nwin ) ; MPI_Win_create(& pi, sizeof ( double ), 1, MPI_INFO_NULL, MPI_COMM_WORLD, &piwin ) ; } else { MPI_Win_create (MPI_BOTTOM, 0, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &nwin ) ; MPI_Win_create (MPI_BOTTOM, 0, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &p i w i n ) ; } Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 36/48
Przykład: RMA Równoległe we-wy Przykład równoległego zapisu Przykład równoległego odczytu Zdalne operacje na pamięci (RMA) Przykład: RMA Dynamiczna struktura obliczeniowa Przykład: dynamiczny model master-slave while ( 1 ) { i f ( myid == 0) { p r i n t f ( " Enter the number of i n t e r v a l s : (0 q u i t s ) " ) ; scanf ( "%d ",&n ) ; p i = 0. 0 ; } MPI_Win_fence ( 0, nwin ) ; i f ( myid!= 0) MPI_Get(&n, 1, MPI_INT, 0, 0, 1, MPI_INT, nwin ) ; MPI_Win_fence ( 0, nwin ) ; i f ( n == 0) break ; else { h = 1.0 / ( double ) n ; sum = 0. 0 ; for ( i = myid + 1; i <= n ; i += numprocs ) { x = h ( ( double ) i 0. 5 ) ; sum += ( 4. 0 / ( 1. 0 + x x ) ) ; } Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 37/48
Przykład: RMA Równoległe we-wy Przykład równoległego zapisu Przykład równoległego odczytu Zdalne operacje na pamięci (RMA) Przykład: RMA Dynamiczna struktura obliczeniowa Przykład: dynamiczny model master-slave mypi = h sum ; MPI_Win_fence ( 0, piwin ) ; MPI_Accumulate(&mypi, 1, MPI_DOUBLE, 0, 0, 1, MPI_DOUBLE, MPI_SUM, piwin ) ; MPI_Win_fence ( 0, piwin ) ; i f ( myid == 0) p r i n t f ( " p i i s approximately %.16 f, E r r o r i s %.16 f \ n ", pi, fabs ( p i PI25DT ) ) ; } } MPI_Win_free(&nwin ) ; MPI_Win_free(& piwin ) ; MPI_Finalize ( ) ; return 0; } Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 38/48
Dynamiczna struktura obliczeniowa Równoległe we-wy Przykład równoległego zapisu Przykład równoległego odczytu Zdalne operacje na pamięci (RMA) Przykład: RMA Dynamiczna struktura obliczeniowa Przykład: dynamiczny model master-slave MPI-2 umożliwia dynamiczne tworzenie procesów w trakcie pracy poprzez funkcję MPI_Comm_Spawn. Maksymalna ilość procesów określa parametr MPI_UNIVERSE_SIZE. Procesy wywołujacy i wywołany łaczy interkomunikator - podawany jako argument w MPI_Comm_Spawn oraz otrzymywany w procesie wywołanym przez MPI_Comm_get_parent. Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 39/48
Przykład: dynamiczny model master-slave Równoległe we-wy Przykład równoległego zapisu Przykład równoległego odczytu Zdalne operacje na pamięci (RMA) Przykład: RMA Dynamiczna struktura obliczeniowa Przykład: dynamiczny model master-slave / master / #include " mpi. h " i n t main ( i n t argc, char argv [ ] ) { i n t world_size, universe_size, universe_sizep, f l a g ; MPI_Comm everyone ; / i n t e r k o m u n i k a t o r / char worker_program [ 1 0 0 ] ; MPI_Init (& argc, &argv ) ; MPI_Comm_size (MPI_COMM_WORLD, &world_size ) ; i f ( world_size!= 1) e r r o r ( " Top heavy with management " ) ; MPI_Attr_get (MPI_COMM_WORLD, MPI_UNIVERSE_SIZE, &universe_sizep, &f l a g ) ; i f (! f l a g ) { p r i n t f ( " This MPI does not support UNIVERSE_SIZE. How many \ n \ processes t o t a l? " ) ; scanf ( "%d ", &universe_size ) ; } else universe_size = universe_sizep ; i f ( universe_size == 1) e r r o r ( "No room to s t a r t workers " ) ; / / uruchamiamy procesy slave mozemy wczesniej sprecyzować l i n i ę poleceń choose_worker_program ( worker_program ) ; MPI_Comm_spawn( worker_program, MPI_ARGV_NULL, universe_size 1, MPI_INFO_NULL, 0, MPI_COMM_SELF, &everyone, MPI_ERRCODES_IGNORE) ; / Tu kod równoległy. Komunikator " everyone " może być używany do komunikacji z uruchomionymi procesami o rank 0,..., MPI_UNIVERSE_SIZE 1 w " everyone " / MPI_Finalize ( ) ; return 0; } Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 40/48
Przykład: dynamiczny model master-slave Równoległe we-wy Przykład równoległego zapisu Przykład równoległego odczytu Zdalne operacje na pamięci (RMA) Przykład: RMA Dynamiczna struktura obliczeniowa Przykład: dynamiczny model master-slave / slave / #include " mpi. h " i n t main ( i n t argc, char argv [ ] ) { i n t size ; MPI_Comm parent ; MPI_Init (& argc, &argv ) ; MPI_Comm_get_parent(& parent ) ; i f ( parent == MPI_COMM_NULL ) e r r o r ( "No parent! " ) ; MPI_Comm_remote_size ( parent, &size ) ; i f ( size!= 1) e r r o r ( " Something s wrong with the parent " ) ; / Tu kod równoległy. Master j e s t procesem o rank 0 w MPI_Comm parent Procesy slave moga komunikować s i ę ze soba przez MPI_COMM_WORLD. / MPI_Finalize ( ) ; return 0; } Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 41/48
MPI a język C++ Przykład: MPI, a C++ Użytkowanie MPICH w ZA Gdzie szukać informacji? Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 42/48
MPI a język C++ MPI a język C++ Przykład: MPI, a C++ Użytkowanie MPICH w ZA Gdzie szukać informacji? W standardzie MPI użyto "konserwatywnego" podejścia do implementacji w C++ - większość funkcji jest metodami klasy MPI. Większość zmiennych charakterystycznych dla MPI (takich jak statusy, żadania, pliki) jest obiektami w C++. Jeżeli funkcja jest naturalnie powiazana z obiektem to stanowi ona jego metodę. Funkcje tworzace obiekty zwracaja je - zamiast kodu błędu. Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 43/48
Przykład: MPI, a C++ MPI a język C++ Przykład: MPI, a C++ Użytkowanie MPICH w ZA Gdzie szukać informacji? i n t main ( i n t argc, char argv [ ] ) { i n t bufsize, buf, count ; char filename [ 1 2 8 ] ; MPI : : Status s t a t u s ; MPI : : I n i t ( ) ; i n t myrank = MPI : :COMM_WORLD. Get_rank ( ) ; i n t numprocs = MPI : :COMM_WORLD. Get_size ( ) ; MPI : : F i l e t h e f i l e = MPI : : F i l e : : Open( MPI : :COMM_WORLD, " t e s t f i l e ", MPI : : MODE_RDONLY, MPI : : INFO_NULL ) ; MPI : : O f f s e t f i l e s i z e = t h e f i l e. Get_size ( ) ; / / w bajtach f i l e s i z e = f i l e s i z e / sizeof ( i n t ) ; / / w i n t b u f s i z e = f i l e s i z e / numprocs + 1; / / do przeczytania l o k a l n i e buf = ( i n t ) malloc ( b u f s i z e sizeof ( i n t ) ) ; t h e f i l e. Set_view ( myrank b u f s i z e sizeof ( i n t ), MPI_INT, MPI_INT, " n a t i v e ", MPI : : INFO_NULL ) ; t h e f i l e. Read ( buf, bufsize, MPI_INT, &s t a t u s ) ; count = s t a t u s. Get_count ( MPI_INT ) ; cout << " process " << myrank << " read " << count << " i n t s " << endl ; t h e f i l e. Close ( ) ; MPI : : F i n a l i z e ( ) ; return 0; } Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 44/48
Użytkowanie MPICH w ZA MPI a język C++ Przykład: MPI, a C++ Użytkowanie MPICH w ZA Gdzie szukać informacji? W laboratorium 102 Zakładu Automatyki dostępnych jest 6 komputerów pracujacych pod kontrola systemu operacyjnego Debian Linux, z zainstalowana biblioteka MPICH i kompilatorem GCC. Komputery posiadaja nazwy domenowe za-51, za-52, itd. Dla uruchamiania programów równoległych przygotowano konta mpilab1, mpilab2,... przypisane do każdego z komputerów (hasło: mpilab). Katalogi domowe s a dzielone przez NFS między wszystkimi maszynami (nie ma zatem potrzeby kopiowania kodów, można stosować metody równoległego we/wy). Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 45/48
Użytkowanie MPICH w ZA MPI a język C++ Przykład: MPI, a C++ Użytkowanie MPICH w ZA Gdzie szukać informacji? Kroki uruchamiania programu: kompilacja mpicc.mpich -g -o binary_file_name source_file.c (w przypadku C++ - mpicc) przygotowanie środowiska - stworzyć plik zawierajacy nazwy używanych komputerów i ilość procesów na każdym z nich np. za-51 za-52 za-54 uruchomienie programu - poprzez wywołanie mpirun np. mpirun.mpich -machinefile plik_z_maszynami -n ilosc_procesów binary_file Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 46/48
Gdzie szukać informacji? MPI a język C++ Przykład: MPI, a C++ Użytkowanie MPICH w ZA Gdzie szukać informacji? Szczególnie polecane sa strony danej implementacji MPI, specyfikacja samego standardu (www.mpi-forum.org) oraz: MPI: The Complete Reference, M. Snir, S. Otto, S. Huss-Lederman, D. Walker, J. Dongarra, (http://www.netlib.org/utk/papers/mpi-book/mpi-book.html) Rozszerzenia standardu MPI: MPI-2, materiały szkoleniowe PCSS, (http://szkolenia.man.poznan.pl/kdm/presentations/ MPI-2/rozszerzenia standardu MPI - MPI-2.pdf ) Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 47/48
Dziękuję za uwagę! Dziękuję za uwagę! Szymon Łukasik, 8 listopada 2006 Łagodne wprowadzenie do MPI - p. 48/48