Programación paralela basada en paso de mensajes (MPI)dopico/MPI/MPI.pdf · La red es clave para...
Transcript of Programación paralela basada en paso de mensajes (MPI)dopico/MPI/MPI.pdf · La red es clave para...
Programación paralelaProgramación paralelabasada en paso de mensajesbasada en paso de mensajes
(MPI)(MPI)(MPI)(MPI)
ÍndiceÍndice ¿Qué es MPI?
Arquitectura de los sistemas de memoria distribuida
Modelos de programación
Esquema básico de un programa MPI
Funciones básicasFunciones básicas
Comunicación punto a punto
M did d l ti Medida del tiempo
Comunicación colectiva
Definición de nuevos tipos de datos
Mensajes de tamaño desconocido
CAR: Programación en MPI 2
¿Qué es MPI?¿ API estándar (portabilidad) para la programación paralela
basada en paso de mensajes (comunicación y sincronización)basada en paso de mensajes (comunicación y sincronización)
Pensado para sistemas de memoria distribuida (clusters, NUMA redes de sistemas heterogéneos )NUMA, redes de sistemas heterogéneos, …)
El programador necesita especificar todos los detalles acercade la distribución de datos y trabajo sincronización y losde la distribución de datos y trabajo, sincronización … y los datos deben ser enviados y recibidos explícitamente
Conjunto de funciones (biblioteca) que ocultan detalles deConjunto de funciones (biblioteca) que ocultan detalles de bajo nivel, tanto hardware como software
Modelos de programación MIMD y SPMD
Diversas implementaciones: MPICH, LAM, OpenMPI, …
Se puede y suele combinar con OpenMPp y p
CAR: Programación en MPI 3
Arquitectura básicaArquitectura básicaNodo
Procesador
Memoria …….
Procesador
Memoria
Procesador
Memoria
Datos Datos
d i
Red de interconexión
send receive
Cada procesador tiene su propia memoria local (no comparten memoria) Los procesos que se ejecutan en cada procesador operan sobre datos locales: si se necesitan datos de otro procesador se debe establecer unalocales: si se necesitan datos de otro procesador, se debe establecer una comunicación con el explícitamente mediante el envío/recepción de mensajes.
• Tiempo para construir y enviar un mensaje.
CAR: Programación en MPI 4
• Tiempo para recibir y desempaquetar el mensaje.
Arquitectura de un cluster (SSI)q ( )
ACAR: Programación en MPI 5
Ejemplo de cluster HPCEjemplo de cluster HPC
201 TFLOPS en 7 racks201 TFLOPS en 7 racks
677 MFLOPS por watio (#9 on Green500, Nov 2010)Keeneland System
(7 Racks)( )
S6500 Chassis(4 N d )
Rack(6 Chassis)
ProLiant SL390s G7(2CPUs, 3GPUs)
(4 Nodes)
M2070
Xeon 5660
5151679
GFLOPS
6718GFLOPS
40306GFLOPS
201528GFLOPS
67GFLOPS
Seis cores HT
515GFLOPS
GFLOPS24/18 GB
ACAR: Programación en MPI 6
RedesRedes La red es clave para un buen rendimiento
Dos factores críticos: Ancho de banda y latencia– Ancho de banda: 10-100 Gb/s Ejemplo:
L t i 1 AB 10Gb/– Latencia ≈1-30 μs
Redes utilizadas:
Latencia = 1 μs, AB = 10Gb/s
¿T en enviar 2000 bits? ¿Y 200KB?¿Y con AB=100Gb/s?
– Infiniband: Enlaces 1X, 4X o 12X, Data rate (Gb/s 1X): SDR (2), DDR (4), QDR (8), FDR (10), FDR (14), EDR (25)
– Gigabit: 10GbE, 40GbE, 100GbEGigabit: 10GbE, 40GbE, 100GbE– Myrinet, en desuso: 10 Gb/s– Cerca de las prestaciones de buses modernos:
• PCI Express 3.0 (x32): 256 Gbit/s• QuickPath Interconnect (4.0 GHz): 256 Gbit/s• HyperTransport 3 1 (3 2 GHz 32 pair): 409 6 Gbit/s• HyperTransport 3.1 (3.2 GHz, 32-pair): 409.6 Gbit/s
CAR: Programación en MPI 7
Modelo de programación SPMDModelo de programación SPMD MPI está pensado principalmente para utilizar el modelo SPMD
(single program multiple data)(single program multiple data)– Al arrancar una aplicación se lanzan en paralelo n copias del
mismo programa (procesos), facilita legibilidad y mantenimientop g (p ), g y– Distinción del código a ejecutar por cada uno: mediante el id del
procesovoid main(…){ int i,j,k;for (i=0; ..)
Código Fuente:
. . . . . .Proceso 1 Proceso n
n Ejecutables: void main(…)void main(…) void main(…)
Proceso 2
…….
n Ejecutables: ( ){ int i,j,k;for (i=0; ..). . . . . .
( ){ int i,j,k;for (i=0; ..). . . . . .
( ){ int i,j,k;for (i=0; ..). . . . . .
CAR: Programación en MPI 8
ProcesadorProcesador Procesador
MPI multithreadMPI multithread Se puede combinar con threads o con OpenMP
Atención al soporte dado si se usa MPI multithread– MPI THREAD SINGLE: Sólo un thread– MPI THREAD FUNNELED: Multithread, pero sólo uno (el
maestro) puede llamar a la biblioteca MPIMPI THREAD SERIALIZED M ltith d d it– MPI THREAD SERIALIZED: Multithread, pero no admite llamadas simultáneas, se serializan
– MPI THREAD MULTIPLE: Multithread, sin restricciones.MPI THREAD MULTIPLE: Multithread, sin restricciones.
MPI_Init_thread(required, provided): Informa del nivel de tsoporte
Ejemplo: Servicio distribuido siempre a la escucha
ACAR: Programación en MPI 9
Ejemplo: Servicio distribuido siempre a la escucha
Esquema básico de un programa (C)Esquema básico de un programa (C)
#include <mpi.h>Fichero de cabecera: definciones y tipos
main(int argc, char** argv){int nproc; // numero de procesosint myrank; // id del proceso
Inicializa la aplicación paralela MPI:S d é d l d fi i ió d i blint myrank; // id del proceso
. . .MPI_Init (&argc,&argv);
Se usa después de la definición de variablesy antes de las llamadas a funciones MPI
MPI_Comm_size (MPI_COMM_WORLD , &nproc);¿Cuántos procesosparticipan en la aplicación?
¿Quién soy yo?MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
Cuerpo del programa: cómputo y comunicación
¿Quién soy yo?0<= myrank <nproc
MPI_Finalize ();}
Finaliza MPI:Se usa después de la última función MPI
CAR: Programación en MPI 10
Esquema de un programa MPI (C)Esquema de un programa MPI (C)#include <mpi.h>
main(int argc, char** argv){int nproc; // numero de procesosint myrank; // id del procesoint myrank; // id del proceso . . .MPI_Init (&argc,&argv);MPI Comm size (MPI COMM WORLD &nproc);MPI_Comm_size (MPI_COMM_WORLD , &nproc);MPI_Comm_rank (MPI_COMM_WORLD, &myrank);if (myrank == 0)
codigo_maestro();else
codigo esclavo();
Esquema maestro-esclavo
Parecen la misma variable codigo_esclavo();MPI_Finalize ();
}
“myrank”, pero en cada proceso tiene distinto valor, es memoria distribuida
CAR: Programación en MPI 11
ComunicadoresComunicadores Comunicador:
C j t d d i t bi j A dConjunto de procesos que pueden intercambiar mensajes. A cada uno se le asigna un identificador único
MPI_Init crea un comunicador compuesto por todos los procesosespecificados al lanzar la ejecución del programa:
MPI_COMM_WORLD (por defecto)
MPI Comm size devuelve el número de procesos que componen _ _ p q pel comunicador
MPI Comm rank devuelve el id del proceso dentro delMPI_Comm_rank devuelve el id del proceso dentro del comunicador
MPI proporciona funciones para definir nuevos comunicadoresMPI proporciona funciones para definir nuevos comunicadores
CAR: Programación en MPI 12
Comunicadores de MPIComunicadores de MPI (default communicator)MPI COMM WORLD
User-createdCommunicatorMPI_COMM_WORLD
0 1 2 3 41
Communicator
size
5 6 7 8 9
1 rank Útil para varias
5 6 7 8 9210 0 apps colaborando
10 11 12 13 14 User-createdCommunicator3 4 5
15 16 17 18 19876
CAR: Programación en MPI 13Credit: Allan Snavely
EjemploEjemplo#include <mpi.h>main(){
int nproc; // numero de procesosint myrank; // id del procesoint myrank; // id del procesoMPI_Init();MPI_Comm_size (MPI_COMM_WORLD , &nproc);_ _ ( _ _ p )MPI_Comm_rank (MPI_COMM_WORLD, &myrank);printf(“Hola, soy el proc. %d de %d\n”, myrank, nproc);
MPI_Finalize ();
} $ mpicc hola.c –o hola$mpirun –np 4 holaHola, soy el proc. 3 de 4Hola, soy el proc. 0 de 4Hola, soy el proc. 2 de 4Hola soy el proc 1 de 4
14
Hola, soy el proc. 1 de 4
CAR: Programación en MPI
Las seis funciones básicasLas seis funciones básicas Arranque y parada
int MPI_Init(int *argc, char **argv);IN argcIN argv
Consulta del entorno de ejecución
int MPI_Finalize(void);
int MPI_Comm_size(MPI_Comm comm, int *size);IN comm communicatorOUT size number of tasks in "comm"OUT size number of tasks in comm
int MPI_Comm_rank(MPI_Comm comm,int *rank);IN comm communicator
Comunicación entre procesos (envío/recepción de mensajes)
OUT rank rank of the calling task
Comunicación entre procesos (envío/recepción de mensajes)
CAR: Programación en MPI 15
Comunicación: Envío de mensajeComunicación: Envío de mensajeint MPI_Send(void* buf, int count, MPI_Datatype datatype,
i t d t i t t MPI C )int dest, int tag, MPI_Comm comm);
IN buf initial address of send buffer IN count number of entries to sendIN count number of entries to sendIN datatype datatype of each entryIN dest rank of destinationIN t message tagIN tag message tagIN comm communicator
Envío de un mensaje contenido en buf de count elementos de tipo datatypeal proceso dest del comunicador comm y con etiqueta tag
Las etiquetas permiten al programador identificar los mensajes, p.e.establecer “tipos de mensaje” (datos, control, errores,…)
CAR: Programación en MPI 16
Comunicación: Recepción de mensajeComunicación: Recepción de mensajeint MPI_Recv(void* buf, int count, MPI_Datatype datatype,
int source, int tag, MPI Comm comm, MPI Status *status);int source, int tag, MPI_Comm comm, MPI_Status status);
OUT buf initial address of receive bufferIN count max # of entries to receiveIN datatype datatype of each entryIN source rank of sourceIN tag message tagIN comm communicatorOUT status return status (inf. acerca del mensaje recibido)
Recepción de un mensaje, a almacenar en buf, … procedente del proceso source …, status es una estructura interna donde se almacena información al finalizar la recepción (o MPI_STATUS_IGNORE)( _ _ )
Los mensajes se pueden filtrar (elegir) por origen, etiqueta y/o comunicador. El uso de comodines permite recibir un mensaje con MPI_ANY_TAG y MPI ANY SOURCEMPI_ANY_SOURCE
CAR: Programación en MPI 17
MPI StatusMPI_StatusInformación principal de la estructura MPI_Status:
int MPI_SOURCE; // id del proceso emisorAccesible directamente,
i
int MPI_TAG; // etiqueta del mensaje
p.e. si se usa MPI_ANY_SOURCE
int MPI ERROR; // el código de error si algo fue mal
Accesible directamente,p.e. si se usa MPI_ANY_TAG
int MPI_ERROR; // el código de error, si algo fue mal
int count; // longitud del mensaje
A ibl t é dAccesible a través de:MPI_Get_count (MPI_Status *status,
MPI_Datatype datatype,int *count)
. . . . CAR: Programación en MPI 18
int *count)
Comunicación: RecepciónComunicación: Recepción El mensaje enviado por el proceso Pq puede ser recibido por Pr si:
recv_comm = send_comm recv_datatype = send_datatyperecv_tag = send_tag rec_buf_size >= send_buf_sizesend dest = Prsend_dest Prrecv_src = Pq
No se puede suponer ningún orden de llegada!!!.p p g g
Ejemplo:for (i=1; i< comm sz; i++) {for (i=1; i< comm_sz; i++) {
MPI_Recv(result, result_sz, result_type; MPI_ANY_SOURCE,result_tag, comm, MPI_STATUS_IGNORE);
Process_result(result);}
CAR: Programación en MPI 19
Tipos de datos predefinidosTipos de datos predefinidos
MPI permite al programador crear nuevos tipos de datos (se verá más adelante)
CAR: Programación en MPI 20
Ejemplo: Hello World!Ejemplo: Hello World!#include <stdio.h>
#include "mpi.h"
int main(int argc, char **argv) {
i t k tint rank, count;
char msg[20];
MPI Status status;MPI_Status status;
MPI Init(&argc, &argv);MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);_ _ ( _ _ , );
...
CAR: Programación en MPI 21
Ejemplo: Hello World!Ejemplo: Hello World!if (rank==0) {
printf ("I am master Sending the message \n\n");printf ( I am master. Sending the message.\n\n );strcpy(msg,"Hello World!");MPI_Send(msg, 13, MPI_CHAR, 1, 100, MPI_COMM_WORLD);
}else {
printf ("I am the slave %d. Receiving the message.\n”, rank);MPI_Recv(msg, 13, MPI_CHAR, 0, 100, MPI_COMM_WORLD, &status);printf ("The message is: %s\n", msg);
MPI_Get_count(&status, MPI_CHAR, &count)printf(“Recibidos %d caracteres de %d con tag= %d\n”,
count, status.MPI_SOURCE, status.MPI_TAG);}MPI_Finalize();_ ()
}CAR: Programación en MPI 22
Tipos de comunicaciónTipos de comunicación Punto a punto: Entre dos procesos (1 emisor - 1 receptor)
P0 P1dest=1
dest=2dest=3
Ejemplo:MPI_Send (..,dest, ..)MPI Recv ( source )
P2P3
dest 3 MPI_Recv (..,source, ..)
Colectiva: Involucra a todos los procesos de un comunicador(1 o N emisores – 1 o N receptores)
P0 P1P0 P1
P2P3P2
P3Ejemplo:
( )
CAR: Programación en MPI 23
MPI_Bcast (..,MPI_COMM_WORLD, ..)
Comunicación punto a puntoComunicación punto a punto Modelos de comunicación:
Tiempo que un proceso pasa bloqueado tras llamar a una función de comunicación (send/recv)
Bl t M ti l bl d h t l– Bloqueante: Mantiene al proceso bloqueado hasta que la operación “finalice”
– No bloqueante : Inicia la operación y recupera el controlMPI_Send/Recv
– No bloqueante : Inicia la operación y recupera el control inmediatamente: el proceso debe encargarse más adelante de averiguar si la operación ha finalizado o no
Finalización de la operaciónE i C d d ibi l b ff l d t d
MPI_Isend/Irecv
– Emisor: Cuando puede reescribir el buffer con los datos de origen sin interferencia
– Receptor: Cuando dispone del mensaje en el buffer designadoReceptor: Cuando dispone del mensaje en el buffer designado
CAR: Programación en MPI 24
Envío no bloqueanteEnvío no bloqueanteint MPI_Isend(void* buf, int count, MPI_Datatype datatype,
int dest int tag MPI Comm comm MPI Request *request);int dest, int tag, MPI_Comm comm, MPI_Request *request);
IN buf initial address of send buffer IN count number of entries to sendIN datatype datatype of each entryIN dest rank of destinationIN tag message tagIN tag message tagIN comm communicatorOUT request request handle
Se utiliza para saber si la operación ha finalizado:Se utiliza para saber si la operación ha finalizado:Solo entonces se puede reutilizar el buffer de envío buf
CAR: Programación en MPI 25
Recepción no bloqueanteRecepción no bloqueanteint MPI_Irecv(void* buf, int count, MPI_Datatype datatype,
int source, int tag, MPI_Comm comm, MPI_Request *request);
OUT buf initial address of receive bufferIN t # f t i t iIN count max # of entries to receiveIN datatype datatype of each entryIN source rank of sourceIN tag message tagIN comm communicatorOUT request request handle
S tili b i l ió h fi li dSe utiliza para saber si la operación ha finalizado:Solo entonces el mensaje está disponible en buf
CAR: Programación en MPI 26
Envío y recepción no bloqueantesEnvío y recepción no bloqueantesint MPI_Wait(MPI_Request *request, MPI_Status * status);
INOUT request request handleOUT status status object
Bloquea al proceso hasta que la operación correspondiente termina:
int MPI_Test(MPI_Request *request, int *flag,
MPI Status *status);_ );
INOUT request request handleOUT flag true if operation completed
t t bj tOUT status status object
Comprueba si la operación ha terminado o no (flag = 1 ó 0)
CAR: Programación en MPI 27
Alternativas al waitAlternativas al wait Espera por todas las operaciones pendientes
int MPI_Waitall(int count, MPI_Request*array_of_requests, MPI_Status*array of statuses)
int MPI_Waitall(int count, MPI_Request*array_of_requests, MPI_Status*array of statuses)*array_of_statuses)
Espera por la primera que termine (indicada con index)
i (
array_of_statuses)
int MPI_Waitany(int count, MPI_Request*array_of_requests, int *index, MPI_Status*status)
int MPI_Waitany(int count, MPI_Request*array_of_requests, int *index, MPI_Status*status)
Espera por al menos una operación. El número de operaciones que terminó se indica con outcount y sus indices y status son devueltos.devueltos.int MPI_Waitsome(int incount, MPI_Request
*array_of_requests, int *outcount, int*array of indices, MPI Status *array of statuses)
int MPI_Waitsome(int incount, MPI_Request*array_of_requests, int *outcount, int
*array of indices, MPI Status *array of statuses)
ACAR: Programación en MPI 28
array_of_indices, MPI_Status array_of_statuses)array_of_indices, MPI_Status array_of_statuses)
Alternativas al TestAlternativas al Test Comprueba si todas las operaciones terminaron (flag=1)
int MPI_Testall(int count, MPI_Request*array_of_requests, int *flag,MPI_Status*array of statuses)
int MPI_Testall(int count, MPI_Request*array_of_requests, int *flag,MPI_Status*array of statuses)*array_of_statuses)
Comprueba si alguna terminó (flag=1), e indica su índice
*array_of_statuses)
int MPI_Testany(int count, MPI_Request*array_of_requests, int *index, int *flag, MPI_Status *status)
int MPI_Testany(int count, MPI_Request*array_of_requests, int *index, int *flag, MPI_Status *status)_ )
Comprueba si algunas terminaron (flag=1), e indica cuántas (outcount) y sus índices
_ )
int MPI_Testsome(int incount, MPI_Request*array_of_requests, int *outcount, int* array of indices MPI Status *array of statuses)
int MPI_Testsome(int incount, MPI_Request*array_of_requests, int *outcount, int* array_of_indices, MPI_Status *array_of_statuses)
array_of_indices, MPI_Status *array_of_statuses)
ACAR: Programación en MPI 29
Envío y recepción no bloqueantesEnvío y recepción no bloqueantes
La idea es solapar cómputo y comunicación.p p yEjemplo: recibir la siguiente tarea a hacer mientras se procesa la actual.Image * Curr_img, *Next_img;
MPI_Recv(Curr_img,…);
while (status.tag != END) {
MPI_Irecv(Next_img,…,Next_req); // No espera!!!
C t i (C i ) // Ti i !!!Compute_img(Curr_img); // Time consuming!!!
MPI_Send(results,…); // Copy data and return
MPI Wait(Next req); // Return quicklyMPI_Wait(Next_req); // Return quickly
Curr_img = Next_req; // Copying pointers
}
CAR: Programación en MPI 30
MPI Send, MPI RecvMPI_Send, MPI_Recv
CAR: Programación en MPI 31
MPI Isend, MPI IrecvMPI_Isend, MPI_Irecv
CAR: Programación en MPI 32
Comunicación punto a puntoComunicación punto a punto Modos de envío
MPI proporciona cuatro versiones para cada modelo de comunicación (bloqueante/no bloqueante):
– Standard: MPI_Send
– Synchronous: MPI Ssend– Synchronous: MPI_Ssend
– Buffered: MPI_Bsend
– Ready: MPI_Rsend
CAR: Programación en MPI 33
Modos de envío: MPI SendModos de envío: MPI_SendSynchronous: MPI_Ssend(…)La operación se da por finalizada sóloLa operación se da por finalizada sólocuando el mensaje ha sido recibido enel destino. Espera al receptor.
Buffered: MPI_BsendEl mensaje se guarda en un buffer,j gdefinido por el usuario. La operaciónse da por finalizada en cuanto se realizala copia. Si no hay espacio, el envíofallafalla.
Ready: MPI Rsendy _La operación sólo tiene éxito si seha iniciado ya la recepcióncorrespondiente (el receptor está(Preparado).
CAR: Programación en MPI 34
Modos de envío: MPI SendModos de envío: MPI_Send Standard (MPI_Send). La biblioteca dedice si espera (bloqueante) o
copia en memoria el mensaje (localmente bloqueante) y retorna. – Según el tamaño del mensaje, para pequeños usa buffer, con grandes espera. – V: Genérico para la mayoría de casos.
Synchronous (MPI Ssend). El envío espera a que alguien pida recibirl d (bl )
y ( _ ) p q g plos datos (bloqueante) – Entonces pone los datos en la red y espera confirmación– No hay buffering adicional. – V: Seguro y portable. I: Larga espera
Buffered (MPI_Bsend). Copia el mensaje en la biblioteca y retorna al llamante– No hay comunicación real hasta que se hace un receive.– V: Desacopla envío y recepción, el emisor no espera– I: Añade el coste de copiar los datos y la gestión del buffer depende del
dp y g p
programador.
Ready (MPI_Rsend). Válido sólo si el receptor está listo– V: Más eficiente ya que no hay dialogo I: PeligrosoV: Más eficiente ya que no hay dialogo. I: Peligroso
ACAR: Programación en MPI 35
MPI SsendMPI_Ssend
Espera al receptor
ACAR: Programación en MPI 36
MPI BsendMPI_Bsend El programador gestiona el buffer. Se copia el mensaje y p g g p j y
retornaMPI Buffer attach(void *buf, int size)_ _
ACAR: Programación en MPI 37
MPI RsendMPI_Rsend
El receptor ya está listo para recibir (sino error)
ACAR: Programación en MPI 38
Modos de comunicación punto a puntoModos de comunicación punto a punto
Modo de envío Bloqueante No bloqueanteStandard Send MPI Send MPI IsendStandard Send MPI_Send MPI_IsendSynchronous Send MPI_Ssend MPI_IssendBuffered Send MPI Bsend MPI IbsendBuffered Send MPI_Bsend MPI_IbsendReady Send MPI_Rsend MPI_Irsend
Recepción (recv) MPI_Recv MPI_Irecv
CAR: Programación en MPI 39
Comunicación punto a punto: ResumenComunicación punto a punto: ResumenSi MPI_Send no es suficiente para nuestros propósitos, podemos elegir entre:
El proceso emisor … Función
.. debe bloquearse hasta quese entregue el mensaje
MPI_SSendse entregue el mensaje
.. debe esperar solo hasta queel mensaje esté en el buffer
MPI_Bsendj
.. debe retornar inmediatamentesin bloquearse nunca
MPI_Isend
CAR: Programación en MPI 40
Medida del tiempoMedida del tiempo MPI Wtime()()
double start, finish, time;
MPI B i (MPI COMM WORLD)MPI_Barrier(MPI_COMM_WORLD);start = MPI_Wtime();……MPI_Barrier(MPI_COMM_WORLD);finish = MPI Wtime();finish = MPI_Wtime();time = finish ‐ start;
CAR: Programación en MPI 41
EjemplosEjemplos Veamos a continuación algunos ejemplos:
– El primer nodo envía un mensaje al siguiente y espera que le vuelva. Cada nodo lo reenvía a su vecino.
– Todos los nodos envían un mensaje al siguiente y esperan que le vuelva. Reenvían los mensajes que le p q j qllegan a su vecino.
Cálculo del número PI– Cálculo del número PI
CAR: Programación en MPI 42
Comunicación collectivaComunicación collectiva Comunicación en la que participan todos los procesos de un
comunicadorcomunicador
La operación debe ser invocada por todos los procesos (mismos parámetros sin tags)(mismos parámetros, sin tags)
Estas operaciones implican un punto de sincronización entre los procesos son bloqueanteslos procesos, son bloqueantes
Todos los procesos deben ejecutarlas antes de seguir
T l Tres clases:– Sincronización: Barreras
T f i d d t B d t S tt G th All th– Transferencia de datos: Broadcast, Scatter, Gather, Allgather– Cómputo colectivo: Reduce, Scan
CAR: Programación en MPI 43
Barrera de sincronizaciónBarrera de sincronización Sincronización global entre todos los procesos del
comunicador
int MPI Barrier(MPI Comm comm)int MPI_Barrier(MPI_Comm comm)
IN comm comunicador
Cualquier proceso que la llame se bloquea hasta que todos los procesos del comunicador lo hayan hecho
CAR: Programación en MPI 44
Envío múltipleEnvío múltiple Broadcast: Envío de los mismos datos desde un proceso
( t) t d l d á(root) a todos los demás
int MPI_Bcast(void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
Ejemplo:root = 0;if (rank root)
Ejecutada por todos los procesosif (rank==root)
sprintf(msg,”Hola, soy el root(%d)”, root); MPI_Bcast(msg, 100, MPI_CHAR, root, MPI_COMM_WORLD);
todos los procesos
printf("Mensaje recibido por %d es: %s\n”, rank, msg);. . .
CAR: Programación en MPI 45
Envío múltipleEnvío múltiple Broadcast: Envío de los mismos datos desde un proceso
( t) t d l d á(root) a todos los demásint MPI_Bcast(void* buffer, int count, MPI_Datatype datatype,
int root MPI Comm comm)int root, MPI_Comm comm)
INOUT buffer starting address of bufferIN count number of entries in bufferIN datatype data type of buffer IN root rank of broadcast rootIN comm communicator
CAR: Programación en MPI 46
Envío múltipleEnvío múltiple Scatter: Distribución de datos del root a todos los procesos.
Cada proceso recibe una parte de los datos.
MPI Scatter(void* sendbuf int sendcount MPI Datatype sendtypeMPI_Scatter(void sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype,int root, MPI_Comm comm)
recbuf
sendbufsendbuf
CAR: Programación en MPI 47
Envío múltipleEnvío múltiple Scatter: Distribución (reparto) de datos de un proceso entre
t dtodos.MPI_Scatter(void* sendbuf, int sendcount, MPI_Datatype sendtype,
void* recvbuf int recvcount MPI Datatype recvtypevoid recvbuf, int recvcount, MPI_Datatype recvtype,int root, MPI_Comm comm)
IN sendbuf address of send buffer IN sendcount nº of elements send to each processIN sendtype datatype of send buffer elementsOUT recvbuf address of receive buffer IN recvcount number of elements in receive bufferIN recvtype data type of recv buffer elementsIN root rank of sending processIN root rank of sending processIN comm communicator
CAR: Programación en MPI 48
Envío múltipleEnvío múltiple Scatterv: Distribución de datos de un proceso entre todos.
C d ib ú d l t di ti tCada proceso recibe un número de elementos distinto.MPI_Scatterv(void* sendbuf, int *sendcounts, int *displs,
MPI Datatype sendtype void* recvbuf int recvcountMPI_Datatype sendtype, void recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
IN sendbuf address of send buffer IN sendcounts integer arrayIN displs integer array of displacementsIN sendtype datatype of send buffer elementsyp ypOUT recvbuf address of receive buffer IN recvcount number of elements in receive bufferIN recvtype data type of recv buffer elementsIN recvtype data type of recv buffer elementsIN root rank of sending processIN comm communicator
CAR: Programación en MPI 49
MPI Scatter: EjemploMPI Scatter: Ejemplo Distribuir una matriz NxN entre P procesosp
float A[N][N], Ap[N/P][N], b[N], c[N], cp[N/P];
MPI_Scatter(A, N/P*N, MPI_Float, Ap, N/P*N, MPI_Float, 0 ,MPI_COMM_WORLD); // root = 0;
ACAR: Programación en MPI CAR: Programación en MPI 50
Recepción múltipleRecepción múltiple Gather: Recolección de datos (resultados) de todos los
d ll (l i d S tt )procesos en uno de ellos (la inversa de Scatter)
Cada proceso manda su parte al root (en orden de id)MPI_Gather(void* sendbuf, int sendcount, MPI_Datatype sendtype,
void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI Comm comm)int root, MPI_Comm comm)
sendbuf
recbufrecbuf
CAR: Programación en MPI 51
Recepción múltipleRecepción múltiple Gather: Recolección de datos (resultados) de todos los
d ll l t (l i d S tt )procesos en uno de ellos, el root (la inversa de Scatter)
MPI Gather(void* sendbuf int sendcount MPI Datatype sendtypeMPI_Gather(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
IN sendbuf starting address of send buffer IN sendcount number of elements in send bufferIN sendtype data type of send buffer elementsIN sendtype data type of send buffer elementsOUT recvbuf address of receive bufferIN recvcount number of elements for any receiveIN recvtype data type of recv buffer elementsIN recvtype data type of recv buffer elementsIN root rank of reciving processIN comm communicator
CAR: Programación en MPI 52
Recepción múltipleRecepción múltiple Gatherv: Recolección de datos de todos los procesos en el
t C d d ú di ti t d l troot. Cada uno manda un número distinto de elementos.
MPI Gatherv(void* sendbuf int sendcount MPI Datatype sendtypeMPI_Gatherv(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int *recvcounts, int *displs,MPI_Datatype recvtype, int root, MPI_Comm comm)
IN sendbuf starting address of send buffer IN sendcount number of elements in send bufferIN sendtype data type of send buffer elementsIN sendtype data type of send buffer elementsOUT recvbuf address of receive bufferIN recvcounts integer arrayIN displs integer array of displacementsIN displs integer array of displacementsIN recvtype data type of recv buffer elementsIN root rank of reciving processIN comm communicator
CAR: Programación en MPI 53
IN comm communicator
MPI Gather: EjemploMPI Gather: Ejemplo Producto vect-Mat Axb=cfl t A[N][N] A [N/P][N] b[N] [N] [N/P]float A[N][N], Ap[N/P][N], b[N], c[N], cp[N/P];for (i = 1; i < N/P; i++) {
cp[i] = 0;for (k = 0; k < N; k++)
cp[i] = cp[i] + Ap[i][k] * b[k];}}MPI_Gather(cp, N/P, MPI_Float, c, N/P, MPI_Float, root,
MPI_COMM_WORLD); // root = 0
ACAR: Programación en MPI CAR: Programación en MPI 54
Recepción y envío múltipleRecepción y envío múltiple Recolección de resultados: Todos los nodos reciben todos los
datos. Es un gather más un broadcast del resultado
MPI Allgather(void* sendbuf, int sendcount,MPI_Allgather(void* sendbuf, int sendcount, MPI D t t dt id* b f i t tMPI_Allgather(void sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
ACAR: Programación en MPI CAR: Programación en MPI 55
Recepción y envío múltipleRecepción y envío múltiple
Recolección de resultados: Todos los nodos reciben todos losRecolección de resultados: Todos los nodos reciben todos los datos. Es un gather más un broadcast del resultado
MPI_Allgather(void* sendbuf, int sendcount, MPI_Datatype_ g ( _ ypsendtype, void* recvbuf, int recvcount, MPI_Datatyperecvtype, MPI_Comm comm) IN sendbuf starting address of send buffer IN sendcount number of elements in send buffer IN sendtype datatype of send buffer elementsIN sendtype datatype of send buffer elementsOUT recvbuf address of receive buffer IN recvcount nº elements received from any processIN recvtype data type of recv buffer elementsIN comm communicator
ACAR: Programación en MPI CAR: Programación en MPI 56
Recepción y envío múltipleRecepción y envío múltiple Recolección de resultados: Todos los nodos reciben todos los
datos. Cada nodo envía un número distinto de elementos
MPI_Allgatherv(void* sendbuf, int sendcount, MPI_Datatypei f i i isendtype, void* recvbuf, int *recvcounts, int *displs,
MPI_Datatype recvtype, MPI_Comm comm)IN sendbuf starting address of send bufferIN sendbuf starting address of send buffer IN sendcount number of elements in send buffer IN sendtype datatype of send buffer elementsOUT recvbuf address of receive buffer IN recvcounts integer array
di l i t f di l tIN displs integer array of displacementsIN recvtype data type of recv buffer elementsIN comm communicator
ACAR: Programación en MPI CAR: Programación en MPI 57
IN comm communicator
MPI AllGather: EjemploMPI AllGather: Ejemplofloat A[N][N], Ap[N/P][N], b[N], c[N], cp[N/P];for (i = 1; i < N/P; i++) {for (i 1; i < N/P; i ) {
cp[i] = 0;for (k = 0; k < N; k++)
cp[i] = cp[i] + Ap[i][k] * b[k];cp[i] = cp[i] + Ap[i][k] b[k];}MPI_AllGather(cp, N/P, MPI_Float, c, N/P, MPI_Float,MPI COMM WORLD);MPI_COMM_WORLD);
ACAR: Programación en MPI CAR: Programación en MPI 58
MPI Scatterv and (All)GathervMPI Scatterv and (All)Gatherv
ACAR: Programación en MPI CAR: Programación en MPI 59
Comunicaciones colectivasComunicaciones colectivasAABroadcast
AP0P1
AA
P1P2P3
AB
DC
Scatter
Gather
B C DAP0P1P2P3 DP3
AB Allgather
P0P1
A B C DA B C D
DC
gP2P3
A0 A1 A2 A3P0
A B C DA B C D
A0 B0 C0 D0A0 A1 A2 A3B0 B1 B2 B3
D0 D1 D2 D3C0 C1 C2 C3
Alltoall(Scatter + Gather)
P0P1P2P3
A0 B0 C0 D0A1 B1 C1 D1
A3 B3 C3 D3A2 B2 C2 D2
CAR: Programación en MPI 60
D0 D1 D2 D3P3 A3 B3 C3 D3
Cómputo colectivoCómputo colectivo Reduce: Combina los datos recibidos de cada proceso,
dejando el resultado en uno de ellos (root)
int MPI_Reduce(void* sendbuf, void* recvbuf, int count,MPI_Datatype datatype, MPI_Op op,int root, MPI_Comm comm)
sendbufsendbuf
recbuf
CAR: Programación en MPI 61
Cómputo colectivoCómputo colectivo Reduce: Combina los datos recibidos de cada proceso,
dejando el resultado en uno de ellos (root)
int MPI Reduce(void* sendbuf void* recvbuf int countint MPI_Reduce(void sendbuf, void recvbuf, int count,MPI_Datatype datatype, MPI_Op op, int root,MPI_Comm comm)
IN sendbuf address of send buffer OUT recvbuf address of receive buffer (at root)IN count number of elements in send bufferIN count number of elements in send bufferIN datatype data type of elements of send buffer IN op reduce operationIN root rank of root processIN root rank of root processIN comm communicator
CAR: Programación en MPI 62
MPI Reduce: EjemploMPI Reduce: Ejemplo
float abcd[4] sum[4];float abcd[4], sum[4];
MPI_Reduce(abcd, sum, 4, MPI_Float, root, MPI_SUM, MPI COMM WORLD); // root = 0MPI_COMM_WORLD); // root = 0
abcd en cada nodo sum en rootabcd en cada nodo sum en root
ACAR: Programación en MPI CAR: Programación en MPI 63
Cómputo colectivoCómputo colectivo Recolección de resultados: Todos los nodos reciben todos los
datos. Es un reduce más un broadcast del resultado
int MPI Allreduce(void* sendbuf void* recvbuf intint MPI_Allreduce(void sendbuf, void recvbuf, intcount, MPI_Datatype datatype, MPI_Op op, MPI_Commcomm)
ACAR: Programación en MPI CAR: Programación en MPI 64
Cómputo colectivop Recolección de resultados: Todos los nodos reciben todos los
datos. Es un reduce más un broadcast del resultado
int MPI_Allreduce(void* sendbuf, void* recvbuf, int count, _ ( , , ,MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
IN sendbuf address of send buffer OUT recvbuf address of receive buffer (at root)IN count number of elements in send bufferIN datatype data type of elements of send buffer IN op reduce operationIN comm communicator
ACAR: Programación en MPI CAR: Programación en MPI 65
MPI AllReduce: EjemploMPI AllReduce: Ejemplo
fl b d[ ] [ ]float abcd[4], sum[4];
MPI_AllReduce(abcd, sum, 4, MPI_Float, MPI_SUM, MPI_COMM_WORLD);
ACAR: Programación en MPI CAR: Programación en MPI 66
Cómputo colectivoC p Recolección de resultados: Todos los nodos mandan
lt d t d l l bi ( d ) ú iresultados a todos los procesos que los combina (reduce) a un único valor. Proceso i recibe y combina datos del proceso 0 al i.
int MPI_Scan(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)_ yp yp _ p p _ )
IN sendbuf address of send buffer OUT recvbuf address of receive buffer (at root)IN count number of elements in send bufferIN datatype data type of elements of send buffer IN op reduce operationIN comm communicator
ACAR: Programación en MPI CAR: Programación en MPI 67
Cómputo colectivoCómputo colectivo
P0
P1
P2
A
B
C
f(ABCD)
ReduceP2
P3 D
C
P0 A f(A)
P1
P2
P3
B
D
C
f(AB)
f(ABC)
f(ABCD)
Scan
P3 D f(ABCD)
CAR: Programación en MPI 68
Operaciones predefinidasOperaciones predefinidasOperandos (C)
integer, float
integer
integer, MPI_BYTE
float, double, long double
CAR: Programación en MPI 69
Funciones avanzadasFunciones avanzadasDe más usadas a menos usadas:
Empaquetar/desempaquetar
Definir nuevos tipos.
Comunicación persistenteComunicación persistente
Mensajes de tamaño desconocido
Creación de nuevos comunicadores (se verá por encima)
Creación dinámica de procesos (se verá por encima) Creación dinámica de procesos (se verá por encima)
CAR: Programación en MPI 70
Empaquetado/desempaquetadoEmpaquetado/desempaquetado
El coste de enviar varios mensajes pequeños es muy El coste de enviar varios mensajes pequeños es muy alto, por la latencia, mejor agruparlos y mandar uno:
int MPI Pack(void* inbuf int incount MPI Datatypeint MPI_Pack(void* inbuf, int incount, MPI_Datatypedatatype, void *outbuf, int outsize, int *position, MPI_Comm comm)
IN inbuf input buffer startIN incount number of input data itemspIN datatype datatype of each input data itemOUT outbuf output buffer startIN outsize output buffer size, in bytesINOUT position current position in buffer(bytes)IN comm communicator for packed message
ACAR: Programación en MPI 71
IN comm communicator for packed message
Empaquetado/desempaquetadoEmpaquetado/desempaquetado
MPI_Unpack(void* inbuf, int insize, int * position void*outbuf, int outcount, MPI_Datatype * datatype, MPI Comm comm)MPI_Comm comm)
IN inbuf input buffer startIN insize size of input buffer (bytes)INOUT position current position bytes)OUT outbuf output buffer startOUT outbuf output buffer startIN outcount number of items to be unpackedIN datatype datatype of each output data itemIN comm communicator for packed message
ACAR: Programación en MPI 72
Empaquetado/desempaquetadoEmpaquetado/desempaquetado Para asegurar la portabilidad no se debe suponer nada dePara asegurar la portabilidad no se debe suponer nada de
los tamaños y preguntar en cada caso cual es:
int MPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int *size)
IN incount count argument to packing callIN datatype datatype argument to packing callIN comm communicator argument to packing callOUT size upper bound on size of packed
message (bytes)message (bytes)
ACAR: Programación en MPI 73
Ejemplo packEjemplo packint count,counts[64], size1, size2, size,position;char chr[100], *packbuf;...// Enviar N caracteres (chr), N no conocido (count)// Dos mensajes tarda el doble// ll t l l k b ff// allocate local pack buffer
MPI_Pack_size(1, MPI_INT, comm, &size1);MPI Pack size(count MPI CHAR comm &size2);MPI_Pack_size(count, MPI_CHAR, comm, &size2);size = size1+size2;packbuf = (char *)malloc(size);
// pack “count”, seguido de count caracteres
position = 0;position 0;MPI_Pack(&count, 1, MPI_INT, packbuf, size, &position, comm);
// Gracias a position se encadenan uno tras otro
ACAR: Programación en MPI 74
// pMPI_Pack(chr, count, MPI_CHAR, packbuf, size, &position, comm);
Tipos de datos derivadosTipos de datos derivados Tipos básicos: Suficiente cuando se envian bloques de datos
ti d l i ti ( t i )contiguos del mismo tipo (p.e. matriz)
MPI permite crear nuevos tipos de datos para enviar:– Bloques de memoria no contiguos (p.e. ciertos elementos de una
matriz)– Datos heterogéneos (p.e. struct en C)g (p )– Usar tipos definidos por el usuario: ayuda a mejorar la legibilidad ya
que el programa se expresa en términos de la aplicación
Algunos de estos tipos (derived datatypes) son:– Contiguous
V t /H t– Vector/Hvector– Indexed/Hindexed– Struct
CAR: Programación en MPI 75
Tipos de datos “derivados”Tipos de datos derivados Definición
MPI_Datatype nombre
ConstrucciónConstrucciónMPI_Type_contiguous (…)MPI_Type_vector (…)MPI_Type_indexed (…)
Commit:MPI_Type_commit(…)
Enviar y recibir
LiberarMPI Type free(…)MPI_Type_free(…)
CAR: Programación en MPI 76
Tipos de datos “derivados”Tipos de datos derivadosDefinición:
S i dSecuencia de pares:
{(t0,d0), (t1,d1), … , (tn-1,dn-1)}
- ti es un tipo de datos básico- ti es un tipo de datos básico
- di es un desplazamiento respecto al comienzo del mensaje que lo utiliza
MPI_Type_contiguous: Construye un tipo derivado cuyos componentes son elementos de un array, almacenados consecutivamente en memoria.
MPI Type vector: Construye un tipo derivado cuyos componentes son MPI_Type_vector: Construye un tipo derivado cuyos componentes son elementos de un array, espaciados a intervalos regulares
MPI_Type_indexed: Construye un tipo derivado cuyos componentes son y y yelementos arbitrarios de un array
MPI_Type_struct: Construye un tipo derivado cuyos componentes son camposarbitrarios de un structarbitrarios de un struct
CAR: Programación en MPI 77
Tipos de datos “derivados”Tipos de datos derivados1 2 3 4 MPI_Type_contiguous(int count, MPI_Datatype oldtype,
MPI_Datatype *newtype)
5 6 7 89 10 11 12
13 14 15 16
MPI_Datatype filaMPI_Type_contiguous(4, MPI_INT, &fila)MPI_Type_commit(&fila)13 14 15 16MPI_Send(&a[1][0], 1, fila, dest, tag, comm);
5 6 7 8
1 2 3 4MPI_Type_vector(int count, int blocklength, int stride,
1 2 3 45 6 7 89 10 11 12
MPI_Datatype oldtype, MPI_Datatype *newtype)
MPI_Datatype columnaMPI Type vector(4, 1, 4, MPI INT, &columna)
13 14 15 16MPI_Type_vector(4, 1, 4, MPI_INT, &columna)MPI_Type_commit(&columna)MPI_Send(&a[1][0], 1, fila, dest, tag, comm);
CAR: Programación en MPI 78
2 6 10 14
Tipos de datos “derivados”Tipos de datos derivados1 2 3 4 MPI_Type_indexed(int count, int array_of_blocklengths,
int *array of displacement5 6 7 89 10 11 12
13 14 15 16
int *array_of_displacement,MPI_Datatype oldtype,MPI_Datatype *newtype)
MPI Datatype matTrian13 14 15 16 MPI_Datatype matTrianMPI_Type_indexed (4, block_length,disp, MPI_INT, matTrian)MPI_Type_commit(&matTrian)disp[0] = 0
disp[1] = 4disp[2] = 8
MPI_Send(&a, 1, matTrian, dest, tag, comm);
1 5 6 9 10 11 13 14 15 16
disp[2] = 8disp[3] = 12block_length[0] = 1block_length[1] = 2block length[2] = 3 1 5 6 9 10 11 13 14 15 16block_length[2] = 3block_length[3] = 4
CAR: Programación en MPI 79
Tipos de datos “derivados”Tipos de datos derivados Continuous: Conjunto de elementos del mismo tipo y
t ñ l d ti t itamaño almacenados consecutivamente en memoria
MPI T ti (i t t MPI D t t ldtMPI_Type_contiguous(int count, MPI_Datatype oldtype,MPI_Datatype *newtype)
IN count replication countpIN oldtype old datatypeOUT newtype new datatype
CAR: Programación en MPI 80
Tipos de datos “derivados”Tipos de datos derivados Vector: Conjunto de elementos del mismo tipo
espaciados a inter alos reg laresespaciados a intervalos regularesMPI_Type_vector(int count, int blocklength, int stride,
MPI Datatype oldtype MPI Datatype *newtype)MPI_Datatype oldtype, MPI_Datatype *newtype)
IN count number of blocks IN blocklength nº of elements in each block IN t id spacing bet een start of each blockIN stride spacing between start of each block
measured as number of elementsIN oldtype old datatypeOUT newtype new datatypeyp yp
MPI_Type_hvector(int count, int blocklength, int stride, MPI_Datatype oldtype, MPI_Datatype *newtype)
stride en bytes en vez de elementos
CAR: Programación en MPI 81
Tipos de datos “derivados”Tipos de datos derivados Indexed: Los elementos son del mismo tipo pero no
están almacenados consecutivamente en memoriaMPI_Type_indexed(int count, int *array_of_blocklengths,
int *array of displacementint *array_of_displacement,MPI_Datatype oldtype,MPI_Datatype *newtype)
IN count number of blocksIN array_of blocklengths nº of elements per blockIN array_of_displacements displacement for each block
measured as nº of elementsIN oldtype old datatypeOUT newtype new datatype
MPI_Type_hindexed(int count, int *array_of_blocklengths, MPI_Aint*array_of_displacements, MPI_Datatype oldtype, MPI_Datatype *newtype)
displacements En bytes en vez de elementos
CAR: Programación en MPI 82
Tipos de datos “derivados”Tipos de datos derivados Struct: Los elementos son de distinto tipo y
separados entre sí en la memoria
MPI Type struct (int count, _ yp _ ( ,int *array_of_blocklengths,MPI_Aint *array_of_displacement,MPI Datatype *array of typesMPI_Datatype array_of_types,MPI_Datatype *newtype)
IN count number of blocksIN array_of blocklengths nº of elements per blockIN array_of_displacements byte displacement for each blockIN array_of types type of elements in each block OUT newtype new datatypeOUT newtype new datatype
CAR: Programación en MPI 83
Mensajes de tamaño desconocidoMensajes de tamaño desconocidoint MPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status *status)
IN source rank of source or MPI ANY SOURCE_ _IN tag message tag or MPI_ANY_TAG IN comm communicatorOUT status status object
int MPI_Iprobe(int source, int tag, MPI_Comm comm, int *flag,MPI_Status *status)
IN source rank of source or MPI ANY SOURCE_ _
IN tag message tag or MPI_ANY_TAG
IN comm communicator
OUT flag true if message pendingOUT flag true if message pending
OUT status status object
int MPI Get count(MPI Status *status,MPI Datatype datatype, int *count);int MPI_Get_count(MPI_Status status,MPI_Datatype datatype, int count);
IN status status objectIN datatype datatype of each entryOUT t b f t i
CAR: Programación en MPI 84
OUT count number of entries
Comunicación persistenteComunicación persistente Reutiliza la estructura de los mensajes. Siempre asíncrono. Habitual que se repita el mismo esquema de comunicación No inicia comunicación alguna, construye el mensaje
int MPI_Send_init(void* buf, int count, MPI_Datatypedatatype, int dest, int tag, MPI_Comm comm, MPI_Request*request);*request);
IN buf initial address of send buffer IN count number of entries to sendIN datatype datatype of each entryIN dest rank of destinationIN tag message tagg g gIN comm communicatorOUT request communication request handle
ACAR: Programación en MPI CAR: Programación en MPI 85
Comunicación persistenteComunicación persistente
int MPI_Recv_init(void* buf, int count, MPI_Datatypedatatype, int source, int tag, MPI_Comm comm, MPI R t * t)MPI_Request *request);
OUT buf initial address of receive buffIN count max # of entries to receiveIN datatype datatype of each entryIN source rank of sourceIN tag message tagIN comm communicatorOUT request communiction requestOUT request communiction request
ACAR: Programación en MPI CAR: Programación en MPI 86
Comunicación persistenteComunicación persistenteint MPI_Start(MPI_Request *request)
INOUT request communication request handle
int MPI_Startall(int count, MPI_Request *array_requests) IN count list lengthINOUT array of requests array of requestsINOUT array_of_requests array of requests
int MPI_Request_free(MPI_Request *request)INOUT request communication request
i t MPI W it(MPI R t * t MPI St t * t t )int MPI_Wait(MPI_Request *request, MPI_Status *status)INOUT request communication requestOUT status status object
ACAR: Programación en MPI
j
CAR: Programación en MPI 87
Comunicadores y gruposComunicadores y grupos
ACAR: Programación en MPI CAR: Programación en MPI 88
Creación de gruposCreación de gruposint MPI_Comm_group(MPI_Comm comm, MPI_Group *group)
int MPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group*newgroup)
i t MPI G l(MPI G i t i t * k MPI Gint MPI_Group_excl(MPI_Group group, int n, int *ranks, MPI_Group*newgroup)
int MPI_Group_range_incl(MPI_Group group, int n, int ranges[][3], MPI Group *newgroup)MPI_Group *newgroup)
int MPI_Group_range_excl(MPI_Group group, int n, int ranges[][3], MPI_Group *newgroup)
int MPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group*newgroup)
int MPI Group intersection(MPI Group group1, MPI Group group2,int MPI_Group_intersection(MPI_Group group1, MPI_Group group2, MPI_Group *newgroup)
int MPI_Group_difference(MPI_Group group1, MPI_Group group2, MPI Group *newgroup)
ACAR: Programación en MPI
_ p g p)
CAR: Programación en MPI 89
Creación de gruposCreación de grupos Grupos predefinidos: p p
MPI_GROUP_EMPTY: a group with no members. MPI GROUP NULL: constant for invalid groupMPI_GROUP_NULL: constant for invalid group.
i t MPI G f (MPI G * )int MPI_Group_free(MPI_Group *group) int MPI_Group_size(MPI_Group group, int *size) int MPI_Group_compare(MPI_Group group1,MPI_Group group2,
int *result) int MPI_Group_rank(MPI_Group group, int *rank)int MPI_Group_translate_ranks (MPI_Group group1, int n, _ _ _ ( _ p g p
int *ranks1, MPI_Group group2, int *ranks2)
ACAR: Programación en MPI CAR: Programación en MPI 90
Creación de comunicadoresCreación de comunicadoresint MPI Comm size(MPI Comm comm, int *size)int MPI_Comm_size(MPI_Comm comm, int size) int MPI_Comm_rank(MPI_Comm comm, int *rank)
int MPI_Comm_compare(MPI_Comm comm1,MPI_Comm comm2, int *result)
int MPI Comm dup(MPI Comm comm MPI Commint MPI_Comm_dup(MPI_Comm comm, MPI_Comm*newcomm)
int MPI Comm create(MPI Comm comm, MPI Groupint MPI_Comm_create(MPI_Comm comm, MPI_Groupgroup, MPI_Comm *newcomm)
int MPI_Comm_split(MPI_Comm comm, int color, intkey, MPI_Comm *newcomm)
int MPI_Comm_free(MPI_Comm *comm)
ACAR: Programación en MPI CAR: Programación en MPI 91
Creación de procesosCreación de procesosint MPI Comm spawn(char *command, char *argv[], int_ _ p ( , g [],
maxprocs, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *intercomm, int array_of_errcodes[])
IN command name of program to be spawned (root)IN argv arguments to command (root)IN maxprocs max nº of processes to start (root)IN maxprocs max. nº of processes to start (root)IN info a set of key‐value telling where and
how to start the processes (root)IN rootIN rootIN comm intracommunicatorOUT intercomm intercommunicator between original
group and the newly spawned group
OUT array_of_errcodes one code per process
ACAR: Programación en MPI CAR: Programación en MPI 92
Creación de procesosCreación de procesosint MPI_Comm_spawn_multiple(int count, char *array_of_commands[], char
**array of argv[], int array of maxprocs[], MPI Info array of info[], y_ _ g [], y_ _ p [], _ y_ _ [],int root, MPI_Comm comm, MPI_Comm *intercomm, int array_of_errcodes[])
IN count number of commands (root)IN array_of_commands programs to be executed (root)IN array_of_argv arguments for commands (array of
array of strings, root)IN array_of_maxprocs maximum number of processes to
start for each command (root)IN array_of_info info objects telling where and how
to start processes (root)to start processes (root)IN rootIN comm intracommunicatorOUT intercomm intercommunicator between originalOUT intercomm intercommunicator between original
group and newly spawned group
OUT array of errcodes one error code per process
ACAR: Programación en MPI
y_ _ p p
CAR: Programación en MPI 93
Tipos de datos “derivados”Tipos de datos derivados Definición:
Secuencia de pares:
{(t0,d0), (t1,d1), … , (tn-1,dn-1)}
- ti es un tipo de datos básico
- di es un desplazamiento respecto al comienzo del mensaje que lo utiliza
Ejemplo:variable tipo básico dirección
a MPI_FLOAT 24
b MPI_FLOAT 40
n MPI_INT 48
Tipo derivado para enviar a, b y n en un solo mensaje:
{(MPI FLOAT 0) (MPI FLOAT 16) (MPI INT 24)}{(MPI_FLOAT,0), (MPI_FLOAT, 16), (MPI_INT, 24)}
CAR: Programación en MPI 94