¿Cómo ejecuto un programa usando un planificador de trabajos?

En el cluster y los servidores de procesamiento bioinformático, se tiene instalado un software que se encarga de programar, enviar y gestionar la ejecución distribuida y remota de múltiples procesos o tareas de los usuarios, de forma secuencial, concurrente o paralela, y que administra también los recursos computacionales destinados a esas tareas.

El software planificador de trabajos (job scheduler) que usamos es el Sun Grid Engine o SGE, conocido también como sistema manejador de colas.

El cluster es adecuado para ejecutar una gran cantidad de instancias de programas (quizá miles), de forma concurrente en los diferentes nodos de ejecución o cómputo de los que se compone, usando SGE desde el nodo maestro. En los servidores standalone, de multiprocesamiento simétrico o SMP, se puede usar SGE para manejar las ejecuciones como si se tratara de un cluster de un único nodo de cómputo.

El uso del planificador de trabajos es recomendado sobre, o preferible a, la ejecución directa en segundo plano o background, o la programación de ejecución posterior de comandos.

En el caso específico del CCG, se puede usar SGE en los servidores chichen, bonampak y litza, y en el cluster kayab. En la LCG se puede usar SGE en los servidores tepeu y buluc, y en el cluster kukun. Al iniciar sesión en ellos, aparecerá información relevante sobre la configuración de SGE.

A continuación se revisarán algunos conceptos y procedimientos básicos del manejador de colas.

¿Qué es un trabajo o job?

Es la ejecución de un programa, puede ser en batch, paralelo o interactivo.

¿Qué es una cola o queue?

Es un contenedor para trabajos que serán ejecutados en uno o varios nodos de cómputo. Las colas pueden tener configuración para la ejecución, como número de CPUs, prioridad o tiempo de procesador. El sistema manejador de colas recibe un trabajo y dependiendo de la configuración de su ejecución, y de los recursos disponibles en ese momento, decide ejecutarlo o bien esperar, “formarlo en la cola”, hasta que haya recursos disponibles.

¿Cómo veo el estado de uso del cluster o del servidor?

En un cluster se puede ver la lista de los nodos de cómputo y su estado de uso de recursos usando el comando qhost. Este comando muestra por cada renglón un nodo de cómputo, y principalmente las columnas:

  • NCPU: número de cpus
  • LOAD: carga de procesador
  • MEMTOT: memoria RAM total del nodo
  • MEMUSE: memoria RAM en uso

En el caso del cluster kayab, con Rocks Linux, también se puede ver el estado accediendo a la interfaz web Ganglia, en la dirección http://kayab.ccg.unam.mx/ganglia.
En un servidor SMP con SGE se puede usar también el comando qhost, sin embargo se puede ver información más detallada usando el comando htop.

En la siguiente figura se ve un ejemplo de la salida de qhost.

Ejemplo de salida de qhost

¿Cómo veo el estado de los trabajos?

Para ver la lista de trabajos actuales y su estado de ejecución, se usa el comando qstat. Sin opciones, solamente se muestran los trabajos del usuario actual.
Si se usa la opción -u se pueden ver los trabajos de todos los usuarios.
$ qstat -u '*'
El comando qstat muestra las columnas:

  • job-ID: identificador del trabajo
  • prior: prioridad
  • name: nombre del trabajo
  • user: usuario dueño del trabajo
  • state: estado, puede ser q (encolado o queued), w (esperando o waiting), r (en ejecución o running), E (en error)
  • submit/start at: fecha y hora de envío
  • queue: nombre de la cola donde se está ejecutando
  • slots: número de slots o cpus asignados
  • ja-task-ID: el identificador de la tarea en caso de que se haya enviado un arreglo de tareas

En la siguiente figura se ve un ejemplo de la salida del comando qstat.

Ejemplo de salida de qstat

¿Cómo veo las colas disponibles?

El sistema puede disponer de distintas colas, con distintas configuraciones de ejecución. Para ver la lista de las colas disponibles se usa el comando:
$ qconf -sql
Normalmente se tiene la cola default o all.q. En los clusters puede haber una cola fast. Tal vez haya alguna cola específica para algún programa, como canuq. O bien una cola que se componga de un grupo específico de nodos, por ejemplo Big.q. Si no se especifica una cola al enviar un trabajo, se usa la cola default.

