680 likes | 823 Views
Taller de MPI. Mecanismo de switches o Bus. Modelos de Computación Paralela. 1. Multiprocesadores de Acceso Uniforme a Memoria. CPUs. Bancos de Memoria. Dispositivos de I/O. 2. Multiprocesadores de Acceso No uniforme a Memoria. Memorias Locales. CPUs. Mecanismo de Enrutamiento.
E N D
. . . Mecanismo de switches o Bus Modelos de Computación Paralela 1. Multiprocesadores de Acceso Uniforme a Memoria CPUs . . . . . . Bancos de Memoria Dispositivos de I/O 2. Multiprocesadores de Acceso No uniforme a Memoria Memorias Locales . . . CPUs Mecanismo de Enrutamiento
Memoria Compartida Local Memoria Compartida Local Memoria Compartida Local . . . . . . . . . . . . Mecanismo de interconexión Modelos de Computación Paralela 3. Máquinas con Memoria Compartida Distribuida
Plataforma de CeCalCULA Scalable Power Parallel System (SP2/IBM) • Multicomputador MIMD • Basado en AIX/6000 (Power2) • 16 nodos por Modulo [1 Módulo, 8 Nodos,64 MB c/u, 2 GB c/u], hasta 8 Módulos (128 Nodos) • Switch de alta eficiencia • Omega (2x2 Crossbar switches) • Múltiples etapas con buffer • Packet-Switch
Plataforma de CeCalCULA SGI Origin 2000 • Multicomputador MIMD de Memoria Compartida Distribuida (MCD) • Basada en el R10000 • 2 procesadores por nodo (máximo 128 procesadores) [2 Nodos, 128 MB c/u, 9 GB c/u] • Conectados por una fibra de interconexión • HUB. Controlador de la MCD
Contenido • Generalidades • Inicialización y finalización de MPI • Comunicaciones • Punto a punto • Colectivas • Operaciones Globales • Síncronas/Asíncronas • Transferencia de datos dispersos (no homogéneos) • Comunicadores y Grupos • Topologías
MPI (Message Passing Interface) • Estándar que define un sistema de pase de mensajes diseñado para ser utilizado en cualquier sistema paralelo (MPP,redes de estaciones de trabajo, etc.). • Portátil, eficiente y flexible. No difiere demasiado de las herramientas de pase de mensajes de mayor uso. (PVM, P4, Express, etc.)
Implementaciones MPI • MPICH (MPI/Chamaleon). Argonne (USA) • LAM (Local Area Multicomputer). Ohio • Chimp (Common High-level Interface to Message Passing). CCP de Edinburgo • Unify. Combina PVM y MPI. Mississipi • MPICH/NT, WIN32MPI,WinMPI • MPI-FM. SPARCStation con Myrinet • Origin2000. SGI • Futjitsu AP1000 • CRI/EPCC (Cray/T3D) • MPI- POE (IBM SP1/2)
Generalidades • MPI mueve datos entre las memorias de los elementos de procesamiento (PE) • Todos los PEs ejecutan el mismo código (SPMD) MEM. PE 0 1 2 3 Interconexión
Vocabulario • Elemento de Procesamiento (PE) • Punto a Punto • Colectivas • Bloqueado • Buffer • Rank
Convenciones MPI • Fortran: Definiciones (Constantes, tipos, rutinas, etc.) en el archivo mpif.h Sintaxis: call MPI_OPERATION(....,ierr) • C: Definiciones (Constantes, tipos, rutinas, etc.) en el archivo mpi.h Sintaxis: ierr = MPI_Operation(....) Primer carácter en mayúscula
Inicialización • Todos los programas MPI necesitan las instrucciones de inicialización y finalización. • Necesitan saber el número de PEs (nPEs) y su propio número (Rank) • El grupo inicial de PEs esta definido por el parámetro: MPI_COMM_WORLD • El número que tiene un PE esta en el rango de 0 a nPEs - 1
Inicialización (Cont.) • C • #include <mpi.h> • /* Inicializando MPI */ • MPI_Init(&argc,&argv); • /* Cuántos PEs Hay ? */ • ierr = MPI_Comm_size(MPI_COMM_WORLD,&nPEs); • /* Cuál nodo soy yo (Cuál es mi Rank ) ? */ • ierr = MPI_Comm_rank(MPI_COMM_WORLD,&iam); • MPI_Finalize(); ....
Inicialización (Cont.) • Fortran • include ‘mpi.h’ • c Inicializando MPI • call MPI_INIT(ierr) • c Cuántos PEs Hay ? • call MPI_COMM_SIZE(MPI_COMM_WORLD,&nPEs,ierr) • c Cuál nodo soy yo (Cuál es mi Rank ) ? • call MPI_COMM_RANK(MPI_COMM_WORLD,&iam,ierr) • call MPI_Finalize(ierr) ....
Ejercicio: Hola Mundo • Escriba una versión paralela para el programa Hola Mundo • Iniciar MPI • Imprimir el mensaje: Hola Mundo, número del proceso y total de procesos. • Finalizar MPI
Comunicaciones Definiciones • Los bytes son transferidos de un procesador a otro • Se debe especificar el destino/fuente, dirección de los datos (buffer), número de elementos, tipo de datos, identificador del mensaje (denominado tag), etc. • Envío síncrono: La llamada no retorna hasta que el mensaje es enviado. • Envío asíncrono: La llamada retorna inmediatamente, idealmente, el envío ocurre durante otro cálculo. • Recepción síncrona: La llamada no retorna hasta tanto no se reciba el mensaje. • Recepción asíncrona: La llamada retorna inmediatamente. Cuando se necesitan los datos, se debe llamar a una subrutina de espera. • Las comunicaciones asíncronas intentan solapar las comunicaciones con los cálculos.
Envío Síncrono • Envío de mensaje con bloqueo • C ierr = MPI_Send(&buffer,count, datatype, destination, tag, communicator); • Fortran call MPI_SEND(&buffer,count, datatype, destination, tag, communicator,ierr); • La ejecución se bloquea hasta que el mensaje este en el canal
Parámetros del MPI_Send • buffer: Dirección de inicio de los datos • count: Longitud del arreglo fuente (número de elementos) • datatype: Tipo del dato. (caracter, entero, real, etc.) • destination: Número lógico del proceso destino. • Tag: Tipo del mensaje (Número entero) • communicator: Conjunto (grupo) de procesos al que pertenecen el enviador y el receptor. • ierr: Resultado del envío.
Recepción Síncrona • Recepción de mensajes con bloqueo • C ierr = MPI_Recv(&buffer,count, datatype, source, tag, communicator, &status); • Fortran call MPI_RECV(buffer,count, datatype, source, tag, communicator, status, ierr);
Tipos de datos en MPI Algunos tipos de datos de MPI, definidos en el archivo mpi.h, son: Tipo de dato MPITipo de dato C MPI_CHAR signed char MPI_SHORT signed short int MPI_INT signed int MPI_LONG signet long int MPI_UNSIGNED_CHAR unsigned char MPI_UNSIGNED_SHORT unsigned short int MPI_UNSIGNED unsigned int MPI_UNISIGNED_LONG unsigned long int MPI_FLOAT float MPI_DOUBLE double MPI_LONG_DOUBLE long double MPI_BYTE MPI_PACKED
Tipos de datos en MPI (Cont.) Tipos de datos de MPI, definidos en el archivo mpif.h: Tipo de dato MPITipo de dato Fortran MPI_INTEGER INTEGER MPI_REAL REAL MPI_DOUBLE_PRECISION DOUBLE PRECISION MPI_COMPLEX COMPLEX MPI_LOGICAL LOGICAL MPI_CHARACTER CHARACTER MPI_BYTE MPI_PACKED
Wildcards • Permiten recibir cualquier tipo de mensaje desde cualquier fuente • Ejemplo en Fortran: integer status(MPI_STATUS_SIZE) call MPI_RECV(buffer,count, MPI_INTEGER, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,status,ierr)
El parámetro status • El parámetro status retorna información adicional • Parámetros de alguna rutina MPI • Información adicional de los errores • Información cuando se usan wildcards • Declaración en C: Es una estructura predefinida MPI_Status status; • Declaración en Fortran: Se usa un arreglo INTEGER status(MPI_STATUS_SIZE)
Información en status • El tipo (tag) del mensaje recibido C: status.MPI_TAG Fortran: status(MPI_TAG) • La número del enviador (Fuente) C: status.MPI_SOURCE Fortran: status(MPI_SOURCE) • El código de error de la llamada MPI C: status.MPI_ERROR Fortran: status(MPI_ERROR)
Las seis rutinas MPI !!! Inicializar C: ierr = MPI_Init(&argc,&argv); Fortran: call MPI_INIT(ierr) Número de Procesos ierr = MPI_Comm_size(MPI_COMM_WORLD,&npes); Identificador del Proceso ierr = MPI_Comm_rank(MPI_COMM_WORLD,&iam); Envio de mensajes ierr = MPI_Send(buffer,count,datatype,destination,tag,communicator) Recibir Mensajes ierr = MPI_Recv(buffer,count,datatype,source,tag,communicator,estado) Finalizar ierr = MPI_Finalize()
Medición del tiempo Reloj MPI_Wtime • MPI_WTIME retorna un número real que contiene los segundos que han transcurrido desde algún tiempo pasado. • C float time_now; time_now = MPI_Wtime(); • Fortran DOUBLE PRECISION time_now time_now = MPI_WTIME() • Parámetros: NINGUNO
0 Ejercicio: Hola Maestro • Escriba un programa paralelo donde cada proceso, excepto el 0, envíe el mensaje: “Hola maestro soy #” (# es el número del proceso) al proceso maestro (proceso 0). • El proceso 0 recibirá los mensajes y los mostrará en pantalla . . . 1 N-2 N-1
N-1 . . . 0 1 N-2 N-1 0 1 N-2 Ejercicio: Saludos • Escriba un programa paralelo donde cada proceso envíe su número al vecino sucesor. • Cada proceso debe escribir su número acompañado del mensaje recibido.
0 . . . 1 N-2 N-1 Ejercicio: Producto Punto • Escriba un programa paralelo para calcular el producto escalar de dos vectores. • Divida los vectores A y B entre el número de procesadores (procesos). • Cada proceso calcula el producto punto parcial • Sume los productos puntos parciales para obtener el global.
Comunicaciones Colectivas • Transferencia de datos entre múltiples procesos Acciones Colectivas: • Sincronizar. • Mover datos (difundir, recolectar y esparcir). • Calcular Colectivamente.
Sincronizar • Todos los procesos llaman a la rutina. • La ejecución es bloqueada hasta que todos los procesos ejecuten la rutina. • C ierr = MPI_Barrier(communicator); • Fortran call MPI_BARRIER(communicator,ierr)
Difundir • Un proceso envía un mensaje (root). • Todos los otros reciben el mensaje. • La ejecución se bloquea hasta que todos los procesos ejecuten la rutina. • Automáticamente actúa como punto de sincronización. • C ierr = MPI_Bcast(&buffer,count,datatype, root,communicator); • Fortran call MPI_Bcast(buffer,count,datatype,root, communicator,ierr);
Recolectar • Intercambio global de datos • Cada proceso envía diferentes datos al proceso principal (root) y este los agrupa en un arreglo. • C ierr = MPI_ Gather(sbuf,scount,stype,rbuf,rcount, rtype,root,communicator); • Fortran call MPI_GATHER(sbuf,scount,stype, rbuf, rcount,rtype,root, communicator, ierr)
rbuf 1 1 1 De PE 0 2 2 2 ... ... ... PE1 PE2 PE0 sbuf sbuf sbuf rcount rcount rcount 1 1 1 . . . De PE 1 2 2 2 ... ... ... scount scount scount De PE 2 . . . Recolectar En PE= root • MPI_ Gather(sbuf,scount,stype, • rbuf,rcount, rtype, • root,communicator);
Esparcir • Intercambio global de datos • El proceso principal (root) rompe un arreglo de datos y envíe las partes a cada procesador. • C ierr = MPI_ Scatter(sbuf,scount,stype,rbuf,rcount, rtype,root,communicator); • Fortran call MPI_SCATTER(sbuf,scount,stype, rbuf, rcount,rtype,root, communicator, ierr)
En PE= root sbuf 1 1 1 Hacia PE 0 2 2 2 ... ... ... PE0 PE1 PE2 rbuf rbuf rbuf scount scount scount 1 1 1 Hacia PE 1 2 2 2 ... ... ... rcount rcount rcount Hacia PE 2 . . . Esparcir . . . • MPI_ Scatter(sbuf,scount,stype, • rbuf,rcount, rtype, • root,communicator);
Cálculos Colectivos Definiciones • El usuario puede combinar cálculos parciales de • todos los procesos. • Los resultados están disponibles en un proceso particular o • en todos los procesos. • Ejecución sincronizada.
Cálculos Colectivos • Combinación de resultados parciales • El proceso principal (root) recibe los cálculos parciales y los combina usando la operación indicada. • C ierr = MPI_ Reduce(sbuf,rbuf,count,datatype, operation, root, communicator); • Fortran call MPI_REDUCE(sbuf, rbuf,count,datatype, operation, root, communicator,ierr); • Todos almacenan el resultado con : MPI_ Allreduce • La rutina no requiere el parámetro root
Tipos de Operaciones MPI_MAX Máximo MPI_MIN Mínimo MPI_PROD Producto MPI_SUM Suma MPI_LAND Y Lógico MPI_LOR O Lógico MPI_LXOR O Exclusivo lógico MPI_BAND Y bit a bit MPI_BOR O bit a bit MPI_BXOR O Exclusivo bit a bit MPI_MAXLOC Máximo y localización MPI_MINLOC Mínimo y localización
Definición de operaciones El usuario puede definir sus propias operaciones • C void function(void *invec,void *inout,int *len, MPI_Datatype *datatype) { Cuerpo de la función } .... int commute; MPI_Op op; .... ierr = MPI_ Op_create(function,commute,&op); ierr=MPI_Op_free(&op); {op = MPI_OP_NULL}
Definición de operaciones • Fortran FUNCTION function(invec(*), inout(*),len,datatype) <type> invec(len), inout(len) INTEGER len, datatype { Cuerpo de la función } .... EXTERNAL FUNCTION LOGICAL COMMUTE INTEGER OP,IERROR call MPI_ OP_CREATE(FUNCTION,COMMUTE,OP,IERROR); call MPI_OP_FREE(OP,IERROR); {OP = MPI_OP_NULL}
Ejemplo para calcular una suma • Cada procesador tiene las variables sum_parcial y suma_global • El valor de la suma_global es actualizado en el proceso root. • C double suma_parcial, suma_global; suma_parcial = ......; ierr = MPI_Reduce(&suma_parcial, &suma_global, 1, MPI_DOUBLE_PRECISION, MPI_SUM, root MPI_COMM_WORLD); • Fortran double precision suma_parcial, suma_global suma_parcial = ...... Call MPI_REDUCE(suma_parcial, suma_global, 1, MPI_DOUBLE_PRECISION, MPI_SUM, root MPI_COMM_WORLD,ierr)
Difunda los vectores Recolecte las sumas parciales 0 . . . 1 N-2 N-1 Ejercicio: Producto Punto • Utilice rutinas de Comunicación colectiva para modificar el programa producto punto.
Comunicaciones Asíncronas Envío MPI_Isend • Envío no bloqueado (inmediato) • C MPI_Request request; ierr = MPI_Isend(&buffer,count, datatype,destination, tag, communicator,request); • Fortran INTEGER request call MPI_ISEND(buffer,count, datatype,destination, tag, communicator,request,ierr) • Parámetros: Los parámetros son los mismos que para MPI_Send, agregándose el parámetro request que establece un enlace entre la operación de comunicación y un objeto MPI (que esta oculto).
Comunicaciones Asíncronas Recepción MPI_Irecv • Recepción sin bloqueo (inmediata) • C ierr = MPI_Irecv(&buffer,count, datatype,source, tag, communicator,request); • Fortran call MPI_IRECV(buffer,count, datatype,source, tag, communicator,request,ierr) • Parámetros: Los parámetros son los mismos que para MPI_Recv, sustituyendose el parámetro status por request para establecer un enlace entre la operación de recepción y un objeto MPI (que esta oculto).
Comunicaciones Asíncronas Espera MPI_Wait • Es usada para completar comunicaciones sin bloqueo • La finalización de la operación de envío permite al remitente modificar libremente el buffer de envío. • La finalización de la recepción indica al destinatario que el buffer de recepción ya contiene el mensaje esperado. • C ierr = MPI_Wait(request,status); • Fortran call MPI_WAIT(request,status,ierr) • Parámetros: request: Enlace con la operación. status: Información de la operación.