You are on page 1of 38

Programowanie współbieżne i rozproszone

Programowanie współbieżne i rozproszone

Tomasz Olas

Instytut Informatyki Teoretycznej i Stosowanej


Politechnika Cz˛estochowska

MPI

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Wstep
˛ do MPI

Koncepcja standardu MPI

MPI (Message Passing Interface) jest standardem, który


definiuje interfejs programistyczny (API) do tworzenia
przenośnych programów równoległych wykorzystujacych˛
model z wymiana˛ komunikatów standardowo dla
architektur z pamieci
˛ a˛ rozproszona.
˛

Memory Memory Memory Memory

...
CPU CPU CPU CPU

Sieć komunikacyjna

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Wstep
˛ do MPI

Własności standardu MPI (I)

Standard MPI zawiera tylko specyfikacje funkcji z API,


które musza˛ zostać zaimplementowane w konkretnej
implementacji biblioteki.
Udostepnia
˛ interfejs dla jezyków
˛ C/C++, Fortran oraz Ada.
Standard MPI został stworzony dla komputerów masywnie
równoległych, jednakże w chwili obecnej pozwala na
efektywna˛ realizacje˛ przetwarzania równoległego na
klastrach, a nawet architekturach z pamieci
˛ a˛
współdzielona.˛
Możliwość pracy w środowiskach heterogenicznych
(składajacych
˛ sie˛ z jednostek różnego typu).

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Wstep
˛ do MPI

Własności standardu MPI (II)

Zaletami standardu MPI jest:


wysoka wydajność oraz możliwość efektywnej obsługi
dużej liczby procesów,
duża funkcjonalność oraz bogata dokumentacja,
standard, który jest public domain.
Wada˛ jest stosunkowo złożony sposób tworzenia
programów równoległych - należy rozdzielić zadania na
poszczególne procesy oraz w jawny sposób zadać
komunikacje˛ pomiedzy
˛ nimi.

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Wstep
˛ do MPI

Historia

Zanim powstał standard MPI nie było rozwiaza


˛ ń, które pozwalały
na tworzenie przenośnych programów równoległych. Dla
każdego typu komputera były dostepne
˛ inne rozwiazania
˛ (np.
CMMD, MPL, NX).
Pierwsza˛ nie do końca udana˛ próba˛ utworzenia przenośnej
biblioteki był PVM (Parallel Virtual Machine).
1992 - Pierwsza propozycja standardu opracowana przez
Dongarre,
˛ Hempela, Heya i Walkera.
1994 - Pierwsza wersja standardu opracowana przez MPI forum.
1995 - Poprawiona wersja standardu (MPI 1.1).
1997 - Wersja 2.0.
2012 - Wersja 3.0.

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Wstep
˛ do MPI

Implementacje standardu MPI

Istnieje wiele implementacji standardu MPI zarówno


komercyjnych, jak i darmowych.
Producenci specjalizowanych komputerów równoległych
cz˛esto dostarczaja˛ własne implementacje MPI
dostosowane do sprzedawanego sprz˛etu.
Najpopularniejszymi darmowymi implementacjami MPI sa˛
Open MPI, MPICH oraz LAM.
Moga˛ one być uruchamiane zarówno w systemach ze
standardowymi sieciami połacze
˛ ń jak Ethernet, jak też
bardziej wyspecjalizowanymi (Infiniband, Myrinet).

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Podstawy MPI

Podstawy programowania

Wszystkie elementy standardu MPI zaczynaja˛ sie˛ od


przedrostka MPI, a poszczególne wyrazy w nazwie
oddzielone sa˛ znakiem podkreślenia.
W przypadku nazw funkcji stosowane sa˛ małe litery poza
pierwszym członem nazwy, który zaczyna sie˛ z dużej litery:
MPI_Comm_rank(...)
Stałe MPI składaja˛ sie˛ wyłacznie
˛ z dużych liter:
MPI_COMM_WORLD
Interfejs programistyczny MPI dostepny
˛ jest poprzez plik
nagłówkowy mpi.h.
Wszystkie funkcje MPI zwracaja˛ MPI_SUCCESS w
przypadku poprawnego zakończenia lub kod błedu ˛ w
przeciwnym przypadku.
Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone
Programowanie współbieżne i rozproszone
Podstawy MPI

Struktura programu

