19
18 de diciembre de 2012

Manual de configuracion de un cluster en Debian

  • Upload
    lavp28

  • View
    312

  • Download
    4

Embed Size (px)

DESCRIPTION

Manual Para Ayudar Con La Configuración de un Cluster en Debian

Citation preview

Page 1: Manual de configuracion de un cluster en Debian

18 de diciembre de 2012

Page 2: Manual de configuracion de un cluster en Debian

MANUAL DE CONFIGURACION

CLUSTER/MPI CON DEBIAN

Introducción

El contenido de este manual describe las acciones a realizar para la

configuración (creación) de un clúster de máquinas linux.

Este cluster permite la ejecución de programas paralelos; esto

significa que su codificación contiene instrucciones especiales para

ser ejecutados de forma paralela. Existen diferentes protocolos para

la creación de este tipo de entornos (pe. PVM o MPI). El cluster que

se describe utiliza el protocolo MPI a través de la implementación

LAM-MPI.

El cluster descrito consiste en un conjunto de máquinas con sistema

operativo linux a las que se les define un usuario (lam). El directorio

de trabajo de este usuario es un directorio remoto (montado usando

samba) que contiene los binarios necesarios para la activación del

nodo. No se supone que cada uno de los nodos sea una máquina

dedicada; de hecho cada máquina del cluster continuará realizando

las tareas asignadas (pe. servidor web, servidor de base de datos,

firewall, servidor de ficheros, etc.) además de pertenecer al cluster.

No es necesaria la ejecución de un daemon de sistema. Cuando el

cluster se activa, el nodo maestro se pone en contacto con cada uno

de los nodos clientes a través del usuario lam y ejecuta el daemon

lamd. Mientras está activo se pueden ejecutar los programas

paralelos dentro del entorno LAM. Cuando el clúster ya no es

necesario, se cierra el daemon lamd y no queda ningún proceso ni

usuario del cluster en ejecución.

Se procura que la seguridad de cada nodo no quede comprometida

por el hecho de pertenecer al cluster. Además, se busca que el propio

cluster sea seguro (no pueda ser usado o modificado por terceros).

Esto se consigue de la forma siguiente:

El acceso al usuario lam se realiza de forma segura a través de una

conexión SSH con clave RSA2 (clave asimétrica). Se garantiza que

nadie accederá a la cuenta del usuario lam a no ser que disponga de

la clave privada.

El sistema de ficheros compartido por el servidor utiliza usuario y

password para su acceso. Este usuario y password puede ser

vulnerado por terceros (aparece de forma plana en los ficheros de

configuración de cada nodo). Queda bajo la responsabilidad del

administrador del cluster garantizar que la gestión o configuración

del servidor de ficheros se realiza de forma segura.

La plantilla HTML usada para la redacción de este documento sigue

el formato de las LAM-FAQ. Gran parte de la información que aquí

se recopila se encuentra explicada en detalle en la documentación de

LAM o en las FAQ-LAM.

Page 3: Manual de configuracion de un cluster en Debian

Comandos y Conceptos Básicos

1. ¿Qué es un Cluster?

Un Cluster de computadoras es un conjunto de computadoras

conectadas entre sí, que trabajan una tarea relacionada, de tal

forma que parecen una gran computadora. Cada procesador

de cada computadora se puede considerar un nodo del

Cluster.

Cuando se habla de programación en paralelo, se entiende

que los distintos procesos que se quieren ejecutar en paralelo

se distribuirán a través de los distintos nodos de un Cluster.

Entonces podemos tener computadoras con multiprocesador,

que tendrían varios nodos del Cluster.

Utilidad

La mayor utilidad de la paralización es la ganancia en

velocidad de la ejecución.

Hay que tener en cuenta que no todo problema/algoritmo

puede ser paralelizable. Y si lo es, no necesariamente hay una

ganancia en velocidad, puesto que debemos considerar el

tiempo de comunicación entre los procesos.

2. LAM

Es la definición que adquiere el usuario, donde el directorio

de este es un directorio remoto que contiene los binarios

necesarios para la activación del nodo.

3. MPI

Es un estándar de paso de mensajes.

Las siglas proceden del inglés “Message Passing Interface” o

Interfaz de Paso de Mensajes.

Se utiliza en la programación paralela en sistemas

distribuidos de computadores.

Puede utilizarse tanto en máquinas con o sin memoria

compartida, siendo estas últimas su objetivo prioritario.

4. LAM/MPI

Es un paquete software que se encarga de distribuir nuestros

programas en la máquina paralela e implementa la interfaz de

paso de mensajes.

Una vez instalado LAM/MPI puede crearse una máquina

paralela.

