background image

10. MPI. Definicja standardu

10. MPI. Definicja standardu

Cz

Cz

ęść

ęść

II

II

Lesław Sieniawski © 2010

background image

Grupy proces

Grupy proces

ó

ó

w

w

Grupa

– uporz

ą

dkowany zbiór procesów 

– procesy identyfikowane przez indeksy (0+)
– grupa jako obiekt posiada własny identyfikator
– skojarzona zawsze z obiektem komunikatora
– predefiniowana grupa pusta 

MPI_GROUP_EMPTY

int MPI_Comm_group(MPI_Commm *comm,\
MPI_Group *group)

Tworzenie kopii grupy okre

ś

lonej komunikatorem 

comm

int MPI_Group_size(MPI_Group *group,\
int *size)

obliczenie liczby procesów nale

Ŝą

cych do grupy 

group

, wynik w

size

background image

Grupy proces

Grupy proces

ó

ó

w (2)

w (2)

Operacje mnogo

ś

ciowe

na grupach (suma, 

iloczyn, ró

Ŝ

nica):

int MPI_Group_

xxxx

(MPI_Group A,\

MPI_Group

B, MPI_Group *wynik)

gdzie

– xxxx

union

– suma grup, A B

– xxxx

intersection

– iloczyn grup, A 

B

– xxxx

difference

– ró

Ŝ

nica grup, A B

background image

Grupy proces

Grupy proces

ó

ó

w (3)

w (3)

int MPI_Group_incl(MPI_Group group,\

int n, int *ranks,\

MPI_Group newgroup) 

utworzenie nowej grupy

newgroup

przez 

doł

ą

czenie nowych procesów do grupy

group

n

= liczba dodawanych procesów 

ranks

= tablica zawieraj

ą

ca ID dodawanych procesów

background image

Grupy proces

Grupy proces

ó

ó

w (4)

w (4)

int MPI_Group_translate_ranks \

(MPI_Group group1, int n,\
int *
ranks1, MPI_Group group2,\
int *
ranks2) 

Okre

ś

lenie numeracji procesów wewn

ą

trz grupy 

group2

utworzonej z grupy 

group1

;  liczba 

n

-

liczebno

ść

nowej grupy, 

ranks1

ranks2

- tablice 

identyfikatorów odpowiednio pierwszej i drugiej 
grupy procesów (rozmiary tablic identyczne)

int MPI_Group_free(MPI_Group group)

usuni

ę

cie grupy o identyfikatorze 

group

background image

#include <mpi.h>

#include <stdio.h>

/* oprac. LS na podstawie
Jedrzej.Ulasiewicz.staff.iiar.pwr.wroc.pl/Progr-Wspol-i-Rozprosz/wyklad/MPI14.pdf
*/

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

MPI_Init(&argc,&argv); 
MPI_Group wszystkie, nieparzyste, parzyste;

int i, p, Nparz, procesy0[8], procesy1[8], Lparzystych, Nrprocesu;

MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_group(MPI_COMM_WORLD, &wszystkie);

// procesy z MPI_COMM_WORLD o numerach parzystych sa umieszczane w nowej grupie
Nparz = (p+1)/2; 

//zero jest parzyste!

for (i=0; i<Nparz; i++) { procesy0[i] = 2*i; };

MPI_Group_incl(wszystkie, Nparz, procesy0, &parzyste);
MPI_Comm_rank(MPI_COMM_WORLD, &Nrprocesu);

if (Nrprocesu==0)

printf("Tworzenie grupy procesów o nrach parzystych\n");

MPI_Group_size(parzyste, &Lparzystych);

printf("Liczba procesów w nowej grupie = %d\n", Lparzystych);

MPI_Group_translate_ranks(wszystkie, Nparz, procesy0, parzyste, procesy1);

printf("Pierwotny nr   Nowy nr\n");
for (i=0; i<Nparz; i++)

printf("%12d   %7d\n", procesy0[i], procesy1[i]);

}

MPI_Finalize();

return 0;

}

Przyk

Przyk

ł

ł

ad #1: Tworzenie grupy proces

ad #1: Tworzenie grupy proces

ó

ó

w

w

background image

[root@p205 openMPI]# 

mpicc selParz.c -o selParz

[root@p205 openMPI]# 

mpirun -n 4 --mca btl tcp,self \

selParz

Tworzenie grupy procesów o nrach parzystych

Liczba procesów w nowej grupie = 2

Pierwotny nr   Nowy nr

0         0

2         1

[root@p205 openMPI]# 

mpirun -n 7 --mca btl tcp,self \

selParz

Tworzenie grupy procesów o nrach parzystych

Liczba procesów w nowej grupie = 4

Pierwotny nr   Nowy nr

0         0

2         1

4         2

6         3

[root@p205 openMPI]#

Przyk

Przyk

ł

ł

ad #1: Kompilacja i uruchomienie

ad #1: Kompilacja i uruchomienie

background image

Komunikatory

Komunikatory

Komunikator

– obiekt zawieraj

ą

cy grup

ę

procesów, które mog

ą

si

ę

wzajemnie 

komunikowa

ć

– Dost

ę

pny tylko poprzez swój ID

– Komunikaty MPI wskazuj

ą

komunikator

Perspektywa programisty

grupa 

komunikator

Grupa – lista procesów słu

Ŝą

ca do utworzenia 

komunikatora („stadium po

ś

rednie”)

background image

Operacje na komunikatorach

Operacje na komunikatorach

int MPI_Comm_dup(MPI_Comm comm,\

MPI_Comm *newcomm)

utworzenie komunikatora 

newcomm

jako duplikatu 

komunikatora 

comm

, zawieraj

ą

cego te same procesy

int MPI_Comm_create(MPI_Comm comm,\

MPI_Group newgroup, MPI_Comm *newcomm)

utworzenie komunikatora 

newcomm

z grupy procesów 

okre

ś

lonej identyfikatorem 

newgroup

nale

Ŝą

cych do

komunikatora 

ź

ródłowego 

comm

background image

Operacje na komunikatorach (2)

Operacje na komunikatorach (2)

int MPI_Comm_split(MPI_Comm comm,\

int color, int key, MPI_Comm *newcomm)

utworzenie komunikatora 

newcomm

przez podział zwi

ą

zanej z nim 

grupy istniej

ą

cego komunikatora na rozł

ą

czne podgrupy, 

color

- parametr klasyfikuj

ą

cy procesy wł

ą

czane do nowego 

komunikatora, 

key

– priorytet; liczba nowych komunikatorów = 

liczebno

ść

zbioru ró

Ŝ

nych warto

ś

ci parametru 

color

