Stručný přehled vlastností a funkcí MPI

(Základním podkladem pro tento přehled byla osmá kapitola z knihy Iana Fostera Designing and Building Parallel Programs)

Poznámka: Kromě příkladů není používána přesná syntaxe funkcí - důraz je na srozumitelnost.

1. Charakteristika MPI

- v PVM jde naprogramovat "skoro cokoliv", ale dá to velkou práci a program pak nejspíš nebude přenositelný,

- dominantní aplikací pro MPI jsou numerické výpočty s regulárními daty (vektory či matice s číselnými prvky), přičemž pro takové aplikace je programování relativně pohodlné a program je dobře přenositelný do jiné instalace MPI.

2. Základní funkce MPI

Je jich jenom 6, přičemž už umožňují napsat jednodušší aplikaci. První čtyři z nich je třeba použít v každém MPI programu. Všechny funkce vrací celočíselný kód úspěšnosti provedené operace, přičemž symbolická hodnota MPI_SUCCESS znamená úspěch. Přehled základních funkcí v C-syntaxi:

Další funkce už nepatří do kategorie "šesti základních", ale uvedeme je zde kvůli úplnosti souboru základních operací pro asynchronní message-passing v MPI:


3. Globální operace MPI

Globální operace jsou operace, do kterých jsou zapojeny všechny procesy patřídí do téhož "komunikačního světa" (tj. jedním parametrem funkcí pro globální operace je příslušný komunikátor). Funkci globální operace volají všechny zúčastněné procesy (což je pochopitelné, protože typicky procesy běží podle téhož programu), přičemž jejich činnost se v obecném případě liší podle čísla procesu. Globální operace jsou "ušité" na manipulace s regulárními datovými strukturami, konkrétně s homogenními vektory a maticemi.

Globální operace v PVM nejsou (kromě broadcastu) a musely by se pracně rozepsat do posloupnosti operací send() a receive(). Globální operace MPI lze rozdělit na tři skupiny - synchronizace, přesuny dat a redukční operace.

3.1 Synchronizace

Každý komunikátor mj. realizuje bariéru, na které se mohou všechny jeho procesy synchronizovat voláním funkce

int MPI_Barrier (MPI_Comm comm)

Volání této funkce je tedy blokující a výpočet každého procesu pokračuje následujícím příkazem až poté, kdy se na bariéře "sejdou" všechny procesy patřící do "komunikačního světa" comm.

3.2 Přesuny dat

Jedná se o operace s charakterem broadcastu, shromáždění či rozptýlení dat a tzv. redukční oprace.

3.3 Redukční operace

Redukční operace má M operandů umístěných ve vstupních bufferech komunikujících procesů. Výsledek operace se zapisuje do výstupního bufferu buď jednoho určeného procesu (root) nebo všech procesů.


4. Komunikátory

Komunikátor je interní objekt MPI (typ MPI_comm, jedná se o typ tzv. "handle", čili jakéhosi zobecněného ukazatele reprezentujícího komunikátor).
Komunikátor reprezentuje skupinu komunikujících procesů a komunikační kontext této skupiny (viz třeba funkci MPI_Barrier() z předchozí kapitoly).
Komunikátor slouží jako prostředek pro modulární členění programu (tj. usnadňuje vytváření knihovních funkcí, speciálně pro výpočet knihovní finkce se vyrobí "extra" komunikátor jako duplikát existujícího komunikátoru a "dosadí se" do volání knihovní funkce).
Dále komunikátor slouží pro paralelní členění programu, či jinak řečeno pro realizaci modelu MPMD (funkční paralelismus), kdy se procesy aplikace rozdělí na skupiny (reprezentované různými komunikátory) a každá skupina "dělá něco jiného" a její procesy "se vybavují jen mezi sebou". Čili uvnitř skupiny procesů (komunikátor) funguje datový paralelismus, kdežto mezi skupinami procesů funguje funkční paralelismus.
Základní funkce nad komunikátory jsou (podrobnosti viz literatura):

Poznámka: Pro jednoduché aplikace (v kategorii semestrálky z PPR, nevytváří se funkčně odlišné skupiny procesů) lze na komunikátory "zapomenout". Všechny procesy aplikace jsou reprezentovány základním (implicitně vytvořeným) komunikátorem se symbolickým označením MPI_COMM_WORLD. Pokud tuto hodnotu systematicky dosazujeme za parametr comm v komunikačních funkcích, probíhá komunikace vždy v "komunikačním světě" všech procesů aplikace.

5. Datové typy pro komunikaci

Jak již bylo řečeno, MPI využívá v komunikačních operacích buffer, který je "netypovaný" (tj. ukazatel na buffer je typu void*). Buffer jde v rámci komunikační operace "překrýt" přes libovolná data v programu. Typ (a počet) datových prvků "přes které buffer leží" se zadává jako jeden z parametrů komunikační operace - viz třeba MPI_Send() dříve v části 2. K tomuto účelu zavádí MPI "primitivní typy", které zhruba odpovídají primitivním typům jazyka C (MPI_INT, MPI_DOUBLE, atd.). Aby bylo možné jednou komunikační operací vyslat i složitěji strukturovaná data, zavádí MPI tzv. "odvozené datové typy", tj. typy, které lze "poskládat" z primitivních či (již dříve) odvozených typů. Odvozené typy jsou ve třech kategoriích (contiguous, vector, indexed).
Základní funkce využitelné pro práci s odvozenými typy (podrobnosti viz literatura) jsou tyto:

Příklad použití odvozeného typu v programu:

float data [1024]; /*definuje data v programu */
MPI_Datatype floatype; /*definuje handle nově vytvářeného typu */
MPI_Type_vector (10, 1, 32, MPI_FLOAT, &floattype); /* dynamicky vytváří nový typ floattype (odvozený od základního typu MPI_FLOAT), což je 10 bloků obsahujících jen 1 položku float, mezi bloky je "mezera" 32 položek float*/
...
MPI_Send (data, 1, floattype, dest, tag, MPI_Comm_world); /*vlastní operace vysílání zprávy */
...
MPI_Type_free (&floattype); /*dynamická likvidace typu */

Poznámka: Pro jednoduché aplikace (v kategorii semestrálky z PPR) lze na odvozené datové typy "zapomenout" a používat jen primitivní MPI typy ( komunikační operace navíc dovolují přímo použít i pole položek primitivního typu).

 

St.R. 20.11.2001