Dołączenie pliku nagłówkowego MPI

#include <mpi.h>

Inicjalizacja obliczeń

MPI_Init(&argc, &argv);

Obliczenia równoległe z wykorzystaniem MPI

MPI_Finalize();

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Podstawy MPI

MPI_Init i MPI_Finalize

Inicjalizacja biblioteki - funkcja MPI_Init:

int MPI_Init(int *argc, char ***argv)

Przekazujemy do niej niezmienione argumenty funkcji


main.
Po zakończeniu pracy z MPI należy wywołać funkcje˛
MPI_Finalize.
Należy zadbać, aby wszystkie wysłane komunikaty zostały
prawidłowo odebrane.
Funkcji MPI można używać tylko pomiedzy
˛ wywołaniami
funkcji MPI_Init i MPI_Finalize.

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Podstawy MPI

Kompilacja i uruchamianie

Do kompilacji wykorzystujemy skrypt zależny od


implementacji (np. mpic++ lub mpicxx). Skrypt ten
konfiguruje środowisko kompilacji, a nastepnie
˛ uruchamia
odpowiedni kompilator (np. g++). Sposób użycia tego
skryptu jest taki sam jak kompilatora. Na przykład:

mpic++ -O3 -o ./lab01 ./lab01.cpp

Program uruchamiamy przy użyciu skryptu mpirun lub


mpiexec podajac ˛ po opcji -np liczbe˛ procesów jaka ma
zostać uruchomiona:
mpirun -np 4 ./lab01

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Podstawy MPI

Przykład - pierwszy program

#include <iostream>
#include <mpi.h>

int main (int argc, char *argv[])


{ > mpic++ -O3 -o hello ./hello.cpp
MPI_Init(&argc, &argv); > mpirun -np 4 ./hello
Hello world
std::cout << "Hello world" Hello world
<< std::endl; Hello world
MPI_Finalize(); Hello world

return 0;
}

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Podstawy MPI

Komunikatory

Komunikator jest obiektem grupujacym ˛ procesy podczas sesji


MPI i określa on zbiór procesów, które moga˛ sie˛ ze soba˛
komunikować. Dodatkowo komunikator ma zdefiniowany tzw.
kontekst, poprzez który określa sie˛ dodatkowe informacje (np.
topologie). Komunikator jest definiowany typem MPI_Comm.
Każdy proces w obrebie
˛ komunikatora ma niezależny
identyfikator (numer w tym komunikatorze).
Proces może należeć do wielu komunikatorów (które moga˛
nakładać sie˛ na siebie).
Po uruchomieniu programu tworzony jest komunikator
MPI_COMM_WORLD, do którego należ wszystkie uruchomione
procesy.
Wszystkie funkcje realizujace
˛ komunikacje˛ wymagaja˛ podania
komunikatora.
Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone
Programowanie współbieżne i rozproszone
Podstawy MPI

Liczba procesów w komunikatorze

Do pobrania liczby procesów w komunikatorze służy


funkcja:

int MPI_Comm_size(MPI_Comm comm, int *size)

W pierwszym argumencie podajemy komunikator, a w


drugim adres zmiennej, w której po wykonaniu funkcji
zostanie zapisana liczba procesów w komunikatorze.

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Podstawy MPI

Pobranie identyfikatora procesu

Do pobrania identyfikatora procesu w komunikatorze służy


funkcja:

int MPI_Comm_rank(MPI_Comm comm, int *rank)

comm - komunikator,
rank - po wykonaniu funkcji pod ta˛ zmienna˛ zostanie
zapisany identyfikator procesu, który ja˛ wywołał.
Identyfikator bieżacego
˛ procesu jest liczba˛ z przedziału od
0 do p − 1, gdzie p oznacza liczbe˛ procesów w
komunikatorze.

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Podstawy MPI

Przykład - informacje o procesach

#include <iostream>
#include <mpi.h>
using namespace std;

int main (int argc, char *argv[])


{
MPI_Init(&argc, &argv); > mpic++ -O3 -o info info.cpp
> mpirun -np 4 ./info
int rank, size; Jestem 0 procesem z 4
Jestem 1 procesem z 4
MPI_Comm_rank(MPI_COMM_WORLD, &rank); Jestem 3 procesem z 4
MPI_Comm_size(MPI_COMM_WORLD, &size); Jestem 2 procesem z 4
cout << "Jestem " << rank
<< " procesem z " << size << endl;
MPI_Finalize();
return 0;
}

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja typu punkt-punkt

Komunikacja typu punkt-punkt

Do wymiany danych (komunikatów) pomiedzy


˛ procesami
niezbedna
˛ jest ich kooperacja.
Podstawowym mechanizmem wymiany danych pomiedzy
˛
procesami jest komunikacja typu punkt-punkt.
Dane sa˛ jawnie wysyłane przez proces nadawce˛ i jawnie
odbierane przez proces odbiorce.˛
Jawnie, czyli poprzez wywołanie odpowiedniej funkcji MPI:
nadawca wysyła komunikat do odbiorcy przy pomocy
funkcji MPI_Send,
odbiorca odbiera komunikat od nadawcy, wykorzystujac
˛ do
tego celu funkcje˛ MPI_Recv.
Niepoprawna kolejność wykonania komunikacji może
spowodować zakleszczenie sie˛ programu.

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja typu punkt-punkt

Komunikat

Komunikat MPI składa sie˛ z koperty i zawartości (treści):


Koperta:
nadawca - identyfikator procesu nadawcy,
odbiorca - identyfikator procesu odbiorcy,
komunikator, w ramach którego realizowana jest
komunikacja,
tag - etykieta danych (dowolna liczba z zakresu od 0 do
MPI_TAG_UB), która może służyć do rozróżniania
komunikatów.
Treść:
bufor - adres, pod którym znajduja˛ sie˛ przesyłane dane,
typ danych - typy określone przez MPI,
count - liczba przesyłanych elementów.

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja typu punkt-punkt

Podstawowe typy danych w MPI

MPI_Datatype Typ C/C++


MPI_CHAR signed char
MPI_SHORT signed short int
MPI_INT signed int
MPI_LONG signed long int
MPI_UNSIGNED_CHAR unsigned char
MPI_UNSIGNED_SHORT unsigned short int
MPI_UNSIGNED unsigned int
MPI_UNSIGNED_LONG unsigned long int
MPI_FLOAT float
MPI_DOUBLE double
MPI_LONG_DOUBLE long double
MPI_BYTE 8 bitów

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja typu punkt-punkt

Wysłanie komunikatu

Do wysłania komunikatu służy funkcja:

int MPI_Send(void *buf, int count, MPI_Datatype datatype,


int dest, int tag, MPI_Comm comm)

Funkcja wysyła count danych typu datatype


(MPI_<DATA_TYPE>) znajdujacych
˛ sie˛ pod adresem buf
do procesu odbiorcy o identyfikatorze dest w ramach
komunikatora comm. Komunikat jest oznaczony etykieta˛
tag.
Niejawnie do procesu odbiorcy wysyłany jest również
identyfikator nadawcy.

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja typu punkt-punkt

Odebranie komunikatu
int MPI_Recv(void *buf, int count, MPI_Datatype datatype,
int src, int tag, MPI_Comm comm,
MPI_Status *status)

Funkcja odbiera maksymalnie count danych typu datatype i


umieszcza je pod adresem buf.
Funkcja czeka na komunikat od nadawcy src oznaczony
etykieta˛ tag. Można również użyć stałej MPI_ANY_TAG jako
argumentu tag. W takim wypadku zostanie odebrany komunikat
o dowolnej etykiecie od procesu src.
Jako src można użyć stałej
˛ MPI_ANY_SOURCE. W takim
wypadku funkcja odbierze komunikat od dowolnego nadawcy.
W argumencie status podajemy MPI_STATUS_IGNORE lub
adres do struktury MPI_Status, w której zostana˛ zapisane
informacje o odebranym komunikacie (liczba odebranych
danych, identyfikator nadawcy, etc.).
Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone
Programowanie współbieżne i rozproszone
Komunikacja typu punkt-punkt

Przykład - komunikacja punkt-punkt

#include <iostream>
#include <mpi.h>
using namespace std;
int main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0)
{ > mpic++ -O3 -o pp pp.cpp
int a = 10;
MPI_Send(&a, 1, MPI_INT, 1, 102, MPI_COMM_WORLD); > mpirun -np 2 ./pp
} Proces 1 odebral liczbe: 10
if (rank == 1)
{
int b;
MPI_Recv(&b, 1, MPI_INT, 0, 102, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
cout << "Proces 1 odebral liczbe: " << b << endl;
}
MPI_Finalize();
return 0;
}

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Komunikacja grupowa

Komunikacja grupowa umożliwia realizacje˛ komunikacji


pomiedzy
˛ wszystkimi procesami w ramach komunikatora.
Jest zazwyczaj wygodniejsza w użyciu i czytelniejsze, niż
realizacja komunikacji przy użyciu pary procesów,
sa˛ zoptymalizowane.
W operacjach grupowych biora˛ udział wszystkie procesy w
ramach komunikatora. To oznacza, że wszystkie proces
musza˛ wywołać ta˛ sama˛ funkcje.
˛
W przypadku komunikacji grupowej komunikaty nie maja˛
etykiet.

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Podstawowe funkcje komunikacji grupowej

MPI_Bcast - wysyłanie jeden do wszystkich,


MPI_Scatter - rozsyłanie jeden do wszystkich,
MPI_Gather - zbieranie wszyscy do jednego,
MPI_Allgather - zbieranie wszyscy do wszystkich,
MPI_Reduce - redukcja wartości wszyscy do jednego,
MPI_Allreduce - redukcja połaczona
˛ z rozgłaszaniem,

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Broadcast

int MPI_Bcast(void *buffer,int count, MPI_Datatype datatype,


int root, MPI_Comm comm)

Służy do wysyłania komunikatu z jednego procesu


(nadawcy) do grupy procesów.
data:
w procesie nadawcy wskaźnik do wysyłanych danych,
w procesach odbiorców wskaźnik do miejsca, w którym
zostana˛ umieszczone dane po ich odebraniu.
count - liczba wysyłanych elementów.
datatype - typ wysyłanych elementów.
root - identyfikator procesu nadawcy wysyłajacego
˛ dane,
comm - komunikator określajacy
˛ procesy, które biora˛ udział
w komunikacji.
Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone
Programowanie współbieżne i rozproszone
Komunikacja grupowa

Broadcast - sposób działania

P0 P1 P2 P3
buffer buffer buffer buffer

0 1 2 3

P0 P1 P2 P3
0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3

buffer buffer buffer buffer

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Przykład - Broadcast

#include <iostream>
#include <mpi.h>
using namespace std;
int main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
> mpirun -np 4 ./bcast
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank); PRZED: rank 0 - ok
PRZED: rank 1 - __
char napis[] = "__"; PRZED: rank 2 - __
if (rank == 0) PRZED: rank 3 - __
{ PO: rank 0 - ok
napis[0] = ’o’; PO: rank 2 - ok
napis[1] = ’k’;
} PO: rank 3 - ok
PO: rank 1 - ok
cout << "PRZED: rank " << rank << " - " << napis << endl;
MPI_Bcast(napis, 3, MPI_CHAR, 0, MPI_COMM_WORLD);
cout << "PO: rank " << rank << " - " << napis << endl;

MPI_Finalize();
return 0;
}

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Scatter
int MPI_Scatter(
void* sendbuf, int sendcount, MPI_Datatype sendtype,
void* recvbuf, int recvcount, MPI_Datatype recvtype,
int root, MPI_Comm comm)

Służy do rozsyłania wektora z jednego procesu (nadawcy) do


grupy procesów.
Proces nadawcy o numerze root dzieli wektor sendbuf na
sendcount elementów typu sendtype i rozsyła te fragmenty
do wszystkich procesów komunikatora comm (również do
samego siebie).
Po wykonaniu operacji w buforach recvbuf poszczególnych
procesów znajduja˛ sie˛ przydzielone im podwektory.
Proces o numerze i odbiera sendcount elementów wektora
poczawszy
˛ od elementu o indeksie i * sendcount.

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Scatter - sposób działania

P0 P1 P2 P3
sendbuf sendbuf sendbuf sendbuf

0 1 2 3

P0 P1 P2 P3
0 1 2 3

recvbuf recvbuf recvbuf recvbuf

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Przykład - Scatter