[

ź

ródło: jedrzej.ulasiewicz.staff.iiar.pwr.wroc.pl/Progr-Wspol-i-Rozprosz/wyklad/MPI14.pdf

background image

Operacje na komunikatorach (3)

Operacje na komunikatorach (3)

int MPI_Comm_free(MPI_Comm comm)

usuni

ę

cie komunikatora o identyfikatorze 

comm

background image

Organizacja proces

Organizacja proces

ó

ó

w

w

w grupy i komunikatory

w grupy i komunikatory

Dynamiczny charakter

grup i komunikatorów -

tworzenie i usuwanie w czasie wykonywania 
programu

Proces

element dowolnej liczby grup i komunika-

torów

40+ procedur

obsługi grup i komunikatorów

background image

Organizacja proces

Organizacja proces

ó

ó

w (2)

w (2)

Typowe post

ę

powanie

:

1.

Utworzenie globalnej grupy z komunikatora 

MPI_COMM_WORLD

za pomoc

ą

procedury 

MPI_Comm_group

pobranie jej ID

2.

Zbudowanie nowej grupy jako podzbioru procesów grupy 
globalnej (procedura 

MPI_Group_incl

)

3.

Utworzenie komunikatora z nowej grupy (procedura 

MPI_Comm_create

)

4.

Okre

ś

lenie ID (rank) procesów w nowym komunikatorze 

(procedura 

MPI_Comm_rank

)

5.

Przeprowadzi

ć

komunikacj

ę

(ró

Ŝ

ne procedury 

przekazywania komunikatów)

6.

Usun

ąć

nowy komunikator (

MPI_Comm_free

) i now

ą

grup

ę

(

MPI_Group_free

)

background image

Organizacja

Organizacja

proces

proces

ó

ó

w (3)

w (3)

Cel

Cel

:

-

tworzenie grup procesów 

do realizacji podobnych 
funkcji
-

umo

Ŝ

liwienie kolektywnej

komunikacji

w podzbiorze 

procesów
-

umo

Ŝ

liwienie budowania

wirtualnych topologii

procesów
-

zapewnienie bezpiecznej 

komunikacji

[

ź

ródło: https://computing.llnl.gov/tutorials/mpi/]

„Lokalne” ID procesów

background image

Komunikacja punkt

Komunikacja punkt

-

-

punkt

punkt

Od
b

ie

ra

n

ie

 

W
y

s

y

ła

n

ie

MPI_Irecv(buffer, count, type, source, 

tag, comm, request) 

Nieblokuj

ą

ce

MPI_Recv(buffer, count, type, source, 

tag, comm, status)

Blokuj

ą

ce

MPI_Isend(buffer, count, type, dest, 

tag, comm, request) 

Nieblokuj

ą

ce

MPI_Send(buffer, count, type, dest, 

tag, comm)

Blokuj

ą

ce

Wywołanie procedury

Rodzaj operacji

background image

Komunikacja punkt

Komunikacja punkt

-

-

punkt (2)

punkt (2)

Obja

ś

nienie parametrów procedur

buffer

– wska

ź

nik bufora danych wysyłanych/odbieranych

count

– liczba elementów danych wskazanego typu

type

– wskazanie typu danych w buforze 

tabela

dest

– ID procesu, do którego komunkat ma by

ć

przekazany

source

– ID procesu, który nadał komunikat, lub 

MPI_ANY_SOURCE

gdy nadawca nie ma znaczenia

tag

– dowolna nieujemna liczba całkowita identyfikuj

ą

ca rodzaj 

komunikatu lub 

MPI_ANY_TAG

, gdy rodzaj nie ma znaczenia;

comm

– ID komunikatora, którego dotyczy ID nadawcy lub odbiorcy, 

lub 

MPI_COMM_WORLD

, gdy dotyczy wszystkich procesów

status

(dla operacji odbierania) wska

ź

nik do struktury typu 

MPI_Status

request

(dla operacji nieblokuj

ą

cych) – wska

ź

nik do struktury typu 

MPI_Request

przechowuj

ą

cej numer operacji, dla ewentualnego 

ź

niejszego wykorzystania np. dla zbadania, czy operacja si

ę

zako

ń

czyła (procedura typu 

Wait

)

background image

Typy danych w komunikatach

Typy danych w komunikatach

Dane spakowane/rozpakowane za pomoc

ą

MPI_Pack()

MPI_Unpack

MPI_PACKED 

8 binary digits 

MPI_BYTE 

long double 

MPI_LONG_DOUBLE 

double 

MPI_DOUBLE 

float 

MPI_FLOAT 

unsigned long int 

MPI_UNSIGNED_LONG 

unsigned int 

MPI_UNSIGNED 

unsigned short int 

MPI_UNSIGNED_SHORT 

unsigned char 

MPI_UNSIGNED_CHAR 

signed long int 

MPI_LONG 

signed int 

MPI_INT 

signed short int 

MPI_SHORT 

signed char 

MPI_CHAR 

Definicja w j

ę

zyku C

Typ danych MPI

[

ź

d

ło

h

tt

p

s

:/

/c

o

m

p

u

ti

n

g

.l

ln

l.

g

o

v

/t

u

to

ri

a

ls

/m

p

i/

]

background image

Wybrane procedury komunikacji punkt

Wybrane procedury komunikacji punkt

-

-

punkt

punkt

int MPI_Send(void *buf, int count,\

MPI_Datatype datatype, int dest, int tag,\

MPI_Comm comm)

[

ź

ródło: jedrzej.ulasiewicz.staff.iiar.pwr.wroc.pl/Progr-Wspol-i-Rozprosz/wyklad/MPI14.pdf

(Wysyłanie blokuj

ą

ce)

background image

Wybrane procedury komunikacji punkt

Wybrane procedury komunikacji punkt

-

-

punkt (2)

punkt (2)

int MPI_Recv(void *buf, int count,\

MPI_Datatype datatype, int srce, int tag,\

MPI_Comm comm, MPI_Status *status)

(Odbieranie blokuj

ą

ce)

[

ź

ródło: jedrzej.ulasiewicz.staff.iiar.pwr.wroc.pl/Progr-Wspol-i-Rozprosz/wyklad/MPI14.pdf

background image

#include "mpi.h"

#include <stdio.h>

int main(int argc, char *argv) 

{

int numtasks, rank, dest, source, rc, count, tag=1;  

char inmsg, outmsg='x';

MPI_Status Stat;

MPI_Init(&argc,&argv);

MPI_Comm_size(MPI_COMM_WORLD, &numtasks);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if (rank == 0) {

dest = 1;

source = 1;

rc = MPI_Send(&outmsg, 1, MPI_CHAR, dest,   tag, MPI_COMM_WORLD);

rc = MPI_Recv(&inmsg,  1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat);

else if (rank == 1) {

dest = 0;

source = 0;

rc = MPI_Recv(&inmsg,  1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat);

rc = MPI_Send(&outmsg, 1, MPI_CHAR, dest, tag, MPI_COMM_WORLD);

}

rc = MPI_Get_count(&Stat, MPI_CHAR, &count);

printf("Task %d: Received %d char(s) from task %d with tag %d \n", rank,\
count, Stat.MPI_SOURCE, Stat.MPI_TAG);

MPI_Finalize();

}

Program #2. Ping

Program #2. Ping

-

-

pong

pong

Proces 

0

wysyła ‘x’ do procesu 

1

i czeka na odzew

[

ź

ródło: https://computing.llnl.gov/tutorials/mpi/]

background image

[root@p205 openMPI]# 

mpirun -n 2 --mca btl tcp,self \

ping-pong

Task 1: Received 1 char(s) from task 0 with tag 1

Task 0: Received 1 char(s) from task 1 with tag 1

[root@p205 openMPI]# 

Przyk

Przyk

ł

ł

ad 

ad 

#2:

#2:

Kompilacja i uruchomienie

Kompilacja i uruchomienie

background image

Synchronizacja komunikacji punkt

Synchronizacja komunikacji punkt

-

-

punkt

punkt

Ze wzgl

ę

du na współdziałanie

nadawcy 

i odbiorcy:

– Synchroniczna

: oczekiwanie nadawcy na 

przyst

ą

pienie odbiorcy do odbierania komunikatu

– Asynchroniczna

: z umieszczeniem przez nadawc

ę

komunikatu w buforze, gdy odbiorca nie jest 
gotowy do odbierania

Ze wzgl

ę

du na blokowanie

procesu:

– Blokuj

ą

ca

: wyj

ś

cie (powrót) z funkcji 

komunikacyjnej dopiero po jej zako

ń

czeniu

– Nieblokuj

ą

ca

: powrót natychmiastowy

background image

Synchronizacja komunikacji punkt

Synchronizacja komunikacji punkt

-

-

punkt (2)

punkt (2)

Obsługa buforowania

w komunikacji asynchronicznej:

int MPI_Buffer_attach(void *buffer,\

int size)

utworzenie bufora, 

size

>= rozmiar pojedynczego 

komunikatu

int MPI_Buffer_detach(void *buffer,\

int size)

zwolnienie bufora wskazanego przez 

buffer

o rozmiarze 

size

background image

Kombinacje tryb

Kombinacje tryb

ó

ó

wsp

wsp

ó

ó

ł

ł

dzia

dzia

ł

ł

ania i buforowania

ania i buforowania

Bez blokowania (natychmiastowy)

Immediate (

I

)

Nieblokuj

ą

cy 

Nadawanie wymaga wcze

ś

niejszej 

gotowo

ś

ci do odbioru

Ready (

R

Przygotowany 

Komunikacja spotkaniowa

Synchronous
(

S

)

Synchroniczny

Umieszczenie komunikatu we 
wcze

ś

niej utworzonym buforze

Buffered (

B

)

Buforowany

Opis sposobu realizacji

Nazwa w j

ę

z. 

angielskim 

i kod nazwy

Nazwa w j

ę

z. 

polskim

np. MPI_Ssend

background image

P

P

-

-

P: Tryb synchroniczny

P: Tryb synchroniczny

int MPI_Ssend(*buffer, count,\

datatype, dest, tag, comm, ierr)

blokada nadawcy do czasu zako

ń

czenia odbioru

[

ź

ródło: jedrzej.ulasiewicz.staff.iiar.pwr.wroc.pl/Progr-Wspol-i-Rozprosz/wyklad/MPI14.pdf

background image

P

P

-

-

P: Tryb buforowany

P: Tryb buforowany

int MPI_Bsend(void *buffer, int count,\

MPI_Datatype datatype, int dest, int tag,\

MPI_Comm comm, int ierr)

buforowanie komunikatu przez nadawc

ę

[

ź

ródło: jedrzej.ulasiewicz.staff.iiar.pwr.wroc.pl/Progr-Wspol-i-Rozprosz/wyklad/MPI14.pdf

background image

P

P

-

-

P: Tryb buforowany nieblokuj

P: Tryb buforowany nieblokuj

ą

ą

cy

cy

int MPI_Ibsend(void *buffer,\

int count, MPI_Datatype datatype,\

int dest, int tag, MPI_Comm comm,\

MPI_Request *request)

Znaczenie parametrów – jak poprzednio; 

request

– identyfikator rozpocz

ę

tej operacji, do 

wykorzystania przez procedury typu Wait

background image

P

P

-

-

P: Tryb przygotowany nieblokuj

P: Tryb przygotowany nieblokuj

ą

ą

cy

cy

int MPI_Irsend(*buffer, count,\

datatype, dest, tag, comm)

operacja wysłania komunikatu wymaga wcze

ś

niejszej 

gotowo

ś

ci odbiorcy (inaczej 

ą

d)

[

ź

ródło: jedrzej.ulasiewicz.staff.iiar.pwr.wroc.pl/Progr-Wspol-i-Rozprosz/wyklad/MPI14.pdf

background image

Ko

Ko

ń

ń

czenie operacji nieblokuj

czenie operacji nieblokuj

ą

ą

cych

cych

MPI_Wait(MPI_Request *request,\

MPI_Status status)

blokowanie procesu

wywołuj

ą

cego te procedur

ę

do 

chwili, gdy operacja wskazywana przez ID 

request

zostanie zako

ń

czona (dla wysyłania oznacza to, 

Ŝ

bufor mo

Ŝ

e by

ć

u

Ŝ

yty ponownie). 

Po wykonaniu procedury 

MPI_Wait 

zmienna 

request

zawiera warto

ść

MPI_REQUEST_NULL

MPI_Waitany, MPI_Waitall, MPI_Waitsome 

wersje procedury blokuj

ą

ce proces a

Ŝ

zako

ń

czy si

ę

jakalokwiek 

operacja, wszystkie operacje lub niektóre z nich

background image

Ko

Ko

ń

ń

czenie operacji nieblokuj

czenie operacji nieblokuj

ą

ą

cych (2)

cych (2)

MPI_Test(MPI_Request *request,\

int *flag, MPI_Status *status)

nieblokuj

ą

ce badanie

zako

ń

czenia operacji wskazanej 

przez ID 

request

flag

=

TRUE

gdy operacja 

zako

ń

czyła si

ę

flag

FALSE

w przeciwnym razie

MPI_Cancel(MPI_Request *request)

anulowanie

operacji nieblokuj

ą

cej wskazanej przez ID 

request

background image

Testowanie operacji nieblokuj

Testowanie operacji nieblokuj

ą

ą

cych

cych

MPI_Iprobe(int source, int tag,\

MPI_Comm comm, int *flag,\

MPI_Status *status)

badanie 

czy w komunikatorze 

comm

jest wiadomo

ść

nadana przez proces 

source

i posiadaj

ą

ca etykiet

ę

równ

ą

tag

, dla której warto

ść

zmiennej 

flag

jest 

równa 

TRUE

background image

Wysy

Wysy

ł

ł

anie z odbieraniem

anie z odbieraniem

MPI_Sendrecv(

void *sendBuf, int sendCnt,\

MPI_Datatype sendType,int dest,int sendTag,\

void *recvBuf, int recvCnt,\

MPI_Datatype recvType,int srce,int recvTag,\

MPI_Comm comm, MPI_Status *status) 

wysłanie komunikatu od

send

do

recv

i oczekiwanie na odpowied

ź

Elementy nazw: 

send

recv

– odpowiednio funkcje nadawania i odbioru, 

dest

srce

- odpowiednio ID procesu odbiorcy i nadawcy, 

Cnt

– liczba, 

Type

– typ danych w komunikacie, 

Tag

– etykieta, 

comm

– komunikator, 

status

– status wykonania

background image

Przyk

Przyk

ł

ł

ad 

ad 

#3:

#3:

Karuzela proces

Karuzela proces

ó

ó

w

w

0

0

2

2

1

1

Ka

Ŝ

dy proces przekazuje swój ID 

s

ą

siadowi z lewej strony, 

i otrzymuje ID swojego prawego 
s

ą

siada.

background image

#include <mpi.h>

#include <stdio.h>

/* ------------------------------------------------------------------------

karuzela.c - przekazywanie komunikatow w pierscieniu procesow

Proces #i otrzyma komunikat z numerem swojego prawego sasiada, tj. i+1

Oprac. LS na podstawie http://mpi.deino.net/mpi_functions/MPI_Sendrecv.html

--------------------------------------------------------------------------*/

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

{

int wlasnyID, Lprocesow, lewySasiad, prawySasiad;

char buforSend[5], buforRecv[5];

MPI_Status status;

MPI_Init(&argc,&argv);

// identyfikacja srodowiska

MPI_Comm_size(MPI_COMM_WORLD, &Lprocesow);

MPI_Comm_rank(MPI_COMM_WORLD, &wlasnyID);

// przygotowanie odpowiedzi w postaci tekstowej – wlasny ID procesu

sprintf(buforSend,"%d", wlasnyID);    

// okreslenie ID sasiadow

prawySasiad = (wlasnyID + 1) % Lprocesow;

lewySasiad = wlasnyID - 1;

if (lewySasiad < 0) lewySasiad = Lprocesow - 1;

// nadanie komunikatu do sasiada z lewej strony i odebranie komunikatu od tego z prawej

// UWAGA: etykiety musza byc zgodne!

MPI_Sendrecv(\

buforSend, 5, MPI_CHAR, lewySasiad,  11,buforRecv, 5, MPI_CHAR, prawySasiad, 11,\

MPI_COMM_WORLD, &status);

// raportowanie otrzymanych komunikatow

printf("Tu proces %d. Sasiad z prawej strony ma nr %s\n", wlasnyID, buforRecv);

MPI_Finalize();

return 0;

}

Program #3. Karuzela

Program #3. Karuzela

background image

[root@p205 openMPI]# 

mpicc karuzela.c –o karuzela

[root@p205 openMPI]#

mpirun –n 4 -–mca btl tcp,self \

karuzela

Tu proces 0. Sasiad z prawej strony ma nr 1

Tu proces 3. Sasiad z prawej strony ma nr 0

Tu proces 1. Sasiad z prawej strony ma nr 2

Tu proces 2. Sasiad z prawej strony ma nr 3

[root@p205 openMPI]#

Przyk

Przyk

ł

ł

ad 

ad 

#3:

#3:

Kompilacja i uruchomienie

Kompilacja i uruchomienie

background image

Wszystkie zademonstrowane tu przykłady 

wykonano na maszynie o architekturze 
SMP (tj. wieloprocesorowej  z pami

ę

ci

ą

współdzielon

ą

)