Komunikacja zbiorowa – część I Komunikacja zbiorowa: przesyłanie danych pomiędzy wszystkimi procesorami grupy zdefiniowanymi przez dany komunikator. Typy.

Slides:



Advertisements
Podobne prezentacje
Tablice 1. Deklaracja tablicy
Advertisements

Teoria układów logicznych
Język C/C++ Funkcje.
Programowanie obiektowe PO PO - LAB 4 Wojciech Pieprzyca.
Grażyna Mirkowska PJWSTK 15 listopad 2000
Programowanie w języku Visual Basic
Język ANSI C Funkcje Wykład: Programowanie komputerów
Różniczkowanie numeryczne
Funkcje c.d. Strukturalność. Algorytmy. Ćwiczenia przed kolokwium.
PROGRAMOWANIE STRUKTURALNE
ZŁOŻONOŚĆ OBLICZENIOWA
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 7: Procedury i funkcje © Jan Kaczmarek.
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 6: Tablice, rekordy, zbiory.
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 5: Typy porządkowe, wyliczeniowe i okrojone. Definiowanie.
Podstawowe składniki funkcjonalne procesora i ich rola.
Programowanie imperatywne i język C Copyright, 2004 © Jerzy R. Nawrocki Wprowadzenie.
Programowanie imperatywne i język C
Programowanie imperatywne i język C Copyright, 2004 © Jerzy R. Nawrocki Wprowadzenie.
Wprowadzenie do Mathcada
Typy prywatne 1 Typy prywatne W Adzie typy prywatne (private types) służą do bezpiecznego udostępniania danych zdefiniowanych w pakiecie, z którego korzysta.
Instytut Fizyki Teoretycznej
Wykład 2 struktura programu elementy języka typy zmienne
Komunikacja zbiorowa: część II
Wyrażenia Wyrażenie w Fortranie jest poprawną syntaktycznie kombinacją zmiennych, stałych, operatorów i funkcji. Wyrażenia są jednozdaniowymi przepisami.
Instrukcja skoku GO TO etykieta Np. GO TO 100 ….. 100WRITE (*,*) Przeskok do instrukcji 100 Uwaga! NIE WOLNO skakać do wnętrzna złożonych instrukcji warunkowych.
Topologie wirtualne Topologia wirtualna: zadany schemat połączeń pomiędzy procesorami; inaczej mówiąc schemat ich wzajemnego sąsiedztwa. W MPI można określić.
Wykład 10 Proste zastosowania mechaniki statystycznej
Podstawy MPI-2: część II Dynamiczne zarządzanie procesami
Wielkości skalarne i wektorowe
Typy wyrażenia, schematy blokowe, writeln, readln, if, pętle
Typy złożone, case, stałe. Typ zbiorowy type typ_zb = set of typ_podstawowy; Typem podstawowym może być tylko typ porządkowy. Typem podstawowym może być
Zastosowanie środowiska MUSCLE do rozproszonych obliczeń numerycznych
dr inż. Piotr Muryjas Wyższa Szkoła Przedsiębiorczości i Administracji
Podstawy układów logicznych
Dane do obliczeń.
Podstawy programowania
Programowanie w języku Matlab
Równoległy algorytm metody Jacobiego rozwiązywania zagadanienia brzegowego dla eliptycznych równań różniczkowych cząstkowych.
ETO w Inżynierii Chemicznej
TABLICE C++.
Procedury i funkcje.
Współczynnik przyspieszenia n - wielkość zadania p - liczba procesorów T(n,p) – czas wykonania.
Jerzy F. Kotowski1 Informatyka I Wykład 14 DEKLARATORY.
JAVA c.d.. Instrukcji wyboru SWITCH używamy, jeśli chcemy w zależności od wartości pewnego wyrażenia wykonać jeden z kilku fragmentów kodu. Jest to w.
Programowanie obiektowe III rok EiT
Zbiory i rekordy mgr inż. Agata Pacek. Deklaracja typu zbiorowego (określa ilość elementów w zbiorze) type biegi=set of 0..6; Definiowanie zmiennej typu.
Instrukcja warunkowa i wyboru
Definiowanie typów danych użytkownika
Przekazywanie parametrów do funkcji oraz zmienne globalne i lokalne
Przykładowy algorytm geometryczny (geometria płaska)
Wykład 10 typ zbiorowy rekurencja.
MOiPP Matlab Przykłady metod obliczeniowych Obliczenia symboliczne
Zagadnienia AI wykład 6.
Metody matematyczne w inżynierii chemicznej
WYKŁAD 06 Programowanie dynamiczne Grażyna Mirkowska.
Zasady arytmetyki dwójkowej
MPI: podstawy i komunikacja punktowa. Charakterystyka standardowego interfejsu przesyłania wiadomości MPI: Kod jest napisany w „zwyczajnym” języku programowania.
1 An Introduction to MPI Parallel Programming with the Message Passing Interface William Gropp Ewing Lusk Argonne National Laboratory Wprowdzenie do MPI.
Definiowanie typów danych użytkownika Każdy typ danych w MPI jest określony przez tablice typemap podającą dla każdego elementu parami typ podstawowy i.
Podstawy MPI-2: część I Literatura: Using MPI-2. Advanced Features of the Message-Passing Interface, W. Gropp, E. Lusk, R. Thakur, MIT Press, Cambridge,
Funkcje - rekurencja Zajęcia 8. Funkcje - definicja Ogólna postać funkcji w C++: typZwracany nazwaFunkcji(listaParametrówWejściowychFunkcji) { ciało funkcji.
Programowanie imperatywne i język C Copyright, 2007 © Jerzy R. Nawrocki Wstęp do.
Podsumowanie wiedzy MPDI2 sem.3 INFORMATYKA. tworzenie nowego pliku i katalogu, nawigacja po katalogach, listowanie zawartości katalogu, zmiana nazw,
SciLab.
Wstęp do programowania wykład 3 Typy wyliczeniowe, tablice.
P ASCAL Definicje, deklaracje, podstawowe instrukcje 1.
Algorytmy. Co to jest algorytm? Przepis prowadzący do rozwiązania zadania.
Liczbami naturalnymi nazywamy liczby 0,1,2,3,..., 127,... Liczby naturalne poznaliśmy już wcześniej; służą one do liczenia przedmiotów. Zbiór liczb.
ETO w Inżynierii Chemicznej
Przykładowy algorytm geometryczny (geometria płaska)
Zapis prezentacji:

Komunikacja zbiorowa – część I Komunikacja zbiorowa: przesyłanie danych pomiędzy wszystkimi procesorami grupy zdefiniowanymi przez dany komunikator. Typy komunikacji zbiorowej : 1.Bariera (synchronizacja). 2.Globalna wymiana danych. 3.Globalne operacje redukcji. Szczegółowy opis procedur komunikacji zbiorowej można znaleźć w książce „MPI - the complete reference” pod adresem book/node91.htmlhttp:// book/node91.html

Bariera Bariera: synchronizacja wszystkich procesorów grupy (MPI_BARRIER). Składnia procedury MPI_BARRIER w C i Fortranie 77:MPI_BARRIER MPI_BarrierMPI_Barrier(MPI_Comm comm) MPI_BARRIERMPI_BARRIER(COMM, IERROR) INTEGER COMM, IERROR comm - komunikator

Globalna wymiana danych:  Broadcast: rozesłanie wiadomości przez jeden procesor (root) do pozostałych procesorów grupy (MPI_BCAST).MPI_BCAST  Gather: zebranie wiadomości przez jeden procesor (root) od wszystkich procesorów grupy (MPI_GATHER, MPI_GATHERV).MPI_GATHER MPI_GATHERV  Scatter: rozproszenie danych od jednego procesora (roota) do wszystkich elementów grupy (MPI_SCATTER, MPI_SCATTERV).MPI_SCATTER MPI_SCATTERV  Allgather: każdy procesor zbiera wiadomości od pozostałych procesorów grupy (MPI_ALLGATHER, MPI_ALLGATHERV).MPI_ALLGATHER MPI_ALLGATHERV  All-to-all (all-scatter-all-gather): każdy procesor rozprasza swoje dane do wszystkich procesorów grupy i zbiera wiadomości od wszystkich procesorów grupy (MPI_ALLTOALL, MPI_ALLTOALLV).MPI_ALLTOALLMPI_ALLTOALLV

Składnia procedury MPI_BCAST w C i Fortranie 77: MPI_BcastMPI_Bcast(void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm ) MPI_BCASTMPI_BCAST(BUFFER, COUNT, DATATYPE, ROOT, COMM, IERROR) BUFFER(*) INTEGER COUNT, DATATYPE, ROOT, COMM, IERROR buffer - początkowy adres bufora transmitowanych danych count - liczba transmitowanych elementów danych datatype - identyfikator typu transmitowanych danych (w sensie MPI) root - rząd (numer) procesora, który rozsyła dane comm - komunikator.

Przykład (C): rozesłanie przez procesor 0 tablicy 100 liczb całkowitych: MPI_Comm comm; int array[100]; int root=0;... MPI_Bcast( array, 100, MPI_INT, root, comm); Przykład (Fortran): rozsyłanie rozkazu oraz danych do „robotników” przez „nadzorcę”: subroutine func1(n,What,x,zz,obf,obg)... integer What double precision x(n)... call MPI_Bcast( What, 1, MPI_INTEGER, Master, Comm1, IERROR) call MPI_Bcast(x(1),n,MPI_DOUBLE_PRECISION, Master, Comm1, IERROR) if (What.le.0) return

Składnia procedur MPI_GATHER w C i Fortranie 77: MPI_GatherMPI_Gather(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) MPI_GATHERMPI_GATHER(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR) SENDBUF(*), RECVBUF(*) INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR sendbuf - początkowy adres bufora transmitowanych danych recvbuf - początkowy adres bufora przyjmowanych danych sendcount, sendcounts - liczba wysyłanych elementów danych (w przypadku MPI_Gatherv jest to tablica) recvcount, recvcounts - liczba przyjmowanych elementów danych (w przypadku MPI_Gatherv jest to tablica) sendtype - identyfikator typu wysyłanych danych (w sensie MPI) recvtype - identyfikator typu przyjmowanych danych (w sensie MPI) root - rząd (numer) procesora, który przyjmuje dane comm - komunikator.

Efekt działania MPI_Gather dla układu n procesorów można przedstawić jako wykonanie instrukcji MPI_Send przez każdy procesor (łącznie z rootem) a następnie przyjęcie przez root danych od kolejnych procesorów (łącznie z sobą samym) w ten sposób, że dane zawarte w buforze procesora pierwszego są lokowane na początku bufora przyjmującego, dane pochodzące od procesora drugiego są w buforze przyjmującym przesunięte o RECVCOUNT, itd.:

Oddzielna specyfikacja dla SENDCOUNT i SENDTYPE oraz RECVCOUNT i RECVTYPE umożliwia inną specyfikację danych dla roota a inną dla pozostałych procesorów; należy jednak pamiętać, że całkowita długość SENDBUF musi się zgadzać z długością części RECVBUF, do której root przyjmuje te dane. Przykład: zebranie przez procesor 0 (root) tablicy 100 liczb całkowitych od każdego procesora: integer comm, gsize, sendarray(100) integer root, rbuf(100*MaxProcs)... call MPI_Comm_size(comm, gsize) call MPI_Gather( sendarray, 100, MPI_INT, rbuf, 100, MPI_INT, root, comm)

Składnia procedur MPI_GATHER w C i Fortranie 77: MPI_GathervMPI_Gatherv(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, int root, MPI_Comm comm) MPI_GATHERVMPI_GATHERV(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNTS, DISPLS, RECVTYPE, ROOT, COMM, IERROR) SENDBUF(*), RECVBUF(*) INTEGER SENDCOUNT, SENDTYPE, RECVCOUNTS(*), DISPLS(*), RECVTYPE, ROOT, COMM, IERROR recvcounts - tablica zawierająca liczbę elementów danych przyjmowanych od poszczególnych procesorów displs - tablica zawierająca przesunięcia porcji danych przyjmowanych od poszczególnych procesorów w buforze przyjmującym.

Przykład: Zbieranie przez „nadzorcę” od „robotników” wyliczonych przez nich części energii struktur: ii=0 do i=indstart(me),indend(me) ii=ii+1 call restore_coords(iprot,ii) call chainbuild call etotal(energia(0)) enetb(i,0)=energia(0) enddo... if (What.eq.2) then call MPI_Gatherv(enetb(indstart(me),0), scount(me),MPI_DOUBLE_PRECISION, enetb(1,0),scount(0),idispl(0), MPI_DOUBLE_PRECISION,Master,Comm1, IERROR) endif

Składnia procedur MPI_SCATTER, MPI_ALLGATHER i MPI_ALLTOALL w C i Fortranie 77 MPI_ScatterMPI_Scatter(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) MPI_SCATTERMPI_SCATTER(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR) SENDBUF(*), RECVBUF(*) INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR MPI_AllgatherMPI_Allgather(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm) MPI_ALLGATHERMPI_ALLGATHER(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT, RECVTYPE, COMM, IERROR) SENDBUF(*), RECVBUF(*) INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT, RECVTYPE, COMM, IERROR MPI_AlltoallMPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm) MPI_ALLTOALLMPI_ALLTOALL(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT, RECVTYPE, COMM, IERROR) SENDBUF(*), RECVBUF(*) INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT, RECVTYPE, COMM, IERROR

Globalne operacje redukcji  Redukcja: Wykonywanie danej operacji (np. dodawania) na grupie danych zebranych od wszystkich procesorów. Wynik jest zwracany albo do jednego procesora (roota; zwykła redukcja) albo do wszystkich (allreduce) (MPI_REDUCE, MPI_ALLREDUCE).MPI_REDUCEMPI_ALLREDUCE  Redukcja z rozproszeniem wyników (MPI_REDUCE_SCATTER).MPI_REDUCE_SCATTER  Redukcja „od procesorów wstecz” (MPI_SCAN).MPI_SCAN

Globalne operatory redukcji MPI_MAXmaksimum MPI_MINminimum MPI_SUMsuma MPI_PRODiloczyn MPI_LANDlogiczne „and” MPI_BANDbitowe „and” MPI_LORlogiczne „or” MPI_BORbitowe „or” MPI_LXORlogiczne „xor” MPI_BXORbitowe „xor” MPI_MAXLOCmaksimum oraz jego położenie MPI_MINLOCminimum oraz jego położenie Użytkownik może również definiować własne operatory redukcji, za pomocą funkcji MPI_OP_CREATE.MPI_OP_CREATE

Składnia procedury MPI_REDUCE w C i Fortranie 77 MPI_ReduceMPI_Reduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm) MPI_REDUCEMPI_REDUCE(SENDBUF, RECVBUF, COUNT, DATATYPE, OP, ROOT, COMM, IERROR) SENDBUF(*), RECVBUF(*) INTEGER COUNT, DATATYPE, OP, ROOT, COMM, IERROR sendbuf - adres buforu wysyłanych danych recvbuf - adres bufora przechowującego wynik operacji redukcji count - liczba wysyłanych przez każdy procesor elementów danych datatype - identyfikator typu wysyłanych/przyjmowanych danych op - identyfikator operacji redukcji root - rząd (numer) roota comm - komunikator