5. ¿Qué ventajas tiene el MPI?

El MPI permite distribuir sus nodos tanto en distintas

computadoras como en distintos procesadores en una misma

computadora. Permite también que se asignen varios

procesos a un mismo procesador, así pues si se tiene un

Cluster heterogéneo de computadoras, se puede, por ejemplo,

asignar más procesos (es decir, más tareas) a los procesadores

más rápidos.

Page 4: Manual de configuracion de un cluster en Debian

Instrucciones básicas del MPI

Las instrucciones básicas del MPI cubren 3 aspectos:

Inicialización y terminación del MPI.

Todo programa MPI debe comenzar con la instrucción:

MPI Init(&argc, &argv);

Y debe terminar con:

MPI Finalize();

Identificación de quien soy y cuantos somos.

Con las siguientes instrucciones se puede obtener la

información básica de los nodos, es decir, cuántos son, y cual

soy.

int myrank; // Número de proceso.

int nprocs; // Número total de procesos.

MPI Comm rank(MPI COMM WORLD, &myrank);

MPI Comm size(MPI COMM WORLD, &nprocs);

Envío y recepción de mensajes entre los procesos.

Las instrucciones que soportan el esqueleto de todo pro-

grama MPI son:

Enviar mensaje:

MPI Send(buffer, contador, tipodato, destino,

tag, MPI COMM WORLD);

Recibir mensaje:

MPI Recv(buffer, maxcontador, tipodato,

origen, tag, MPI COMM WORLD,

&status);

6. MPICC

mpicc/mpiCC/mpif77, Son comandos que se utilizan para

compilar los binarios a ejecutar en el cluster. Se trata de

wrappers a los compiladores de sistema. Utilícese

exactamente igual (los mismos argumentos, etc.) que los

comandos originales, normalmente gcc.

7. MPICXX

mpicxx, Comando que se utiliza para compilar y enlazar

programas en C++ que hagan uso de MPI.

8. MPICC Y MPICXX

mpicc y mpicxx, Pueden utilizarse con las mismas opciones

que el compilador de C/C++ usual.

9. MPIRUN

mpirun, Ejecuta el programa de ejemplo hello en el clúster.

La opción C, indica que debe ejecutarse en todas las CPU's;

la opción N indica que solamente debe ejecutarse una

instancia en cada nodo.

10. LAMEXEC

lamexec, Comando similar a mpirun para lanzar programas

estándar unix (programas no MPI, pe. date). La opción C,

Page 5: Manual de configuracion de un cluster en Debian

indica que debe ejecutarse en todas las CPU's; la opción N

indica que solamente debe ejecutarse una instancia en cada

nodo.

11. LAMCLEAN

lamclean, Este comando solamente debe utilizarse cuando un

programa del cluster acaba de forma incorrecta o inesperada

y mantiene recursos del cluster alocados. Mata todos los

programas que se están ejecutando en aquel momento en el

cluster.

12. MPITASK/LAMINFO/LAMNODES|TPING

Comandos informativos. mpitask lista el conjunto de tareas

que está ejecutando el cluster en este momento. Es el

equivalente al comando unix ps. laminfo proporciona

información del entorno LAM. Tiene multitud de opciones,

para más información consulte las páginas

de man. lamnodes lista el conjunto de nodos que forman el

cluster. Proporciona una información muy parecida al

contenido del fichero lam-bhost.def. tping comprueba que

todos los nodos están activados.

13. LAMBOOT

lamboot, Comando usado para arrancar el cluster. La

configuración del cluster debe la obtiene del fichero

$HOME/etc/lam-bhost.def. Utiliza las variables de entorno

LAMHOME para determinar donde se encuentra la

instalación de LAM y LAMRSH para indicar que la conexión

a los nodos se realize usando SSH.

14. RECON

recon, Comando para comprobar si el cluster está preparado

para ser arrancado. Utiliza las variables de entorno

LAMHOME para determinar donde se encuentra la

instalación de LAM y LAMRSH para indicar que la conexión

a los nodos se realize usando SSH.

15. LAMHALT

Comando utilizado para deshabilitar el cluster. En caso de

retorno de error o falta de respuesta utilice wipe -v

$HOME/etc/lam-bhost.def.

16. ITHOUT-FC

El componente ithout-fc se caracteriza por el uso como una

fuente CW por cable y redes DWDM. El cw se acoplada a

CC con un TEC incorporado, termistor, y un fotodiodo

monitor. El dispositivo está montado en un pasador, paquete

pinout mariposa compatible con el aislador óptico montado

en el TEC.

El ithout-fc incorpora un sistema de alta eficiencia de

acoplamiento para entregar cc, mW, ymW de potencia óptica

