Compilación Paralela

He empezado a aprender como hacer compilación paralela para obtener más rendimiento en el clúster. Para ello me he metido con OpenMPI que es un proyecto abierto derivado de la estructura LAM/MPI mantenido por la comunidad.

El primer paso es obtener el software de esta dirección y compilarlo:

$ tar jxvf openmpi-1.4.1.tar.bz2
$ ./configure --prefix=/usr/local/openmpi
# make all install

Una vez compilado, debemos actualizar el enlazador dinámico para que nuestro software enlace correctamente con las librerías dinámicas de OpenMPI

# ldconfig /usr/local/openmpi/lib

Con esto, le decimos al programa ld que busque en /usr/local/openmpi/lib las librerias que haces falta en tiempo de ejecución de nuestro programa.

A continuación, es obligatorio que todos los nodos del clúster tengan acceso a los ejecutables tanto de nuestro programa como de OpenMPI, por lo que vamos ha crear un par de comparticiones por NFS.

/usr/local/openmpi   192.168.0.0/24(ro,root_squash)
/home/openmpi   192.168.0.0/24(rw,root_squash)

Donde /home/openmpi es nuestro usuario de cluster, en su directorio $HOME estará el programa a ejecutar. Y la otra compartición contiene los ejecutables del compilador.

Vamos a lanzar el programa clásico HelloWorld en paralelo, para ello utilizamos el siguiente código.

/* helloworld.c */
/* http://www.semicomplete.com/presentations/mpi/#slide_2 */
#include <stdio.h>
/* Esto es para añadir las funciones de OpenMPI */
#include "mpi.h"

int main(int argc, char **argv) {
int rank;
char host[150];
int namelen;

/* Inicializar MPI. Maneja la línea de comando especifica de mpich */
MPI_Init(&argc, &argv);

/* Devuelve el rango. Mi número de rango (de la instancia del programa) queda almacenado en la variable rank */
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

/* Vemos en qué maquina me ejecutando y lo guardamos en host */
MPI_Get_processor_name(host,&namelen);

printf("Hello world (Rank: %d / Host: %s)\n", rank, host);
fflush(stdout);

/* Fin: Cerramos las conexiones con los demás nodos y liberamos la memora que el programa ha reservado,... */
MPI_Finalize();
return 0;

Lo compilamos

$ PATH=$PATH:/usr/local/openmpi/bin
$ mpicc helloworld.c -o helloworld

El PATH podemos añadirlo a nuestro ~/.bashrc para que esté siempre disponible. Ejecutamos.

$ mpirun -np 5 --hostfile=hosts helloworld

Donde

  1. -np Es el número de procesos que vamos a lanzar.
  2. –hostfile Es el fichero que almacena los nombres de los hosts, cada nodo del cluster.

La salida debe ser algo como esto

Hello world (Rank: 0 / Host: master)
Hello world (Rank: 2 / Host: master)
Hello world (Rank: 4 / Host: master)
Hello world (Rank: 1 / Host: cluster01)
Hello world (Rank: 3 / Host: cluster01)

Vemos que ha lanzado tres procesos en master y dos en cluster01.

De momento esto es lo poco que sé, pero sigo avanzando, el asunto de tener que resolver matrices de gran tamaño voy a necesitar escribir código para lanzar paralelizado.

This entry was posted in HPC and tagged , , , , . Bookmark the permalink.