51. Metody komunikacji nieblokującej. Funkcje nieblokujace różnia sie od wersji blokujacych przedrostkiem I (immediate) w nazwie oraz jednym dodatkowym argumentem: request, który jest używany do sprawdzenia, czy dana operacja została zakończona Wysyłanie nieblokujące Funkcja MPI Isend: (standardowa) int MPI Isend( void *buf, Funkcja MPI Ibsend: (buforowana) int MPI Ibsend( void *buf, Funkcja MPI Issend: (synchroniczna) int MPI Issend( void *buf, Funkcja MPI Irsend: (natychmiastowa) int MPI Irsend( void *buf,
Odbiór nieblokujący Funkcja MPI Irecv: nie ma argumentu MPI Status może odbierać także komunikaty wysyłane w spospób blokujący (i vice-versa) int MPI Irecv( void *buf, int source, Funkcja MPI Wait: pozwala czekać na zakończenie nieblokującej operacji(wysyłania, odbierania) wskazanej przez argument request pod adresem status wpisuje status zakończonej operacji po zakończeniu funkcja wpisuje pod adresem request wartość MPI REQUEST NULL int MPI Wait(MPI Request *request, MPI Status *status) Funkcja MPI Test: jeżeli operacja o uchwycie wskazywanym przez request skończyła się, to funkcja działa jak MPI Wait i dodatkowo pod adresem flag wpisuje wartość true jeżeli operacja się nie zakończyła, funkcja pod adresem flag wpisuje false i powraca int MPI Wait(MPI Request *request, int *flag, MPI Status *status) Jeśli funkcje MPI Wait i MPI Test sygnalizują zakończenie operacji, to następuje zwolnienie zajmowanych przez nią zasobów. Jawnie można zwolnić zasoby funkcją int MPI Request free( Funkcja MPI Waitany: czeka na zakończenie jakiejkolwiek z count operacji na uchwytach przkazanych w tablicy array of requests indeks (z array of requests) zakończonej operacji jest zapisywany pod adresem index status operacji zapisywany pod adresem status jeśli kilka operacji się zakończyło, funkcja wybiera tylko jedną z nich (dla pozostałych można wywołać ją ponownie) zasoby są zwalniane, a w odpowiednią pozycję tablicy array of requests wpisywane MPI REQUEST NULL int MPI Waitany( MPI Request *array of requests, int *index, MPI Status *status)
Pozostałe funkcje: Funkcja MPI Testany int MPI Testany( MPI Request *request, int *index, int *flag, MPI Status *status) Funkcja MPI Waitall int MPI Waitall( MPI Request *array of requests, MPI Status *array of statuses) Funkcja MPI Testall int MPI Testall( MPI Request *array of requests, int *flag, MPI Status *array of statuses) Anulowanie komunikacji: int MPI Cancel( pozwala przerwać oczekującą nieblokującą komunikację nie oznacza to zwolnienia zasobów (należy użyć MPI Request Free, MPI Wait lub MPI Test) użycie tej funkcji może znacznie spowalniać wykonanie, nie należy jej nadużywać sprawdzenie czy anulowanie się powiodło umożliwia funkcja MPI Test cancelled int MPI Test cancelled(mpi Status *status, int *flag) /jeśli flag=true to status jest nieokreślony/ Sprawdzanie rozmiaru bufora Funkcja MPI Iprobe /wersja nieblokująca (flag=true jeśli komunikat jest gotowy do odbioru)/ int MPI Iprobe( int source, MPI Comm comm, int *flag, MPI Status *status)
52. Komunikacja łączona. Operacja Send-Receive łączy w jednym wywołaniu wysyłanie komunikatu do określonego odbiorcy oraz odbiór od określonego nadawcy innego komunikatu. Użyteczna w cyklicznych operacjach przesunięć: odporna na powstawanie blokad(deadlock) Funkcja MPI Sendrecv: (blokująca) int MPI Sendrecv ( void *sendbuf, int sendcount, MPI Datatype sendtype, int sendtag, void *recvbuf, int recvcount, MPI Datatype recvtype, int source, int recvtag, MPI Status status) 53. Stosowanie typów pochodnych. Typ pochodny można zdefiniować za pomocą specjalnej funkcji (patrz następne pytania) Po zdefiniowaniu nowego typu należy go ustanowić (skompilować) przed użyciem typu do przesyłania komunikatów ale nie koniecznie przed definiowaniem kolejnych typów pochodnych Po zakończeniu używania typu należy zwolnić przydzielone mu zasoby 54. Mapowanie typów. Określa rozłożenie w pamięci obiektów tworzących dany typ danych Typemap - mapa typu - jest to sekwencja par: ( typ podstawowy, przesunięcie w pamieci/w bajtach/ ) typemap={(type 0, disp 0 ),..., (type n 1, disp n 1 )} Sygnatura typu - lista typów zawarytch w typemap: type signature={type 0,..., type n 1 } lb - dolne ograniczenie przesunięć: lb(typemap) = min j (disp j ) ub - górne ograniczenie przesunięć: ub(typemap) = max j (disp j +sizeof(type j )) extent - zakres (różnica ub-lb powiększona o wyrównanie): extent(typemap) = ub(typemap) - lb(typemap) + pad
55. Tworzenie typów pochodnych i ich rodzaje. Ustanowienie typu: int MPI Type commit (MPI Datatype *datatype) ustanawia wskazany typ do komunikacji ustanowiony typ może dalej służyć do tworzenia dalszych typów pochodnych system może dokonać kompilacji wewnętrznej reprezentacji typu pod kątem optymalizacji komunikacji go wykorzystujących Zwolnienie typu: int MPI Type free (MPI Datatype *datatype) zwalnia zasoby zaalokowane przez wskazny typ ustawia wskazanie datatype na MPI DATATYPE NULL zaległ komunikacje wykorzystujące typ będą dokończone normalnie (opoźnienie dealokacji) funkcja nie wpływa na stan typów pochodnych od datatype Rodzaje: 1.Tablica typów int MPI Type contiguous ( najprostszy konstruktor typu pochodnego argument count określa liczbę elementów w tablicy argumant oldtype określa typ składowy wynikowy identyfikator typu jest umieszczany pod adresem newtype przesunięcia powiększane o zakres typu składowego 2.Wektor int MPI Type vector ( int blocklength, int stride, definiuje typ składający się z count bloków, zawierających blocklength elementów typu oldtype każdy między początkami bloków występują odstępy o długości stride elementów oldtype
3.Wektor heterogeniczny int MPI Type hvector ( MPI A int blocklength, int stride, argument stride określa przesunięcia wyrażone w bajtach, a nie w długościach zakresu elementu oldtype typ podstawowy MPI Aint odnosi się do adresów (liczba całkowita przechowująca adres na danej architekturze) 4.Wektor indeksowany int MPI Type indexed ( int *array of blocklengths, int *array of displacements, tablica array of blocklengths określa ilości powieleń count bloków o zakresach odpowiadających zakresowi typu oldtype dla każdego powielenia przesunięcie wyrażone w jednostkach zakresu typu oldtype jest pobierane z odpowiedniego pola tablicy array of displacements argument count określa także rozmiar tablic array of blocklengths i array of displacements 5.Wektor indeksowany heterogeniczny int MPI Type hindexed ( int *array of blocklengths, MPI Aint *array of displacements, przesunięcia w tablicy array of displacements wyrażone są w bajtach 6.Struktura int MPI Type struct ( int *array of blocklengths, MPI Aint *array of displacements, MPI Datatype *array of types, definiuje najogólniejszą postać typu pochodnego typ newtype składa się z count bloków, każdy o innym typie i długości zakresu typy poszczególnych bloków określa tablica array of types, a ich długości (wyrażone liczbą elementów składowych) tablica array of blocklengths elementy tablicy array of displacements określają przesunięcie bloków względem początku
Funkcje pomocnicze int MPI Address (void *location, MPI Aint *address) zwraca adres położenia w pamięci int MPI Type extent (MPI datatype datatype, MPI Aint *extent) zwraca długość zakresu danego typu int MPI Type size (MPI datatype datatype, int *size) zwraca całkowitą wielkość(w bajtach) elementów składowych typu stała MPI BOTTOM oznacza początek obszaru pamięci adresowanego absolutnie np. z użyciem MPI Address Przykład: