Brevísimo tutorial de MPI (Message Passing Interface) Miguel Vargas



Documentos relacionados
Cómputo en paralelo con MPI

Brevísimo tutorial de MPI (Message Passing Interface) MC. Miguel Vargas Félix

MPI es un estándar de programación en paralelo mediante paso de mensajes que permite crear programas portables y eficientes.

Programación en Paralelo con MPI en Clusters Linux

Introduccion al Lenguaje C. Omar Andrés Zapata Mesa Grupo de Fenomenología de Interacciones Fundamentales, (Gfif) Universidad de Antioquia

Implementación de un Cluster de Computadoras con software libre para Computación Científica en Jicamarca

Descomposición de dominios

Objetivo: Introducción conceptual y aplicación básica de los lenguajes del lado del servidor.

Tutorial: Primeros Pasos con Subversion

Computacion de Alto Performance

Arquitectura de Computadores: Exámenes y Controles

UNIVERSIDAD CARLOS III DE MADRID DEPARTAMENTO DE INFORMÁTICA INGENIERÍA EN INFORMÁTICA. ARQUITECTURA DE COMPUTADORES II 19 de junio de 2007

INTRODUCCIÓN A LA PROGRAMACIÓN DE COMPUTADORES DE MEMORIA DISTRIBUIDA USANDO MPI SISTEMAS PARALELOS Y DISTRIBUIDOS

Preliminares. Tipos de variables y Expresiones

Novedades en Q-flow 3.02

Tema: Arreglos de Objetos en C++.

Identificadores, palabras reservadas, tipos de datos, operadores aritméticos y el sistema estándar de salida en Java

Paso de Borland Turbo C (bajo DOS) a Anjuta (Linux) 1.

SOLUCION EXAMEN junio 2006

SISTEMAS PARALELOS Y DISTRIBUIDOS. 3º GIC. PRÁCTICA 9 Departamento de Arquitectura y Tecnología de Computadores Universidad de Sevilla

Introducción a la Programación en MATLAB

El lenguaje de Programación C. Fernando J. Pereda

Instalación de Winisis en Windows 8 (64 bits) usando Virtual Box Oracle Ernesto Spinak 10/07/2013 borrador 1

Bienvenidos a la presentación, producción de informes y depuración (debugging). En esta unidad discutiremos la producción de informes utilizando la

Instalación de OpenMPI

Familia de Windows Server 2003

Capítulo 3 Usando GUIDE. 3.1 Acerca de GUIDE

Apéndice 5 Manual de usuario de ColeXión. ColeXión 1.0. Manual de usuario

FUNDAMENTOS DE PROGRAMACION CON C#

LABORATORIO 9. Replicación de base de datos en SQL Server

Programación Orientada a Objetos con Java

Creación y administración de grupos de dominio

Cluster Beowulf/MPI en Debian

1. Visualización de datos con Octave

Introducción a PHP. * No es necesario declarar previamente las variables.

Arquitectura de sistema de alta disponibilidad

Práctica 00: Compilador

Instalación del Software Magaya

El lenguaje C. #define MAX LINEA 1000 /* maximo tamanio de linea de entrada */

Computación Matricial y Paralela

Entre los más conocidos editores con interfaz de desarrollo tenemos:

DBSURE. Disponemos de una copia de la base de datos de forma remota, que podemos contabilizar como segundo juego de copias.

Prof. Dr. Paul Bustamante

Lenguaje de Programación: Go

Sistemas Operativos Windows 2000

Anexo B. Comunicaciones entre mc y PC

Introducción a la programación orientada a objetos

PRESENCIAL TEMAS 5 Y 6 SAD. Victor Martin

Instalación de cygwin-x. Pablo Sanz Mercado.

Punteros. Definición Un puntero es un dato que contiene una dirección de memoria.

DOCENTES FORMADORES UGEL 03 PRIMARIA

Guía de instalación y configuración de IBM SPSS Modeler Social Network Analysis 16

Universidad Tecnológica del Valle del Mezquital. Desarrollo de Aplicaciones Web. Manual JSP

Entorno de Programación Visual Studio 6

Instalación de un nodo (cliente) - GIA

INSTALACIÓN DEL PROGRAMA

Sistema de Captura Electrónica

MANUAL DE INSTALACIÓN DEL SISTEMA LMS LMS: LEARNING MANAGEMENT SYSTEM

Información del Producto: XenData X1500 LTO-5 Digital Video Archive System

Cómo compilar y ejecutar programas en ĺınea de comandos

TP 0 - Implementación de codificador y estructura básica. BitsTranslation. 1.0

Uso de Visual C++ Pre-Practica No. 3

General Parallel File System

Sistemas Operativos Práctica 3

INDICE. 1. Introducción El panel Entities view El panel grafico Barra de botones Botones de Behavior...

Almacenamiento virtual de sitios web HOSTS VIRTUALES

Elementos requeridos para crearlos (ejemplo: el compilador)

"Binary Diffing" visual en Linux con Radare2 "UNA IMAGEN DICEN MÁS QUE MIL PALABRAS"

Manual de usuario de IBAI BackupRemoto

Acronis License Server. Guía del usuario

Instrucciones de instalación de IBM SPSS Modeler Server 16 para Windows

SIIGO PYME PLUS. Proceso de Recuperación. Cartilla I

Agente local Aranda GNU/Linux. [Manual Instalación] Todos los derechos reservados Aranda Software [1]

OPTICAL DISC ARCHIVE FILE MANAGER ODS-FM1

Manual de Instalación. Sistema FECU S.A.

Introducción a las redes de computadores

Instalación de un Super-Servidor de procesamiento paralelo basado en MPI

MANUAL PARA CREAR UNA RED CON MAQUINAS VIRTUALES

Capítulo 1 Introducción a la Computación

AGREGAR UN EQUIPO A UNA RED Y COMPARTIR ARCHIVOS CON WINDOWS 7

1. Manejo de memoria estática 2. Manejo de memoria dinámica

RESUMEN DE CONCEPTOS BASICOS DE PROGRAMACION JAVA

CAPITULO 9. Diseño de una Base de Datos Relacional Distribuida

Tutorial de Eclipse CDT

Cómputo en paralelo con OpenMP 1

Como ejecutar el programa PRUF. Cía. HASAR saic

Manual del programador

APROVECHAR LA BASE DE DATOS BIBLIOGRÁFICOS REBECA CON EL PRO- GRAMA ABIES.

Proyecto 3 Programación de aplicaciones Cliente/Servidor

Tutorial: Cómo realizar tu primer programa en C++ En el Sistema Operativo Windows

Organización del Centro de Cálculo

Acceso al Disco Compartido y Dispositivos USB y DVD

DATOS EN SERVIDOR DE RED PROCEDIMIENTO PARA INSTALACIÓN Y CONFIGURACIÓN DE BASES DE DATOS EN SERVIDORES DE RED

Capítulo 5 Programación del algoritmo en LabVIEW

Transcripción:

Brevísimo tutorial de MPI (Message Passing Interface) Miguel Vargas 19/10/10 1/33

Contenido Contenido Clusters Beowulf MPI (Message Passing Interface) Comunicación entre procesos Un programa simple con MPI Comunicación con bloqueo Comunicación sin bloqueo Ejecución en un cluster Depuración de programas MPI Algunos resultados MPI + OpenMP Sistemas grandes Preguntas? Bibliografía 2/33

Clusters Beowulf Clusters Beowulf Computadoras nodos escalvo Computadora nodo maestro Red externa Switch de red Características: Tecnología estandar Fáciles de instalar Costo reducido 3/33

Clusters Beowulf Existen sistemas operativos open source preparados para este tipo de arquitectura Rocks Clusters: http://www.rocksclusters.org PelicanHPC: http://pareto.uab.es/mcreel/pelicanhpc Scientific Linux: http://www.scientificlinux.org También es posible utilizar Windows Windows HPC Server 2008: http://www.microsoft.com/hpc 4/33

