Gestor de trabajos


Cuando los usuarios inician sesión en el sistema, lo hacen en los frontends que dan acceso a los recursos del sistema. Los usuarios no deben ejecutar ningún trabajo sobre estos equipos. Todos los usuarios trabajan sobre estas máquinas y la ejecución de procesos en ellas, ralentiza el trabajo del resto de usuarios.
Todos los trabajos HPC que se ejecuten en el sistema deben ser ejecutados en los nodos de cálculo mediante el envío de un script al gestor de trabajos de SCAYLE.
El gestor de trabajos o gestor de colas es un sistema que se encarga de enviar los trabajos a los nodos de cálculo a los que cada usuario tiene acceso, controla su ejecución y evita que varios trabajos compartan los mismos recursos, viendo así incrementados sus tiempos de ejecución. El gestor usado por SCAYLE es SLURM.

En el caso de SLURM, los comandos más utilizados en su uso habitual son:

  • sbatch: este comando de Slurm se utiliza para enviar al gestor de trabajos el script del trabajo que querramos ejecutar. Por ejemplo:

    [usuario@frontend1 ~]$ sbatch run_openfoam.sh

    Enviará el script de ejecución del software de dinámica de fluidos OpenFOAM al gestor de trabajos.

  • squeue: muestra el estado de los trabajos enviados.

    [usuario@frontend1 ~]$ squeue 
             JOBID PARTITION    NAME     USER     ST  TIME     NODES  NODELIST(REASON)
             94631 cascadelake  JOB_OF   usuario  R   3:47:29  2      cn[5008-5009]

    La información nos muestra todos los trabajos que nuestro usuario tiene en ejecución. Por razones de seguridad y privacidad, los usuarios solo pueden tener acceso a la información de sus propios trabajos, no pudiendo acceder a ningún tipo de información del resto de usuarios.
    En el ejemplo anterior, el usuario tiene un único trabajo en ejecución con un valor de JOBID de 94631. Este JOBID es un número único que el gestor de trabajos asigna a cada uno de los trabajos que gestiona. Bajo PARTITION informa de en qué grupo de servidores está siendo ejecutado el trabajo. NAME informa del nombre del trabajo que fue definido en el script de envío. USER indica el propietario del trabajo. ST informa del estado del trabajo, en este caso R (running) en ejecución. Existe otro estado PD, pendiente, que indica que el trabajo está en espera para ser ejecutado. TIME informa del tiempo que lleva el trabajo siendo ejecutado. Finalmente, el número de servidores utilizados y el nombre de los mismos se detallan en las columnas NODES y NODELIST.

  • scancel: cancela la ejecución de un trabajo que está en funcionamiento. Por ejemplo, según el ejemplo anterior si deseamos cancelar el trabajo con JobID 94631:

    [usuario@frontend1 ~]$ scancel 94631
  • salloc: crea una sesión interactiva con los nodos de cálculo. El uso principal de este comando es poder compilar trabajos en los nodos con las mismas características que en los que va a ser ejecutado posteriormente. Por ejemplo, ejecutando el siguiente comando:

    [usuario@frontend1 ~]$ salloc --ntasks=16 --time=60 --partition=cascadelake

    El gestor de trabajos asignará un acceso a uno de los nodos de cálculo de la partición llamada cascadelake (--partition=cascadelake), durante un máximo de 60 minutos (--time=60) y nos permitirá usar 16 cores para nuestras tareas de compilación o test de nuestro código.

El primer paso para poder enviar un trabajo al gestor de trabajos es escribir un script de envío (submission script) que contenga dos tipos de líneas: directivas para el gestor de trabajos y comandos Linux.

