Envío de trabajos al clúster con múltiples directorios de trabajo
Control de versiones
| Fecha | Actividad | Autor |
|---|---|---|
| 03/11/2010 | Publicación inicial | Jorge Iván Meza Martínez. |
Introducción
Otra facilidad que permite la sintáxis del envío de trabajos ( condor_submit) al cluster, además de múltiples subtrabajos con argumentos diferentes, es la de utilizar múltiples subtrabajos con directorios de trabajo diferentes.
Esta variante es muy útil cuando cada uno de los subtrabajos necesite archivos de configuración o archivos de datos diferentes para desarrollar su finalidad específicas.
Tiempo estimado
30 minutos.
Precondición
- El cluster se encuentra completo y en operación.
Supuestos
Ninguno.
Descripción del ejemplo
En este caso se utiliza una versión modificada de la aplicación para hallar números primos: FindPrimesData la cual obtiene los límites iniciales y finales del rango de valores a evaluar de un archivo llamado data.txt.
Esta aproximación crea subdirectorios individuales para cada uno de los subtrabajos y ubica allí archivos data.txt con los límites específicos para cada uno de los subrangos.
Implementación del ejemplo
El código fuente de la aplicación findPrimes utilizado es el siguiente.
$ vi findPrimesData.c
- findPrimesData.c
#include <stdio.h> #include <stdlib.h> #define true 1 #define false 0 /** * Verifica si el número especificado es primo o no. * * @param int Número a verificar. * @return int true es primo, false no. */ int isPrime(int num) { int i = 0; int start = 2; int end = num; if(num == 2 || num == 3 || num == 5 || num == 7 || num == 11) { return true; } if(num % 2 == 0) { return false; } for(i=start; i<=end; ++i) { if(i != num && num % i == 0) { return false; } } return true; } /** * Obtiene los límites del rango de valores a partir del archivo data.txt, * la primera línea de su contenido será el valor inicial y la segunda * línea será el valor final del rango. * * @param int Valor de inicio del rango (referencia). * @param int Valor de terminación del rango (referencia). * @return int true si la lectura del archivo es exitosa, false de lo contrario. */ int getValueRange(int* start, int* end) { char line1[256]; char line2[256]; FILE* file = fopen("data.txt", "r"); if(file == NULL) return false; fgets(line1, sizeof(line1), file); fgets(line2, sizeof(line2), file); *start = atoi(line1); *end = atoi(line2); return true; } /** * Aplicación de demostración para la búsqueda de números primos. * * @param argv[1] - string Valor inicial (entero) del rango a revisar. * @param argv[2] - string Valor final (entero) del rango a revisar. */ int main(int argc, char *argv[]) { int start, end, i, val; // Verifica la existencia de los parámetros necesarios. if(argc != 1) { printf("Usage: %s\n", argv[0]); exit(1); } // Obtiene la representación entera de los límites del rango de // valores a revisar. int control = getValueRange(&start, &end); if(control == false) { printf("Error: I could find/read the data.txt file!\n"); exit(2); } // Revisa uno a uno los valores del rango verificando si son números // primos o no. for(i=start; i<=end; i++) { val = isPrime(i); // En caso de ser "i" un número primo lo imprime a través de stdout. if(val == true) printf("%d\n", i); } // Termina exitosamente. exit(0); }
La aplicación es compilada de acuerdo con los requerimientos del universo Standard.
$ condor_compile gcc findPrimesData.c -o FindPrimesData
En el archivo de envío del trabajo se especifican los subtrabajos con diferentes directorios de trabajo (Initialdir).
$ vi FindPrimesData.submit
- FindPrimesData.submit
Executable = FindPrimesData Universe = standard Log = _FindPrimes.log Initialdir = part1 Output = _FindPrimes-$(Process).out Error = _FindPrimes-$(Process).err Queue Initialdir = part2 Output = _FindPrimes-$(Process).out Error = _FindPrimes-$(Process).err Queue Initialdir = part3 Output = _FindPrimes-$(Process).out Error = _FindPrimes-$(Process).err Queue Initialdir = part4 Output = _FindPrimes-$(Process).out Error = _FindPrimes-$(Process).err Queue Initialdir = part5 Output = _FindPrimes-$(Process).out Error = _FindPrimes-$(Process).err Queue
Se crean los directorios de trabajo enunciados y dentro de cada uno de ellos se ubica un archivo data.txt con dos líneas de texto de las cuales la primera corresponderá con el límite inferior y la segunda con el límite superior del rango de valores.
$ tree . |-- FindPrimesData |-- findPrimesData.c |-- findPrimesData.submit |-- part1 | `-- data.txt |-- part2 | `-- data.txt |-- part3 | `-- data.txt |-- part4 | `-- data.txt `-- part5 `-- data.txt
El envío del trabajo al cluster se realiza de manera habitual.
$ condor_submit FindPrimesData.submit
Después de la ejecución de todas los subtrabajos se puede apreciar como sus archivos de registro se ubicaron en cada uno de los subdirectorios.
$ tree . |-- FindPrimesData |-- findPrimesData.c |-- findPrimesData.submit |-- part1 | |-- _FindPrimes-0.err | |-- _FindPrimes-0.out | |-- _FindPrimes.log | `-- data.txt |-- part2 | |-- _FindPrimes-1.err | |-- _FindPrimes-1.out | |-- _FindPrimes.log | `-- data.txt |-- part3 | |-- _FindPrimes-2.err | |-- _FindPrimes-2.out | |-- _FindPrimes.log | `-- data.txt |-- part4 | |-- _FindPrimes-3.err | |-- _FindPrimes-3.out | |-- _FindPrimes.log | `-- data.txt `-- part5 |-- _FindPrimes-4.err |-- _FindPrimes-4.out |-- _FindPrimes.log `-- data.txt