Mar 08

Hasta la fecha se han realizado los siguientes avances con respecto a la implementación del proyecto.

Tagged with:



En March 8 de 2011, Jorge Iván Meza Martínez escribió acerca de Avances del proyecto – 20110308.
Jul 15

Introducción.

Hay un detalle muy simple que debe tenerse en cuenta cuando se ejecutan en el cluster programas escritos en C y C++ con respecto al manejo de los parámetros de línea de comando que recibe el programa.  En estos lenguajes siempre el primer parámetro, es decir argv[0], recibe el nombre y ruta del archivo ejecutable del programa que se está corriendo.  Muchos desarrolladores utilizan este valor para conocer alguna información interesante como el directorio hogar del programa.

En Condor, debido a su arquitectura y método de ejecución de los procesos en los nodos trabajadores, esto tiene una variación que debe ser tenida en cuenta.  El primer parámetro de línea de comando de los trabajos que se ejecutan en el cluster no hará referencia al programa como tal sino al condor_exec quien es el proceso que efectivamente ejecuta el programa en el nodo trabajador.

When Condor starts up your job, it renames argv[0] (which usually contains the name of the program) to condor_exec. This is convenient when examining a machine’s processes with the Unix command ps; the process is easily identified as a Condor job.  Unfortunately, some programs read argv[0] expecting their own program name and get confused if they find something unexpected like condor_exec.
Tomado de la sección 2.15.1 del manual de Condor: Potencial problems, Renaming of argv[0].

Verificación.

Crear el programa de prueba.

$ vi argv0.c
#include <stdio.h>

int main(int argc, char* argv[])
{
 int i = 0;

 printf("\nParameters count: %d.\n\n", argc);

 for(i=0; i<argc; i++)
 {
    printf("\tParameter '%d': %s.\n", i, argv[i]);
 }

 printf("\nDone!\n\n");

 return 0;
}

Compilarlo (de una vez con soporte para el Cluster).

$ condor_compile gcc argv0.c -o argv0

Ejecución local.

$ ./argv0 p1 p2 p3 p4

Condor: Notice: Will checkpoint to ./argv0.ckpt
Condor: Notice: Remote system calls disabled.

Parameters count: 5.

Parameter ’0′: ./argv0.
Parameter ’1′: p1.
Parameter ’2′: p2.
Parameter ’3′: p3.
Parameter ’4′: p4.

Done!

Creación del archivo de envío de trabajos al cluster.

$ vi argv0.submit

executable = argv0
universe   = vanilla
output     = argv0.out
error      = argv0.error
log        = argv0.log
arguments  = p1 p2 p3 p4

Enviar el trabajo al cluster.

$ condor_submit argv0.submit

Verificar la salida estándar del trabajo ejecutado.

$ cat argv0.out

Parameters count: 5.

Parameter ’0′: condor_exec.exe.
Parameter ’1′: p1.
Parameter ’2′: p2.
Parameter ’3′: p3.
Parameter ’4′: p4.

Done!

Tagged with:



En July 15 de 2010, Jorge Iván Meza Martínez escribió acerca de Cuidado sobre el manejo de argv[0] en las aplicaciones escritas en C/C++.
Jul 13

Introducción.

Frecuentemente será necesario enviar múltiples trabajos al cluster que se encuentren basados en el mismo ejecutable, esto es especialmente útil cuando una misma tarea se debe ejecutar en varias ocasiones de manera concurrente o cuando se necesita procesar de manera concurrente una gran cantidad de información dispersa en múltiples archivos.

Ejecutar varios trabajos.

Para indicarle a Condor que se desea ejecutar varias instancias del mismo trabajo sólo es necesario indicarle la cantidad a través de la instrucción Queue del archivo de lanzamiento.

Para evitar la confusión que puede generar el registro de n trabajos volcado sobre los tres únicos archivos de error, salida y log, es posible indicarle a Condor que los diferencie para cada una de las instancias del trabajo ejecutado, utilizando la seudovariable $(Process).

Otra variable del archivo de lanzamiento que cobra especial importancia en este contexto es Input la cual permite especificar la información que se ingresaría al programa a través de la entrada estándar (stdin).  Esto permite que se personalice la ejecución de cada uno de los trabajos a pesar de que se basan en el mismo ejecutable.