Przykład: obliczanie iloczynu skalarnego dwóch wektorów. Poszczególne m-elementowe części wektorów zostały już wcześniej rozprowadzone pomiędzy procesory: SUBROUTINE PAR_BLAS1(m, a, b, c, comm) REAL a(m), b(m) ! zawieraja czesci wektorow a i b ! przypisane danemu procesorowi REAL c ! wynik (otrzymany przez procesor 0 - root) REAL sum ! suma czastkowa dla kazdego procesora INTEGER m, comm, i, ierr ! suma czastkowa dla danego procesora sum = 0.0 DO i = 1, m sum = sum + a(i)*b(i) ENDDO ! obliczanie sumy calkowitej przez procesor 0 CALL MPI_REDUCECALL MPI_REDUCE(sum, c, 1, MPI_REAL, MPI_SUM, 0, comm, ierr) RETURN END

Składnia procedur MPI_ALLREDUCE, MPI_REDUCE_SCATTER i MPI_SCAN w C i Fortranie 77 MPI_AllreduceMPI_Allreduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) MPI_ALLREDUCEMPI_ALLREDUCE(SENDBUF, RECVBUF, COUNT, DATATYPE, OP, COMM, IERROR) SENDBUF(*), RECVBUF(*) INTEGER COUNT, DATATYPE, OP, COMM, IERROR MPI_Reduce_scatterMPI_Reduce_scatter(void* sendbuf, void* recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) MPI_REDUCE_SCATTERMPI_REDUCE_SCATTER(SENDBUF, RECVBUF, RECVCOUNTS, DATATYPE, OP, COMM, IERROR) SENDBUF(*), RECVBUF(*) INTEGER RECVCOUNTS(*), DATATYPE, OP, COMM, IERROR MPI_ScanMPI_Scan(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm ) MPI_SCANMPI_SCAN(SENDBUF, RECVBUF, COUNT, DATATYPE, OP, COMM, IERROR) SENDBUF(*), RECVBUF(*) INTEGER COUNT, DATATYPE, OP, COMM, IERROR

