0% encontró este documento útil (0 votos)
52 vistas5 páginas

Programación en MPI: Comunicación de Procesos

Este documento describe el uso de MPI para implementar programas de cómputo distribuido. MPI proporciona funciones para comunicación entre procesos, incluyendo envío y recepción de mensajes de forma síncrona y asíncrona. La actividad propuesta es desarrollar programas MPI que permitan a nodos compartir información para reconstruir la topología de una red.

Cargado por

Salazar Axel
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
52 vistas5 páginas

Programación en MPI: Comunicación de Procesos

Este documento describe el uso de MPI para implementar programas de cómputo distribuido. MPI proporciona funciones para comunicación entre procesos, incluyendo envío y recepción de mensajes de forma síncrona y asíncrona. La actividad propuesta es desarrollar programas MPI que permitan a nodos compartir información para reconstruir la topología de una red.

Cargado por

Salazar Axel
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Sistemas Distribuidos

Practica 2: MPI (Message Passing Interface) Interface de Paso de Mensajes.


Objetivos:

a) Desarrollar algunos programas de cómputo distribuido empleando las bibliotecas que


proporciona MPI.
b) Emplear comunicación punto a punto con MPI.

Introducción:

MPI es un estándar que propone un conjunto de bibliotecas que permiten implementar


programas de cómputo distribuido o concurrente. La idea básica de MPI es la de proporcionar un
conjunto de funciones/procedimientos, para que un conjunto de procesos pueda comunicarse y lograr
colaborar entre ellos.

En MPI, todos los procesos que se registran o integran, poseen un identificador único que inicia con
cero y pertenecen a un conjunto global o universal. El conjunto global posee un comunicador llamado
MPI_COMM_WORLD el cual, es el manejador que permite que todos los nodos pertenecientes a un
grupo, se puedan comunicar. Es posible crear subgrupos a partir del conjunto global o incluso, a partir
de subgrupos, ver Fig. 1. Cada grupo o subgrupo tendrá su propio comunicador, y los procesos dentro
cada grupo o subgrupo tendrán su propio identificador dentro del grupo.

Figura 1. Grupos y subgrupos de procesos en MPI. Note que es posible intersectar los grupos, por ejemplo, el proceso P0
pertenece a todos los grupos, además, tendrá 4 identificadores, uno por cada grupo.
Todos los procesos en MPI son iguales, por lo que no existe una jerarquía de procesos, a menos que
por medio de la programación se establezca la jerarquía.

Las primitivas básicas de MPI incluyen funciones para:

a) Iniciar el proceso de comunicación.


b) Obtener el identificador de cada proceso.
c) El número de procesos totales.
d) Envío y recepción de mensajes en forma síncrona y asíncrona.

La estructura básica de un programa en MPI es la siguiente (no olvide agregar la cabecera mpi.h):

int main(int iArgc, char *pscArgv[])


{
int iRank; /*Este es el idenficador de nodo*/
int iSize; /*Número total de nodos*/
. . .
MPI_Init (&iArgc, &pscArgv);
MPI_Comm_size (MPI_COMM_WORLD, &iSize);
MPI_Comm_rank (MPI_COMM_WORLD, &iRank);

/*Código . . . */

MPI_Finalize();
return (0);
}

Todo programa dentro en MPI inicia con la instrucción MPI_Init, a la cual se le deberán pasar las
direcciones de memoria en donde están los argumentos que se reciban en la línea de comando. La
función MPI_Comm_size, junto con el comunicador para el conjunto global, retornará el tamaño del
conjunto; en cambio, la función MPI_Comm_rank proporciona el identificador del proceso dentro del
conjunto. Note que todos los programas en MPI deberán terminar llamando a la función
MPI_Finalize; el llamado a esta función no “mata” al proceso, este podría continuar, pero tiene la
tarea de “sacar” al proceso de todos los grupos dentro de MPI.

Podemos decir que MPI_COMM_WORLD es el identificador del grupo global, pero no el manejador con
el cuál podamos hacer “operaciones” sobre el grupo; los subgrupos poseen manejadores, con los
cuales es posible hacer “operaciones”, operaciones tales, como agregar un proceso al grupo.

En esta práctica trataremos la comunicación de procesos punto a punto, la cual en MPI es de dos tipos:

• Síncrona: en donde un proceso esperará hasta que le sea enviado/recibido un mensaje.


• Asíncrona: el proceso no espera por la recepción/envío del mensaje y continuara con su
ejecución.

Para los casos anteriores se emplean las funciones: MPI_Send y MPI_Recv para comunicación síncrona,
y MPI_Isend y MPI_Irecv para comunicación asíncrona.

Por otra parte, es sabido que, al momento de comunicar mensajes que involucran estructuras de datos,
un problema son los tipos de datos de dichas estructuras. Por lo tanto, cuando se envían mensajes
entre los diferentes nodos, es necesario especificar los tipos de datos que se envían. MPI posee los
siguientes tipos de datos válidos 1 : MPI_INT, MPI_FLOAT, MPI_CHAR, MPI_LONG, MPI_DOUBLE y

1
No son todos, aquí le mostramos solo algunos.
MPI_LONG_DOUBLE; sin embargo, es posible definir otros tipos mediante estructuras de datos, desde
luego, dichas estructuras de datos deberán estar elaboradas considerando los tipos de datos válidos
de MPI.

El listado en Código 1, muestra un ejemplo de comunicación síncrona entre dos nodos, mediante
mensajes síncronos. En este caso, ambos nodos, receptor y transmisor, se bloquean hasta que mensaje
se haya recibido o que por alguna razón exista un error.

