Operaciones Colectivas en MPI        Manuel Martín Salvador        draxus@correo.ugr.es          http://draxus.org        ...
Operaciones colectivas        Operaciones en las que participan todos los               procesos de un comunicador    -   ...
Barrier (barerra)int MPI_Barrier(MPI_Comm comm)   Bloquea a los procesos de un comunicador hasta que todos elloshan llegad...
Broadcast (difusión)int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm com)    Sirve para qu...
Broadcast (difusión)                                        0                        0                               1    ...
Gather (recolección)int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_...
Gather (recolección)Ejemplo: Recolectar 100 enteros de cada proceso en el proceso raízint main(){    MPI_Comm comm;    int...
Gather (recolección)int MPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, i...
Gather (recolección)Ejemplo: Recolectar 100 enteros de cada proceso en el proceso raízint main(){    MPI_Comm comm;     in...
Gather (recolección)int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, M...
Gather (recolección)Ejemplo: recoger en todos los procesos 100 enteros que han distribuido todos los procesos.int main(){ ...
Scatter (distribución)int MPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, M...
Scatter (distribución)Ejemplo: distribuir 100 enteros desde el raíz a todos los procesosint main(){   MPI_Comm comm;    in...
Scatter (distribución)int MPI_Scatterv(void *sendbuf, int *sendcounts, int *displs, MPI_Datatype sendtype, void *recvbuf, ...
Scatter (distribución)Ejemplo: distribuir 100 enteros desde el raíz a todos los procesosint main(){    MPI_Comm comm;     ...
Comunicación todos con todosint MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvc...
Reduce (reducción)int MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_...
Reduce (reducción)      En ocasiones resulta útil que el resultado de unareducción esté disponible para todos los procesos...
Gráficamente                
Gráficamente                
Ejemplo: cálculo de Pidouble f( double a ){                                           if (n == 0)    return (4.0 / (1.0 + ...
Referencias    ●   MPI: The Complete Reference        http://www.netlib.org/utk/papers/mpi-book/mpi-book.html    ●   Paral...
FIN      Gracias por vuestra atención                               
Upcoming SlideShare
Loading in …5
×

Operaciones Colectivas en MPI

2,743 views

Published on

2 Comments
0 Likes
Statistics
Notes
  • Be the first to like this

No Downloads
Views
Total views
2,743
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
24
Comments
2
Likes
0
Embeds 0
No embeds

No notes for slide

Operaciones Colectivas en MPI

  1. 1. Operaciones Colectivas en MPI Manuel Martín Salvador draxus@correo.ugr.es http://draxus.org Programación Concurrente I.T. Informática de Sistemas Granada, 16 enero 2007   
  2. 2. Operaciones colectivas Operaciones en las que participan todos los procesos de un comunicador - Barreras de sincronización - Broadcast (difusión) - Gather (recolección) - Scatter (distribución) - Operaciones de reducción (suma, mínimo...) - Combinaciones de todas ellas   
  3. 3. Barrier (barerra)int MPI_Barrier(MPI_Comm comm) Bloquea a los procesos de un comunicador hasta que todos elloshan llegado a la barrera.int main(){  ...   rank = MPI_Rank();   if(rank==0){ a[0][0] = b[0][0] + c[0][0]; a[0][1] = b[0][1] + c[0][1];   }else{ a[1][0] = b[1][0] + c[1][0]; a[1][1] = b[1][1] + c[1][1];   }   MPI_Barrier(MPI_COMMWORLD);   if(MPI_Rank()==0)  //Imprimo matriz a   }
  4. 4. Broadcast (difusión)int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm com) Sirve para que un proceso, el raíz, envíe unmensaje a todos los miembros del comunicador.   
  5. 5. Broadcast (difusión) 0 0 1 0 2 1 3 0 4 2 6 1 5 3 7 Ejemplo: Difusión de un vector de 100 enteros int main(){    MPI_Comm comm;     int array[100];     int root=0;     ...     MPI_Bcast(array, 100, MPI_INT, root, comm);    ...  }  
  6. 6. Gather (recolección)int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) Realiza una recolección de datos en el proceso raíz.Recopila un vector de datos, al que contribuyen todos losprocesos del comunicador con la misma cantidad de datos.Almacena las contribuciones de forma consecutiva.   
  7. 7. Gather (recolección)Ejemplo: Recolectar 100 enteros de cada proceso en el proceso raízint main(){ MPI_Comm comm;    int gsize,sendarray[100];    int root, myrank, *rbuf;    ...    MPI_Comm_rank(comm, myrank);    if (myrank == root) {       MPI_Comm_size(comm, &gsize);       rbuf = (int *)malloc(gsize*100*sizeof(int));    }    MPI_Gather(sendarray, 100, MPI_INT, rbuf, 100, MPI_INT, root, comm);  ...}   
  8. 8. Gather (recolección)int MPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, int root, MPI_Comm comm) Permite almacenar los datos recogidos en formano consecutiva y que cada proceso contribuya conbloques de datos de diferente tamaño.   
  9. 9. Gather (recolección)Ejemplo: Recolectar 100 enteros de cada proceso en el proceso raízint main(){ MPI_Comm comm;  int gsize,sendarray[100];  int root, *rbuf, stride;  int *displs,i,*rcounts;  ... MPI_Comm_size( comm, &gsize); rbuf = (int *)malloc(gsize*stride*sizeof(int)); displs = (int *)malloc(gsize*sizeof(int)); rcounts = (int *)malloc(gsize*sizeof(int)); for (i=0; i<gsize; ++i) { displs[i] = i*stride; rcounts[i] = 100; } MPI_Gatherv( sendarray, 100, MPI_INT, rbuf, rcounts, displs, MPI_INT, root, comm);  ...}    
  10. 10. Gather (recolección)int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)int MPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, int root, MPI_Comm comm)Distribuyen a todos los procesos el resultado de una recolecciónprevia.   
  11. 11. Gather (recolección)Ejemplo: recoger en todos los procesos 100 enteros que han distribuido todos los procesos.int main(){ MPI_Comm comm;  int gsize,sendarray[100];  int *rbuf;  ...  MPI_Comm_size(comm, &gsize);  rbuf = (int *)malloc(gsize*100*sizeof(int));  MPI_Allgather(sendarray, 100, MPI_INT, rbuf, 100, MPI_INT, comm);  ...}Después de la ejecución, cada proceso tiene la concatenación de cada uno de los arrays de los otros procesos.   
  12. 12. Scatter (distribución)int MPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) El proceso raíz posee un vector de elementos, uno porcada proceso del comunicador. Tras realizar la distribución,cada proceso tiene una copia del vector inicial.   
  13. 13. Scatter (distribución)Ejemplo: distribuir 100 enteros desde el raíz a todos los procesosint main(){ MPI_Comm comm;  int gsize,*sendbuf;  int root, rbuf[100];  ...  MPI_Comm_size(comm, &gsize);  sendbuf = (int *)malloc(gsize*100*sizeof(int));  ...  MPI_Scatter(sendbuf, 100, MPI_INT, rbuf, 100, MPI_INT, root, comm); ...}   
  14. 14. Scatter (distribución)int MPI_Scatterv(void *sendbuf, int *sendcounts, int *displs, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) Si los datos a enviar no están almacenados deforma consecutiva en memoria, o los bloques a enviar acada proceso no son todos del mismo tamaño.   
  15. 15. Scatter (distribución)Ejemplo: distribuir 100 enteros desde el raíz a todos los procesosint main(){ MPI_Comm comm;  int gsize,*sendbuf;  int root, rbuf[100], i, *displs, *scounts;  ... MPI_Comm_size(comm, &gsize); sendbuf = (int *)malloc(gsize*stride*sizeof(int)); ... displs = (int *)malloc(gsize*sizeof(int)); scounts = (int *)malloc(gsize*sizeof(int)); for (i=0; i<gsize; ++i) { displs[i] = i*stride; scounts[i] = 100; } MPI_Scatterv(sendbuf, scounts, displs, MPI_INT, rbuf, 100, MPI_INT, root, comm); ...}    
  16. 16. Comunicación todos con todosint MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)int MPI_Alltoall(void *sendbuf, int *sendcounts, int *sdispls, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, MPI_Datatype recvtype, int *rdispls, MPI_Comm comm) Cada proceso tiene un vector con tantos elementos comoprocesos hay en el comunicador. Sean i, j y k entre 0 y N-1 (siendoN=nº procesos). Cada proceso i envía una copia de sendbuf[j] alproceso j, y recibe del proceso k un elemento que almacena enrecvbuf[k].   
  17. 17. Reduce (reducción)int MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm) Una reducción es una operación realizada deforma cooperativa entre todos los procesos de uncomunicador. El resultado final se almacena en elproceso raíz. Operaciones por defecto: MPI_MAX (máximo),MPI_MIN (mínimo), MPI_SUM (suma), MPI_PROD(producto), MPI_LAND (and lógico), MPI_BAND (and bit abit), etc.int MPI_Op_create(MPI_User_function *function,    int commute, MPI_Op *op)
  18. 18. Reduce (reducción) En ocasiones resulta útil que el resultado de unareducción esté disponible para todos los procesos.int MPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) Si el resultado es un vector que hay que distribuir entre todos los procesos, usaremos:int MPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)  Si queremos que cada proceso reciba un resultado parcial:int MPI_Scan(void *sendbuf, void *recvbuf, int count,    MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
  19. 19. Gráficamente   
  20. 20. Gráficamente   
  21. 21. Ejemplo: cálculo de Pidouble f( double a ){         if (n == 0)    return (4.0 / (1.0 + a*a));             done = 1;}         else{             h   = 1.0 / (double) n;int main( int argc, char *argv[]){             sum = 0.0;    int done = 0, n, myid, numprocs, i;             for (i = myid + 1; i <= n; i +=     double PI25DT = 3.141592653589793238462643; numprocs){    double mypi, pi, h, sum, x;                 x = h * ((double)i ­ 0.5);    double startwtime = 0.0, endwtime;                 sum += f(x);    int  namelen;             }    char processor_name[MPI_MAX_PROCESSOR_NAME];             mypi = h * sum;    MPI_Init(&argc,&argv);             MPI_Reduce(&mypi, &pi, 1,     MPI_Comm_size(MPI_COMM_WORLD,&numprocs); MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);    MPI_Comm_rank(MPI_COMM_WORLD,&myid);    MPI_Get_processor_name(processor_name,&namelen);             if (myid == 0){                 printf("pi is approximately     fprintf(stderr,"Proceso %d en %sn", myid,  %.16f, Error is %.16fn", pi, fabs(pi ­ processor_name); PI25DT));       endwtime = MPI_Wtime();    n = 0;       printf("wall clock time = %fn",     while (!done){ endwtime­startwtime);        if (myid == 0){   }     if (n==0) n=100; else n=0;         }     startwtime = MPI_Wtime();     }        }     MPI_Finalize();        MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);     return 0; }    
  22. 22. Referencias ● MPI: The Complete Reference http://www.netlib.org/utk/papers/mpi-book/mpi-book.html ● Parallel programming with MPI - Peter S. Pacheco ● Cálculo de PI http://www.ace.ual.es/~jamartin/Multi_2005_2006_html/practica1.html ● Especificación de MPI http://www-unix.mcs.anl.gov/mpi/www/ ● Servidor público de MPI ftp://ftp.mcs.anl.gov/pub/mpi/   
  23. 23. FIN Gracias por vuestra atención   

×