CW.

Page 6: Manual de configuracion de un cluster en Debian

17. SSH-KEYGEN

SSH, se utiliza a menudo para iniciar sesión desde un sistema

a otro sin necesidad de contraseñas.

Ssh-keygen , se utiliza para generar, gestionar y convertir las

claves de autenticación de ssh. Con la ayuda de la

herramienta ssh-keygen, un usuario puede crear frase de

teclas para ambos SSH protocolo de la versión 1 y versión 2.

SSH-keygen genera RSA claves para el protocolo SSH

versión 1 y RSA o DSA claves para el uso de SSH versión 2

del protocolo.

¿Cómo funciona?

La herramienta ssh-keygen almacena la clave privada en $

HOME / .ssh / id_rsa y la clave pública en $ HOME / .ssh /

id_rsa.pub en el directorio home del usuario. Entonces, el

usuario debe copiar el id_rsa.pub a $ HOME / .ssh /

authorized_keys en su directorio de inicio en el equipo

remoto. También pide una contraseña. La frase de contraseña

puede estar vacío para indicar ninguna contraseña (claves de

host debe tener una contraseña vacía), o puede ser una cadena

de longitud arbitraria. En lugar de RSA, DSA también se

puede utilizar. Los pasos para crear claves de autorización

mediante el uso de la herramienta ssh-keygen son los

siguientes:

Archivos que utiliza ssh-keygen

La utilidad ssh-keygen tiene varios archivos para almacenar

las claves públicas y privadas. Los archivos utilizados por

SSH-Keygen utilidad son los siguientes:

$ HOME / .ssh / identity: El directorio $ HOME / .ssh /

archivo de identidad contiene la clave privada RSA cuando se

utiliza el protocolo SSH versión 1.

$ HOME / .ssh / identity.pub: El directorio $ HOME / .ssh /

identity.pub contiene la clave pública RSA para la

autenticación cuando se utiliza el protocolo SSH versión 1.

Un usuario debe copiar su contenido en el directorio $

HOME / .ssh / authorized_keys del sistema remoto donde un

usuario desea conectarse mediante la autenticación RSA.

$ HOME / .ssh / id_dsa: El directorio $ HOME / .ssh /

id_dsa contiene la versión 2 del protocolo de autenticación de

identidad DSA del usuario.

$ HOME / .ssh / id_dsa.pub: El directorio $ HOME / .ssh /

id_dsa.pub contiene la clave pública DSA para la

autenticación cuando se utiliza el protocolo SSH versión 2.

Un usuario debe copiar su contenido en el directorio $

HOME / .ssh / authorized_keys del sistema remoto donde un

usuario desea iniciar sesión con autenticación DSA.

$ HOME / .ssh / id_rsa: El directorio $ HOME / .ssh /

id_rsa contiene la versión 2 del protocolo de autenticación de

Page 7: Manual de configuracion de un cluster en Debian

identidad de RSA del usuario. Este archivo no debe ser leído

por nadie más que el usuario.

$ HOME / .ssh / id_rsa.pub: El directorio $ HOME / .ssh /

id_rsa.pub archivo contiene la versión 2 del protocolo clave

pública RSA para la autenticación. El contenido de este

archivo debe ser añadido a $ HOME / .ssh / authorized_keys

en todos los equipos en los que un usuario desea iniciar

sesión con autenticación de clave pública.

CONFIGURACION DE LA RED

Todas las máquinas del cluster deben poder resolver por nombre el

resto de nodos. El esquema propuesto consiste en la existencia de un

servidor de nombres (DNS) donde todas las máquinas están

referenciadas y todas las máquinas tienen este servidor de nombres

asignado por defecto. La configuración de los servidores de nombres

no entra dentro del ámbito de este documento.

Para asignar el dominio y el servidor de nombres al nodo edite el

fichero /etc/resolv.conf y compruebe que contiene las siguientes

líneas:

domain domainname

search domainname

nameserver ip_nameserver

La implementación LAM-MPI actual gestiona la asignación de

puertos de forma dinámica (el primero que encuentra libre). En un

futuro está previsto que se pueda fijar los puertos usados por LAM-

MPI. Debe tenerse esto en cuenta si la máquina se encuentra detrás

de un firewall. En este caso las reglas a habilitar en el firewall son:

debe permitirse todo tipo de tráfico entre todas las máquinas

pertenecientes al cluster.

Page 8: Manual de configuracion de un cluster en Debian

CREACION DEL USUARIO LAM EN CADA NODO

El usuario utilizado por el cluster es el usuario lam. Las

características de este usuario son las siguientes:

Nombre: lam

Home: /home/lam

Grupo: users (puede ser otro grupo)