Clusters Beowulf Cluster del CIMAT El Insurgente 5/33

MPI (Message Passing Interface) MPI (Message Passing Interface) Es una colección de funciones y programas para: Facilitar la comunicación entre procesos Ejecutar multiples veces un programa en un cluster Computadora Computadora Computadora Procesador Procesador Procesador Procesador Procesador Procesador Memoria Memoria Memoria Interfaz de red Interfaz de red Interfaz de red Switch de red Interfaz de red Interfaz de red Memoria Memoria Procesador Procesador Procesador Procesador Computadora Computadora Usualmente se ejecuta un proceso por core Tiene soporte para threads y además es posible combinarlo con OpenMP 6/33

MPI (Message Passing Interface) La comunicación entre procesos se realiza por medio de: Mensajes de red entre nodos (via ethernet, Myrinet, InfiniBand) Memoria compartida (polling) entre procesos en una misma computadora Mensajes por sockets locales entre procesos en una misma computadora Funciona con: C C++ Fortran 77/90/95 Es el estandard de facto para comunicaciones en clusters con aplicaciones al cómputo matemático. Implementaciones open source: MPICH2: http://www.mcs.anl.gov/research/projects/mpich2 OpenMPI: http://www.open-mpi.org 7/33

Comunicación entre procesos Comunicación entre procesos Cada proceso se identifica por un número llamado rango. Desde el punto de vista del software un proceso puede enviar y recibir mensajes de/y hacia cualquier otro proceso: rango 1 rango 0 rango 2 rango N-1 rango 3 rango 4 8/33

Comunicación entre procesos El programador no se tiene que preocupar por el medio de comunicación. Cada nodo reserva memoria independientemente, MPI proporciona las funciones para copiar esa información a otros nodos y para recibir esa información. MPI tiene funciones para: Enviar datos nodo a nodo Recibir datos nodo a nodo Enviar datos a muchos nodos (broadcasting) Recibir datos de muchos nodos (reduction) Sincronización de procesos Lectura/escritura de datos en paralelo Manejo de threads Vamos a revisar brevemente 10 funciones básicas 4 de control y 6 de comunicación. 9/33

Un programa simple con MPI Un programa simple con MPI El ejemplo siguiente muestra el programa mínimo con MPI. #include <stdio.h> #include <mpi.h> int main(int argc, char** argv) { int size, rank; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); printf("hola mundo (size = %i, rank = %i)\n", size, rank); MPI_Finalize(); return 0; } 10/33

Un programa simple con MPI Compilación En Windows con GCC y MPICH2 gcc -o hola hola.cpp -l mpi En Linux con GCC y OpenMPI o MPICH2 mpicc -o hola hola.cpp Para programas en C++ mpicxx -o hola hola.cpp Ejecución El comando para ejecutar es mpiexec, hay que especificar el número de procesos y el path al programa mpiexec -n 5 hola 11/33

Un programa simple con MPI Funciones básicas MPI_Init(<pointer_to_int>, <pointer_to_char*>) Inicializa el proceso en MPI, bloquea la ejecución hasta que todos los procesos hayan sido inicializados. MPI_Comm_size(MPI_COMM_WORLD, <pointer_to_int>) Obtiene el número de procesos ejecutados en el grupo MPI_COMM_WORLD, éste es el grupo por default. Se pueden crear subgrupos de procesos. MPI_Comm_rank(MPI_COMM_WORLD, <pointer_to_int>) Obtiene el número de rango del proceso actual, los rangos van de 0 a size 1. MPI_Finalize() Termina la conección MPI, bloquea la ejecución hasta que todos los procesos terminen. 12/33