Estos últimos son los comandos que serán interpretados por el shell de Linux definido en la primera línea del script (#!/bin/bash). Las directivas para el gestor de trabajos se colocan al comienzo del script y en el caso del SLURM son líneas que comienzan por la cadena “#SBATCH”seguida de las distintas opciones disponibles. Estas directivas son procesadas por el gestor cuando el script se envía con el comando sbatch y sirven para proporcionar información al gestor y permitir así que los nodos de ejecución realicen el trabajo de la forma deseada por el usuario. Por ejemplo, el siguiente batch script:

#!/bin/bash 
#SBATCH –-ntasks=32 
#SBATCH –-job-name=hello_world 
#SBATCH –-mail-user=email@scayle.es
#SBATCH –-mail-type=ALL 
#SBATCH --output=hello_world_%A_%a.out 
#SBATCH --error=hello_world_%A_%a.err 
#SBATCH –-partition=haswell 
#SBATCH –-qos=normal 
#SBATCH --time=0-00:05:00 
source /soft/calendula2/intel/ipsxe_2018_u4/parallel_studio_xe_2018/psxevars.sh 
srun -n $SLURM_NTASKS hello_world.exe

muestra un ejemplo de un batch script que ejecutará un programa básico sobre 32 cores. En la línea 1, como ya se ha detallado, se especifica el tipo de shell que ejecutará los comandos linux del script. Todas las líneas que comienzan con #SBATCH son las directivas que interpretará el gestor de tareas.
En este ejemplo:

#SBATCH –-ntasks=32; fija el número de cores deseados para la ejecución del script.
#SBATCH –-job-name=hello_world; nombre asignado al trabajo.
#SBATCH –-mail-user=email@scayle.es; dirección de correo electrónico a donde se enviarán las notificaciones relacionadas con el trabajo .
#SBATCH –-mail-type=ALL; define en qué circunstancias se enviará un correo electrónico al usuario. en este caso “ALL” será al comienzo de la ejecución, al finalizar la misma y en caso de que la tarea sea cancelada. 
#SBATCH --output=hello_world_%A_%a.out; es el fichero de salida estándar. Si no se define un fichero de salida para los errores, por defecto se unifica en un solo archivo la salida estándar de la ejecución y la salida de los posibles errores. 
#SBATCH --error=hello_world_%A_%a.err; define el fichero de salida de errores. 
#SBATCH –-partition=haswell; partición a la que se envía el trabajo. 
#SBATCH --qos=normal; qos con la que se envía el trabajo.
#SBATCH --time=0-00:05:00; (D-HH:MM:SS) límite de tiempo para el trabajo.

IMPORTANTE: Para que el trabajo funcione correctamente es obligatorio añadir el parametro #SBATCH --time=(D-HH:MM:SS) al script.
Donde D son días, HH son horas, MM son minutos y SS son segundos.
El tiempo definido con el parámetro ---time en ningún caso tendrá prioridad sobre el tiempo máximo de ejecución asociado a la QOS del trabajo.

Como hemos indicado previamente, para comprobar el estado de los trabajos enviados por el usuario el comando será:

 $ squeue

Cada QOS (Quality Of Services) permite personalizar diversos parámetros como el tiempo máximo que un trabajo puede ejecutarse, el número máximo de cores que pueden ser solicitados por un usuario o qué usuarios pueden enviar trabajos a esa partición. La QOS por defecto que utilizan los usuarios si no se especifica nada, es la QOS normal.
Por defecto, los usuarios tienen acceso a determinados límites. Para solicitar el acceso a una QOS en particular, el usuario debe ponerse en contacto con el personal de soporte.

A continuación se muestran los límites de las QOS que tenemos disponibles donde:

  • MaxWall: Es el tiempo máximo que se puede pedir al enviar un trabajo (días-horas:minutos:segundos).
  • MaxTRESPU: Es el número máximo de cores que un usuario puede reservar de forma simultánea.
  • MaxJobsPU: Es el número máximo de trabajos en ejecución por un usuario de forma simultánea.
Nombre Prioridad MaxWall MaxTRESPU MaxJobsPU
normal 100 5-00:00:00 cpu=512 50
long 100 15-00:00:00 cpu=256
xlong 100 30-00:00:00 cpu=128

Estas QOS pueden cambiar dependiendo de las necesidades del sistema.

Cuando un mismo trabajo debe repetirse una serie de veces variando únicamente el valor de algún parámetro, el gestor de tareas permite realizar esta tarea de forma automatizada. A este tipo de trabajos se les denomina array jobs.
Para enviar un array job se debe usar la opción --array del comando sbatch, por ejemplo desde la línea de comandos:

 frontend> sbatch ... --array 1-20 ... test.sh

enviaría 20 ejecuciones simultáneas del programa test.sh. Si quisieramos incluirlo en el própio script, deberíamos añadirlo al resto de opciones del gestor de tareas:

  #SBATCH --output=hello_world_%A_%a.out 
  #SBATCH --error=hello_world_%A_%a.err
  #SBATCH –-partition=haswell 
  #SBATCH –-qos=normal 10
  #SBATCH –-array=1-20

Dadas las carácteristicas de los límites del sistema de colas, en Slurm existe la opción de determinar el número de trabajos que queremos tener de forma simultánea en ejecución.

  #SBATCH –-array=1-20%4

Con la línea anterior indicamos que queremos lanzar un array job de 20 trabajos y que de forma simultánea se estén ejecutando 4.

Nota: esto no garantiza que los trabajos entren uno detrás de otro ya que depende de la carga de la máquina y las prioridades.

Existen un número de variables de entorno que se definen en el entorno del trabajo cuando el script se ejecuta a través del gestor de tareas. Estas variables se pueden usar en el script. Entre las más interesantes para el uso habitual están las siguientes:

  • $SLURM_JOB_ID: identificador del trabajo.
  • $SLURM_JOB_NAME: nombre del trabajo.
  • $SLURM_SUBMIT_DIR: directorio de envío.
  • $SLURM_JOB_NUM_NODES: número de nodos asignados al trabajo.
  • $SLURM_CPUS_ON_NODE: número de cores/nodo.
  • $SLURM_NTASKS: número total de cores por trabajo.
  • $SLURM_NODEID: índice del nodo que se ejecuta en relación a los nodos asignados al trabajo.
  • $SLURM_PROCID: índice de la tarea en relación con el trabajo.