Shell: bash

Password: A decidir por el administrador de la máquina. Local al nodo.

Descripción: usuario cluster LAM-MPI

En el fichero /etc/password debe constar una línea parecida a la

siguiente:

lam:x:500:100:usuario

cluster LAM MPI:/home/lam:/bin/bash

El directorio de trabajo ($HOME) de los nodos es un directorio

compartido. Antes de crear el usuario, comprobar que existe el grupo

donde será asignado (por defecto users). Para crear el usuario con las

características indicadas, ejecutar como root el siguiente comando:

useradd -c "usuario cluster LAM-MPI" -d /home/lam -g

users -n -s /bin/bash lam

Si se desea añadir una contraseña al usuario creado, ejecutar como

root el siguiente comando e indicar el password deseado (no es

necesario que sea conocido por el resto del cluster):

passwd lam

SISTEMA DE FICHEROS COMPARTIDOS. CLIENTES

El sistema de ficheros compartidos es de tipo samba con

autentificación. Es necesario tener instalado el cliente samba en cada

nodo del cluster. Para montar y desmontar manualmente un sistema

de ficheros de este tipo teclear:

mount -t smbfs –o username=foo,password=bar//

host_name/dir /mnt

...

umount /mnt

Nos interesa que el directorio de trabajo del usuario lam sea único en

todo el cluster para poder garantizar lo siguiente:

Ejecutables LAM-MPI únicos. La versión de los ejecutables

debe ser la misma para que el cluster funcione correctamente.

Simplificación en la distribución de programas a ejecutar.

Dentro de la carpeta compartida existe un directorio para

albergar los programas que ejecutará el cluster. Nos evitamos

el distribuir el programa antes de ejecutarlo.

Distribución automática de las claves públicas para SSH.

Cada nodo permite que el nodo master se conecte a él al

disponer de la clave pública. La posesión de esta clave no

significa que cualquier persona pueda acceder al usuario lam.

Solamente lo podrá hacer aquella que disponga de la clave

privada (el nodo master). La clave privada no se encontrará

en el sistema de ficheros compartido.

Para montar de forma automática un sistema de ficheros samba

usando autentificación debe añadirse la siguiente línea en el

fichero /etc/fstab:

Page 9: Manual de configuracion de un cluster en Debian

//host_name/lam /home/lam smbfs

username=lam,passwd=lam,user,exec,fmask=644,dmask=755 0

0

Es responsabilidad del administrador del cluster garantizar la

accesibilidad e integridad de los ficheros compartidos (evitar que una

máquina no perteneciente al cluster monte el sistema de ficheros y

modifique su contenido).

SISTEMA DE FICHEROS COMPARTIDOS. SERVIDOR

Es necesario tener instalado el servidor samba. El objetivo es

explicar la configuración del sistema de ficheros compartido para el

cluster, no la instalación del servidor samba. Puedes encontrar más

información en www.samba.org. Los objetivos a cumplir son los

siguientes:

Disponer de un sistema de ficheros compartido instalado por

defecto en la mayoría de nodos.

Compartir el directorio /home/lam con los nodos del cluster.

Garantizar el acceso mediante usuario y contraseña.

Impedir que el contenido del directorio compartido sea

modificado por terceros.

Comprobar que el usuario lam existe en /etc/passwd. Añadir el

usuario lam en la lista de usuarios samba, usando la siguiente

instrucción (cuando solicite el password, introducir lam):

smbpasswd -a lam

Localizar el fichero smb.conf. Normalmente se encuentra

en /etc/samba/smb.conf. En caso de no encontrarlo en este path

usar la instrucción locate smb.conf para determinar la ruta del

fichero o buscarlo en /etc/smb.conf. Realizar las siguientes

modificaciones al fichero smb.conf:

[global]

workgroup = WORKGROUP

hosts allow = 192.9.199. 127.

encrypt passwords = yes

smb passwd file = /etc/samba/smbpasswd

[lam]

comment = lam

path = /home/lam

valid users = lam

public = no

writable = yes

printable = no

Una vez realizadas las modificaciones indicadas, ejecutar el

comando testparm -s para comprobar que la configuración final

del servidor samba es correcta y reiniciar el servicio.

Page 10: Manual de configuracion de un cluster en Debian

CONFIGURACION DE CLUSTER/MPI CON DEBIAN

Podemos configurar un cluster de alto rendimiento en Debian

utilizando la interfaz de paso de mensajes LAM/MPI.

Los prerrequisitos de este manual es disponer de una instalación

básica de debian Etch, en nuestro caso hemos usado 2 máquinas

aisladas en una red propia que se usará tan solo para el cluster de alto

rendimiento, las hemos llamado: (192.168.1.23) nodo0,

