Sari la conținutul principal

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_DatatypeEchivalentul din C/C++
MPI_INTint
MPI_LONGlong
MPI_CHARchar
MPI_FLOATfloat
MPI_DOUBLEdouble

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:

img