13.07.2015 Views

La Interfaz de Paso de Mensajes: MPI. - Departamento de ...

La Interfaz de Paso de Mensajes: MPI. - Departamento de ...

La Interfaz de Paso de Mensajes: MPI. - Departamento de ...

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Introducción a la <strong>Interfaz</strong><strong>de</strong> paso <strong>de</strong> mensajes (<strong>MPI</strong>)<strong>MPI</strong> communicator 1P0value<strong>MPI</strong> communicator 2 0 1P1P2value2 3P3José Miguel Mantas RuizDepto. <strong>de</strong> Lenguajes y Sistemas InformáticosUniversidad <strong>de</strong> Granada


Contenido1. Message Passing Interface (<strong>MPI</strong>)2. Funciones <strong>MPI</strong> básicas3. Envío y recepción simultánea4. Operaciones <strong>de</strong> comunicación colectiva5. Comunicación No bloqueante6. Comunicadores7. Topologías Cartesianas8. Tipos <strong>de</strong> datos <strong>de</strong>rivados y Empaquetado9. Referencias útiles


1. Message Passing Interface (<strong>MPI</strong>)• Funciones para paso <strong>de</strong> mensajes y operaciones. complementarias (>120rutinas con numerosos parámetros y variantes).• “<strong>Interfaz</strong>” estándar para C y Fortran con diversas implementaciones.• Objetivo diseño: paso <strong>de</strong> mensajes portable y fácil <strong>de</strong> usar.• Basta con un pequeño subconjunto <strong>de</strong> <strong>MPI</strong>.• Mo<strong>de</strong>lo <strong>de</strong> Programación en <strong>MPI</strong>:– Computación ⇒ Número fijado <strong>de</strong> procesos se comunican mediante llamadasa funciones <strong>de</strong> envío y recepción <strong>de</strong> mensajes.– Mo<strong>de</strong>lo básico: SPMD– Extensión: cada proceso pue<strong>de</strong> ejecutar diferentes programas → MPMD• Creación e inicialización <strong>de</strong> procesos– No <strong>de</strong>finido en el estándar: <strong>de</strong>pen<strong>de</strong> implementación.– En mpich: mpirun prog1 –machinefile maquinas –np 4• Comienza 4 copias <strong>de</strong>l ejecutable “prog1”.• <strong>La</strong> asignación <strong>de</strong> procesos a máquinas se <strong>de</strong>fine en el archivo “maquinas”.


1. Message Passing Interface (<strong>MPI</strong>)1.1. Asuntos <strong>de</strong> implementación• #inclu<strong>de</strong> "mpi.h“– Define ctes, tipos <strong>de</strong> datos y los prototipos <strong>de</strong> las funciones <strong>MPI</strong>• Funciones <strong>de</strong>vuelven código <strong>de</strong> error– <strong>MPI</strong>_SUCCESS ⇒ Ejecución correcta• <strong>MPI</strong>_Status: estructura con 2 campos:– status.<strong>MPI</strong>_SOURCE: proceso fuente– status.<strong>MPI</strong>_TAG: etiqueta <strong>de</strong>l mensaje.• Tipos <strong>de</strong> datos <strong>MPI</strong>– <strong>MPI</strong>_CHAR, <strong>MPI</strong>_INT, <strong>MPI</strong>_LONG, <strong>MPI</strong>_UNSIGNED_CHAR,<strong>MPI</strong>_UNSIGNED, <strong>MPI</strong>_UNSIGNED_LONG, <strong>MPI</strong>_FLOAT, <strong>MPI</strong>_DOUBLE,<strong>MPI</strong>_LONG_DOUBLE, etc.• Comunicador= Grupos <strong>de</strong> procesos + contexto


2. Funciones <strong>MPI</strong> básicas• <strong>MPI</strong>_INIT :• <strong>MPI</strong>_FINALIZE :• <strong>MPI</strong>_COMM_SIZE :• <strong>MPI</strong>_COMM_RANK:• <strong>MPI</strong>_SEND :• <strong>MPI</strong>_RECV :Inicializa entorno <strong>de</strong> ejecución <strong>MPI</strong>.Finaliza entorno <strong>de</strong> ejecución <strong>MPI</strong>.Determina nº procesos <strong>de</strong>l comunicador.Determina id. proceso en el comunicador.Envío básico mensaje.Recepción básica mensaje.2.1. Iniciando y finalizando <strong>MPI</strong>• int <strong>MPI</strong>_Init (int *argc, char ***argv)– Llamado antes <strong>de</strong> cualquier otra función <strong>MPI</strong>– Llamar más <strong>de</strong> una vez durante ejecución ⇒ Error– Argumentos argc, argv: Argumentos <strong>de</strong> la línea <strong>de</strong> or<strong>de</strong>n <strong>de</strong>l progr.• int <strong>MPI</strong>_Finalize ( )– Llamado al fin <strong>de</strong> la computación: Tareas <strong>de</strong> limpieza para finalizarentorno <strong>de</strong> ejecución


2. Funciones <strong>MPI</strong> básicas2.2. Introducción a los Comunicadores• Comunicador = variable <strong>de</strong> tipo <strong>MPI</strong>_Comm = Grupo_procs + Contexto– Grupo <strong>de</strong> procesos: Subconjunto <strong>de</strong> procesos– Contexto <strong>de</strong> comunicación: Ámbito <strong>de</strong> paso <strong>de</strong> mensajes en el que secomunican dichos procesos. Un mensaje enviado en un contexto sólo se conoce enese contexto ⇒ elemento <strong>de</strong>l “sobre” <strong>de</strong>l mensaje.• Argumento en funciones <strong>de</strong> transferencia.• <strong>MPI</strong>_COMM_WORLD : Comunicador <strong>MPI</strong> por <strong>de</strong>fecto– Incluye todos los procesos en ejecución<strong>MPI</strong>_COMM_WORLDP0 P1 P2 P3 P4 P5comm1P6 P7 P8 P9 P10 P11


2. Funciones <strong>MPI</strong> básicas2.2. Introducción a los Comunicadores (cont.)• I<strong>de</strong>ntificación unívoca <strong>de</strong> procesos participantes en comunicador– Un proceso pue<strong>de</strong> pertenecer a diferentes comunicadores– Cada proceso tiene un i<strong>de</strong>ntificador: <strong>de</strong>s<strong>de</strong> 0 a size_comm-1– <strong>Mensajes</strong> <strong>de</strong>stinados a diferentes contextos <strong>de</strong> comunicación nointerfieren entre sí.comm1<strong>MPI</strong>_COMM_WORLDcomm1P0 P1 P2 P3 P4 P5P0P1P6 P7 P8 P9 P10 P11P2P3


2. Funciones <strong>MPI</strong> básicas2.3. Obteniendo Informaciónint <strong>MPI</strong>_Comm_size ( <strong>MPI</strong>_Comm comm, int *size )– size= nº <strong>de</strong> procs que pertenecen al comunicador comm.– Ej.: <strong>MPI</strong>_Comm_size ( <strong>MPI</strong>_COMM_WORLD, &size) ⇒ size = nº total <strong>de</strong> procs.int <strong>MPI</strong>_Comm_rank ( <strong>MPI</strong>_Comm comm, int *rank )– rank= I<strong>de</strong>ntificador <strong>de</strong>l proceso llamador en comm.#inclu<strong>de</strong> #inclu<strong>de</strong> "mpi.h"int main(int argc, char **argv ) {int rank, size;<strong>MPI</strong>_Init( &argc, &argv );<strong>MPI</strong>_Comm_size( <strong>MPI</strong>_COMM_WORLD, &size );<strong>MPI</strong>_Comm_rank( <strong>MPI</strong>_COMM_WORLD, &rank );printf( "Hello world from process %d of %d\n", rank, size );<strong>MPI</strong>_Finalize( ); return 0;}% mpicc -o helloworld helloworld.c% mpirun -np 4 helloworldHello world from process 0 of 4Hello world from process 3 of 4Hello world from process 1 of 4Hello world from process 2 of 4


2. Funciones <strong>MPI</strong> básicas2.4. Envío y recepción <strong>de</strong> mensajesint <strong>MPI</strong>_Send ( void *buf, int count, <strong>MPI</strong>_Datatype datatype, int <strong>de</strong>st, int tag,<strong>MPI</strong>_Comm comm )– Envía datos almacenados en buffer (count elem. <strong>de</strong> tipo datatype) apuntado porbuf al proc. <strong>de</strong>st con la etiqueta tag (entero >0) <strong>de</strong>ntro <strong>de</strong>l comunicador comm.– Existen implementaciones bloqueantes y no bloqueantesint <strong>MPI</strong>_Recv ( void *buf, int count, <strong>MPI</strong>_Datatype datatype, int source, int tag,<strong>MPI</strong>_Comm comm, <strong>MPI</strong>_Status *status )– Recibe mensaje <strong>de</strong> proceso source <strong>de</strong>ntro <strong>de</strong>l comunicador comm.• Semántica bloqueante– Sólo se recibe un mensaje enviado <strong>de</strong>s<strong>de</strong> source con etiqueta tag pero existenargumentos comodín: <strong>MPI</strong>_ANY_SOURCE, <strong>MPI</strong>_ANY_TAG.– Mensaje es almacenado en posiciones continuas <strong>de</strong>s<strong>de</strong> buf.commsourcebufbuf<strong>de</strong>st