(192.168.1.24). En cada una de las máquinas hemos creado un

usuario al que hemos llamado “cluster” con contraseña “123456”.

Instalación del build-essential

Una vez tengamos la instalación básica y comprobamos que tengan

connectividad entre ellas y lleguen a un gateway con salida internet

(para la instalación de paquetes con apt-get), procederemos a instalar

el paquete build-essential en cada una de las máquinas para compilar

LAM/MPI que nos descargaremos de la web oficial.

Así que en cada uno de los nodos ejecutaremos

>> apt-get install build-essential

Instalación de LAM/MPI

En nuestro caso no vamos a usar C++ y no necesitamos Fortran para

programar en el cluster, así que no necesitaremos el compilador

Fortran, eso sí le especificaremos la opción –without-fc en el

configure, compilamos también el paquete en cada una de las

máquinas:

>> tar -xzvf lam-7.1.4.tar.gz

>> cd lam-7.1.4

>> ./configure --without-fc && make && make install

Configuración de la Variable PATH

Una vez tenemos LAM/MPI instalado en todas las máquinas,

modificaremos el archivo .bashrc del usuario cluster, que

encontraremos en la home de este /home/cluster/.bashrc, al final del

archivo añadiremos las siguientes líneas:

PATH=/usr/local/lam/bin:$PATH

export PATH

PATH=/usr/local/lam/bin:$PATH

export PATH

Page 11: Manual de configuracion de un cluster en Debian

Registramos los nodos

Modificaremos en el nodo0 el archivo /etc/hosts donde le

indicaremos donde están todos los nodos, y luego lo podemos copiar

a los otros nodos:

>> (gedit/nano) /etc/hosts

127.0.0.1 localhost

192.168.1.23 nodo0

192.168.1.24 nodo1

Instalación de ssh en debían

Para la instalación podemos hacerlo colocando el cd de instalación o

con conexión a internet

>> apt-get install ssh

Generar contraseña para el Maestro (nodo0)

Una vez podamos localizar todos los nodos, debemos conseguir que

el nodo0 pueda acceder usando ssh a todos los nodos sin necesidad

de password, para ello nos vamos al nodo principal y ejecutaremos

ssh-keygen:

>> ssh-keygen -t rsa

Generating public/private rsa key pair.

Enter file in which to save the key (/home/cluster/.ssh/id_rsa):

[ENTER]

Enter passphrase (empty for no passphrase): [ENTER]

Enter same passphrase again: [ENTER]

Your identification has been saved in /home/cluster/.ssh/id_rsa.

Your public key has been saved in /home/cluster/.ssh/id_rsa.pub.

The key fingerprint is:

Page 12: Manual de configuracion de un cluster en Debian

17:4f:9b:88:55:e2:dc:25:c3:74:01:c7:49:52:08:4f cluster@debian-

frontend

Copiamos la clave a todos los nodos

>> scp /home/cluster/.ssh/id_rsa.pub

[email protected]:/home/cluster/

Accedemos a cada uno de los nodos y guardamos la clave:

>> cd /home/cluster/

>> mkdir .ssh

>> cat id_rsa.pub >> /home/cluster/.ssh/authorized_keys

>> rm id_rsa.pub

Nos volvemos al nodo0, y comprobamos que podemos acceder a los

hosts ejecutando un comando que debería mostrar el shell en uso sin

necesidad de introducir ningún password:

> rsh nodo1 -n 'echo $SHELL'

>> /bin/bash

Creación del archivo boot_schema

Crearemos un archivo, al que yo he llamado boot_schema donde

indicaremos todos los nodos del cluster, y el número de CPUs, si

tenemos SMP le indicaremos dos CPU añadiendo cpu=2 despues del

nodo (por ejemplo debian-node4 cpu=2):

#Mis nodos del cluster

nodo0

nodo1

Page 13: Manual de configuracion de un cluster en Debian

Arranque de Cluster

Momento de arrancar el cluster, para ello le pasaremos el archivo

boot_schema que creamos en el paso anterior, y si todo ha ido bien

veremos algo parecido a esto:

lamboot -v -ssi boot rsh boot_schema

LAM 7.1.4/MPI 2 C++/ROMIO - Indiana University

n-1<6023> ssi:boot:base:linear: booting n0 (nod0)

n-1<6023> ssi:boot:base:linear: booting n1 (nod1)

n-1<6023> ssi:boot:base:linear: finished

Probando en Cluster

EJERCICIO 1:

Tenemos a nuestra disposición una suite de tests para probar nuestra

instalación, pero que hay más bonito que empezar con un “Hola

Mundo” en C para abrir nuestro apetito, para ello crearemos un