Przykład użycia procedury MPI_REDUCESCATTER Rozproszone obliczanie iloczynu wektora a przez macierz b z dystrybucją wynikowego wektora c pomiędzy procesory: b a = c

Macierz b oraz wektor a są podzielone pomiędzy procesory na odpowiadające sobie,,plasterki''. Każdy procesor oblicza wkład do elementów wektora wynikowego odpowiadający swoim danym. Następnie przy pomocy procedury MPI_REDUCESCATTER wkłady te są sumowane a wynikowy wektor c jest dystrybuowany pomiędzy procesory.

subroutine matvec( n, m, lmatrix, lx, ly, counts, comm ) use mpi integer n, m, comm, counts(*) real lmatrix(n,m), lx(m), ly(m) integer i, j real sum real, allocatable :: tmp(:) allocate (tmp(n)) ! Perform the local matrix-vector multiply ! Should use the level-2 BLAS routine SGEMV do i=1,n sum = 0 do j=1,m sum = sum + lmatrix(i,j)*lx(j) enddo tmp(i) = sum enddo ! Perform the local matrix-vector product call MPI_REDUCE_SCATTER( tmp, ly, counts, MPI_REAL, MPI_SUM, comm, ierr) deallocate (tmp) ! We're done! end Kod źródłowy (Fortran90)