Executable  = MyJob
Universe    = standard
Input       = MyJob-$(Process).in
Output      = _MyJob-$(Process).out
Error       = _MyJob-$(Process).err
Log         = _MyJob-$(Process).log

Queue 3

Si se consulta la cola de trabajos del cluster inmediatamente después de lanzar el trabajo podrán apreciarse los 3 trabajos lanzados efectivamente, todos bajo el mismo identificador (38 en este caso) y diferentes subidentificadores (los representados finalmente por $(Process)).

$ condor_q

– Submitter: c-head.jorgeivanmeza.com : <192.168.1.210:9293> : c-head.jorgeivanmeza.com
ID      OWNER            SUBMITTED     RUN_TIME ST PRI SIZE CMD
38.0   jimezam         7/12 23:51   0+00:00:01 R  0   7.3  MyJob
38.1   jimezam         7/12 23:51   0+00:00:01 R  0   7.3  MyJob
38.2   jimezam         7/12 23:51   0+00:00:00 I  0   7.3  MyJob

3 jobs; 1 idle, 2 running, 0 held

La ejecución del archivo de lanzamiento anterior ejecutaría tres procesos basados en el programa MyJob el cual se deberá encontrar recompilado para el universo estándar, tomará la entrada estándar para cada una de las instancias de los archivos MyJob-#.in (que por obvias razones deberán existir previamente) y generará los archivos individuales de salida estándar, error y registro para cada una de las instancias ejecutadas con los nombres de _MyJob-#.out, _MyJob-#.err y _MyJob-#.log respectivamente.  El caracter # será reemplazado por el subidentificador interno del trabajo que empezará en cero y aumentará consecutivamente según la cantidad de trabajos que se haya solicitado encolar.

Después de la ejecución del trabajo propuesto como ejemplo este podría ser el contenido del directorio de trabajo.

-rw-rw-r– 1 jimezam jimezam       0 Jul 12 23:32 _MyJob-0.err
-rw-rw-r– 1 jimezam jimezam       4 Jul 12 23:40 MyJob-0.in
-rw-rw-r– 1 jimezam jimezam     622 Jul 12 23:32 _MyJob-0.log
-rw-rw-r– 1 jimezam jimezam     101 Jul 12 23:32 _MyJob-0.out

-rw-rw-r– 1 jimezam jimezam       0 Jul 12 23:32 _MyJob-1.err
-rw-rw-r– 1 jimezam jimezam       4 Jul 12 23:40 MyJob-1.in
-rw-rw-r– 1 jimezam jimezam     622 Jul 12 23:32 _MyJob-1.log
-rw-rw-r– 1 jimezam jimezam     101 Jul 12 23:32 _MyJob-1.out

-rw-rw-r– 1 jimezam jimezam       0 Jul 12 23:32 _MyJob-2.err
-rw-rw-r– 1 jimezam jimezam       4 Jul 12 23:40 MyJob-2.in
-rw-rw-r– 1 jimezam jimezam     622 Jul 12 23:32 _MyJob-2.log
-rw-rw-r– 1 jimezam jimezam     101 Jul 12 23:32 _MyJob-2.out

-rwxrwxr-x 1 jimezam jimezam 5461004 Jul 12 23:07 MyJob
-rw-rw-r– 1 jimezam jimezam     384 Jul 12 23:06 MyJob.c
-rw-rw-r– 1 jimezam jimezam     211 Jul 12 23:32 MyJob.submit

Utilizar directorios de inicio diferentes.

Otra facilidad que provee la sintáxis del archivo de lanzamiento de trabajos es la posibilidad de ejecutar los diferentes trabajos basados en el mismo ejecutable pero ubicados en diferentes directorios.  Esto evita las colisiones con los nombres de los archivos (solventadas inicialmente con el uso de $(Process)) y brinda un mayor orden a los archivos de datos.

Executable     = MyJob
Universe       = standard
Input          = MyJob.in
Output         = _MyJob.out
Error          = _MyJob.err
Log            = _MyJob.log           
initialdir     = job_$(Process)

Queue 3

Para lanzar este trabajo será necesario que existan los directorios iniciales de trabajo (job_0, job_1 y job_2) previamente y en cada uno de ellos exista el archivo MyJob.in cuyo contenido se utilizará como entrada estándar para cada una de las instancias.  Nótese como no habrá colisiones entre los nombres de los archivos (in, out, err y log) entre los diferentes trabajos aunque no se utilizó la seudovariable $(Process) para diferenciarlos ya que se ubicarán en diferentes directorios.

Después de la ejecución del trabajo propuesto como ejemplo este podría ser el contenido de los directorios de trabajo.

-rw-rw-r– 1 jimezam jimezam   0 Jul 12 23:51 job_0/_MyJob.err
-rw-rw-r– 1 jimezam jimezam   4 Jul 12 23:51 job_0/MyJob.in
-rw-rw-r– 1 jimezam jimezam 622 Jul 12 23:51 job_0/_MyJob.log
-rw-rw-r– 1 jimezam jimezam 107 Jul 12 23:51 job_0/_MyJob.out

-rw-rw-r– 1 jimezam jimezam   0 Jul 12 23:51 job_1/_MyJob.err
-rw-rw-r– 1 jimezam jimezam   4 Jul 12 23:51 job_1/MyJob.in
-rw-rw-r– 1 jimezam jimezam 622 Jul 12 23:51 job_1/_MyJob.log
-rw-rw-r– 1 jimezam jimezam 107 Jul 12 23:51 job_1/_MyJob.out

-rw-rw-r– 1 jimezam jimezam   0 Jul 12 23:51 job_2/_MyJob.err
-rw-rw-r– 1 jimezam jimezam   4 Jul 12 23:51 job_2/MyJob.in
-rw-rw-r– 1 jimezam jimezam 622 Jul 12 23:51 job_2/_MyJob.log
-rw-rw-r– 1 jimezam jimezam 107 Jul 12 23:51 job_2/_MyJob.out

Enlaces.

Tagged with:



En July 13 de 2010, Jorge Iván Meza Martínez escribió acerca de Enviando al cluster varios trabajos basados en el mismo ejecutable.
Jul 12

El universo Java.

Este universo permite el acceso uniforme a las máquinas virtuales de los nodos que dispongan de este servicio de manera independiente a la arquitectura de la máquina física o de su sistema operativo formando un ambiente de cómputo distribuido y homogéneo basado en la plataforma Java.

Verificar los nodos con soporte Java.

$ condor_status -java

Name               JavaVendor Ver    State     Activity LoadAv Mem   ActvtyTime

c-wn1.jorgeivanmez Sun Micros 1.6.0_ Unclaimed Idle     0.030   246  0+00:03:01
c-wn2.jorgeivanmez
Sun Micros 1.6.0_ Unclaimed Idle     0.000   246  0+00:10:04
Total Owner Claimed Unclaimed Matched Preempting Backfill

X86_64/LINUX     2     0       0         2       0          0        0

Total     2     0       0         2       0          0        0

Se puede apreciar que los nodos c-wn1 y c-wn2 del cluster tienen soporte para la ejecución de trabajos Java, ambos tienen las máquinas virtuales de Sun Microsystems 1.6.0.

Ejemplo.

El código fuente.

$ vi HelloClusterJava.java

public class HelloClusterJava
{
 public static void main(String args[])
 {
   String hostname = "*** desconocido *** ";

   try
   {
     java.net.InetAddress localMachine = java.net.InetAddress.getLocalHost();
     hostname = localMachine.getHostName();
   }
   catch (java.net.UnknownHostException e)
   {
     hostname = e.getMessage();
   }

   System.out.println("Hello cluster, my name is: " + hostname + ".\n\n");
 }
}

La compilación.

$ javac HelloClusterJava.java

El archivo de envío del trabajo.

$ vi HelloClusterJava.submit

executable = HelloClusterJava.class
arguments  = HelloClusterJava
universe   = java
log        = _HelloClusterJava.log
output     = _HelloClusterJava.out
error      = _HelloClusterJava.err
queue

Debe notarse como el nombre del archivo de la clase principal se referencia por la variable executable mientras que en la variable arguments debe referenciarse el nombre de la clase principal.

El envío del trabajo al cluster.

$ condor_submit HelloClusterJava.submit

La obtención de los resultados.

$ cat _HelloClusterJava.log

000 (028.000.000) 07/12 18:16:47 Job submitted from host: <192.168.1.210:9362>

001 (028.000.000) 07/12 18:16:50 Job executing on host: <192.168.1.211:9335>