archivo helloworld.c con el siguiente contenido, en un directorio al

que he llamado test dentro de nuestra home:

#include <stdio.h>

#include <mpi.h>

int main(int argc, char *argv[]) {

int rank, size;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

MPI_Comm_size(MPI_COMM_WORLD, &size);

printf("Hello, world! I am %d of %d\n", rank,

size);

MPI_Finalize();

return 0;

}

Lo compilamos y pasamos el ejecutable a los otros nodos:

cd /home/cluster/test

mpicc helloworld.c -o helloworld

rsh debian-node1 -n 'mkdir /home/cluster/test'

scp hello 10.11.12.2:/home/cluster/test/

rsh debian-node2 -n 'mkdir /home/cluster/test'

scp hello 10.11.12.3:/home/cluster/test/

Page 14: Manual de configuracion de un cluster en Debian

[...]

Hora de probar, deberíamos obtener un resultado como este (aunque

no necesariamente en el mismo orden):

mpirun C hello

Hello, world! I am 0 of 5

Hello, world! I am 2 of 5

Hello, world! I am 1 of 5

Hello, world! I am 4 of 5

Hello, world! I am 3 of 5

Tenemos también como hemos dicho una suite de tests que nos

permitiran comprobar el correcto funcionamiento de la instalación

MPI:

cd /home/cluster

tar -xzvf lamtests-7.1.4.tar.gz

cd lamtests-7.1.4/

./configure

make

make -k check 2>&1 | tee check.out

EJERCICIO 2:

hola.c programa MPI: activacion de procesos

#include <mpi.h>

#include <stdio.h>

int main(int argc, char *argv[])

{

int lnom;

char nombrepr[MPI_MAX_PROCESSOR_NAME];cat circu

int pid, npr;

int A = 2; // identificador y numero de proc.

MPI_Init(&argc, &argv);

MPI_Comm_size(MPI_COMM_WORLD, &npr);

MPI_Comm_rank(MPI_COMM_WORLD, &pid);

MPI_Get_processor_name(nombrepr, &lnom);

A = A + 1;

printf(" >> Proceso %2d de %2d activado en %s, A =

%d\n", pid, npr, nombrepr, A);

MPI_Finalize();

return 0;

}

Page 15: Manual de configuracion de un cluster en Debian

EJERCICIO 3: circu.c - paralelizacion MPI de un bucle

#include <mpi.h>

#include <stdio.h>

#define DECBIN(n,i) ((n&(1<<i))?1:0)

void test (int pid, int z)

{

int v[16], i;

for (i=0; i<16; i++) v[i] = DECBIN(z,i);

if ((v[0] || v[1]) && (!v[1] || !v[3]) && (v[2] || v[3])

&& (!v[3] || !v[4]) && (v[4] || !v[5])

&& (v[5] || !v[6]) && (v[5] || v[6])

&& (v[6] || !v[15]) && (v[7] || !v[8])

&& (!v[7] || !v[13]) && (v[8] || v[9])

&& (v[8] || !v[9]) && (!v[9] || !v[10])

&& (v[9] || v[11]) && (v[10] || v[11])

&& (v[12] || v[13]) && (v[13] || !v[14])

&& (v[14] || v[15]))

{

printf(" %d) %d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d (%d)\n",

pid, v[15],v[14],v[13],

v[12],v[11],v[10],v[9],v[8],v[7],v[6],v[5],v[4],v[3],v[2],v[1

],v[0], z);

fflush(stdout);

}

}

int main (int argc, char *argv[])

{

int i, pid, npr;

MPI_Init(&argc, &argv);

MPI_Comm_size(MPI_COMM_WORLD, &npr);

MPI_Comm_rank(MPI_COMM_WORLD, &pid);

for (i=pid; i<65536; i += npr) test(pid, i);

MPI_Finalize();

return 0;

}

EJERCICIO 4: envio.c - se envia un vector desde el procesador 0 al 1

#include <mpi.h>

#include <stdio.h>

#define N 10

int main (int argc, char **argv)

{

int pid, npr, origen, destino, ndat, tag;

int VA[N], i;

MPI_Status info;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &pid);

MPI_Comm_size(MPI_COMM_WORLD, &npr);

for (i=0; i<N; i++) VA[i] = 0;

if (pid == 0)

{

for (i=0; i<N; i++) VA[i] = i;

destino = 1; tag = 0;

MPI_Send(&VA[0], N, MPI_INT, destino, tag,

MPI_COMM_WORLD);

}

else if (pid == 1)

{

printf("\nvalor de VA en P1 antes de recibir datos\n\n");

for (i=0; i<N; i++) printf("%4d", VA[i]);

printf("\n\n");

origen = 0; tag = 0;

MPI_Recv(&VA[0], N, MPI_INT, origen, tag, MPI_COMM_WORLD,

&info);

MPI_Get_count (&info, MPI_INT, &ndat);

printf("Pr 1 recibe VA de Pr %d: tag %d, ndat %d \n\n",

info.MPI_SOURCE, info.MPI_TAG, ndat);

for (i=0; i<ndat; i++) printf("%4d", VA[i]);

printf("\n\n");

}

MPI_Finalize();

return 0;

}