Comunicación con bloqueo Comunicación con bloqueo MPI_Send(<pointer_to_data>, <length>, <type>, <target>, <tag>, MPI_COMM_WORLD) Envia los datos en <pointer_to_data> de tamaño <length> y tipo <type> al proceso <target>. El identificador del mensaje es <tag> (un entero). MPI_Recv(<pointer_to_data>, <length>, <type>, <source>, <tag>, MPI_COMM_WORLD, MPI_STATUS_IGNORE) Recibe <length> datos de tipo <type> del proceso <source> y lo almacena en <pointer_to_data>. El identificador del mensaje es <tag> (un entero). La comunicación con bloqueo significa que la ejecución del proceso se para hasta que se envíe o reciba el mensaje. Los nombres predefinidos para los tipos de datos más comunes son: MPI_CHAR MPI_INT MPI_UNSIGNED MPI_LONG MPI_UNSIGNED_LONG MPI_FLOAT MPI_DOUBLE char int unsigned int long unsigned long float double 13/33

Comunicación con bloqueo El siguiente es un ejemplo de comunicación con bloqueo en el que el nodo con rango 0 actuará como maestro y los nodos con rangos 1 a N-1 actuarán como esclavos. El nodo maestro enviará un vector a cada nodo esclavo. rango 1 rango 0 rango 2 rango N-1 rango 3 rango 4 Cada esclavo tendrá que reservar memoria para el vector a recibir. 14/33

Comunicación con bloqueo #include <stdio.h> #include <stdlib.h> #include <mpi.h> else // Esclavos { int length; printf("slave (rank = %i)\n", rank); #define TAG_LENGTH 1 #define TAG_DATA 2 MPI_Recv(&length, 1, MPI_INT, 0, TAG_LENGTH, MPI_COMM_WORLD, MPI_STATUS_IGNORE); int main(int argc, char** argv) { int size; int rank; double* data = (double*)malloc(sizeof(double)*length); MPI_Recv(data, length, MPI_DOUBLE, 0, TAG_DATA, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) // Maestro { printf("master (size = %i)\n", size); int length = 20; double* data = (double*)malloc(sizeof(double)*length); for (int r = 1; r < size; ++r) { MPI_Send(&length, 1, MPI_INT, r, TAG_LENGTH, MPI_COMM_WORLD); MPI_Send(data, length, MPI_DOUBLE, r, TAG_DATA, MPI_COMM_WORLD); } free(data); } free(data); } MPI_Finalize(); return 0; } 15/33

Comunicación sin bloqueo Comunicación sin bloqueo En el ejemplo siguiente es un esquema peer-to-peer. Cada nodo envía un mensaje al nodo con el siguiente rango. La comunicación no puede hacerse con bloqueo. Por qué? rango 1 rango 0 rango 2 rango N-1 rango 3 rango 4 16/33

Comunicación sin bloqueo En el siguiente código muestra la implementación de este ejemplo: #include <stdio.h> #include <stdlib.h> #include <mpi.h> int send_data; int recv_data; MPI_Request send_request; MPI_Request recv_request; #define TAG_MESSAGE 1 int main(int argc, char** argv) { int size; int rank; send_data = 1000 + rank; MPI_Isend(&send_data, 1, MPI_INT, (rank + 1) % size, TAG_MESSAGE, MPI_COMM_WORLD, &send_request); MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Irecv(&recv_data, 1, MPI_INT, (rank + size - 1) % size, TAG_MESSAGE, MPI_COMM_WORLD, &recv_request); MPI_Waitall(1, &recv_request, MPI_STATUSES_IGNORE); printf("%2i recibio mensaje %i\n", rank, recv_data); MPI_Finalize(); return 0; } Introducimos el tipo de dato MPI_Request que es un identificador de solicitud. Sirve tanto para identificar solicitudes de envio o de recepción. 17/33

Comunicación sin bloqueo Las nuevas funciones utilizadas son: MPI_Isend(<pointer_to_data>, <length>, <type>, <target>, <tag>, MPI_COMM_WORLD, <pointer_to_request>) Solicita enviar <pointer_to_data> a <target>, con mensaje <tag>. La solicitud se almacena en <pointer_to_request> MPI_Irecv(<pointer_to_data>, <length>, <type>, <source>, <tag>, MPI_COMM_WORLD, <pointer_to_request>) Solicita recibir de <source> el mensaje <tag>, los datos se almacenarán en <pointer_to_data>. La solicitud se almacena en <pointer_to_request> MPI_Waitall(<request_count>, <pointer_to_requests>, MPI_STATUSES_IGNORE) Espera a que se completen todo un arreglo de solicitudes. 18/33