#include <iostream>
#include <mpi.h>
using namespace std;
int main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank); > mpirun -np 3 ./scatter
int source[] = {0,1,2,3,4,5}; rank 0 - 0 1
int dest[2]; rank 1 - 2 3
MPI_Scatter(source, 2, MPI_INT, rank 2 - 4 5
dest, 2, MPI_INT,
0, MPI_COMM_WORLD);
cout << "rank " << rank << " - "
<< dest[0] << " " << dest[1] << endl;

MPI_Finalize();
return 0;
}

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Gather

int MPI_Gather(
void* sendbuf, int sendcount, MPI_Datatype sendtype,
void* recvbuf, int recvcount, MPI_Datatype recvtype,
int root, MPI_Comm comm)

Odwrotnościa˛ funkcji MPI_Scatter jest MPI_Gather, który


polega na zbieraniu danych przez jeden proces od wszystkich
procesów.
Każdy proces z komunikatora comm wysyła podwektor danych
sendbuf typu sendtype o długości sendcount.
Proces root zbiera te dane i umieszcza w buforze recvbuf.
Dane umieszczane sa˛ w kolejności zgodnej z identyfikatorami
nadawców.

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Gather - sposób działania

P0 P1 P2 P3
sendbuf sendbuf sendbuf sendbuf

0 1 2 3

P0 P1 P2 P3
0 1 2 3

recvbuf recvbuf recvbuf recvbuf

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Przykład - Gather

#include <iostream>
#include <mpi.h>
using namespace std;
int main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int source = rank; > mpirun -np 4 ./gather
int dest[4]; 0 1 2 3
MPI_Gather(&source, 1, MPI_INT,
dest, 1, MPI_INT,
3, MPI_COMM_WORLD);
if (rank == 3)
cout << dest[0] << " " << dest[1] << " "
<< dest[2] << " " << dest[3] << endl;
MPI_Finalize();
return 0;
}

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Allgather

int MPI_Allgather(
void* sendbuf, int sendcount, MPI_Datatype sendtype,
void* recvbuf, int recvcount, MPI_Datatype recvtype,
MPI_Comm comm)

P0 P1 P2 P3
sendbuf sendbuf sendbuf sendbuf

0 1 2 3

P0 P1 P2 P3
0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3

recvbuf recvbuf recvbuf recvbuf

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Reduce

int MPI_Reduce(void* sendbuf, void* recbuf, int count,


MPI_Datatype type, MPI_Op op, int root, MPI_Comm comm)

Funkcja zbiera elementy znajdujace


˛ sie˛ w procesach z grupy
comm w wektorze sendbuf i wykonuje na nich operacje˛ op.
Wynik zapisywany jest do wektora recbuf w procesie o
identyfikatorze root.

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Reduce - sposób działania

0P P 1 P
2 P
3
sendbuf sendbuf sendbuf sendbuf

0 1 2 3

+ MPI_SUM

P0 P1 P2 P3
6

recvbuf recvbuf recvbuf recvbuf

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Reduce - podstawowe operacje

Stała MPI Operacja Typ


MPI_MAX maksimum int, float
MPI_MIN minimum int, float
MPI_SUM suma int, float
MPI_PROD iloczyn int, float
MPI_LAND logiczne AND int
MPI_BAND bitowe AND int, MPI_BYTE
MPI_LOR logiczne OR int
MPI_BOR bitowe OR int, MPI_BYTE
MPI_LXOR logiczne XOR int
MPI_BXOR bitowe XOR int, MPI_BYTE

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Przykład - Reduce

#include <iostream>
#include <mpi.h>
using namespace std;
int main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);

int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
> mpirun -np 4 ./reduce
int source = rank; Suma: 6
int sum;
MPI_Reduce(&source, &sum, 1, MPI_INT,
MPI_SUM, 2, MPI_COMM_WORLD);
if (rank == 2)
cout << "Suma: " << sum << endl;
MPI_Finalize();
return 0;
}

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone


Programowanie współbieżne i rozproszone
Komunikacja grupowa

Allreduce
int MPI_Allreduce(void* sendbuf, void* recbuf, int count,
MPI_Datatype type, int op, MPI_Comm comm)

P0 P 1 P2 P3
sendbuf sendbuf sendbuf sendbuf

0 1 2 3

+ MPI_SUM

P0 P1 P2 P3
6 6 6 6

recvbuf recvbuf recvbuf recvbuf

Dr inż. Tomasz Olas Programowanie współbieżne i rozproszone

You might also like