Üzenetátadási felület

MPI

logó
Alapadatok

fejlesztő MPI fórum
Jelenlegi  verzió 4.0 verzió (PDF; 4,3 MB)
(2021. június 9.)
operációs rendszer Linux , Unix , Microsoft Windows NT , macOS
kategória API
Németül beszélő Nem
MPI webhely

Az Message Passing Interface ( MPI ) egy szabvány, amely leírja az üzenetek cseréjét az elosztott számítógépes rendszerek párhuzamos számításai során. Meghatározza a műveletek és szemantikájuk gyűjteményét, azaz egy programozási felületet , de nincs külön protokoll és nincs megvalósítás.

Az MPI alkalmazás általában több , egymással kommunikáló folyamatból áll, amelyek párhuzamosan indulnak a program végrehajtásának elején. Mindezek a folyamatok együtt dolgoznak egy problémán, és olyan üzeneteket használnak az adatcseréhez, amelyeket kifejezetten egyik folyamatról a másikra küldenek. Ennek az elvnek az egyik előnye, hogy az üzenetek cseréje a számítógép határain túl is működik. A párhuzamos MPI programok így futtathatóak mind PC- fürtökön (itt üzenetváltás pl. TCP- n keresztül ), mind dedikált párhuzamos számítógépeken (itt az üzenetek cseréje nagysebességű hálózaton, például InfiniBand vagy Myrinet, vagy a megosztott főhálózaton keresztül történik) memória ).

történelem

1992-ben az MPI 1.0 szabvány fejlesztése tervezetekkel kezdődött (1992. november, 1993. február, 1993. november). A kiindulópont olyan régebbi kommunikációs könyvtárak voltak, mint a PVM, a PARMACS, a P4, a Chameleon és a Zipcode. A szabvány 1994. május 5-én jelent meg

  • Pont-pont kommunikáció
  • globális kommunikáció
  • Csoportok, kontextus és kommunikátorok
  • Környéke
  • Profilozási felület
  • A C és a Fortran 77 nyelvintegrációja

1995 júniusában a hibákat kijavították az MPI 1.1-vel.

1997. július 18-án megjelent az MPI 1.2 stabil verzió, amely a további hibajavítások mellett lehetővé teszi a verzió azonosítását. MPI-1 néven is ismert.

2008. május 30-án megjelent az MPI 1.3 további hibajavításokkal és pontosításokkal.

Az 1.2 verzióval egyidejűleg 1997. július 18-án elfogadták az MPI 2.0 szabványt. Ez MPI-2 néven is ismert, és a következő kiterjesztéseket tartalmazza:

  • párhuzamos fájl bemenet / kimenet
  • dinamikus folyamatmenedzsment
  • Hozzáférés más folyamatok memóriájához
  • a C ++ és a Fortran 90 további nyelvi integrációja

2008. június 23-án a korábban különálló MPI-1 és MPI-2 részeket egy közös dokumentumba egyesítették, és MPI 2.1 néven tették közzé. Az MPI Standard 2.2 verzió 2009. szeptember 4-én kelt, és további fejlesztéseket és kisebb fejlesztéseket tartalmaz.

2012. szeptember 21-én az MPI Fórum közzétette az MPI-3-at, amely olyan új funkciókat tartalmaz, mint a nem blokkoló kollektívák, a továbbfejlesztett egyirányú kommunikációs modell (RMA, Remote Memory Access), egy új Fortran interfész, a topográfiával kapcsolatos kommunikáció és nem párhuzamos bemenet és kimenet blokkolása.

Az MPI-4 2021. június 9-én jelent meg. A fő újítások a funkcióinterfészek, amelyek nagyobb értéktartománnyal támogatják a paramétereket. Korábban a megadott 32 bites adattípus miatt olyan alapvető paraméterek, mint a B. a közlendő adatelemek száma alig több mint kétmilliárdra korlátozódik. A kitartó kollektívák lehetőséget kínálnak az ismételt kommunikáció optimalizálására, és a már meglévő kollektív műveletekkel ellentétben bármilyen sorrendben végrehajthatók. Ezenkívül sok ponton javult a hibakezelés, és új munkamenet-modell került bevezetésre az MPI által kezelt erőforrások dinamikus felhasználása érdekében.