005 (028.000.000) 07/12 18:16:51 Job terminated.
(1) Normal termination (return value 0)
Usr 0 00:00:00, Sys 0 00:00:00  -  Run Remote Usage
Usr 0 00:00:00, Sys 0 00:00:00  -  Run Local Usage
Usr 0 00:00:00, Sys 0 00:00:00  -  Total Remote Usage
Usr 0 00:00:00, Sys 0 00:00:00  -  Total Local Usage
0  -  Run Bytes Sent By Job
0  -  Run Bytes Received By Job
0  -  Total Bytes Sent By Job
0  -  Total Bytes Received By Job

$ cat _HelloClusterJava.err

(vacío)

$ cat _HelloClusterJava.out

Hello cluster, my name is: c-wn1.jorgeivanmeza.com.

Otros parámetros interesantes del archivo de envío de trabajos.

Uso de archivos JAR.

executable = MyMain.jar
jar_files  = One.jar, Two.jar, Three.jar

Uso de archivos JAR ejecutables.

executable = MyMain.jar
jar_files  = One.jar, Two.jar, Three.jar
arguments  = my.package.MyClass

Versión específica y características de la VM.

requirements = (JavaVersion=="6.0")

Velocidad mínima.

Cuando se agrega un nodo con soporte de Java al cluster se determina cual es su velocidad en términos de JavaMFlops utilizando los algoritmos de benchmark de SciMark2.  Este parámetro permite filtrar los nodos en los que se podrá ejecutar el trabajo de acuerdo a su velocidad, tomando a la velocidad especificada como mínima requerida.

requirements = (JavaMFlops>500)

Opciones específicas de la VM.

java_vm_args = -DMyProperty=Value -verbose:gc

Enlaces.

Tagged with:



En July 12 de 2010, Jorge Iván Meza Martínez escribió acerca de Enviando trabajos al universo Java del cluster.
Jul 12

El universo vanilla.

Este universo se utiliza para ejecutar los trabajos que no pueden ser reenlazados con las librerías de Condor, un caso importante de estos trabajos son los scripts del shell.

En este universo no se cuenta con puntos de chequeo ni con llamados al sistema remoto, por este motivo se hace necesario controlar la entrada y la salida de los trabajos, para lo cual se puede utilizar un sistema de archivos compartido (como NFS o AFS) o utilizar el mecanismo de Condor de transferir archivos.

Ejemplo.

El archivo de envío del trabajo.

$ vi hostname.submit

executable = /bin/hostname
universe   = vanilla
log        = _hostname.log
output     = _hostname.out
error      = _hostname.err
queue

El envío del trabajo al cluster.

$ condor_submit hostname.submit

La obtención de los resultados.

$ cat _hostname.log

000 (025.000.000) 07/12 10:51:26 Job submitted from host: <192.168.1.210:9204>
...
001 (025.000.000) 07/12 10:51:42 Job executing on host: <192.168.1.212:9875>
...
005 (025.000.000) 07/12 10:51:43 Job terminated.
(1) Normal termination (return value 0)
Usr 0 00:00:00, Sys 0 00:00:00  -  Run Remote Usage
Usr 0 00:00:00, Sys 0 00:00:00  -  Run Local Usage
Usr 0 00:00:00, Sys 0 00:00:00  -  Total Remote Usage
Usr 0 00:00:00, Sys 0 00:00:00  -  Total Local Usage
0  -  Run Bytes Sent By Job
0  -  Run Bytes Received By Job
0  -  Total Bytes Sent By Job
0  -  Total Bytes Received By Job
...

$ cat _hostname.err

(vacío)

$ cat _hostname.out

c-wn2.jorgeivanmeza.com

Enlaces.

Tagged with:



En July 12 de 2010, Jorge Iván Meza Martínez escribió acerca de Enviando trabajos al universo vanilla del cluster.
Jul 12

El universo standard.

Este universo provee puntos de chequeo (checkpointing) y llamados a sistemas remotos.  Los programas que vayan a ser ejecutados deberán ser reenlazados con las librerías de Condor, para esto no se requiere necesaria el código fuente pero si tener acceso a los archivos objeto (*.o).

Durante la ejecución de los trabajos Condor realiza en este universo, puntos puntos de chequeo a intervalos regulares.  Estos consisten en una imagen (snapshot) del estado actual del trabajo lo que permite migrarlo a otras máquinas sin perder lo realizado hasta el momento.  Esto es especialmente útil como tolerancia a fallos en el caso en que se presenten problemas en el nodo trabajador en donde se estaba ejecutando.