Kompletny przykladowy program (FORTRAN 77) Wyniki (2 procesory)

Przykład programu wykorzystującego procesury komunikacji zbiorowej: obliczanie liczby  przez całkowanie numeryczne Ilustracja przybliżonego obliczania liczby p przez całkowanie numeryczne dla liczby przedziałów n=10.

Zrównoleglenie algorytmu 1.Przedział całkowania dzieli się na n części: 1, 2,..., n 2.W układzie m procesorów, procesor 1 sumuje wkłady dla części 1, m+1, procesor 2 dla 2, m+2itd. 3.Procesory przesyłają swoje obliczone cząstkowe sumy do mastera, który oblicza sumę całkowitą. Źródło programu w C Źrodło programu w Fortranie77

Wyniki (4 procesory) ~/MPI/scali > mpirun -np 4 pif /opt/scali/bin/mpimon -stdin all pif -- gal72 1 gal71 1 gal65 1 gal64 1 Enter the number of intervals: (0 quits) 100 Processor 1 mypi Processor 0 mypi Processor 3 mypi Processor 2 mypi pi is approximately: Error is: Enter the number of intervals: (0 quits) 0 FORTRAN STOP

OPERATORY MIN_LOCK i MAX_LOCK Te operatory redukcji służą do wyszukania minimalnych (maksymalnych) wartości rozproszonych danych oraz odpowiadających im indeksów (np. indeks może być rzędem procesora). Bufor danych musi być wtedy strukturą zawierającą zarówno porównywane wartości, jak i stowarzyszone z nimi indeksy, np. proc1x1ind1x2ind2x3ind3 proc2x1ind1x2ind2x3ind3 proc3x1ind1x2ind2x3ind3 proc4x1ind1x2ind2x3ind3 x1 min ind1 min x2 min ind2 min x3 min ind3 min

W celu stworzenia bufora danych o strukturze jak podanej tabeli w MPI zdefiniowano następujące złożone typy danych: MPI_FLOAT_INTfloat+int MPI_DOUBLE_INTdouble+int MPI_LONG_INTlong+int MPI_2INTint+int MPI_SHORT_INTshort+int MPI_LONG_DOUBLElong+double C: FORTRAN: MPI_2REAL2*REAL MPI_2DOUBLEPRECISION2*DOUBLE PRECISION MPI_2INTEGER2*INTEGER

W przypadku FORTRANu indeks ma typ zgodny z typem danych, w zbiorze których jest wyszukiwane minimum/maksimum. Jest to spowodowane brakiem typów złożonych w standarcie FORTRANu 77. Aby w tym przypadku posługiwać się parami dana-indeks jak w C należy zdefiniować własne operatory i typy danych. Definicja typu MPI_2REAL oraz MPI_FLOAT_INT: FORTRAN call MPI_TYPE_CONTIGUOUS(2, MPI_REAL, MPI_2REAL) C type[0] = MPI_FLOAT type[1] = MPI_INT disp[0] = 0 disp[1] = sizeof(float) block[0] = 1 block[1] = 1 MPI_TYPE_STRUCT(2, block, disp, type, MPI_FLOAT_INT)

Przykład programu wykorzystującego operator MAX_LOC Każdy procesor wypełnia tablicę 10 liczb podwójnej precyzji, zgodnie z następującą formułą: A[i] = sin(rank*i), i=1,2,...10 gdzie rank jest rzędem procesora. Następnie jest wyszukiwana największa wartość danego elementu tablicy po wszystkich procesorach oraz rząd odpowiadającego jej procesora. Wielkości te są zbierane przez procesor o rzędzie 0. Źródło programu w C Źródło programu w FORTRANie 77

/opt/scali/bin/mpimon -stdin all maxloc -- gal72 1 gal71 1 gal65 1 gal i 1 ind 2 value i 2 ind 1 value i 3 ind 3 value i 4 ind 2 value i 5 ind 3 value i 6 ind 0 value i 7 ind 2 value i 8 ind 1 value i 9 ind 3 value i 10 ind 2 value Wyniki (4 procesory)