2. Funciones <strong>MPI</strong> básicas2.4. Envío y recepción <strong>de</strong> mensajes (cont.)– Argumentos count y datatype: especifican la longitud <strong>de</strong>l buffer.– Objeto status → Estructura con campos <strong>MPI</strong>_SOURCE y <strong>MPI</strong>_TAG.– Permite obtener información sobre el mensaje recibido– Obtener tamaño <strong>de</strong>l mensaje recibido: Función <strong>MPI</strong>_Get_count– int <strong>MPI</strong>_Get_count( <strong>MPI</strong>_Status *status, <strong>MPI</strong>_Datatype dtype, int *count )Ejemplo: Programa para dos procesos<strong>MPI</strong>_Init( &argc, &argv );<strong>MPI</strong>_Comm_rank( <strong>MPI</strong>_COMM_WORLD, &rank );<strong>MPI</strong>_Comm_size( <strong>MPI</strong>_COMM_WORLD, &size );if (rank == 0) { value=100;<strong>MPI</strong>_Send (&value, 1, <strong>MPI</strong>_INT, 1, 0, <strong>MPI</strong>_COMM_WORLD );else <strong>MPI</strong>_Recv ( &value, 1, <strong>MPI</strong>_INT, 0, 0, <strong>MPI</strong>_COMM_WORLD, &status );<strong>MPI</strong>_Finalize( );


2. Funciones <strong>MPI</strong> básicas2.4. Envío y recepción <strong>de</strong> mensajes. Ejemplo#inclu<strong>de</strong> #inclu<strong>de</strong> "mpi.h"int main(int argc, char **argv); {P0valueint rank, value, size; <strong>MPI</strong>_Status status;<strong>MPI</strong>_Init( &argc, &argv );P1 value<strong>MPI</strong>_Comm_rank( <strong>MPI</strong>_COMM_WORLD, &rank );<strong>MPI</strong>_Comm_size( <strong>MPI</strong>_COMM_WORLD, &size );P2 valuedo {P3if (rank == 0) { scanf( "%d", &value );<strong>MPI</strong>_Send( &value, 1, <strong>MPI</strong>_INT, rank + 1, 0, <strong>MPI</strong>_COMM_WORLD ); }else { <strong>MPI</strong>_Recv( &value, 1, <strong>MPI</strong>_INT, rank - 1, 0, <strong>MPI</strong>_COMM_WORLD, &status );if (rank < size - 1) <strong>MPI</strong>_Send( &value, 1, <strong>MPI</strong>_INT, rank + 1, 0, <strong>MPI</strong>_COMM_WORLD )}printf( "Process %d got %d\n", rank, value ); }while (value >= 0); <strong>MPI</strong>_Finalize( ); return 0; }


3. Envío y recepciónsimultáneaint <strong>MPI</strong>_Sendrecv( void *sendbuf, int sendcount, <strong>MPI</strong>_Datatype sendtype, int <strong>de</strong>st, intsendtag, void *recvbuf, int recvcount, <strong>MPI</strong>_Datatype recvtype, int source, intrecvtag, <strong>MPI</strong>_Comm comm, <strong>MPI</strong>_Status *status )– Envía un mensaje a <strong>de</strong>st y simultáneamente los recibe <strong>de</strong> source– Muy útil para patrones <strong>de</strong> comunicación circulares– Combina argumentos <strong>de</strong> <strong>MPI</strong>_Send y <strong>MPI</strong>_Recv.• Los buffers <strong>de</strong>ben ser disjuntos, y se permite que source=<strong>de</strong>stsourcerecvbufsendbuf<strong>de</strong>stint <strong>MPI</strong>_Sendrecv_replace( void *buf, int count, <strong>MPI</strong>_Datatype datatype, int <strong>de</strong>st, intsendtag, int source, int recvtag, <strong>MPI</strong>_Comm comm, <strong>MPI</strong>_Status *status )– Igual que <strong>MPI</strong>_Sendrecv pero con un único buffer.– Los datos recibidos reemplazan a los enviados.– Tanto send como receive tratan con datos <strong>de</strong>l mismo tipo.


4. Operaciones <strong>de</strong>comunicación colectiva• Tienen un comunicador como argumento: <strong>de</strong>fine el grupo afectado.• Participan todos los procesos <strong>de</strong>l comunicador:– <strong>La</strong> <strong>de</strong>ben llamar todos con los mismos parámetros.– <strong>MPI</strong>_Barrier: Sincroniza todos los procesos.– <strong>MPI</strong>_Broadcast: Envía un dato <strong>de</strong> un proc. al resto.– <strong>MPI</strong>_Gather: Recolecta datos <strong>de</strong> todos los procesos a uno.– <strong>MPI</strong>_Scatter: Reparte datos <strong>de</strong> un proceso a todos.– <strong>MPI</strong>_Reduce: Realiza operaciones simples sobre datos distribuidos.– <strong>MPI</strong>_Scan: Operación <strong>de</strong> reducción <strong>de</strong> prefijo.4.1. Sincronización <strong>de</strong> barrera• int <strong>MPI</strong>_Barrier ( <strong>MPI</strong>_Comm comm )– Bloquea todos los procesos <strong>de</strong> comm hasta que todos la invoquen.


4. Operaciones <strong>de</strong>comunicación colectiva4.2. Movimiento <strong>de</strong> datosTodos los procesos interactúancon un proceso distinguido (root)para difundir, recolectar orepartir datosint <strong>MPI</strong>_Bcast ( void* buffer, intcount, <strong>MPI</strong>_Datatype datatype, introot, <strong>MPI</strong>_Comm comm )• Envía datos almacenados enbuffer (count elem. <strong>de</strong> tipodatatype) en root al resto.• Datos recibidos se almacenanen buffer, count y datatype<strong>de</strong>ben coincidir en todos.


4. Operaciones <strong>de</strong>comunicación colectiva4.2. Movimiento <strong>de</strong> datos (cont.)int <strong>MPI</strong>_Gather ( void* sendbuf, int sendcount, <strong>MPI</strong>_Datatype sendtype, void*recvbuf, int recvcount, <strong>MPI</strong>_Datatype recvtype, int root, <strong>MPI</strong>_Comm comm )– Cada proceso envía datos almacenados en el array sendbuf a root.– Proc root recibe size(comm) buffers dispuestos consecutivamente enrecvbuf.– Argumentos sendtype y sencount→ mismos valores en todos los procs.– recvcount=nº items recibidos <strong>de</strong> cada proc ⇒ recvcount=sendcount, sisendtype coinci<strong>de</strong> con recvtype.– Información sobre buffer <strong>de</strong> recepción sólo tiene sentido en root.int <strong>MPI</strong>_Scatter(void* sendbuf, int sendcount, <strong>MPI</strong>_Datatype sendtype, void*recvbuf, int recvcount, <strong>MPI</strong>_Datatype recvtype, int root, <strong>MPI</strong>_Comm comm)– source envía una parte diferente <strong>de</strong> sendbuf al recvbuf <strong>de</strong> cada proc.– Todos con mismos valores <strong>de</strong> sendcount, sendtype, recvbuf, recvcount,recvtype, root y comm.– sendcount=nº items enviados por cada proc


4. Operaciones <strong>de</strong>comunicación colectiva4.3. Operaciones <strong>de</strong> Reducción Globalint <strong>MPI</strong>_Reduce (void* sendbuf, void* recvbuf, int count, <strong>MPI</strong>_Datatypedatatype, <strong>MPI</strong>_Op op, int root, <strong>MPI</strong>_Comm comm)– Combina los elementos almacenados en sendbuf <strong>de</strong> cada proc,usando operación op. Devuelve resultado en recvbuf <strong>de</strong> root.– Args sendbuf y recvbuf <strong>de</strong>ben tener count items <strong>de</strong> tipo datatype.– Todos <strong>de</strong>ben proporcionar array recvbuf– Si count>1 ⇒ la operación se aplica elemento a elemento.– Args count, datatype, op, root, comm <strong>de</strong>ben ser idénticos en todos.– Operaciones pre<strong>de</strong>finidas• <strong>MPI</strong>_MAX (máximo), <strong>MPI</strong>_MIN (mínimo), <strong>MPI</strong>_SUM (suma), <strong>MPI</strong>_PROD(producto), <strong>MPI</strong>_LAND (AND lógico), <strong>MPI</strong>_BAND (AND bit a bit), <strong>MPI</strong>_LOR (ORlógico), PI_BOR (OR bit a bit), <strong>MPI</strong>_LXOR (XOR lógico), <strong>MPI</strong>_BXOR (XOR bit abit).• Es posible <strong>de</strong>finir otras operaciones: <strong>MPI</strong>_OP_CREATE .


4.4. Ejemplos4. Operaciones <strong>de</strong>comunicación colectiva• Difun<strong>de</strong> 20 reales <strong>de</strong> proceso 0 al resto en comunicador commdouble vector[20];<strong>MPI</strong>_Bcast ( vector, 20, <strong>MPI</strong>_DOUBLE, 0, comm);• Recoge 20 reales <strong>de</strong> cada proceso en el proceso 0<strong>MPI</strong>_Comm comm= <strong>MPI</strong>_COMM_WORLD;int gsize; double invec[20], *outvec;<strong>MPI</strong>_Comm_size( comm, &gsize);outvec = (double *)malloc(gsize*20*sizeof(double));<strong>MPI</strong>_Gather (invec, 20, <strong>MPI</strong>_DOUBLE, outvec, 20, <strong>MPI</strong>_DOUBLE, 0, comm);• Inversa anterior: Reparte 20 reales <strong>de</strong>s<strong>de</strong> proc 0<strong>MPI</strong>_Scatter( outvec, 20, <strong>MPI</strong>_DOUBLE, invec, 20, <strong>MPI</strong>_DOUBLE, 0, comm);


4. Operaciones <strong>de</strong>4.4. Ejemplos. Cálculo <strong>de</strong> π#inclu<strong>de</strong> "mpi.h"#inclu<strong>de</strong> int main(int argc, char **argv) {int n, myid, numprocs, i; double mypi, pi, h, sum, x;<strong>MPI</strong>_Init (&argc,&argv);<strong>MPI</strong>_Comm_size (<strong>MPI</strong>_COMM_WORLD,&numprocs);<strong>MPI</strong>_Comm_rank (<strong>MPI</strong>_COMM_WORLD,&myid);if (myid == 0) { printf(“Number of intervals: "); scanf("%d",&n); }<strong>MPI</strong>_Bcast (&n, 1, <strong>MPI</strong>_INT, 0, <strong>MPI</strong>_COMM_WORLD);h = 1.0 / (double) n; sum = 0.0;for (i = myid + 1; i


5. Comunicación Nobloqueante• <strong>La</strong>s operaciones <strong>de</strong> comunicación vistas son “bloqueantes”– Incluso <strong>MPI</strong>_Send pue<strong>de</strong> ser bloqueante si la implementación nosoporta suficiente buferización.• Se necesitan operaciones <strong>de</strong> comunicación no bloqueantes– Solapar comunicación con computación:• <strong>MPI</strong>_Isend: Inicia envío pero retorna antes <strong>de</strong> copiar en buffer.• <strong>MPI</strong>_Irecv: Inicia recepción pero retorna antes <strong>de</strong> recibir.• <strong>MPI</strong>_Test: Chequea si la operación no bloqueante ha finalizado.• <strong>MPI</strong>_Wait: Bloquea hasta que acabe la operación no bloqueante.– Comunicación Asíncrona, .• <strong>MPI</strong>_Iprobe: Chequeo no bloqueante para un mensaje.• <strong>MPI</strong>_Probe: Chequeo bloqueante para un mensaje.


5. Comunicación No5.1. Solapando Comunicación con Computación• int <strong>MPI</strong>_Isend(void* buf, int count, <strong>MPI</strong>_Datatype datatype, int <strong>de</strong>st, inttag, <strong>MPI</strong>_Comm comm, <strong>MPI</strong>_Request *request)• int <strong>MPI</strong>_Irecv(void* buf, int count, <strong>MPI</strong>_Datatype datatype, int source, inttag, <strong>MPI</strong>_Comm comm, <strong>MPI</strong>_Request *request)– Argumento request: I<strong>de</strong>ntifica operación cuyo estado se preten<strong>de</strong>consultar o se espera que finalice.– No incluyen argumento status: Se obtiene con otras 2 funciones• int <strong>MPI</strong>_Test(<strong>MPI</strong>_Request *request, int *flag, <strong>MPI</strong>_Status *status)– flag > 0 ⇒ operación i<strong>de</strong>ntificada ha finalizado, libera request ,inicializa statusbloqueante– Versión para varias count operaciones : int <strong>MPI</strong>_Testall (int count,<strong>MPI</strong>_Request *array_of_requests, int *flag, <strong>MPI</strong>_Status*array_of_statuses)


5. Comunicación Nobloqueante5.1. Solapando Comunicación con Computación (cont.)• int <strong>MPI</strong>_Wait(<strong>MPI</strong>_Request *request, <strong>MPI</strong>_Status *status)– Bloquea hasta que operación finaliza– Versión para varias count operaciones : int <strong>MPI</strong>_Waitall( intcount, <strong>MPI</strong>_Request array_of_requests[], <strong>MPI</strong>_Statusarray_of_statuses[] )• Posible conectar operaciones no bloqueantes con contrapartesbloqueantes– int <strong>MPI</strong>_Request_free(<strong>MPI</strong>_Request *request) ⇒ Liberaciónexplícita request


5. Comunicación Nobloqueante5.2. Comunicación Asíncrona. Son<strong>de</strong>o <strong>de</strong> mensajes.• Accceso no estructurado a recurso compartido– Comprobar existencia <strong>de</strong> mensajes sin recibirlos• int <strong>MPI</strong>_Iprobe( int source, int tag, <strong>MPI</strong>_Comm comm, int *flag,<strong>MPI</strong>_Status *status )– No bloquea si no hay mensajes,. Si hay mensaje, se recibe con<strong>MPI</strong>_Recv– flag > 0 ⇒ ∃ mensaje pendiente que encaja con (source, tag, comm).• Más información mediante status.• int <strong>MPI</strong>_Probe(int source, int tag, <strong>MPI</strong>_Comm comm, <strong>MPI</strong>_Status*status )– Retorna sólo cuando hay mensaje que encaje con los argumentos.– Esperar la llegada mensaje sin conocer proce<strong>de</strong>ncia, etiqueta otamaño.


5. Comunicación Nobloqueante5.2. Comunicación Asíncrona. Ejemplo.• Recepción <strong>de</strong> fuente <strong>de</strong>sconocidaint count, *buf, source;<strong>MPI</strong>_Probe(<strong>MPI</strong>_ANY_SOURCE, 0, comm, &status);<strong>MPI</strong>_Get_count(status, <strong>MPI</strong>_INT, &count);buf=malloc(count*sizeof(int));source= status.<strong>MPI</strong>_SOURCE;<strong>MPI</strong>_Recv(buf, count, <strong>MPI</strong>_INT, source, 0, comm, &status);


6. Comunicadores• int <strong>MPI</strong>_Comm_split ( <strong>MPI</strong>_Comm comm, int color, int key,<strong>MPI</strong>_Comm *comm_out )– Operación colectiva que divi<strong>de</strong> grupo asociado a comm ensubgrupos, cada uno asociado a un comunicador diferentecomm_out.– Cada subgrupo contiene los procesos con el mismo valor <strong>de</strong>color.– color=<strong>MPI</strong>_UNDEFINED ⇒proceso no pertenece a nuevogrupo– <strong>La</strong> or<strong>de</strong>nación en el nuevo grupo se hace en base a key.• int <strong>MPI</strong>_Comm_free(<strong>MPI</strong>_Comm *comm)– Libera el comunicador comm


6. Comunicadores6.1. Ejemplos <strong>de</strong> creación <strong>de</strong> comunicadores<strong>MPI</strong>_Comm comm, comm1,comm2,comm3;int myid, color;<strong>MPI</strong>_Comm_rank(comm, &myid);color = myid%3;<strong>MPI</strong>_Comm_split (comm, color, myid, &comm1);if (myid < 8) color = 1; else color = <strong>MPI</strong>_UNDEFINED;<strong>MPI</strong>_Comm_split (comm, color, myid, &comm2);• comm2= Nuevo Comunicadorcon 8 primeros procs <strong>de</strong> comm.<strong>MPI</strong>_Comm_split (comm, 0, myid, &comm3);• comm3= Nuevo Comunicadorcon el mismo grupo <strong>de</strong> procsque comm.


6. Comunicadores6.2. Objetivos <strong>de</strong> los Comunicadores. Modularidad• Restringir <strong>de</strong>terminadas operaciones comunicación a ciertosgrupos → Implementación mo<strong>de</strong>lo MPMD– Programación por grupos• Separar paso <strong>de</strong> mensajes en grupos <strong>de</strong> procesos solapados.– Etiquetas no bastan. Fallan para <strong>de</strong>sarrollo modular.– Aplicación que usa módulo <strong>de</strong> biblioteca– Asegurar que el módulousa diferentes etiquetas– Solución: Nuevo comunicador• Argumento <strong>de</strong>l módulo• Desacopla paso <strong>de</strong> mensajes


7. Topologías Cartesianas• Numeración lineal (0,…,P-1) → No apropiada para algunas aplicaciones.– Ejemplo: Algoritmos <strong>de</strong> multiplicación <strong>de</strong> matrices → Malla 2D– Asignar proceso <strong>MPI</strong> a un proceso en una topología n-dimensional7.1. Creación• int <strong>MPI</strong>_Cart_create ( <strong>MPI</strong>_Comm comm_old, int ndims, int *dims, int*periods, int reor<strong>de</strong>r, <strong>MPI</strong>_Comm *comm_cart )– Crea comunicador cartesiano comm_cart con ndims dimensiones apartir <strong>de</strong> comm.– dims[i] = número <strong>de</strong> procesos en dimensión i-ésima.– periods[i] > 0 ⇒ dimensión i periódica, periods[i]=0 ⇒ No periódica– reor<strong>de</strong>r=0 ⇒ Se sigue la numeración <strong>de</strong> comm.– reor<strong>de</strong>r>0 ⇒ Se permite que <strong>MPI</strong> reor<strong>de</strong>ne la numeración según suconveniencia, por ejemplo, para hacer coincidir la topología con latopología física <strong>de</strong> la red.


7. Topologías Cartesianas7.2. I<strong>de</strong>ntificación <strong>de</strong> procesos.• int <strong>MPI</strong>_Cart_coords (<strong>MPI</strong>_Comm comm_cart, int rank, int maxdims, int*coords )– Devuelve coor<strong>de</strong>nadas <strong>de</strong>l proceso rank <strong>de</strong>ntro <strong>de</strong>l comunicadorcartesiano comm_cart con maxdims dimensiones– coords= array, coor<strong>de</strong>nadas <strong>de</strong>l proc. en cada dimensión.• int <strong>MPI</strong>_Cart_rank ( <strong>MPI</strong>_Comm comm_cart, int *coords, int *rank )– Devuelve el i<strong>de</strong>ntificador (rank) <strong>de</strong>l proceso que tiene lascoor<strong>de</strong>nadas coords en el comunicador cartesiano comm_cart.• int <strong>MPI</strong>_Cart_shift ( <strong>MPI</strong>_Comm comm_cart, int direction, int displ, int*source, int *<strong>de</strong>st )– Devuelve el i<strong>de</strong>ntificador <strong>de</strong> los procesos fuente y <strong>de</strong>stino (source,<strong>de</strong>st) para una operación <strong>de</strong> <strong>de</strong>splazamiento <strong>de</strong> displ pasos (displ>0 →arriba, < 0 → abajo) en la dimensión direction <strong>de</strong>ntro <strong>de</strong> comm_cart.


7. Topologías Cartesianas7.3. Ejemplo.<strong>MPI</strong>_Comm comm_2d;int myrank, size, P, Q, p, q, reor<strong>de</strong>r; <strong>MPI</strong>_Status status;int dims[2], local[2], period[2];int remain_dims[2],izqda, dcha, abajo, arriba;double buf;……………………..:::::::::::::::::::::::::::::::<strong>MPI</strong>_Comm_rank (<strong>MPI</strong>_COMM_WORLD, &myrank);dims[0] = dims[1] = 2; reor<strong>de</strong>r = 0; period[0] =1; period[1] = 0;0 12 3<strong>MPI</strong>_Cart_create(<strong>MPI</strong>_COMM_WORLD, 2, dims, period, reor<strong>de</strong>r, &comm_2d);<strong>MPI</strong>_Cart_coords(comm_2d, myrank, 2, local);<strong>MPI</strong>_Cart_shift(comm_2d, 1, 1, &arriba, &abajo);<strong>MPI</strong>_Sendrecv_replace( &buf, 1, <strong>MPI</strong>_DOUBLE, arriba, 0, abajo, 0, comm_2d, &status)


8. Tipos <strong>de</strong> datos <strong>de</strong>rivadosy empaquetado• int <strong>MPI</strong>_Type_vector( int count, int blocklen, int stri<strong>de</strong>,<strong>MPI</strong>_Datatype old_type, <strong>MPI</strong>_Datatype *newtype )– Crea tipo newtype = count bloques (cada uno con blocklenunida<strong>de</strong>s <strong>de</strong> tipo old_type) separados por stri<strong>de</strong> unida<strong>de</strong>s.• int <strong>MPI</strong>_Type_commit ( <strong>MPI</strong>_Datatype *datatype )– Prepara el nuevo tipo datatype para su uso en una función <strong>de</strong>comunicación.• int <strong>MPI</strong>_Type_free ( <strong>MPI</strong>_Datatype *datatype )– Libera el tipo <strong>de</strong> datos datatype


8. Tipos <strong>de</strong> datos <strong>de</strong>rivadosy empaquetado8.1. Ejemplo <strong>de</strong> Tipos <strong>de</strong> datos <strong>de</strong>rivados• Enviar un bloque 4x4, comenzando por A[0][2] <strong>de</strong> una matriz A <strong>de</strong>proceso 0 al 1float A[10][10];<strong>MPI</strong>_Datatype bloque;……………..<strong>MPI</strong>_Type_vector(4,4,10,<strong>MPI</strong>_FLOAT,&bloque);<strong>MPI</strong>_Type_commit(&bloque);If (myrank==0)<strong>MPI</strong>_Send(&(A[0][2]),1,bloque,1,0, <strong>MPI</strong>_COMM_WORLD);else<strong>MPI</strong>_Sendrecv(&(A[0][2]),1,bloque, 0, 0, <strong>MPI</strong>_COMM_WORLD,&status);


8. Tipos <strong>de</strong> datos <strong>de</strong>rivados8.3. Empaquetando datosy empaquetado• int <strong>MPI</strong>_Pack ( void *inbuf, int incount, <strong>MPI</strong>_Datatype datatype, void*outbuf, int outcount, int *position, <strong>MPI</strong>_Comm comm )– Empaqueta mensaje (inbuf , incount, datatype) en área contigua conoutcount bytes, <strong>de</strong>s<strong>de</strong> outbuf.– Entrada position = 1ª posición buffer salida a usar para empaquetar.– position se incrementa en el tamaño <strong>de</strong>l mensaje empaquetado– Salida <strong>de</strong> position = 1ª posición en buffer salida <strong>de</strong>spués empaquetar.– comm= comunicador para enviar mensaje empaquetado.– Mensaje empaquetado se envía como tipo <strong>MPI</strong>_PACKED• Función <strong>de</strong> Temporización (para medir tiempos)double <strong>MPI</strong>_Wtime() → Tiempo <strong>de</strong> retardo (en segs.) <strong>de</strong>s<strong>de</strong> un tiempoarbitrario en el pasado.


8. Tipos <strong>de</strong> datos <strong>de</strong>rivados8.3.1. Desempaquetando datosy empaquetado• int <strong>MPI</strong>_Unpack ( void *inbuf, int insize, int *position, void *outbuf, intoutcount, <strong>MPI</strong>_Datatype datatype, <strong>MPI</strong>_Comm comm )– Desempaqueta mensaje en (outbuf, outcount, datatype) <strong>de</strong>s<strong>de</strong> el áreacontigua con insize bytes que comienza en inbuf.– Entrada position= 1ª posición en buffer <strong>de</strong> entrada ocupada por elmensaje empaquetado.– position se incrementa en el tamaño <strong>de</strong>l mensaje empaquetado– Salida <strong>de</strong> position= 1ª posición en buffer entrada <strong>de</strong>spués <strong>de</strong>empaquetar posiciones ocupadas por el mensaje <strong>de</strong>sempaquetado.– comm=comunicador para recibir mensaje empaquetado


8. Tipos <strong>de</strong> datos <strong>de</strong>rivadosy empaquetado8.3.2. Empaquetando datos. Ejemploint position, i, j, a[2]; char buff[1000]; <strong>MPI</strong>_Comm comm= <strong>MPI</strong>_COMM_WORLD;....<strong>MPI</strong>_Comm_rank(<strong>MPI</strong>_COMM_WORLD, &myrank);if (myrank == 0){ position = 0;<strong>MPI</strong>_Pack(&i, 1, <strong>MPI</strong>_INT, buff, 1000, &position, comm);<strong>MPI</strong>_Pack(&j, 1, <strong>MPI</strong>_INT, buff, 1000, &position , comm);<strong>MPI</strong>_Send( buff, position, <strong>MPI</strong>_PACKED, 1, 0 , comm); }else<strong>MPI</strong>_Recv( a, 2, <strong>MPI</strong>_INT, 0, 0 , comm);/* ALTERNATIVA A LO ANTERIOR */{ <strong>MPI</strong>_Recv( buff, 1000, <strong>MPI</strong>_PACKED, 0, 0, &status);position = 0; <strong>MPI</strong>_Unpack(buff, 1000, &position, &i, 1, <strong>MPI</strong>_INT, comm);<strong>MPI</strong>_Unpack(buff, 1000, &position, &j, 1, <strong>MPI</strong>_INT, comm) }


9. Referencias útilesReferencias bibliográficas• <strong>MPI</strong>: A Message-Passing Interface Standard– http://www-unix.mcs.anl.gov/mpi/mpi-standard/mpi-report-1.1/mpi-report.html• <strong>MPI</strong>: The complete reference– Marc Snir, Steve Otto, Steven Huss-Le<strong>de</strong>rman, David Walker and JackDongara, MIT Press– /nfs/workshops/mpi/docs/mpi_complete_reference.ps.Z• Parallel Programming with <strong>MPI</strong>– Peter S. Pacheco, Morgan Kaufman Publishers, Inc• Using <strong>MPI</strong>: Portable Parallel Programing with Message PassingInterface– William Gropp, E. Lusk and A. Skjellum, MIT Press

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!