Az egyik fő fejlesztő Bill Gropp .

Pont-pont kommunikáció

A kommunikáció legalapvetőbb típusa két folyamat között zajlik: egy küldési folyamat információt továbbít a fogadó folyamat felé. Az MPI-ben ezeket az információkat úgynevezett üzenetekbe csomagolják a paraméterekkel buffer, countés datatypeaz alábbiakban leírják őket. Minden küldési művelethez megfelelő fogadó műveletnek kell léteznie. Mivel a feldolgozási műveletek puszta szekvenciája nem mindig elegendő párhuzamos alkalmazásoknál, az MPI is felajánlja a tagparamétert - csak akkor, ha ez az érték azonos a küldés és fogadás műveleteknél, akkor mindkettő összeillik.

Küldés és fogadás blokkolása

A pont-pont kommunikáció legegyszerűbb műveletei a küldés és fogadás :

int MPI_Send (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
  • buf : Mutató az elküldési pufferhez
  • count : a küldési pufferben lévő elemek száma
  • adattípus : adatok típusát az elemek a küldési pufferben
  • dest : A célfolyamat rangja
  • tag : címke az üzenet
  • comm : a folyamatcsoport kommunikátora
int MPI_Recv (void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status* status)
  • buf: Mutató egy megfelelő méretű vételi pufferhez
  • count: Az elemek száma a vételi pufferben
  • datatype: A vételi puffer elemeinek adattípusa
  • source: A forrásfolyamat rangja ( source=MPI_ANY_SOURCEbármely folyamat megkapja)
  • tag: az üzenet várható megjelölése ( tag=MPI_ANY_TAGminden üzenet érkezik)
  • comm: A folyamatcsoport kommunikátora
  • status: Olyan állapotstruktúra mutatója, amelyben a fogadott üzenetre vonatkozó információkat tárolni kell

A két művelet blokkoló és aszinkron . Azt jelenti:

  • MPI_Recva társított MPI_Sendindítása előtt végrehajtható
  • MPI_Recv blokkolva van, amíg az üzenetet teljesen meg nem kapják

A következők analóg módon érvényesek:

  • MPI_Senda társított MPI_Recvindítása előtt végrehajtható
  • MPI_Send addig blokkolva, amíg a küldési puffer újrafelhasználható (azaz az üzenetet teljesen továbbították vagy ideiglenesen pufferelték)

Minta program

A MPI_Sendés MPI_Recvaz alábbi ANSI-C példát szemlélteti 2 MPI folyamathoz:

#include "mpi.h"
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int myrank, message_size=50, tag=42;
    char message[message_size];
    MPI_Status status;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

    if (myrank == 0) {
        MPI_Recv(message, message_size, MPI_CHAR, 1, tag, MPI_COMM_WORLD, &status);
        printf("received \"%s\"\n", message);
    }
    else {
        strcpy(message, "Hello, there");
        MPI_Send(message, strlen(message)+1, MPI_CHAR, 0, tag, MPI_COMM_WORLD);
    }
    MPI_Finalize();
    return 0;
}

Nem blokkoló kommunikáció

A párhuzamos alkalmazások hatékonysága gyakran növelhető azzal, hogy átfedik a kommunikációt a számítással és / vagy elkerülik a szinkronizálással kapcsolatos várakozási időket. Erre a célra az MPI szabvány meghatározza az úgynevezett nem blokkoló kommunikációt, amelyben a kommunikációs műveletet csak elindítják. Ezután külön funkciót kell meghívni egy ilyen művelet befejezéséhez. A blokkoló változattal ellentétben a művelet indításakor Requestlétrejön egy objektum, amely felhasználható a művelet ellenőrzésére vagy megvárására.

int MPI_Isend (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request)
  • ...
  • request: A műveletről információkat tartalmazó adatstruktúra címe
int MPI_Irecv (void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request* request)
  • ...

Lekérdezés előrehaladása

Ezen műveletek egyikének előrehaladásának megismeréséhez a következő műveletet kell használni:

int MPI_Test (MPI_Request* request, int* flag, MPI_Status* status)

