Revista de Tecnología - Journal of Technology • Volumen 7, No. 2, Julio - Diciembre 2008 • ISSN1692-1399 • P. 43-49 Fractal Mandelbrot con MPI - Estándar de Paso de Mensajes* Mandelbrot Fractal with MPI - Message Passing Interface. Guiovanna Paola Sabogal Alfaro** Diego Iván Sánchez Ramírez*** Resumen Abstract El desarrollo de programas para la ejecución en paralelo, está relacionado estrechamente con las bibliotecas (librerías) que permiten la comunicación entre los nodos que conforman un Cluster. Esas bibliotecas (librerías) implementan el estándar de Paso de Mensajes (MPI Message Passing Interface). Hay muchas implementaciones disponibles, la mayoría de libre distribución. El uso de OpenMPI, MPICH, LAM/MPI, OpenMP, entre otras, depende del tipo de plataforma de hardware disponible para implementarlas. Program development for parallel execution is linked to libraries that allow communication between the nodes that make up a Cluster. Those libraries implement the Message Passing Interface (MPI). There are many implementations already available; most of them are free distributed. The usage of MPICH, OpenMPI, LAM / MPI, OpenMP, just to name a few of them, depends on the hardware platform available to implement them. Aunque MPI no es un lenguaje de programación, define la semántica y la sintaxis de las funciones contenidas en él y tiene gran cantidad de instrucciones, que se conocen como llamados, para realizar y controlar la comunicación entre los nodos. Este artículo presenta el estándar MPI y muestra los resultados de la aplicación de una implementación en el cálculo del fractal de Mandelbrot. Palabras claves: Estándar MPI, Modo Bloqueante, LAM / MPI, Interfase de Aplicación de Programas, interfase de Dispositivo Abstracto, Programación de clusters. Although MPI is not a programming language, it does define syntax and semantics of functions contained therein, including a great number of instructions known as calls, allowing control and communication between nodes. This paper introduces the MPI standard and shows results of one of its implementation by calculating the Mandelbrot fractal. Key words: MPI Standard, Blocking Mode, LAM/MPI, Application Programmer Interface, Abstract Device interface, cluster programming. Recibido: 17/09/08. Evaluado: 14/10/08. Aceptado: 30/10/08. *Trabajo producido en el Grupo de Investigación EQUIS Equipo de Investigación en Software, de la Universidad El Bosque. **Coordinadora Grupo de Investigación EQUIS, Profesor Asistente, Facultad de Ingeniería de Sistemas, Universidad El Bosque. *** Ingeniero de Sistemas, Universidad El Bosque. 43 Revista de Tecnología - Journal of Technology • Volumen 7, No. 2, Julio - Diciembre 2008 • ISSN1692-1399 • P. 43-49 I. INTRODUCCIÓN El manejo de grandes cantidades de información, la necesidad de tener rápidamente resultados del la ejecución de procesos, los experimentos científicos, los repositorios de datos como los grandes portales de internet, las simulaciones computacionales, son sólo algunos de los ejemplos más comunes en los cuales se decide implementar un cluster ya que estos disminuyen considerablemente el tiempo en los cuales el resultado de dichas operaciones es dado al usuario final o a otro que lo espera. Alrededor del año 1994 se liberó la primera versión del estándar MPI, que permitió crear librerías que se encargan de realizar la comunicación entre los nodos pertenecientes al cluster, para así distribuir de la mejor forma la carga de trabajo asignada a cada uno de ellos, y dejando así la ejecución secuencial de programas para conseguir la paralelización de dichos procesos. Se podría afirmar que MPI, es el enlace entre los procesos secuenciales y las bibliotecas (librerías) de paso de Mensajes. 2. ARQUITECTURA MPI consta de tres (3) capas en su arquitectura: 1. La Interfase de Aplicación de Programa (API), 2. La Interfase de Dispositivo Abstracto (ADI) y 3. La Interfase de Canal. [2] (figura 1). La API, es la interfaz entre el programador y la Interfase de Dispositivo Abstracto ADI, ésta usa a la ADI para enviar y recibir información y ésta a su vez controla el flujo de datos entre la API y el hardware, con esto se asegura que el mensaje es enviado y/o recibido, también MPI maneja colas de los mensajes pendientes y contiene los protocolos de paso de mensajes. La estructura de los mensajes usada por la ADI está compuesta de dos elementos principales, la envoltura y el cuerpo.[7]. La Interfase entre el programador y la Interfase de Dispositivo Abstracto ADI se llama API, la cual usa a la ADI para enviar y recibir información entre proceso, la ADI realiza control del flujo de datos entre la API y el hardware asegurando que el mensaje es enviado y/o recibido, MPI maneja colas de los mensajes pendientes y contiene los protocolos de paso de mensajes. En el presente artículo se describirá el estándar MPI, y las pr incipales funciones que per miten realizar la comunicación entre nodos y la paralelización de los procesos bajo el lenguaje de programación C. Se toma como ejemplo un programa que genere un fractal, explicando cada una de las funciones pertenecientes a este estándar. 1. ¿QUE ES MPI? MPI se diseñó para programas que se ejecuten en múltiples procesadores, la implementación tanto en sistemas que utilicen paso de mensajes, como sistemas de memoria compartida es una de las grandes ventaja que posee este estándar, desarrollado entre los años de 1993 y 1994 por un grupo interdisciplinario, pertenecientes al sec tor industr ial, guber nament al y académico, implementa la comunicación vía sockets y las implementaciones de memoria compartida. Además no planifica los procesos, da soporte de dispositivos de E/S y dispone de herramientas de configuración. MPI también es implementado como interfaz de comunicaciones. Como describen los autores, en MPI se incluyen: “Comunicaciones P unto a P unto, Operaciones Colectivas, Procesos Grupales, Comunicación de Dominios, Topología de Procesos, Ambiente de Administración e investigación, Entorne de Interfase, Administración Dinámica de procesos, operaciones de un solo lado[8]”. 44 Figura 1. Arquitectura de MPI [3]. Un mensaje de MPI, está compuesto por dos partes: La envoltura y el cuerpo (figura 2). Por su parte la envoltura se divide a su vez en cuatro partes: la fuente, el destino, el comunicator y una etiqueta. El cuerpo se divide en tres partes (figura 2): cuenta, tipo de dato y buffer. Figura 2. Estructura de un mensaje MPI [4]. Revista de Tecnología - Journal of Technology • Volumen 7, No. 2, Julio - Diciembre 2008 • ISSN1692-1399 • P. 43-49 MPI puede enviar mensajes con bloqueo en el cual la ADI no retorna el control a la API, hasta que se realice una validación del cuerpo del mensaje para su uso, para los no bloqueantes permite realizar a las comunicaciones y a los nodos otros procesos mientras que recibe confirmación del mensaje enviado. La asignación de la cantidad de procesos requeridos antes de la ejecución y la no inclusión de adicionales mientras se realiza la ejecución, son algunos de los fundamentos de MPI, ya que cada proceso se le asigna una variable llamada rank, quien es la que determina cuál proceso se está ejecutando. La definición del comunicator es esencial ya que es éste el que permite enviar mensajes de un computador al otro, la función MPI_COMM_WORLD, es el comunicador básico de MPI y agrupa los procesos activos mientras la aplicación se ejecute. 3. PRINCIPALES FUNCIONES DE MPI Las llamadas para inicializar, administrar y finalizar comunicaciones, son las principales cuatro en total: MPI_Init permite inicializar una sesión, debe ser utilizada antes de llamar a cualquier otra función de MPI. MPI_Finalize permite terminar una sesión MPI, debe ser la última llamada a MPI que un programa realice y permite liberar la memoria usada por MPI. MPI_Comm_size permite determinar el número total de procesos que pertenecen a un comunicator. MPI_Comm_rank permite determinar el identificador (rank) del proceso actual [5]. Las llamadas para transferir datos son las que pertenecen al cuerpo del programa y distribuyen los procesos entre los nodos: Las funciones No bloqueantes de envío y recibe son MPI_Isend y MPI_Irecv, su finalización se debe realizar de forma explícita. MPI_Test permite verificar si la operación de envío o recepción ha finalizado. Esta función primero chequea el estado de la operación de envío o recepción y luego retorna. MPI_Wait que es una llamada bloqueante y retorna cuando la operación de envío o recepción se completa [8]. El tercer grupo de llamadas transfiere datos entre varios procesos, realizando procesos de multidifusión (broadcast), recolección (gather), distribución (scatter) y reducción las más utilizadas son: MPI_Barrier es la encargada de realizar operaciones de sincronización entre procesos, esta llamada no realiza un intercambio de información, utilizada principalmente para dar por terminada una etapa del programa y así continuar con la siguiente [8]. MPI_Bcast se encarga de enviar una copia de los datos de un proceso a otros procesos dentro de un grupo definido por un comunicator [8]. MPI_Scatter establece una operación de distribución, en la cual un dato (arreglo de algún tipo de datos) se distribuye en diferentes procesos. MPI_Gather establece una operación de recolección, en la cual los datos son recolectados en un sólo proceso. MPI_Reduce permite que el proceso raíz recolecte datos desde otros procesos en un grupo, y los combine en un solo ítem de datos. MPI_Type_struct permite al programador definir un nuevo tipo de datos. MPI_Pack empaqueta los datos [8]. MPI_Send con la siguiente sintaxis: int MPI_Send (void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm ). Para realizar un programa en MPI, programando bajo C, se debe tener en cuenta la siguiente estructura: MPI_Recv con la siguiente sintaxis: int MPI_Recv( void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status ). [7] La primera parte es la inclusión de las librerías de paso de mensajes. El resultado es el retorno de un código de éxito o fracaso y ambas funciones son bloqueantes, es decir que el proceso que realiza la llamada se bloquea hasta que la operación de comunicación se complete. Y la definición de las etiquetas, las cuales se pasarán como parámetro a las funciones dentro del programa WORKTAG 1 (etiqueta de Trabajo), y DIETAG 2 (Etiqueta de dejar de trabajar) el nombre de la etiqueta puede o 45 Revista de Tecnología - Journal of Technology • Volumen 7, No. 2, Julio - Diciembre 2008 • ISSN1692-1399 • P. 43-49 según el tipo de proceso se puede nombrar como mejor se acomode a la forma de programar. La segunda parte consta de definir las funciones globales de la aplicación. Función del nodo maestro, ésta es la función que se ejecutara en el nodo maestro y que generalmente es la que le envía los mensajes a los nodos. MPI, y contiene todos los procesos que intervienen en el cálculo, con este comunicador se pueden ejecutar programas básicos de MPI. Se define la función MPI_Comm_rank , donde se le indica el comunicador y la variable definida para llevar el rango, La variable &myrank &myrank, es la variable que se define para definir el numero de procesos a ejecutar. Esta función determina el rango de los procesos llamados en el comunicador. Función del nodo Esclavo, de igual forma la función esclavo recibe las instrucciones del nodo maestro, recopila y le envía los resultados al nodo maestro para que el muestro los resultados de los procesos. Después de definir MPI_Comm_rank Señores: valida que función se va a ejecutar según la variable myrank (Si la variable myrank = 0, llama la función del maestro, si no ejecuta la función de los esclavos). También define las funciones que se asignan del maestro a los nodos y reciben resultados de los nodos al maestro, y en las cuales se desarrollan los procesos, funciones, o procedimientos que los nodos esclavos van a procesar y/o calcular. Por último y para finalizar el programa se llama la función MPI_Finzalize(); la cual Apaga MPI. Dentro de estas funciones, se definen las funciones del programa como tal, los procesos, los cálculos entre otros, de igual el programador define los nombres, que identifiquen mejor a la funciones. //FIN DEL PROGRAMA El cuarto paso después de definir las funciones, es definir la estructura del programa “función main main”, en esta función se declara la función que inicia a MPI. MPI_Init(&argc, &argv) &argv), también en la función main, se debe definir el comunicador, para este caso se define el comunic ador est ánda r MPI_COMM_WOR D D, el comunicador agrupa los procesos activos mientras la aplicación se ejecute. El comunicador MPI define un grupo de procesos dentro de los cuales se pro duce una comunic ación. MPI_COMM_WORLD es el comunicador por defecto de 46 El ejemplo que se toma para explicar MPI, es la generación de un fractal tipo Maldebrot, para este tipo de programas a los cuales no se les puede realizar una asignación de procesos directamente a cada nodo, se realiza una asignación dinámica de procesos, que se basa en que los procesos se van asignando cuando los nodos dejan de ejecutarlos. Para procesar el fractal, el cluster toma unas coordenadas iniciales 0, 0, el primer nodo recibe las coordenadas iniciales, envía el resultado al nodo maestro, esta asignación se realiza ya que no todos los píxeles se pintan igual y todos los nodos del cluster, no tienen la misma capacidad, por eso el nodo maestro va recibiendo información, pinta los colores en las coordenadas recibidas y asigna a otro nodo u otros nodos los procesos para que realicen esta operación una y otra vez hasta que por coordenadas los nodos reciban, ejecuten y envíen el último resultado del proceso. Los nodos no realizan otra operación que calcular la posición de los píxeles que se ejecutan y con esta información, devuelve la posición donde se debe pintar el Revista de Tecnología - Journal of Technology • Volumen 7, No. 2, Julio - Diciembre 2008 • ISSN1692-1399 • P. 43-49 color negro, o el color rojo, para que finalmente, el nodo maestro ejecute el fractal. Las funciones que se ejecutan en el nodo Maestro asignan a los nodos esclavos, las tareas y dentro de ellas está la función que realiza los cálculos matemáticos, para que, de acuerdo con la posición, los colores sean rojo, rojo oscuro o negro. De manera similar, las funciones que se ejecutan en los nodos esclavos tienen como propósito realizar la ejecución, recopilarla y enviarla para que el maestro que es el que finalmente ejecuta la parte gráfica, que es la ventana donde se dibuja el fractal y cada uno de los píxeles que lo conforman. Las funciones principales del programa son: slaveBusy[i]=0; XGUIInit(width,height); //inicia la GUI (Graphics use Interface), para pintar el fractal Master_CallSlaves(); //Gestiona la inicialización de esclavos XGUIShutdown(); //Desconecta desde X y apaga }//fin void master /* Función para dibujar el gráfico usando reúne datos: puede utilizar OpenGL, GTK, QT (o cualquier otro conjunto de herramientas de programación gráfica*/[1]. FUNCIÓN DE ESCLAVO void Slave() { //Primero obtiene los parámetros de la gráfica desde BCast MandelInfo info; //obtiene la infor mación de la gráfica (info:height,width,blocksize) FUNCIÓN DE MAESTRO MPI_Bcast(&info,1,MandelInfoType,0,MPI_COMM_WORLD); void Master() { //Obtiene los primeros parámetros iniciales de la gráfica y los envía utilizando BCAST printf("Ingrese el alto de la gráfica:"); scanf("%d",&width); printf("ingrese el ancho de la gráfica:"); scanf("%d",&height); if(&width==NULL | width<10) width=640; //si no se ingresan datos los toma por defecto if(&height==NULL |height<10) width=640;//si no se ingresan datos los toma por defecto printf("Ingrese el blocksize para el nodo en pixels :"); scanf("%d",&blocksize); height=info.height; width=info.w idth; blocksize=info.blocksize; width=getDividingNumber(width,blocksize); //Asigna a width el resultado de la función height=getDividingNumber(height,blocksize); //Asigna a height el resultado de la función MandelInfo info; info.w idth=width; info.height=height; info.blocksize=blocksize; /*La función MPI_Bcast envía información a todos los nodos, la estructura los parámetros son: MPI_Bcast( buffer, count, datatype, root, comm) IN OUT buffer; A partir de la dirección de buffer (chioce) IN count; número de entradas en buffer (integer) IN datatype tipo de dato del buffer (handle) IN root rango de emisión de raíz (integer) IN comm comunicator (handle)*/ MPI_Bcast(&info,1,MandelInfoType,0,MPI_COMM_WORLD); //Asigna a la variable el número de nodos, desde que la raíz no se un nodo esclavo freeSlaves=numofnodes-1; slaveBusy=(int*)malloc(sizeof(int)*numofnodes); /*mantiene el rastro de que nodo esta ocupado el puntero se asigna a la variable slaveBusy*/ //Inicializa los nodos que están libres int i; For(i=0;i<numofnodes;i++) printf("Yo soy un esclavo %d A tu servicio nodo maestro!!!\n",myrank); int done=0; MPI_Status status; MPI_Send(NULL,0,MPI_INT,0,666,MPI_COMM_WORLD); while(!done) { MPI_Probe(0,MPI_ANY_TAG,MPI_COMM_WORLD,&status); if(status.MPI_TAG==tag_calc) //Si la etiqueta recibida requiere cálculos o procesamiento { int section[2]; MPI_Recv(&section,2,MPI_INT,status.MPI_SOURCE,tag_calc,MPI_C OMM_WORLD,&status); //obtiene el numero de fila para calcular el proceso pr int f("Nodo :%d Estoy Calculando de Sección: %d %d\n",myrank,section[0],section[1]); //Aquí se envía la función para que los nodos calculen Slave_CalcAndSend(section[0],section[1]); //procesa y envía al maestro } // fin if (status.MPI_TAG==tag_calc) else if(status.MPI_TAG==tag_shutdown) //Si se apaga, termina el proceso en este punto { MPI_Recv(NULL,0,MPI_INT,status.MPI_SOURCE,tag_shutdown,MPI _COMM_WORLD,&status); done=1; } else printf("Valor de la etique desconocida"); } printf("Nodo %d trabajo terminado \n",myrank); } // fin de las funciones del esclavo [1]. Después de ejecutar la aplicación, el resultado se evidencia en la figura 3: 47 Revista de Tecnología - Journal of Technology • Volumen 7, No. 2, Julio - Diciembre 2008 • ISSN1692-1399 • P. 43-49 (velocidad de procesamiento) para alcanzar los mismos tiempos de respuesta. Por todo lo anterior, la programación en paralelo permite optimizar los recursos con los que se cuentan y crear así un comput ador capa z de desar rollar procesos importantes, con las implicaciones económicas positivas al mantener bajos niveles de inversión en tecnología informática. REFERENCIAS [1] Ashika Umanga Umagiliya, http://www.planet-sourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=11015& lngWId=3#zip, 11/24/2006 11:25:45 AM (Todo el código de software MANDEL.C, MANDEL.H, X11GUI.C Y X11GUI.) Figura 3. Fractal Mandel con MPI. II. CONCLUSIÓN La implementación del estándar MPI y librerías puede conducir a resolver dificultades en el procesamiento de información en entornos de investigación, empresa y gobierno, ya que el procesamiento el paralelo agiliza la ejecución de procesos, por la rápidez con la que los usuarios esperan recibir los datos resultantes de una operación. Las comunidades y grupos de software libre proveen al mundo entero de estas herramientas, que han sido estudiadas y experimentadas por gran cantidad de instituciones educativas, de carácter investigativo y por algunas empresas del sector privado y público en distintos países, el hecho de ser de libre distribución permite realizar mejoras y cambios que beneficien a todos los miembros que la utilicen, y el aprovechamiento de éstas es de gran importancia, tanto como para dichos grupos como para las instituciones educativas que encuentran en ellas un gran apoyo para desarrollar el conocimiento de sus miembros. Con el ejemplo del fractal se evidencia que el procesamiento en paralelo permite agilizar los procesos, ya que por la asignación dinámica con la que se programó la aplicación permite aprovechar los nodos esclavos ampliamente. El fractal de no ejecutarse de forma paralela, tendría que ejecutarse en una máquina con alto poder de cómputo 48 [2] Burbano Sefair, Daniel Alberto. Mpich Communication Protocols: Study of Their Behavior in a Hybrid System, Mayagüez, Puerto Rico, 2001, University of Puerto Rico, Electrical and Computer Engineering Department. pp 1. [3] Burbano Daniel Alberto, Mpich Communication Protocols: Study of Their Behavior in a Hybrid System, Mayagüez, Puerto Rico, 2001, University of Puerto Rico, Electrical and Computer Engineering Department. pp 2 [4] Herramientas de Desarrollo de Aplicaciones, http://clusterfie.epn.edu.ec/clusters/Definiciones/definici ones3.html [5] Herramientas de Desarrollo de aplicaciones http://clusterfie.epn.edu.ec/clusters/Definiciones/definici ones3.html, ultimo acceso Enero 20, 2008 [7] Redes-Linux.com, ht t p://bet a.redes-linux.com/manuales/cluster/mpispanish.pdf [8] Shir Marc, Steven Otto, Huss-Lederman Steven, Walker David, MPI The complete Reference, Vol 1 The MPI Core Revista de Tecnología - Journal of Technology • Volumen 7, No. 2, Julio - Diciembre 2008 • ISSN1692-1399 • P. 43-49 Artículo de Investigación Científica y Tecnológica (Tipo I). Sometido a Arbitraje. Los autores declaran que no tienen conflicto de interés. Los Autores Giovanna Paola Sabogal Alfaro Docente de la Facultad de Ingeniería de Sistemas y Coordinadora del Equipo de investigación en Software, EQUIS, de la Universidad El Bosque. Ingeniera Electrónica y Especialista en Teleinformática de la Universidad Distrital Francisco José de Caldas. Carrera 7 B Bis 132 - 11, Bogotá D.C., Colombia. guiovannasabogal@unbosque.edu.co Diego Iván Sánchez Ramírez Ingeniero de Sistemas de la Universidad El Bosque, miembro de Equipo de Investigación en Software EQUIS. Carrera 7 B Bis 132-11, Bogotá D.C., Colombia. diegoisr@gmail.com 49