Page 16: Manual de configuracion de un cluster en Debian

EJERCICIO 5: dlock1.c - intercambio de dos variables #include <mpi.h>

#include <stdio.h>

int main (int argc, char **argv)

{

int pid, origen, destino, tag;

int A, B, C;

MPI_Status info;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &pid);

if (pid == 0)

{

A = 5;

printf("\n >> recibiendo datos de P1 \n");

origen = 1; tag = 1;

MPI_Recv(&B, 1, MPI_INT, origen, tag, MPI_COMM_WORLD,

&info);

printf("\n >> enviando datos a P1 \n");

destino = 1; tag = 0;

MPI_Send(&A, 1, MPI_INT, destino, tag, MPI_COMM_WORLD);

C = A + B;

printf("\n C es %d en proc 0 \n\n", C);

}

else if (pid == 1)

{

B = 6;

printf("\n >> recibiendo datos de P0 \n");

origen = 0; tag = 1;

MPI_Recv(&A, 1, MPI_INT, origen, tag, MPI_COMM_WORLD,

&info);

printf("\n >> enviando datos a P0 \n");

destino = 0; tag = 0;

MPI_Send(&B, 1, MPI_INT, destino, tag, MPI_COMM_WORLD);

C = A + B;

printf("\n C es %d en proc 1 \n\n", C);

}

MPI_Finalize();

return 0;

}

EJERCICIO 6: send-dead.c -prueba para ver el tamaino del buffer de la funcion send el programa

se bloquea al enviar un paquete mas grande #include <stdio.h>

#include "mpi.h"

#define N 100000

int main(int argc, char** argv)

{

int pid, kont; // Identificador

del proceso

int a[N], b[N], c[N], d[N];

MPI_Status status;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &pid);

for (kont=100; kont<=N; kont=kont+100)

{

if (pid == 0)

{

MPI_Send(&a[0], kont, MPI_INT, 1, 0, MPI_COMM_WORLD);

MPI_Recv(&b[0], kont, MPI_INT, 1, 0, MPI_COMM_WORLD,

&status);

printf("emisor %d \n", kont);

}

else

{

MPI_Send(&c[0], kont, MPI_INT, 0, 0, MPI_COMM_WORLD);

MPI_Recv(&d[0], kont, MPI_INT, 0, 0, MPI_COMM_WORLD,

&status);

printf(" receptor %d \n", kont);

}

}

MPI_Finalize();

return 0;

} /* main */

Page 17: Manual de configuracion de un cluster en Debian

EJERCICIO 7: ssend.c - Ping-pong entre dos procesadores Comunicacion sincrona ssend

#include <stdio.h>

#include <mpi.h>

#include <math.h>

#include <unistd.h>

#define VUELTAS 4

double calculo()

{

double aux;

sleep(1);

aux = rand() % 100;

return(aux);

}

int main(int argc, char** argv)

{

double t0, t1, dat= 0.0, dat1, dat_rec;

int pid, i;

MPI_Status status;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &pid);

if (pid == 0) t0 = MPI_Wtime();

for(i=0; i<VUELTAS; i++)

{

if (pid == 0)

{

MPI_Ssend(&dat, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD);

dat1 = calculo();

MPI_Recv(&dat_rec, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD,

&status);

dat = dat1 + dat_rec;

}

else

{

dat1 = calculo();

MPI_Recv(&dat_rec, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD,

&status);

dat = dat1 + dat_rec;

MPI_Ssend(&dat, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);

}

}

if (pid == 0)

{

t1 = MPI_Wtime();

printf("\n Tiempo de ejecucion = %f s \n", t1-t0);

printf("\n Dat = %1.3f \n\n", dat);

}

MPI_Finalize();

return 0;

} /* main */

EJERCICIO 8: isend.c - Ping-pong entre dos procesadores Comunicacion inmediata isend

#include <stdio.h>

#include <mpi.h>

#include <unistd.h>

#define VUELTAS 4

double calculo()

{

double aux;

sleep(1);

aux = rand() % 100;

return(aux);

}

int main(int argc, char** argv)