Hol flag=1vagy van 0beállítva attól függően, hogy a művelet befejeződött-e vagy még folyamatban van.

Blokkolásra vár

A következő művelettel blokkoló módon várhatunk egy MPI_Isend- vagy - MPI_Irecvműveletet:

int MPI_Wait (MPI_Request* request, MPI_Status* status)

Küldés szinkronizálása

A szinkron változatok, MPI_Ssendés a küldési műveletekhez is MPI_Issendmeg vannak határozva. Ebben az üzemmódban a küldés addig nem ér véget, amíg a társított vételi művelet meg nem indul.

Puffer változatok

...

Csoportok és kommunikátorok

A folyamatok csoportokban foglalhatók össze, ahol mindegyik folyamathoz egyedi számot, az úgynevezett rangot rendelünk . A csoport eléréséhez kommunikátor szükséges. Ha egy globális kommunikációs műveletet egy csoportra kívánnak korlátozni, meg kell adni a csoporthoz tartozó kommunikátort. Az összes folyamat halmazának kommunikátorát hívjuk MPI_COMM_WORLD.

A kommunikátorhoz commtartozó csoport szerepel

int MPI_Comm_group (MPI_Comm comm, MPI_Group* group)

A folyamatcsoportok számára a szokásos beállított műveletek állnak rendelkezésre.

Unió

Két csoport, group1és group2új csoportba vonhatók össze new_group:

int MPI_Group_union (MPI_Group group1, MPI_Group group2, MPI_Group* new_group)

A folyamatok group1megtartják eredeti számozásukat. Azokat group2, amelyek még nem szerepelnek az elsőben, sorozatosan számozzuk.

Útkereszteződés

Két csoport metszéspontját kapjuk

int MPI_Group_intersection (MPI_Group group1, MPI_Group group2, MPI_Group* new_group)

különbség

Két csoport közötti különbséget a

int MPI_Group_difference (MPI_Group group1, MPI_Group group2, MPI_Group* new_group)

Globális kommunikáció

A párhuzamos alkalmazásokban gyakran találkozunk olyan speciális kommunikációs mintákkal, amelyekben egyszerre több vagy akár az összes MPI folyamat részt vesz. Az MPI szabvány ezért meghatározta saját műveleteit a legfontosabb mintákhoz. Ezek nagyjából három típusra oszthatók: szinkronizálás (akadály), kommunikáció (pl. Sugárzás, összegyűjtés, összeszerelés) és számítással párosított kommunikáció (pl. Csökkentés vagy szkennelés). Ezen műveletek némelyike ​​egy kiválasztott MPI folyamatot használ, amelynek különleges szerepe van, és általában erre roothivatkoznak. A rendszeres kommunikációs műveletek mellett vannak olyan vektor-alapú változatok is (pl. Scatterv), amelyek különböző argumentumokat engednek meg minden folyamathoz, ahol van értelme.

Adás

Három folyamat sugárzási művelete

A műsorszórási művelettel egy kiválasztott MPI folyamat ugyanazt az adatot küldi a rootcsoport összes többi folyamatának comm. Az ehhez definiált funkció minden érintett folyamatban azonos:

int MPI_Bcast (void *buffer, int count, MPI_Datatype type, int root, MPI_Comm comm)

Az MPI folyamat elérhetővé rootteszi bufferaz adatait, míg a többi folyamat ide továbbítja a vételi puffer címét. A többi paraméternek minden folyamatban azonosnak (vagy egyenértékűnek) kell lennie. A függvény visszatérése után az összes puffer azokat az adatokat tartalmazza, amelyek eredetileg csak rootelérhetőek voltak.

Gyűjtsd össze

Az összegyűjtési művelet

A Gather művelettel az MPI folyamat összegyűjti rootaz összes érintett folyamat adatait. Az összes küldési puffer adatait egymás után tároljuk (rang szerint rendezve) a vételi pufferben:

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

Vektor-alapú változat

Az összegyűjtési művelet vektoralapú változata lehetővé teszi a folyamatfüggő elemek számát:

int MPI_Gatherv (void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, int root, MPI_Comm comm)

  • recvcounts: Az egyes folyamatok által beérkezett elemek számát tartalmazó mező (csak rootreleváns)
  • displs: Az i mező, amelynek i bejegyzése meghatározza az eltolódást a vételi pufferben, amelyben az i folyamat adatai tárolásra kerülnek (szintén csak rootrelevánsak)

