Currently Browsing

google SoC

LAM/MPI y mis problemas con MPI_Scatter / MPI_Gather

He tenido un problema mientras utilizaba LAM/MPI para generar un pequeño programa ejemplo que hiciera uso de MPI_Spawn, MPI_Gather y MPI_Scatter. Situémonos en contexto.

En MPI-2 hay dos tipos de comunicadores, el intracomunicador y el intercomunicador. Un intracomunicador es un comunicador como el definido en el estándar MPI-1: todos los procesos del comunicador se comunican de igual a igual.

Sin embargo, el intercomunicador define dos grupos de procesos, el local y el remoto (nombres arbitrarios que dependen del punto de vista del proceso actual), que podemos denominar A y B.

Supongamos que un proceso M ha realizado una llamada a MPI_Spawn generando un conjunto de K procesos S. Ahora el proceso M puede utilizar el intercomunicador que devolvió MPI_Spawn para comunicarse con los procesos de K, y cualquier proceso de K puede llamar a MPI_Comm_get_parent para obtener un intercomunicador que le permita comunicarse con proceso que lo creó. El intercomunicador obtenido en ambos casos es el mismo.

El intercomunicador tiene dos grupos, el grupo A conteniendo al “proceso” M y el grupo B conteniendo los K procesos. Una llamada a MPI_Gather o MPI_Scatter funciona de forma distinta cuando se utiliza un intercomunicador que cuando se utiliza un intracomunicador. La principal ventaja del intercomunicador en este caso es que el proceso M puede comunicarse con todos los procesos del conjunto S mediante MPI_Scatter y MPI_Gather sin recibir el mismo ningún paquete de datos (cosa que ocurre cuando se utiliza un intercomunicador).

Para que el esquema funcione del modo que deseamos, utilizamos una constante de MPI denominada MPI_ROOT, que define un proceso como origen de los datos. Utilizando en el proceso M:

MPI_Scatter(sendbuf, n, MPI_INT, NULL, 0, MPI_INT, MPI_ROOT, comm);

y en todos los procesos de K:

MPI_Scatter(NULL, 0, MPI_INT, recvbuf, n, MPI_INT, rank, parent_comm);

Donde rank es el rango del proceso M en el grupo A. Muy posiblemente rank sea 0 cuando en A sólo hay un proceso; podrí­a ser que el grupo A tuviera más de un proceso (el “proceso” M que creó el conjunto S era un conjunto de procesos M’) y en este caso los otros procesos de A pasarí­an MPI_PROC_NULL en lugar de MPI_ROOT.

Pues bien, esto funciona bien en MPICH2, aunque en LAM/MPI 7.1.1 no funciona. Estoy compilando LAM/MPI 7.1.2 para asegurarme de que no ha sido corregido desde la versión anterior. MPICH2 no termina de gustarme porque no es todo lo transparente que necesito que sea. En DaVinci se utiliza un wrapper para ejecutar correctamente el verdadero intérprete, y ese wrapper da problemas cuando se ejecuta con el mpiexec de MPICH2.

Cómo utilizar MPI_Spawn y acerca de OpenMPI

OpenMPI me ha decepcionado. He descubierto un bug en MPI_Spawn: Cuando utilizas MPI_Spawn para crear nuevas instancias del mismo programa que esta ejecutando MPI_Spawn, estas nuevas instancias se bloquean y abortan la ejecución en la llamada MPI_Init, y sin embargo… ¡los valores de retorno son 0! Es decir, el proceso que ejecutó MPI_Spawn recibe un falso positivo: piensa que los procesos se crearon correctamente.

Contaré como lo descubrí­: Después de una tarde de frustración, decido instalar LAM/MPI (una implementación de MPI mucho más madura, aunque ahora en mantenimiento debido a que sus miembros estan trabajando en OpenMPI). Después de configurarla (dirí­a que es un poco más complicado que OpenMPI) compilo el mismo código fuente que utilizaba para las pruebas de MPI_Spawn cuando utilizaba OpenMPI. Grande es mi sorpresa cuando funciona sin problemas.

El código fuente del programa de prueba se puede descargar aquí­: Spawntest

Además de MPI_Spawn, también muestra el uso de MPI_Bcast para enviar el mismo mensaje a los procesos creados con el MPI_Spawn. Próximamente, uso de MPI_Scatter para distribuir un conjunto de datos entre los procesos.

MPI_Scatter and MPI_Scatterv

In this post I will explain the difference between MPI_Scatter and MPI_Scatterv and why this last is needed.

MPI_Scatter sends a vector of data along the processes in the MPI communicator, sending the same number of data to each process. ie, if there is a vector[100] and there are 10 processes, each process will receive a 10 ints vector.

Suppose there is a matrix of size (x, y) and you want to send each column of size (1, y) to a MPI process using MPI_Scatter; but there are only n < x processes. There will be a problem because MPI_Scatter sends the same quantity of data to each process.

MPI_Scatterv allows to control the number of data sent to each process, in such a way you can control the above problem, sending a determinate number of columns to each process.

OpenMPI: Using MPI_Pack and MPI_Unpack to pack heterogeneous data

I have written a little example of how to use MPI_Pack and MPI_Unpack to pack heterogeneuos data types and transmit them along the MPI universe of processes. With these two MPI routines, data of different types can be stored as bytes in a char * buffer and sent along the network. Receiving processes just use unpack to recover the data in its original state.

The example can be downloaded PackTest.

I compiled it using OpenMPI, but I think it will run in any MPI implementation.

In order to compile

$ mpicc packtest.c -o packtest

In order to run

$ mpirun -np 10 packtest