Comunicación sin bloqueo El siguiente es un ejemplo de una comunicación donde todos los nodos envian mensajes a todos los demás nodos. rango 1 rango 0 rango 2 rango N-1 rango 3 rango 4 Ahora necesitaremos arreglos de solicitudes (MPI_Request) para manejar las comunicaciones sin bloqueo. A continuación el código de este ejemplo: 19/33

Comunicación sin bloqueo #include <stdio.h> #include <mpi.h> else { send_request[r] = MPI_REQUEST_NULL; recv_request[r] = MPI_REQUEST_NULL; } #define TAG_MESSAGE 1 int main(int argc, char** argv) { int size; int rank; } int received = 0; do { int r; MPI_Waitany(size, recv_request, &r, MPI_STATUS_IGNORE); printf("%i recibio mensaje '%i' desde %i\n", rank, recv_data[r], r); ++received; } while (received < size - 1); MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); int* send_data = new int[size]; int* recv_data = new int[size]; delete [] recv_request; delete [] send_request; delete [] recv_data; delete [] send_data; MPI_Request* send_request = new MPI_Request[size]; MPI_Request* recv_request =new MPI_Request[size]; for (int r = 0; r < size; ++r) { if (r!= rank) { send_data[r] = rank*1000 + r; MPI_Isend(&send_data[r], 1, MPI_INT, r, TAG_MESSAGE, MPI_COMM_WORLD, &send_request[r]); MPI_Irecv(&recv_data[r], 1, MPI_INT, r, TAG_MESSAGE, MPI_COMM_WORLD, &recv_request[r]); } MPI_Finalize(); return 0; } 20/33

Comunicación sin bloqueo La nueva función utilizada es: MPI_Waitany(<request_count>, <pointer_to_requests>, <pointer_to_int>, MPI_STATUS_IGNORE) Espera a que se complete una solicitud de un arreglo de solicitudes. El número de solicitud cumplida se almacena en <pointer_to_int>. 21/33

Ejecución en un cluster Ejecución en un cluster Necesitamos un archivo hosts compute-0-0 compute-0-1 compute-0-2 compute-0-3 compute-0-4 Ejemplo de archivo de hosts La ejecución sería con: mpiexe -n 5 -hostfile hosts <ejecutable> De esta forma se ejecutaría una instancia del programa (proceso) en cada computadora. 22/33

Ejecución en un cluster Multiples procesos por nodo Es posible ejecutar varios procesos por nodo. Usando MPICH2 necesitamos un archivo machines compute-0-0:1 compute-0-1:4 compute-0-2:4 compute-0-3:4 compute-0-4:4 La ejecución sería: mpiexe -n 17 -machinefile machines <ejecutable> Usando OpenMPI se usa el archivo hosts con el formato: compute-0-0 slots=1 compute-0-1 slots=4 compute-0-2 slots=4 compute-0-3 slots=4 compute-0-4 slots=4 La ejecución sería: mpiexe -n 17 -hostfile hosts <ejecutable> 23/33

Ejecución en un cluster El estado del cluster 24/33

Depuración de programas MPI Depuración de programas MPI Depurar programas con MPI puede ser difícil, procesos ejecutándose en varias computadoras al mismo tiempo, muchos gigabytes de información, problemas de sincronización, etc. La forma más simple de hacer esto es hacer que los programas impriman mensajes. Hay debugers comerciales: TotalView (GNU-Linux/Unix) http://www.totalviewtech.com/products/totalview.html Microsoft Visual Studio Professional Edition (Windows) http://www.microsoft.com/visualstudio/en-us/products/professional También puede hacerse con herramientas gratuítas/libres como el GNU Debugger (GDB) y el Microsoft Visual Studio Express Edition. A continuación vamos a mostrar varios trucos para depurar programas con MPI. Estos trucos solo funcionarán con unos pocos procesos (probablemente menos de cinco) ejecutándose en le misma computadora. Esto puede ser suficiente para pruebas conceptuales del código. 25/33

