Implementarea unui program distribuit în MPI
Implementarea unui program distribuit în MPI
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#define MASTER 0
int main (int argc, char *argv[]) {
int numtasks, rank, len;
char hostname[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Get_processor_name(hostname, &len);
if (rank == MASTER)
printf("MASTER: Number of MPI tasks is: %d\n",numtasks);
else
printf("WORKER: Rank: %d\n",rank);
MPI_Finalize();
}
Un comunicator (MPI_Comm) reprezintă un grup de procese care comunică între ele. MPI_COMM_WORLD reprezintă comunicatorul default, din care fac parte toate procesele.
Funcții:
- MPI_Init - se inițializează programul MPI, mai precis se creează contextul în cadrul căruia rulează procesele. Argumentele din linie de comandă sunt pasate către contextul de rulare a proceselor.
- MPI_Comm_size - funcție care determină numărul de procese (numtasks) care rulează în cadrul comunicatorului (de regulă MPI_COMM_WORLD)
- MPI_Comm_rank - funcție care determină identificatorul (rangul) procesului curent în cadrul comunicatorului.
- MPI_Get_processor_name - determină numele procesorului
- MPI_Finalize - declanșează terminarea programului MPI
În cadrul schimbului de date între procese, este necesar mereu să precizăm tipul acestora. În MPI, se folosește enum-ul MPI_Datatype, care se mapeaz ă cu tipurile de date din C/C++, după cum puteți vedea în tabelul de mai jos:
MPI_Datatype | Echivalentul din C/C++ |
---|---|
MPI_INT | int |
MPI_LONG | long |
MPI_CHAR | char |
MPI_FLOAT | float |
MPI_DOUBLE | double |
Putem crea comunicatoare dintr-un alt comunicator folosind funcția MPI_Comm_split, care împarte un comunicator în mai multe comunicatoare mai mici. Semnătura funcției este următoarea:
int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm * newcomm)
Unde:
- comm - comunicatorul care este împărțit
- color - identificator al noului comunicator, din care face parte un proces (de regulă rang_vechi_proces / dimensiune_comunicator_nou)
- key - noul rang al procesului în cadrul noului comunicator (de regulă rang_vechi_proces % dimensiune_comunicator_nou)
- newcomm - noul comunicator format
Aveți mai jos o imagine care ilustrează cum funcționează MPI_Comm_split: