Download Anexos Parallel Java - LCAR - Universidad Nacional Experimental

Document related concepts
no text concepts found
Transcript
Anexo C
UNIVERSIDAD NACIONAL EXPERIMENTAL DEL TÁCHIRA
INGENIERÍA EN INFORMÁTICA
Anexos Parallel Java
Autor: Leonel Hernández
Anexo C.1
Instalación, configuración y compilación del Parallel Java.
Luego de estudiar las características y funcionalidad del Algoritmo Paralelizado se
procedió con estudio e instalación de PJ. Parallel Java es una API y middleware para
programación en paralelo en Java sobre multiprocesadores de memoria compartida (SMP)
en paralelo, cluster, e híbridos entre estas dos tecnologías.
Al instalar este paquete se debe tener en cuenta lo siguiente:
 Para la instalación en el cluster beowulf basado en Debian 6.0 o anterior, se
recomienda la versión pre-empaquetada de la librería. Se instala con la siguiente
sentencia:
$apt-get install libpj-java
La librería quedara ubicada en la siguiente ubicación /usr/share/java/.

Agregar el PJ al entorno de ambiente de variable $CLASSPATH.
$ export CLASSPATH=/usr/share/java/pj.jar:$CLASSPATH

Para poder correr programas en PJ sobre un cluster beowulf se requiere tener
configurado el acceso del servicio SSH* a los nodos mediante llaves públicas. Se
procede de la siguiente manera:
o Primero se ingresa en el nodo principal como usuario de trabajo y se
generan los archivos de las llaves pública y privada SSL. El parámetro
contraseña deja en blanco:
#ssh-keygen
o Esto generara 2 archivos id_rsa.pub e id_rsa y se crea el directorio
/home/nombre_usuario/.ssh.
La
/home/nombre_usuario/id_rsa.
llave
y
privada
la
llave
se
guarda
publica
en
en
/home/nombre_usuario/id_rsa.pub.
o Finalmente, dado que es un cluster beowulf *NIX, los directorios /home
se encuentran compartidos, se añade la nueva llave privada al archivo
autorized_keys dentro del mismo directorio .ssh del usuario:
$cat .ssh/id_rsa.pub >> .ssh/authorized_keys‟

Se requiere de la creación del planificador de Parallel Java para que la librería
haga la conexión entre el nodo principal y los nodos secundarios. Para configura
el planificador se debe crear un archivo de texto nombrado scheduler.conf que
se puede ubicar en la dirección que el usuario de la librería lo desee. El archivo
de configuración del planificador de trabajos contiene lo siguiente:
o Cluster: el nombre del cluster.
o Logfile: la ubicación y el nombre del archivo donde se añadirán las
entradas de registro de PJ.
o WebHost: host name de la interfaz web del planificador de trabajos.
o WebPort: el número del puerto para la interfaz web del planificador. Por
defecto el número del puerto es 8080, para nuestro caso fue modificado
ya que este coincide con el puerto de escucha de Apache Tomcat.
o Schedulehost: host name a la que el planificador de trabajos escucha
para las conexiones de los procesos de interfaz de trabajo. Si no se
especifica, por defecto este toma localhost.
o Shedulerport: el número del puerto donde el planificador escucha para
las conexiones de interfaz de procesos. Si no es especificada el número
del puerto por defecto es 20617.
o Frontendhost: La dirección IP del nodo principal que escuchan las
conexiones de los nodos secundarios.
o Backend: de las computadoras paralelas se incluyen el nombre del nodo,
el número de procesadores que posee, la dirección IP para el acceso
remoto, la ruta de acceso absoluta a la Java Virtual Machine (JVM) y la
ubicación de la clase PJ en el nodo secundario.
Un ejemplo del archivo de configuración del planificador de trabajos se
puede ver en el anexo C.2

Configurado el planificador se debe ejecutar antes de poner a prueba cualquier
aplicación con la librería. La sentencia para ejecutar el planificador es la
siguiente:
$java
-classpath
scheduler.conf
/usr/share/java/pj.jar
edu.rit.pj.cluster.JobScheduler
Esta sentencia se debe ejecutar desde la dirección donde se encuentra el archivo
scheduler.conf

