MPI

MPI es una especificación para desarrolladores y usuarios de librerias de pasaje de mensajes. Su objetivo es ser una interfaz práctica, portable, eficiente y flexible. Una gran ventaja de MPI es que está adaptada para cualquier arquitectura de memoria (distribuida, compartida e híbrida). Implementaciones de MPI: MPICH, OpenMPI, Intel MPI. Tiene soporte para C, C++ y Fortran.

Para invocar la libreria usamos:

C fortran
#include "mpi.h" include 'mpif.h

Luego la sintaxis es casi idéntica para C/C++ y Fortran. En C, los comandos siguen la siguiente sintaxis:

rc = MPI_Xxxxx(param, ...)

En fortran la sintaxis es:

call MPI_XXXXX(param,..., ierr)

Ejemplo simple:

Un programa hola mundo paralelizado con MPI en fortran sería:

program hola
    implicit none
    integer :: ierr

    include 'mpif.h'

    !Código serial...
    call MPI_INIT(ierr)
        print '("Hola mundo!")'
    call MPI_FINALIZE(ierr)
    !Código serial...
end program

Para compilarlo:

$> mpif90  hola_mundo.f 

Luego lo ejecutamos así:

$> mpirun -np 4 a.out 

Comunicadores, Grupos y rank

MPI usa unos objetos llamados comunicadores (comm) y grupos (group) para definir que colección de procesos se comunican con otros.

Los comunicadores definen un grupo de procesos que tienen la capacidad de comunicarse entre si. En este grupo a cada proceso se le asigna un rank único (también llamado task ID) que le permite comunicarse explicitamente con el resto.

La mayoría de las rutinas de MPI requieren que se especifique el comunicador como argumento. Hay un type MPI_Comm y hay un comunicador predeterminado MPI_COMM_WORLD.

Dentro de cada comunicador, cada proceso tiene su propio y único identificador. Cuando un proceso se inicia un identificador (un número entero) es asignado por el sistema. A los rangos aveces tambien se los llaman task ID. Los rangos son contiguos y empiezan en 0.

La comunicación se basa en operaciones de envio (send) y recepción (receive) entre procesos.

Se utilizan para especificar el origen y destino de los mensajes. Comunmente se usa condicionalmente por la aplicación para controlar la ejecución del programa (so rank==0 hacer esto / si rank==1 hacer esto otro)

Manejo de Errores

Generalmente las rutinas MPI retornan un parametro de error, sin embargo el comportamiento standard de MPI es abortar si un error ocurre.

Rutinas de manejo de ambiente:

Principales rutinas en MPI:

Otras rutinas:

Comunicación punto a punto

Comunicación entre dos tasks distintos. Un task realiza la operación de envío y el otro la de recepción. Hay distintos tipos de rutinas de envío y recepción usadas para distintos propositos. Por ejemplo:

Cualquier tipo de rutina de envío está asociada a una de recivo.

MPI también provée rutinas asociadas a operaciones envío-recivo tal como aquellas usadas para mensajes de espera de arrivo ó probar si un mensaje ha llegado.

Buffering

Idealmente, toda operación de envío está perfectamente sincronizada con la operación de recibo. Esto raramente ocurre. De alguna forma u otra MPI tiene que ser capaz de manejarse con datos almacenados cuando un dos tasks están fuera de sincronía.

Por ejemplo:

MPI decide que pasa con estos datos. Tipicamente hay un area buffer del sistema reservada para sostener el transito.

El espacio buffer:

Blocking

Las rutinas de MPI point-to-point puedn ser usadas en modo blocking ó non-blocking.

Orden & Fairness

Orden + MPI garantiza que los mensajes no se adelanten los unos a los otros.

Justicia / Fairnes + MPI no garantiza justicia, esto quiere decir que si dos tasks envían una señal al mismo taks, entonces sólo uno de los mensajes se completará.

Rutinas y argumentos

Las comunicaciones punto a punto (por ejemplo MPI_Send y MPI_Recv) generalmente tienen la siguiente lista de argumentos:

Ejemplos:

|——————————————————————————————–| | emisión bloqueada | MPI_SEND ( *buffer, count, type, dest, tag, comm* ) | | emisión no bloquada | MPI ISEND( *buffer, count, type, dest, tag. comm, request* ) | | recepción bloqueada | MPI_RECV ( *buffer, count, type, source, tag, comm, status* ) | | recepción no bloqueada | MPI_IRECV( *buffer, count, type, source, tag, comm, request* )| |——————————————————————————————–|

Rutinas de paso de mensajes

** Bloqueadas **

** No-Bloqueadas **


Comunicación colectiva

La comunicación colectiva involucra a todos los procesos en el alcance del comunicador.

Tipos de Operaciones colectivas:

Rutinas de comunicación colectiva:

Grupos y Comunicadores

Un grupo es un conjunto de procesos ordenados. Cada proceso en un grupo está asociado con un único rango entero. Los valores de rangos comienzan en 0. Los grupos son representados como un objeto en un sistema de memoria. Son solo accesibles por el usuario a ‘mano’. Todo objeto está asociado a un objeto comunicador.

Un comunicador engloba a un grupo de procesos que pueden comunicarse entre ellos. Todos los ensajes MPI deben especificar al comunicador. En el sentido más simple el comunicado es un tag extra que debe incluirse en las llamadas de MPI. Como en los grupos, los comunicadores está representados como un objeto en un sistema de memoria y son solo accesibles manualmente.

Desde el punto de vista del usuario, un grupo y un comunicador son uno. Las rutinas de grupo son principalmente para especificar que procesos deben ser usados para contruir un comunicador.

Principales propositos de grupos y comunicadores:

  1. Permitir reconocer tasks, basado en funciones, en grupos de taks.
  2. Habilitar operaciones de comunicaciones colectivas a lo largo de un subconjunto de tasks relacionados.
  3. Provéer bases para immplementar topologías virtuales definidas por el usuario.
  4. Provéer de comunicaciones seguras.

Algunas consideraciones:

Topologías virtuales

Por qué usarlas:


Edit this page.

Licensed MIT.