{

double t0, t1, dat = 0.0, dat1, dat_rec;

int pid, i;

MPI_Status status;

MPI_Request request;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &pid);

if (pid == 0) t0 = MPI_Wtime();

for(i=0; i<VUELTAS; i++)

{

Page 18: Manual de configuracion de un cluster en Debian

if (pid == 0)

{

MPI_Isend(&dat, 1, MPI_DOUBLE, 1, 0,

MPI_COMM_WORLD,&request);

dat1 = calculo();

MPI_Wait(&request, &status);

MPI_Recv(&dat_rec, 1, MPI_DOUBLE, 1, 0,

MPI_COMM_WORLD, &status);

dat = dat1 + dat_rec;

}

else

{

dat1 = calculo();

if (i!=0) MPI_Wait(&request, &status);

MPI_Recv(&dat_rec, 1, MPI_DOUBLE, 0, 0,

MPI_COMM_WORLD, &status);

dat = dat1 + dat_rec;

MPI_Isend(&dat, 1, MPI_DOUBLE, 0, 0,

MPI_COMM_WORLD,&request);

}

}

if (pid == 0)

{

t1 = MPI_Wtime();

printf("\n Tiempo de ejecucion = %f s \n",

t1-t0);

printf("\n Dat = %1.3f \n\n", dat);

}

MPI_Finalize();

return 0;

} /* main */

EJERCICIO 9: probe.c - ejemplo de uso de la funcion probe de MPI

#include <mpi.h>

#include <stdio.h>

int main (int argc, char **argv)

{

int pid, npr, origen, destino, ndat, tag;

int i, longitud, tam;

int *VA, *VB;

MPI_Status info;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &pid);

MPI_Comm_size(MPI_COMM_WORLD, &npr);

if (pid == 0)

{

srand(time(NULL));

longitud = rand() % 100;

VA = (int *) malloc (longitud*sizeof(int));

for (i=0; i<longitud; i++) VA[i] = i;

printf("\n valor de VA en P0 antes de enviar

los datos\n\n");

for (i=0; i<longitud; i++) printf("%4d",

VA[i]);

printf("\n\n");

destino = 1; tag = 0;

MPI_Send(VA, longitud, MPI_INT, destino, tag,

MPI_COMM_WORLD);

}

else if (pid == 1)

{

origen = 0; tag = 0;

MPI_Probe(origen, tag, MPI_COMM_WORLD, &info);

MPI_Get_count(&info, MPI_INT, &tam);

if(tam != MPI_UNDEFINED)

Page 19: Manual de configuracion de un cluster en Debian

{

VB = (int *) malloc(tam*sizeof(int));

MPI_Recv(VB, tam, MPI_INT, origen, tag,

MPI_COMM_WORLD, &info);

}

printf("\n valor de VB en P1 tras recibir los

datos\n\n");

for (i=0; i<tam; i++) printf("%4d", VB[i]);

printf("\n\n");

}

MPI_Finalize();

return 0;

}

EJERCICIO 10: sumvecser.c - Calcula V(i) = V(i) * sumatorio(V(j)) Codigo serie;

#include <stdio.h>

int main(int argc, char **argv)

{

int N, i;

int *V, sum=0;

printf("\nLongitud del vector: ");

scanf("%d", &N); // Multiplo

del numero de procesos

V = (int *)malloc(sizeof(int) * N);

for(i=0; i<N; i++) V[i] = rand() % 100 - 50; //

inicializacion del vector

// Procesamiento del vector

for (i=0; i<N; i++) sum = sum + V[i];

for (i=0; i<N; i++) V[i] = V[i] * sum;

// Imprimir unos resultados

printf("\n sum = %d\n", sum);

printf("\n V[0] = %d, V[N/2] = %d, V[N-1] = %d\n\n\n",

V[0],V[N/2],V[N-1]);

return 0;

}

CONCLUSIONES

Dentro de la distribución de LAM existen ejemplos que se pueden

ejecutar para comprobar el funcionamiento del entorno. Si nos

interesa determinar el número de megaflops (millones de

operaciones en punto flotante por segundo) del cluster sin recurrir a

los benchmarks estándar (incluyen resolución de sistemas lineales,

resolución de EDP's, etc.) puedes hacerlo usando mflops.

El siguiente paso es dotar al cluster de herramientas que faciliten su

gestión. La herramienta ganglia permite la monitorización del cluster

(carga por cpu, memoria usada, usuarios conectados, etc.) a través de

web y con gráficos.

Si deseamos dar un uso intenso al cluster con múltiples tareas y de

forma constante nos hará falta un planificador de tareas que se

encargue de ejecutarlas a su tiempo, balancear la carga, determinar

los recursos necesarios para llevar a cabo una tarea, etc.