Depuración de programas MPI GNU-Linux/Unix Tenemos que ejecutar el GDB de tal manera que sea éste el que llame nuestro programa. Para hacer esto visualmente más cómodo, vamos a ejecutar cada instacia del GDB en una ventana diferente. Primero hay que crear un archivo con los comandos para inicializar el GDB. Por ejemplo, el archivo gdb.txt pone breakpoints en las funciones Master y Slave, además ejecutará el programa utilizando in.dat y out.dat como argumentos. b Master b Slave r in.dat out.dat Para correr tres instancias de un programa llamando al GDB tres veces, cada una en una terminal diferente: mpiexec -n 3 xterm -e gdb -q -tui -x gdb.txt./programa 26/33

Depuración de programas MPI La siguiente imagen muestra la ejecución de este ejemplo: 27/33

Depuración de programas MPI Windows Tenemos que ejecutar el Visual Studio varias veces, una vez por cada instancia del programa. Para depurar es necesario que el código fuente del programa esté ubicado en el directorio donde se compilo el programa. Hay que crear un archivo batch que contenga los parametros, la ruta del ejecutable, etc. @echo off set MPI = "c:\program Files\MPICH2\bin\mpiexec.exe" set IDE = "c:\program Files\Visual Studio\Common7\IDE\VCExpress.exe" set EXE = "c:\development\program.exe" set IN = "c:\development\test\in.dat" set OUT = "c:\development\test\out.dat" %MPI% -n 3 %IDE% /SafeMode /debugexe %EXE% %IN% %OUT% La base de datos de símbolos del programa (archivo.pdb) debe estar en el mismo directorio que el ejecutable. 28/33

Depuración de programas MPI La siguiente imagen muestra la ejecución de este ejemplo: 29/33

Algunos resultados MPI + OpenMP Algunos resultados MPI + OpenMP Number of threads 8 6 4 2 1 Total time [s] 48.8 45.9 49.9 67.1 101.4 Edificio 3 264,250 326,228 978,684 69,255,522 1e-4 27 3 Parallel cholesky Total iterations 204 204 204 204 204 120.0 Iteration time [s] 0.114 0.095 0.092 0.095 0.096 101.4 100.0 80.0 67.1 Time [s] Problem: Dimension: Elements: Nodes: Variables: nnz(a): Global tolerance Partitions Overlapping Solver 49.9 45.9 48.8 60.0 40.0 La memoria total: 13,438,244,806 [bytes] Memoria nodo maestro: 308,703,548 [bytes] Memoria en nodos esclavo: 486,279,305 [bytes] 20.0 0.0 1 2 4 6 8 Threads 30/33

Sistemas grandes Sistemas grandes Ecuaciones 3,970,662 14,400,246 32,399,048 41,256,528 63,487,290 78,370,466 82,033,206 Tiempo [h] 0.12 0.93 1.60 2.38 4.93 5.59 5.13 Memoria [GB] 17 47 110 142 215 271 285 Procesadores 52 52 60 60 84 100 100 PCs 13 13 15 15 29 29 29 6 5.6 5 5.1 4.9 Tiempo [horas] 4 3 2.4 2 1.6 1 0.9 0 0.1 3,970,662 14,400,246 32,399,048 41,256,528 63,487,290 78,370,466 82,033,206 Número de ecuaciones 31/33

Preguntas? Preguntas? 32/33

Bibliografía Bibliografía [Ster95]T. Sterling, D. J. Becker, D. Savarese, J. E. Dorband, U. A. Ranawake, C. V. Packer. BEOWULF: A Parallel Workstation For Scientific Computation. Proceedings of the 24th International Conference on Parallel Processing, 1995. [MPIF08]Message Passing Interface Forum. MPI: A Message-Passing Interface Standard, Version 2.1. University of Tennessee, 2008. 33/33