La facilidad de los llamados a sistemas remotos permite hacer creer a los trabajos ejecutados en diferentes máquinas del cluster que están siendo ejecutados en su máquina local.  Esto logra gracias al proceso condor_shadow que se ejecuta en la máquina lanzadora y procesa localmente los llamados al sistema (como abrir un archivo) que el trabajo intenta realizar en la máquina remota, enviando posteriormente su resultado para que sea suministrado como respuesta a su invocación.

Restricciones del universo.

  1. No están permitidos los trabajos multiproceso (fork(), exec() o system()).
  2. No setá permitida la comunicación entre los procesos (pipes, semáforos o memoria compartida).
  3. La comunicación en red deberá ser breve de lo contrario se interferirá con la generación de los puntos de chequeo y la migración.
  4. El envío de señales SIGUSR2 y SIGTSTP está prohibída ya que Condor las utiliza internamente, las demás pueden utilizarse normalmente.
  5. No está permitido el uso de alarmas como alarm(), getitimer() y sleep().
  6. No está permitido utilizar múltiples hilos del kernel, sin embargo los hilos del nivel de usuario si lo están.
  7. No están permitidos los archivos de memoria mapeada (mmap() y munmap()).
  8. Los bloqueos de archivo (file locks) se permiten pero no se mantienen entre puntos de chequeo.
  9. Los archivos deben abrirse en modo sólo-lectura o sólo-escritura, el modo lectura-escritura podrá causar problemas si se requiere restaurar un punto de chequeo anterior (rollback), por este motivo si se utiliza se generará una advertencia.
  10. Debe considerarse en la máquina que envía el trabajo un espacio en disco suficiente para almacenar las imágenes de los puntos de chequeo del trabajo.  Cada imagen de estas ocupa aproximadamente el tamaño de la memoria virtual que consume el trabajo mientras se ejecuta.
  11. En Linux el trabajo deberá estar enlazado estáticamente mientras que en Solaris deberá estar enlazado dinámicamente.
  12. No está soportado leer o escribir archivos de mas de 2GB.

Ejemplo.

El código fuente.

$ vi HelloCluster.c

#include <stdio.h>
#include <unistd.h>

int main(void)
{
 char hn[256];
 int control = gethostname(hn, sizeof(hn));

 if(control == -1)
 {
   perror("gethostname");
   return 1;
 }

 printf("Hello cluster, my name is: %s.\n\n", hn);

 return 0;
}

La compilación.

$ gcc -c HelloCluster.c

El enlace.

$ condor_compile gcc HelloCluster.o -o HelloCluster

Si se cuenta con el código fuente (como en este caso), el proceso de compilar & enlazar puede realizarse en un sólo paso.

$ condor_compile gcc HelloCluster.c -o HelloCluster

El archivo de envío del trabajo.

$ vi HelloCluster.submit

Executable     = HelloCluster
Universe       = standard
Output         = _HelloCluster.out
Error          = _HelloCluster.err
Log            = _HelloCluster.log
Queue

El envío del trabajo al cluster.

$ condor_submit HelloCluster.submit

La obtención de los resultados.

$ cat _HelloCluster.log

000 (024.000.000) 07/12 10:32:43 Job submitted from host: <192.168.1.210:9204>
...
001 (024.000.000) 07/12 10:32:52 Job executing on host: <192.168.1.212:9875>
...
005 (024.000.000) 07/12 10:32:53 Job terminated.
(1) Normal termination (return value 0)
Usr 0 00:00:00, Sys 0 00:00:00  -  Run Remote Usage
Usr 0 00:00:00, Sys 0 00:00:00  -  Run Local Usage
Usr 0 00:00:00, Sys 0 00:00:00  -  Total Remote Usage
Usr 0 00:00:00, Sys 0 00:00:00  -  Total Local Usage
1050  -  Run Bytes Sent By Job
5462131  -  Run Bytes Received By Job
1050  -  Total Bytes Sent By Job
5462131  -  Total Bytes Received By Job
...

$ cat _HelloCluster.err

(vacío)

$ cat _HelloCluster.out

Hello cluster, my name is: c-wn2.jorgeivanmeza.com.

Enlaces.

Tagged with:



En July 12 de 2010, Jorge Iván Meza Martínez escribió acerca de Enviando trabajos al universo estándar del cluster.