Meg kell jegyezni, hogy a mezőkben a vételi pufferben hiányosságok engedélyezettek, de nincsenek átfedések. Ha, például 1, 2 és 3-elemek a integer típusú kell kapott 3 folyamatok , akkor recvcounts = {1, 2, 3}és kell lennie displs = {0, 1 * sizeof(int), 3 * sizeof(int)}készlet.

Szétszór

A szórási művelet

A szórás művelet az MPI folyamat küld rootminden folyamat vesz részt egy másik, de hasonlóan nagy adat elem:

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

Vektor-alapú változat

int MPI_Scatterv (void *sendbuf, int *sendcounts, int *displs, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)

felhalmozódás

Az összegyűjtés az összegyűjtési művelet speciális formája . Az összes érintett folyamat adatait itt is összegyűjtjük, de egy meghatározott redukciós művelet segítségével szintén dátumra redukáljuk. Tegyük fel például, az értéket a folyamat Rank , majd szállít csökkentése (+) teljes minden érték: .

int MPI_Reduce (void *sendbuf, void *recvbuf, int count, MPI_Datatype type, MPI_Op op, int root, MPI_Comm comm)

A opkövetkező előre definiált csökkentési műveletek léteznek a paraméterhez :

Logikai műveletek

  • MPI_LAND: logikai ÉS link
  • MPI_BAND: bitenkénti ÉS művelet
  • MPI_LOR: logikus VAGY link
  • MPI_BOR: bitenként VAGY művelet
  • MPI_LXOR: logikai kizárólagos-VAGY link
  • MPI_BXOR: bitenként exkluzív VAGY művelet

Számtani műveletek

  • MPI_MAX: Maximum
  • MPI_MIN: Minimum
  • MPI_SUM: Teljes
  • MPI_PROD: Termék
  • MPI_MINLOC: Minimum a folyamattal
  • MPI_MAXLOC: Folyamat mellett maximum

A műveletek MPI_MINLOCés MPI_MAXLOCaz eredményt meghatározó MPI folyamat rangját is visszaadják.

Egyéni műveletek

Az előre definiált csökkentési műveletek mellett használhatja saját csökkentési műveleteit is. Ebből a célból egy szabadon programozható bináris logikai műveletet, amelynek asszociatívnak és adott esetben kommutatívnak kell lennie, bejelenti az MPI:

int MPI_Op_create (MPI_User_function *function, int commute, MPI_Op *op)

A társított felhasználói függvény két bemeneti értékből számítja ki a kimeneti értéket, és ezt - optimalizálási okokból - nem csak egyszeri skalárral, hanem elemenként, tetszőleges hosszúságú vektorokon:

typedef void MPI_User_function (void *invec, void *inoutvec, int *len, MPI_Datatype *datatype)

Prefix Reduction

A fent említett felhalmozás mellett létezik egy Allreduce variáns is - amely ugyanazt az eredményt teszi elérhetővé minden MPI folyamat számára, és nem csak egy rootfolyamat számára. Az úgynevezett előtagcsökkentés most kiterjeszti ezt az opciót azzal, hogy nem minden folyamatra kiszámítja ugyanazt az eredményt, hanem egy folyamatspecifikus részeredményt számol. Tegyük fel például, ismét az értéket a folyamat rangot , majd elszállítja scan (+) részleges értékek összegét rang a : .

int MPI_Scan (void *sendbuf, void *recvbuf, int count, MPI_Datatype type, MPI_Op op, MPI_Comm comm)

Ha a saját értéket nem kell belefoglalni a számításba (azaz kizárni), akkor ezt az exkluzív szkennelési funkcióval lehet megtenni MPI_Exscan.

Allgather

Az Allgather művelet

Az Allgather műveletben minden folyamat ugyanazokat az adatokat küldi minden más folyamatnak. Ezért ez egy több sugárzású művelet, amelyben nincs külön MPI folyamat.

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

Mindenki (teljes csere)

A mindenre kiterjedő művelet

