Tutorial MPI en debian linux
La instalación de un cluster para procesamiento paralelo supone la utilización
de recursos de cpu y memoria distribuido en hardware conectado en red. Para que
sean visibles los beneficios de usar esta arquitectura es necesario utilizar un cluster
con varios nodos, al menos 3. Si no es posible usar al menos tres PCs físicos se
pueden crear máquinas virtuales sobre un PC con procesador de varios núcleos.
Pueden utilizar virtualbox o QEmu para crear las máquinas virtuales,
asignando una cantidad de memoria y un núcleo exclusivo a cada máquina virtual si
no cuenta con al menos 3 PCs.
Para este tipo de cluster es recomendable utilizar hardware homogéneo, sin
interfaz gráfica. Es necesario mantener la misma versión de mpi en todos los nodos.
Software requerido
● openmpi
● openssh
● nfs
● herramientas de desarrollo.
● un editor de texto sin formato
Debian/Ubuntu mantienen 2 versiones de MPI en su repositorio:
1. openmpi-bin
2. mpich
Configuración de la red
Antes de instalar el software MPI, empezaremos por configurar varios aspectos
de la red.
Configuración de las direcciones IP
Configure las direcciones ip en cada nodo, configure direcciones fijas o reserve
las direcciones por medio de un servidor dhcp.
El archivo de configuración de las interfaces es /etc/network/interfaces
El archivo se ve como sigue para configuración dinámica:
# The loopback network interface
auto lo
iface lo inet loopback
# Configuración dinámica de eth0
allow-hotplug eth0
iface eth0 inet manual
El archivo se ve como sigue para configuración fija:
# dirección fija de eth1
auto eth1
iface eth1 inet static
address 192.168.0.100
netmask 255.255.255.0
gateway 192.168.0.1
Para más información consulte el manual con el comando:
man interfaces
El servicio dhcp puede ser implementado en el nodo master. No es requerido si
se configuran los nodos con direcciones fijas.
Configuración /etc/hosts
El archivo /etc/hosts es una tabla que mantiene una relación de direcciones ip
a nombre, la primera columna contiene las direcciones ip, la segunda el nombre
(hostname); otras columnas corresponde a los aliases y son opcionales. El
separador de campos es cualquier carácter o secuencia que represente espacios en
blanco. La utilidad de este archivo es permitirnos utilizar nombres en lugar de
direcciones ip al momento de direccionar la comunicación entre nodos. Más
información en la línea de comando con la orden:
man hosts
En el nodo master, liste todos los nodos esclavos con sus direcciones y
nombres. En los nodos esclavos introduzca al menos el nodo master.
Para mejor consistencia en los nombres cree un archivo hosts y copielo a
todos los nodos.
A continuación se muestra como se ve el archivo /etc/hosts
# ip address hostname aliases
# ------------------------------------
127.0.0.1 localhost this
#
192.168.1.100 maestro master
192.168.1.100 esclavo_1 cliente_1 slave1
192.168.1.101 esclavo_2
192.168.1.108 esclavo_3
192.168.1.105 esclavo_4
Crear un usuario para el cluster
Aunque puede operar su clúster con su cuenta de usuario existente, lo
recomendable es crear una nueva para mantener nuestras configuraciones simples.
Cree un nuevo usuario mpiuser en todas las máquinas para mantener las
cosas simples.
Desde el usuario root ejecute la siguiente línea de comando para crear el
usuario:
adduser mpiuser
Introduzca la contraseña cuando sea solicitada y responda las demás
solicitudes.
Instalación y configuración SSH
Los nodos van a estar hablando en la red a través de SSH y compartir archivos
a través de NFS.
Se requiere la configuración del servidor ssh en los nodos esclavos y el cliente
ssh en el nodo master. Es posible instalar el servidor y el cliente de manera
independiente o instalar ambos y configurar cada cual según requerimiento.
Para instalar el servidor:
apt-get install openssh-server
Para instalar el cliente:
apt-get install openssh-client
Para instalar ambos:
apt-get install ssh
En el nodo master ingrese con el usuario mpiuser creado anteriormente.
su mpiuser
Ingrese la contraseña del usuario mpiuser cuando sea solicitada.
En la sesión de mpiuser genere una llave con la siguiente línea de comando:
ssh-keygen -t dsa
Esto generará un par de claves: pública y privada en los archivos
/home/mpiuser/.ssh/id_dsa.pub y /home/mpiuser/.ssh/id_dsa respectivamente.
Con la intención es evitar la solicitud de password cada vez que se quiera
comunicar con los otros nodos a través de ssh se copia la llave pública en los
esclavos del cluster (ssh server).
utilice el método que prefiera de los siguientes:
ssh-copy-id esclavo_1
scp /home/mpiuser/.ssh/id_dsa.pub mpiuser@esclavo_1:.ssh/authorized_keys
Para verificar la conexión, utilice la siguiente línea de comando:
ssh esclavo_1
Repetir para cada esclavo.
En caso de falla verificar:
/home/mpiuser/.ssh tenga permisos 700 (rwx------)
/home/mpiuser/.ssh/authorized_keys tenga permisos 600 (rw-------)
Utilice el comando chmod para modificar de ser necesario.
Instalación y configuración de NFS
En el nodo maestro se comparte un directorio con NFS para que los clientes
accedan a los datos.
Para instalar NFS ejecutamos desde el root:
apt-get install nfs-kernel-server
Ahora en la sesión de mpiuser, creamos un directorio para compartir:
mkdir data
Para compartirlo, editamos el archivo /etc/exports y agregamos la siguiente
línea:
/home/mpiuser/data *(rw,sync,no_root_squash,no_subtree_check)
a continuación ejecutar:
exportfs -a
Para mayor información verifique el manual en línea de comando.
man exports
En los nodos esclavos (cliente nfs) se instala el software necesario:
apt-get install nfs-common
Se crea el directorio de datos con el mismo nombre que el creado en el master
mkdir data
Se monta el directorio compartido en el directorio de datos para tener la misma
ruta a los archivos de aplicación.
sudo mount -t nfs maestro:/home/mpiuser/data ~/data
maestro debe estar listado en el archivo /etc/hosts del esclavo y ~ corresponde
al homedir del usuario actual (ver variable de entorno $HOME)
Para hacerlo permanente se monta el directorio modificando el archivo
/etc/fstab, agregando la línea:
maestro:/home/mpiuser/data /home/mpiuser/data nfs
fstab es una tabla donde se configura los sistemas de archivos a montar en el
inicio del sistema. mayor información en la línea de comandos:
man fstab
Instalación Open MPI
Seleccione una implementación e instale en cada nodo siguiendo el
procedimiento a continuación:
Instalación openmpi
Como usuario root instalar con el siguiente comando:
apt-get install openmpi-bin libopenmpi-dev
Acepte las sugerencias de apt.
Instalación mpich
Como usuario root instalar con el siguiente comando:
apt-get install mpich
Acepte las sugerencias de apt.
En adelante asumiremos openmpi como nuestro cluster.
Configuración de openmpi
Para que Open MPI sepa qué máquinas deben ejecutar sus programas, puede
crear un archivo para almacenarlo en el nodo maestro. Utilizaremos el archivo
/home/mpiuser/.mpi_hosts y podría contener lo siguiente:
# The hostfile for Open MPI
# filename:~/.mpi_hosts
# The master node, 'slots=2' is used because it is a dual-processor machine.
localhost slots=2
# The following slave nodes are single processor machines:
esclavo_1
esclavo_2
esclavo_3
En la configuración el número de slots corresponde al número de núcleos o
procesadores, los nombres esclavo_# corresponde a los nombres en /etc/hosts
Compilación de programas con openmpi
OpenMPI se puede utilizar con una variedad de lenguajes, dos de los más
populares son FORTRAN y 'C'. Si sus programas están escritos en 'C', entonces
puede usar mpicc en lugar de su compilador 'C' normal o puede pasar los
argumentos adicionales directamente a su compilador 'C'. Con mpicc los
argumentos que pasa son pasados a su compilador 'C' normal.
Si desea utilizar mpicc para compilar un archivo fuente 'C' llamado testmpi.c:
mpicc -o testmpi testmpi.c
Si desea ver qué se pasará a su compilador 'C' al compilar y vincular:
mpicc -showme -o testmpi testmpi.c
Ejecutar los programas MPI
Puede iniciar un programa en una sola máquina y ejecutarlo en varios
procesadores/núcleos. Esto es útil si tiene una máquina potente o está
depurando/probando un programa. Como alternativa, puede ejecutar el programa a
través del clúster y solicitar tantos procesos como desee ejecutar sobre él.
Para ejecutar miprograma en dos procesos en la máquina local:
$ mpirun -np 2 ./miprograma
Para ejecutar miprograma sobre cinco procesos en el clúster utilizando el
.mpi_hostfile creado anteriormente (Tenga en cuenta que miprograma debe estar en
la misma ruta en cada máquina):
mpirun -np 2 --hostfile .mpi_hosts ./miprograma
Código ejemplo
#include
#include
#include
int main(int argc, char *argv[])
{
const int MASTER = 0;
const int TAG_GENERAL = 1;
int numTasks;
int rank;
int source;
int dest;
int rc;
int count;
int dataWaitingFlag;
char inMsg;
char outMsg;
MPI_Status Stat;
// Initialize the MPI stack and pass 'argc' and 'argv' to each slave node
MPI_Init(&argc,&argv);
// Gets number of tasks/processes that this program is running on
MPI_Comm_size(MPI_COMM_WORLD, &numTasks);
// Gets the rank (process/task number) that this program is running on
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// If the master node
if (rank == MASTER) {
// Send out messages to all the sub-processes
for (dest = 1; dest < numTasks; dest++) {
outMsg = rand() % 256; // Generate random message to send to slave
nodes
// Send a message to the destination
rc = MPI_Send(&outMsg, 1, MPI_CHAR, dest, TAG_GENERAL, MPI_COMM_WORLD);
printf("Task %d: Sent message %d to task %d with tag %d\n",
rank, outMsg, dest, TAG_GENERAL);
}
// Else a slave node
else {
// Wait until a message is there to be received
do {
MPI_Iprobe(MASTER, 1, MPI_COMM_WORLD, &dataWaitingFlag,
MPI_STATUS_IGNORE);
printf("Waiting\n");
} while (!dataWaitingFlag);
// Get the message and put it in 'inMsg'
rc = MPI_Recv(&inMsg, 1, MPI_CHAR, MASTER, TAG_GENERAL, MPI_COMM_WORLD,
&Stat);
// Get how big the message is and put it in 'count'
rc = MPI_Get_count(&Stat, MPI_CHAR, &count);
printf("Task %d: Received %d char(s) (%d) from task %d with tag %d \n",
rank, count, inMsg, Stat.MPI_SOURCE, Stat.MPI_TAG);
}
MPI_Finalize();
}
Programación de aplicaciones MPI
... en construcción
Referencias
http://mpitutorial.com
https://www.open-mpi.org
Programación distribuida y paralela