El Código 2 muestra un ejemplo de comunicación asíncrona entre dos nodos. Para este último caso,
note que ambos nodos, receptor y emisor, para asegurarse de que el mensaje se haya recibido o de
que haya ocurrido un error, deberán realizar una prueba con la función MPI_Test. El llamado a esta
función no es bloqueante, por lo que proceso puede continuar con sus actividades, esperando algún
evento sobre un determinado mensaje.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>

#define PRINCIPAL 0 /*El nodo cero será el principal*/


#define NODO_DESTINO 1 /*Pues si son dos nodos y uno es 0, el otro debe ser 1*/

int main(int iArgc, char *pscArgv[])


{
int iRank; /*Este es el idenficador de nodo*/
int iSize; /*Número total de nodos*/
unsigned int w, x, y, z;
char scMsg[] = "Este es el mensaje.\n";
char scRec[100];
MPI_Status mpisEstado;
MPI_Init (&iArgc, &pscArgv);
MPI_Comm_size (MPI_COMM_WORLD, &iSize);
MPI_Comm_rank (MPI_COMM_WORLD, &iRank);
w = strlen (scMsg); /*Cuanto mide el mensaje*/
if (iRank==PRINCIPAL)
{
printf ("Soy el nodo principal, haré tiempo y luego enviaré un mensaje.\n");
for (x=0; x<100000; x++)
for (y=0; y<1000; y++) z = x + y;
printf ("Ahora enviaré el mensaje.\n");
MPI_Send (scMsg, w+1, MPI_CHAR, NODO_DESTINO, 1, MPI_COMM_WORLD);
printf ("El mensaje fue enviado\n");
}
else
{
printf ("Soy el otro nodo, y estoy en espera de recibir un mensaje.\n");
MPI_Recv (scRec, w+1, MPI_CHAR, PRINCIPAL, 1, MPI_COMM_WORLD, &mpisEstado);
printf ("Me enviaron: %s\n", scRec);
}
MPI_Finalize();
return (0);
}
Código 1. Envío de mensajes síncronos.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>

#define FALSE 0
#define TRUE 1
#define PRINCIPAL 0 /*El nodo cero será el principal*/
#define NODO_DESTINO 1 /*Pues si son dos nodos y uno es 0, el otro debe ser 1*/

int main(int iArgc, char *pscArgv[])


{
int iRank; /*Este es el idenficador de nodo*/
int iSize; /*Número total de nodos*/
int iFlag;
MPI_Request mpirReq;
unsigned int w, x, y, z;
unsigned char bSalir;
char scMsg[] = "Este es el mensaje.\n";
char scRec[100];
MPI_Status mpisEstado;
MPI_Init (&iArgc, &pscArgv);
MPI_Comm_size (MPI_COMM_WORLD, &iSize);
MPI_Comm_rank (MPI_COMM_WORLD, &iRank);
w = strlen (scMsg); /*Cuanto mide el mensaje*/
if (iRank==PRINCIPAL)
{
printf ("Soy el nodo principal, haré tiempo y luego enviaré un mensaje.\n");
for (x=0; x<100000; x++)
for (y=0; y<1000; y++) z = x + y;
printf ("Ahora enviaré el mensaje de forma sincrona..\n");
MPI_Isend (scMsg, w+1, MPI_CHAR, NODO_DESTINO, 1, MPI_COMM_WORLD, &mpirReq);
printf ("El mensaje fue enviado, pero aun no sé si ya se recibio.\n");
bSalir = FALSE;
while (!bSalir)
{
MPI_Test (&mpirReq, &iFlag, &mpisEstado);
if (iFlag) bSalir = TRUE;
}
printf ("Ya llego el dato!\n");
}
else
{
scRec[0] = 0;
printf ("Soy el otro nodo, y estoy en espera de recibir un mensaje.\n");
MPI_Irecv (scRec, w+1, MPI_CHAR, PRINCIPAL, 1, MPI_COMM_WORLD, &mpirReq);
bSalir = FALSE;
while (!bSalir)
{
MPI_Test (&mpirReq, &iFlag, &mpisEstado);
if (iFlag) bSalir = TRUE;
}
printf ("Me enviaron: %s\n", scRec);
printf ("TAG: %d, Origen: %d\n", mpisEstado.MPI_TAG, mpisEstado.MPI_SOURCE);
}
MPI_Finalize();
return (0);
}

Actividad:

Desarrolle un programa con MPI que permita crear N procesos, los cuales llamaremos nodos2. Cada
nodo deberá “lanzar un volado” para elegir aleatoriamente M vecinos (M < N); esto generará una
especie de grafo, en donde el número mínimo de nodos vecinos será M.

Una vez que cada nodo tenga presente a sus vecinos, crearán una matriz de adyacencia A de todos los
nodos. Los nodos pueden saber cuántos hay en total, pero no pueden saber qué y cuántos vecinos

2
En este caso, dada la naturaleza del programa, la palabra nodo se refiere a un proceso no aun host o computadora en la
red.
tiene cada nodo, es decir, desconocen la topología de la red o grafo. La idea que se persigue en esta
actividad es hacer que todos los nodos conozcan la topología del grafo a partir de A.

Cada nodo compartirá l veces su matriz A con sus vecinos, permitiendo que cuando un nodo reciba la
matriz de otro nodo, actualice su matriz. La pregunta a resolver será determinar los valores l que
permiten que todos los nodos del grafo conozcan la topología de la red.

Para lo anterior, desarrolle dos programas, para que cada uno de ellos emplee:

• Comunicación síncrona.
• Comunicación asíncrona.

Nota: los programas son un tanto complicados (pero no imposibles), por lo que tendrá que hacer mucha
investigación sobre MPI.

También podría gustarte