A mindenki közötti kommunikációval - hasonlóan az Allgather kommunikációhoz - az adatok minden folyamat között kicserélődnek. Azonban az elküldési puffernek csak az i részét küldi el az i . Folyamat. A j rangú folyamatból származó adatokat ennek megfelelően a vételi puffer j- edik pozíciójában tároljuk.

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

Van egy szinkronizáló MPI_Barrier művelet is. Ez a függvény csak akkor tér vissza, ha a megadott csoport összes MPI folyamata eléri a program ezen részét.

MPI-2

Az MPI szabvány második verziója 1997 óta elérhető, néhány bővítést hozzáadva a még mindig létező MPI-1.1 szabványhoz. Ezek a kiterjesztések többek között tartalmazzák

  • dinamikus folyamatmenedzsment, d. H. A folyamatok most futás közben hozhatók létre és törölhetők
  • [párhuzamos] hozzáférés a fájlrendszerhez
  • egyirányú kommunikáció
  • További nyelvi interfészek (C ++, Fortran 90) meghatározása, amelyeknél a C ++ nyelvhez tartozó interfészeket elavultként jelölik az MPI 2.2 óta

Példa: nx (n + 1) mátrix olvasása párhuzamos fájlbeviteli és méretfolyamatokkal a rang = 0… size-1 számokkal. Az n + 1 oszlop tartalmazza az A * x = b egyenletrendszer jobb oldalát kiterjesztett mátrix formájában [A, b]. A mátrix sorai egyenletesen oszlanak el a processzorok között. Az elosztás ciklikusan megy végbe (minden processzor egy sort, miután a méretvonalak ismét a rang = 0 szolgáltatnak), és nem blokkokban (mindegyik processzor kap egy összefüggő n / méretű vonal blokkot):

   ndims = 1;                /* dimensions          */
   aosi [0] = size * (n+1);  /* array of sizes      */
   aoss [0] = n+1;           /* array of subsizes   */
   aost [0] = rank * (n+1);  /* array of starts     */
   order = MPI_ORDER_C;      /* row or column order */
   MPI_Type_create_subarray (ndims, aosi, aoss, aost, order, MPI_DOUBLE, &ft);
   MPI_Type_commit (&ft);
   MPI_File_open (MPI_COMM_WORLD, fn, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
   MPI_File_set_view (fh, sizeof (int), MPI_DOUBLE, ft, „native“, MPI_INFO_NULL);
   for (i = rank; i < n; i+=size)
   {   MPI_File_read (fh, rdbuffer, n+1, MPI_DOUBLE, &status);
       for (j = 0; j < n+1; j++)
       {   A [i / size] [j] = rdbuffer [j]; /* nur die dem Prozess zugeordneten Zeilen */
   }   }
   MPI_File_close (&fh);

Az interfész a POSIX 1003.1 szabványt követi, a párhuzamosság miatt enyhe változtatásokkal. A fájl közös olvasásra nyílik meg az MPI_File_open alkalmazással. Az egyes folyamatok rekeszei (nézetei) az MPI_File_set_view paranccsal vannak beállítva. Itt meg kell adni a korábban definiált ft (filetype) változót, amelyben egy n + 1 duplájú sort választunk ki egy * (n + 1) duplájú blokkban, kezdve a * (n + 1) pozíciótól. Így a teljes blokkból pontosan egy sort rendelünk egymás után minden folyamathoz. Ezt a típust az MPI_Type_create_subarray az definiálja, és az MPI rendszerben az MPI_Type_commit paranccsal teszi ismertté. Minden folyamat beolvassa a sorait az i = rank, rank + size, rank + 2 * size, ... számokkal, amíg a teljes mátrixot el nem olvassák az MPI_File_read paranccsal. Az (int) argumentum mérete figyelembe veszi a mátrix méretét, amelyet int fájlként tárol a fájl elején.

Előny: A nagyságú processzorokban egy mátrix elosztott módon tárolható, amelynek már nem lenne helye egyetlen processzor memóriájában. Ez indokolja azt is, hogy az egyes magok és az egyes csomópontok memóriájának összegét párhuzamos rendszer memóriájaként határozzuk meg.

Fájlformátum:

n
Zeile 0 (n+1) Zahlen für Prozess rank 0
Zeile 1 (n+1) Zahlen für Prozess rank 1
…
Zeile r (n+1) Zahlen für Prozess rank r
…
Zeile size-1 (n+1) Zahlen für Prozess rank size-1
Zeile size (n+1) Zahlen für Prozess rank 0
Zeile size+1 (n+1) Zahlen für Prozess rank 1
…
Zeile size+r (n+1) Zahlen für Prozess rank r
…
Zeile 2*size-1 (n+1) Zahlen für Prozess rank size-1
Zeile 2*size (n+1) Zahlen für Prozess rank 0
…
…
es folgen entsprechend der Zeilenzahl der Matrix ausreichend viele solcher Blöcke

A tényleges leolvasás az MPI_File_read paranccsal történik. Minden folyamat egymás után csak a hozzá rendelt sorokat olvassa fel. A kollektív művelet az, hogy az MPI könyvtár optimalizálni és párhuzamosítani tudja az olvasást. Az olvasás befejeztével a fájlt a szokásos módon be kell zárni. Ez az MPI_File_close paranccsal történik. Az MPI saját adattípusokkal rendelkezik: MPI_Datatype ft és MPI_File fh a műveletekhez. A fájltípust normál C változókkal írják le: int ndims; int aosi [1]; int aoss [1]; int aost [1]; int rend;

In.

Végrehajtások

C ++, C és Fortran

Az első végrehajtása az MPI-1.x szabvány volt MPICH származó diffraktáltuk és Mississippi State University . Az MPI-2.1 szabványt megvalósító MPICH2 már elérhető. Az ohiói szuperszámítógépes központ LAM / MPI egy másik ingyenes verziója volt, amelynek továbbfejlesztését azóta megszüntették az Open MPI javára.

A Boost Libraries 1.35- ös verziójától kezdve létezik a Boost.MPI, egy C ++ -barát felület a különféle MPI-implementációkhoz. Más projektek, mint pl B. TPO ++ , felajánlja ezt a lehetőséget, és képesek STL konténerek küldésére és fogadására.

C #

piton

Jáva

Gyöngyszem

R.

Haskell

Lásd még

irodalom

  • Heiko Bauke, Stephan Mertens: Cluster Computing. Springer, 2006, ISBN 3-540-42299-4
  • William Gropp, Ewing Lusk, Anthony Skjellum: MPI - Bevezetés - Hordozható párhuzamos programozás az üzenet-továbbító interfésszel . München 2007, ISBN 978-3-486-58068-6 .
  • M. Firuziaan, O. Nommensen: Párhuzamos feldolgozás MPI-n és OpenMP-n keresztül . Linux Enterprise, 10/2002
  • Marc Snir , Steve Otto, Steven Huss-Lederman, David Walker, Jack Dongarra : MPI - A teljes referencia , 1. kötet: Az MPI mag. 2. kiadás. MIT Press, 1998
  • William Gropp, Steven Huss-Lederman, Andrew Lumsdaine, Ewing Lusk, Bill Nitzberg, William Saphir, Marc Snir: MPI-The Complete Reference , 2. kötet: Az MPI-2 kiterjesztések. The MIT Press, 1998.

web Linkek

Egyéni bizonyíték

  1. MPI dokumentumok ( Memento az a eredeti kelt november 6, 2006 a Internet Archive ) Info: A archív linket helyeztünk automatikusan, és még nem ellenőrizték. Kérjük, ellenőrizze az eredeti és az archív linket az utasításoknak megfelelően, majd távolítsa el ezt az értesítést. @ 1@ 2Sablon: Webachiv / IABot / www.mpi-forum.org
  2. ^ Az MPI jövője . (PDF)
  3. Változások az MPI-4.0-ban
  4. MPI-2: Az üzenet-továbbító felület kiterjesztései ( az eredeti emléke 2007. szeptember 21-től az internetes archívumban ) Információ: Az archív linket automatikusan beillesztették, és még nem ellenőrizték. Kérjük, ellenőrizze az eredeti és az archív linket az utasításoknak megfelelően, majd távolítsa el ezt az értesítést. @ 1@ 2Sablon: Webachiv / IABot / www.mpi-forum.org