Está en la página 1de 19

Comunicaciones Punto a

Punto
Send y Receive para pasaje de mensajes
Un comunicador: es una colección de procesos, los cuales se
comunican a través del envío y recepción de mensajes.

❑ Comunicador global: MPI_COMM_WORLD


Puedo tener mundos, en los cuales agrupo procesos

Nosotros usamos el standard, por default

4
0

1
3 MPI_COMM_WORLD este seria el comunicador, se usa en gral para
problemas grandes, donde agrupo distintos tipos de
2 procesos segun alguna caracteristicas, en gral, por
que es lo que resuelve.

Cada mundo se comunica internamente.


Adquisición de Información
MPI Comm_size: indica la cantidad de procesos en el comunicador.
• MPI_Comm_size (MPI_Comm comunicador, int *cantidad)

MPI Comm_rank: indica el "rank" (identificador) del proceso dentro de el


comunicador.
• MPI Comm_rank (MPI_Comm comunicador, int *rank)
- rank es un valor entre [0..cantidad]
- Cada proceso puede tener un rank diferente en cada comunicador.

MPI Get_processor_name: indica el "nombre" (identificador) del nodo en el que se


ejecuta el proceso.
• MPI Get processor_name (char *name, int *resultlen)
- name es un puntero a arreglo de char donde se guardará el nombre del
nodo
- resultlen es un puntero a entero donde se guardará el largo del nombre del
nodo.
MPI Send/Receive básicos

• Veamos en detalle… Proceso 0 Proceso 1

Send(data)

Receive(data)
necesito datos

• Necesitamos especificar:
• ¿Cómo será inicializado “data” ?
• ¿Cómo serán identificados los procesos?
• ¿Cómo lo reconocerá el receptor?
• ¿Qué significará que se completen estas operaciones?

4
¿Qué es el pasaje de mensajes?

• Transferencia de datos más sincronización (de que manera el otro se sincroniza cuando voy a
recibirlo)

Data Proceso 1
Proceso 0 Data Puedo enviar? Data
Data
Data Data consumidor
productor Data Data
Data Data
Data
Data Data
Data Si
Tiempo

• Requiere cooperación del que envía y del que recibe.


• Cooperación no siempre aparente en el código.
5
Enviar y Recibir mensajes

Preguntas:

¿A quién se le envía el dato?


¿Qué se envía?
¿Cómo lo identifica el receptor?
Sintaxis Send/Recv
Comunicaciones punto a punto realizadas entre dos procesos:
Un proceso emisor y un proceso receptor

int MPI_Send (void *buf, int count, MPI _Datatype datatype, int dest, int tag,
MPI _Comm comm)

int MPI _Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag,
MPI_Comm comm, MPI_Status *status)

Estructura MPI_Status:
typedef struct MPI_Status {
int MPI_SOURCE;
int MPI_TAG; ----> el tag indica el numero de send y recv corresp
int MPI_ERROR;
}
Sintaxis Send/Recv
Objeto Status y MPI_Get_count

int MPI _Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag,
MPI_Comm comm, MPI_Status *status)

Estructura MPI_Status:
typedef struct MPI_Status {
int MPI_SOURCE;
int MPI_TAG;
int MPI_ERROR;
}

Obtener tamaño del mensaje recibido: Función MPI_Get_count

- int MPI_Get_count(MPI_Status *status. MPI_Datatype dtype, int *count)


MPI Basic Send

MPI_SEND (*data, count, datatype, dest, tag, comm)

• El buffer del mensaje se describe por (*data, count, datatype).


• El proceso receptor está especificado por dest, que es el rank del proceso
receptor en el comunicador especificado por comm.
• Cuando esta función retorna, el dato debería haber sido entregado al
Sistema y el buffer puede reutilizarse. El mensaje puede no haber sido
recibido por el proceso receptor (dest).

9
MPI Basic (Blocking) Receive

MPI_RECV( *data, count, datatype, source, tag, comm, status)

• Espera hasta que se reciba un mensaje coincidente (en source y tag)


del sistema, y se puede usar el buffer.
• source es rank en el comunicador especificado por comm, o
MPI_ANY_SOURCE. ---> si no quiero poner el número de ranquing del que quiero recibir
• status contiene más información.
• Recibir menos que count ocurrencias de datatype estaría bien, de dónde vino y la cant de
datos que recibi
pero recibir más es un error.

10
Información sobre el mensaje: Status

Status es una estructura de datos declarada en el inicio del programa

Ejemplo:

int recv_tag, recv_from, recv_count;


MPI_Status status;
MPI_Recv(..., MPI_ANY_SOURCE, MPI_ANY_TAG, ..., &status )

---------------------------> como puse que recibo de cualquier con cualquier tag, esto
recv_tag = status.MPI_TAG; desp me permite saber de quién vino y con que tag

recv_from = status.MPI_SOURCE;
MPI es simple

• Muchos programas MPI paralelos pueden ser escritos


usando solo estas seis funciones, de las cuales solo dos
son no triviales:

• MPI_INIT
• MPI_FINALIZE
• MPI_COMM_SIZE
• MPI_COMM_RANK
• MPI_SEND
• MPI_RECV
Ejercicio 1
➢ Queremos hacer un programa paralelo que encadene el envío y recepción de un
mensaje, en nuestro caso el mensaje será el rank (identificador) del proceso que
envía.
➢ Los mensajes se enviarán de forma encadenada, lo que quiere decir que el
primero enviará un mensaje al segundo, el segundo recibirá uno del primero y
enviará uno al tercero, y así sucesivamente para todos los procesos lanzados.
➢ Todo proceso que reciba un mensaje debe imprimirlo de la forma
"Soy el proceso X y he recibido M",
siendo X el rango del proceso y M el mensaje recibido.
P0 envía 0 + 0 a P1 P1 envía 0 + 1 a P2

P2 envía 1 + 2 a P3
Ejercicio 2
➢ El proceso 0 envía un vector al proceso 1
➢ El arreglo estático se declara e inicializa en 0 - El proceso 0 cambia los elementos
tal que Vec[i] = i
➢ El proceso 1 recibe el arreglo y lo muestra antes de recibir los datos de P0 y
luego de recibirlos.
➢ Los mensajes deben tener los carteles que correspondan en cada caso indicando
que proceso lo escribe.
➢ La dimensión del arreglo se ingresa como #define N xx
Ejercicio 3

Modificar el programa del Ejercicio 2 para que devuelva al


procesador 0 la suma de los elementos del vector recibido y
éste último que se encargue de imprimir el resultado.

También podría gustarte