¿Cómo mando un trabajo a una cola?

Para enviar a ejecución un trabajo, se usa el comando qsub. Normalmente se prepara un archivo o script con la definición del trabajo. Este archivo puede tener terminación .jdl (de job definition language) o .sh. La estructura recomendada es:

  • la primera línea debe ser #!/bin/bash
  • inmediatamente después, las opciones que se quieran pasar al comando qsub, iniciando con #$. Estas opciones también se pueden pasar a qsub en la línea de comandos.
    Las opciones más comunes son:

    #$ -N jobname Nombre que queremos dar al trabajo
    #$ -cwd Indica que se use el directorio actual como directorio de trabajo
    #$ -S /bin/bash Indica que se use el shell bash
    #$ -o salida.out Indica el nombre del archivo que tendrá la salida del trabajo
    #$ -e salida.err Indica el nombre del archivo que tendrá los errores del trabajo
  • después, vienen ya los comandos que se quieran ejecutar. Pudiera ser necesario agregar la línea siguiente si es que se requiere definir variables de ambiente (por ejemplo para usar los programas de anaconda):
    source /etc/bashrc

Por ejemplo, un archivo jdl para enviar un trabajo puede verse como en la siguiente figura:

Archivo jdl para SGE

Para encolar el trabajo, se pasa el archivo como argumento a qsub:
$ qsub archivo.jdl
Your job 22 ("jobname") has been submitted

La salida de qsub muestra el identificador del trabajo o job id, en este caso 22.

Posteriormente, se puede monitorear usando el comando qstat, o bien ver todos los detalles del trabajo usando qstat con la opción -j. Por ejemplo, para ver detalles del trabajo con identificador 22:
$ qstat -j 22

¿Cómo elimino un trabajo de la cola?

Si un trabajo está en estado de error, o si por alguna razón se quiere eliminar de la cola, se usa el comando qdel. Por ejemplo para eliminar el trabajo con identificador 22:
$ qdel 22

¿Cómo defino qué recursos usará mi trabajo?

En general para especificar algunos recursos solicitados para el trabajo se puede usar la opción -l seguida de un nombre de recurso y valor, -l recurso=valor.

Por ejemplo, para especificar la cola a donde enviar el trabajo:

$ qsub -l qname=Big.q archivo.jdl

Tiempo máximo para el trabajo:

$ qsub -l h_rt=02:00:00 archivo.jdl

Para reservar una cantidad de memoria para el trabajo:

$ qsub -l h_vmem=2g archivo.jdl

Para reservar dos cores para el trabajo, usando el ambiente de ejecución paralela smp:

$ qsub -pe smp 2 archivo.jdl

Las opciones -l, -pe y otras también pueden incluirse en el archivo jdl como directivas con #$.

¿Cómo ejecuto varias tareas en un trabajo?

Para ejecutar múltiples tareas en un solo trabajo, se puede usar un arreglo de trabajos o array job. Esto es útil si se tiene por ejemplo un archivo con cientos o miles de líneas de comandos independientes, o bien si se va a ejecutar el mismo comando en el que solamente cambie un argumento que pueda tener como valor un número secuencial o un valor proveniente de una línea de un archivo.

Cuando se ejecuta un arreglo de tareas, todas tienen el mismo identificador de trabajo, solamente va cambiando el índice del arreglo o identificador de tarea.

Para ejecutar un arreglo de tareas, se usa el comando qsub con la opción -t. El valor de -t puede tener el formato x-y o x-y:n, donde:

x Índice inferior del arreglo
y Índice superior del arreglo
n Incremento o step (opcional)

Por ejemplo:
$ qsub -t 2-10:2 archivo.jdl
Esto hace disponible directamente en el script archivo.jdl la variable $SGE_TASK_ID. En este ejemplo la variable va tomando valores numéricos de 2 a 10 de 2 en 2. Los valores de x, y y n están disponibles en las variables $SGE_TASK_FIRST, $SGE_TASK_LAST y $SGE_TASK_STEPSIZE, respectivamente.

La opción -t también puede incluirse dentro del archivo jdl como directiva, después de #$.