Para que el scheduler se cargue al iniciar el sistema en una Debían 6.0 se agrega
la siguiente sentencia en el archivo „/etc/rc.local‟:
# su –c “java –classpath /usr/share/java/pj.jar edu.rit.pj.cluster.JobScheduler
/ubicacion/scheduler.conf” nombre_usuario.

Para que un programa sea compatible con el PJ se debe incluir como una librería
externa en el programa que se esté realizando. En la ejecución de este proyecto
se utilizo el entorno de desarrollo NetBeans IDE 6.7* y para incluir la librería en
un proyecto se realizaron los siguientes pasos:
o Se ingresa a la pestaña Herramientas -> Librerías
o En el administrador de Librerías se incluye una nueva librería y se le da
un nombre.
o Luego se presiona el botón Agregar JAR/Carpeta, buscar la librería PJ en
la ubicación donde fue instalada.
o Para finalizar se agrega esta nueva librería al proyecto que se está
creando, en el paquete Bibliotecas del proyecto.

Para ejecutar la aplicación creada en consola se deben utilizar las siguientes
sentencias:
$java –Dpj.np=5 Ejemplo
O sí se utiliza el NetBeans, click derecho del ratón sobre el Proyecto ->
Propiedades » Ejecución, en la casilla de texto “Opciones de VM” se añade lo
siguiente:
–Dpj.np=5
Donde, -Dpj.np=5 es una propiedad de PJ que especifica el número de procesos, estos
procesos son el nodo principal y los nodos secundarios utilizados para ejecutar el programa
paralelo. Para este ejemplo el número de procesos es de 5.
Anexo C.2
Archivo de configuración del planificador de tareas de Parallel Java.
Archivo scheduler.conf
# Archivo de configuración de Parallel Java Job Scheduler
# Frontend node: Nodo00
# Backend nodes: Nodo02-Nodo04-Nodo06-Nodo08
cluster Hydra
logfile /home/leonel-hernandez/scheduler.log
webhost 172.18.40.132
webport 8080
schedulerhost localhost
schedulerport 20617
frontendhost 10.0.25.1
backend nodo02 1 10.0.25.3 /usr/lib/jvm/java-1.5.0-sun/bin/java
backend nodo04 1 10.0.25.5 /usr/lib/jvm/java-1.5.0-sun/bin/java
backend nodo06 1 10.0.25.7 /usr/lib/jvm/java-1.5.0-sun/bin/java
backend nodo08 1 10.0.25.9 /usr/lib/jvm/java-1.5.0-sun/bin/java
backend nodo00 1 10.0.25.1 /usr/lib/jvm/java-1.5.0-sun/bin/java
/usr/share/java/pj.jar
/usr/share/java/pj.jar
/usr/share/java/pj.jar
/usr/share/java/pj.jar
/usr/share/java/pj.jar
-server
-server
-server
-server
-server
Anexo C.3
Hola Mundo con Parallel Java.
Archivo Hello.java
package helloworld;
import edu.rit.pj.*;
import edu.rit.mp.buf.*;
/**
*
* @author leonel-hernandez
*/
public class Hello {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws Exception{
Comm.init(args);
int source;
int dest;
int myrank = Comm.world().rank();
int size = Comm.world().size();
if (myrank != 0){
//System.out.println("Hola soy " + Comm.world().host()+" con Rango: "+myrank);
char [ ] message =("Saludos desde: "+Comm.world().host()+" con Rango:
"+myrank).toCharArray();
Comm.world().send(0, CharacterArrayBuf.buffer(message));
}else{
for(source=1;source<size;source++){
char [] message=new char[37];
Comm.world().receive(source,CharacterArrayBuf.buffer(message));
System.out.println(new String(message));
}
}
}
}
Anexo C.4
Repartir vector con Parallel Java.
Archivo RepartirVector.java
package repartirvector;
import edu.rit.mp.buf.*;
import edu.rit.pj.*;
/**
* @author leonel-hernandez
*/
public class RepartirVector {
static Comm world;
static int rank;
static int size;
static int vector1[], vector2[];
static int pedazo, primero1[], primero2[], sum1[], sum2[] ;
static int x;
public static void main(String[] args) throws Exception {
Comm.init(args);
world = Comm.world();
rank = world.rank();
size = world.size();
x = Integer.parseInt(args[0]);
vector1 = new int[x];
vector2 = new int[x];
primero1 = new int[size];
primero2 = new int[size];
sum1 = new int[1];
sum2 = new int[1];
for(int i=1;i<x;i++) vector1[i] = 0;
for(int l=1;l<size-1;l++) primero2[l] = 0;
pedazo = x/size;
if (rank==0){
int total=0;
for(int j=1;j<size;j++){
primero1[j] = j * pedazo;
world.send(j,IntegerArrayBuf.buffer(primero1));
System.out.println ("Envie a "+j+": "+primero1[j]); }
for(int m=1;m<size;m++){
world.receive(m,IntegerArrayBuf.buffer(sum2));
System.out.println ("Recibi de "+m+": "+sum2[0]);
total=total+sum2[0]; }
System.out.println ("Total:"+total);
}//end if
else{
world.receive(0,IntegerArrayBuf.buffer(primero2));
for(int i=1;i<primero2[rank];i++){
vector1[i]=i;
sum1[0]=sum1[0]+vector1[i];
}//endfor
world.send(0, IntegerArrayBuf.buffer(sum1));
System.out.println ("Soy "+rank + " Y Respondi a 0");
}//endelse
}//end main
}//end class
Anexo C.5
Repartir objetos con Parallel Java.
Archivo vector.java
package repartirobjetos;
import edu.rit.pj.*;
import edu.rit.mp.buf.*;
/** * @author leonel-hernandez */
public class RepartirObjetos {
static Comm world;
static int rank;
static int size;
static int tamaño = 500000, pedazo;
static Circulo enviarObjeto[], circulo[];
static double sum, psumE[], psumR[];
static int primero[], primeroR[];
public static void main(String[] args) throws Exception {
Comm.init(args);
int num =Integer.parseInt(args[0]);
System.out.println("Aqui "+ num);
world = Comm.world();
rank = world.rank();
size = world.size();
//Inicializar Variables
pedazo = tamaño / size;
circulo = new Circulo[tamaño];
psumE = new double[1];
primero = new int [1];
enviarObjeto = new Circulo[1];
if (rank == 0) {
for (int i = 0; i < tamaño; i++)
circulo[i] = new Circulo(i);
for (int j = 1; j < size; j++) {
primero[0] = j * pedazo;
world.send(j,ObjectArrayBuf.buffer(circulo));
world.send(j,IntegerArrayBuf.buffer(primero));
}
sum = 0;
for (int k = 0; k < pedazo; k++)
sum = sum + circulo[k].calcularSuperficie();
System.out.println(world.host()+" Envia: " + sum);
for (int l = 1; l < size; l++) {
world.receive(l,DoubleArrayBuf.buffer(psumE));
sum = sum + psumE[0] + num;
}
System.out.println("El resultado de la suma es:"+ sum+" y recibio: " + world.host());
}//end if
else {
world.receive(0, ObjectArrayBuf.buffer(circulo));
world.receive(0, IntegerArrayBuf.buffer(primero));
pedazo = pedazo + primero[0];
psumE[0] = 0;
for (int i = primero[0]; i < pedazo; i++) {
psumE[0] = psumE[0] + circulo[i].calcularSuperficie();
}
System.out.println(world.host() + " Envia: " + psumE[0]);
world.send(0, DoubleArrayBuf.buffer(psumE));
}//end else
}
}//end main
Archivo Circulo.java
package Repartir;
import java.io.*;
public class Circulo implements Serializable{
double radio;
Circulo (double r) {
radio = r;
}
Circulo () {
radio = 2.0;
}
double calcularSuperficie() {
return radio*radio*3.141592653589793;
}
}