Información y ayuda

HPC Universidad de Oriente

Herramientas de usuario

Herramientas del sitio


hpc-script-array

ARREGLOS DE TRABAJOS

Los arreglos de trabajos permiten enviar muchas tareas que difieren en un solo parámetro (por ejemplo el fichero de entrada, el directorio que contiene los datos, entre otros), de forma más eficiente que enviando las tareas individualmente. Se conocen también como array job, job array y array task.

Especificación

Existen diferentes formas de especificar los arreglos:

#SBATCH --array=0-31         # - intervalo
#SBATCH --array=1,3,5,7      # , valores individuales
#SBATCH --array=1-7:2        # : salto

El número de tareas ejecutándose al mismo tiempo se puede especificar con el signo %.

#SBATCH --array=1-31%5 # 5 tareas ejecutándose del arreglo 1-31.

Es importante especificar el número de tareas ejecutándose a valores no más de 5 o 6, para no ocupar todos los nodos con un solo array job.

JOB ID y Variables de ambiente

Además de la variable SLURM_JOB_ID que se crea para cada trabajo, con los arreglos se crean otras variables de ambiente:

SLURM_ARRAY_JOB_ID  se dará al primer job ID del arreglo.
SLURM_ARRAY_TASK_ID se dará al valor del índice del job array. 
SLURM_ARRAY_TASK_COUNT se dará al número de las tareas en el arreglo. 
SLURM_ARRAY_TASK_MAX se dará al mayor valor del valor del índice del arreglo.  
SLURM_ARRAY_TASK_MIN se dará al menor valor del valor del índice del arreglo. 

Por ejemplo, si se envía un --array1-3 y Slurm responde:

Submitted batch job 36

entonces se tiene:

SLURM_JOB_ID=36
SLURM_ARRAY_JOB_ID=36
SLURM_ARRAY_TASK_ID=1
SLURM_ARRAY_TASK_COUNT=3
SLURM_ARRAY_TASK_MAX=3
SLURM_ARRAY_TASK_MIN=1

SLURM_JOB_ID=37
SLURM_ARRAY_JOB_ID=36
SLURM_ARRAY_TASK_ID=2
SLURM_ARRAY_TASK_COUNT=3
SLURM_ARRAY_TASK_MAX=3
SLURM_ARRAY_TASK_MIN=1

SLURM_JOB_ID=38
SLURM_ARRAY_JOB_ID=36
SLURM_ARRAY_TASK_ID=3
SLURM_ARRAY_TASK_COUNT=3
SLURM_ARRAY_TASK_MAX=3
SLURM_ARRAY_TASK_MIN=1

Todas estas variables se pueden utilizar en los scripts de envío, pero las más usadas son SLURM_JOB_ID y SLURM_ARRAY_JOB_ID.

Nombres de ficheros

Para especificar los nombres de ficheros de stdin, stdout y sterr, se sustituyen %A por SLURM_ARRAY_JOB_ID y %a por SLURM_ARRAY_TASK_ID. Por ejemplo:

#SBATCH --output=array_%A_%a.out
#SBATCH --error=array_%A_%a.err

Especificar correo

Por defecto Slurm envía correos cuando el trabajo termina, comienza o falla (END, BEGIN, FAIL). En el caso de los arreglos de trabajo, el correo se refiere al job array y no a las tareas. En caso que se desee el envío del correo por las tareas añada: ARRAY_TASKS.

Se debe tener cuidado al usar ARRAY_TASKS por el número de correos que pueda generar.

Ejemplos

Caso 1. 1000 trabajos similares con los mismos recursos, pero con ficheros de entrada diferentes

Ficheros de entrada: fichero-1, fichero-2, …, fichero-1000

#SBATCH --array=1-1000%5           # 1000 trabajos ejecutándose 5 cada vez
#SBATCH --output=array_%A_%a.out
#SBATCH --error=array_%A_%a.err  

./programa < fichero-$SLURM_ARRAY_TASK_ID

Caso 2. El caso anterior pero con ficheros en diferentes directorios

Directorios: directorio1/, directorio2/, … con fichero-1, fichero-2, … en cada directorio respectivamente.

Crear el fichero lista_directorios.txt con los nombres de los directorios en columna.

Es importante notar que los nombres de los directorios pueden no tener una raíz única, no ser iguales e incluso no tener números consecutivos, sino números en cualquier orden.

#SBATCH --array=1-1000%5           # 1000 jobs ejecutándose 5 cada vez
#SBATCH --output=array_%A_%a.out
#SBATCH --error=array_%A_%a.err         

# Define la variable DIR usando sed y la lista_directorios.txt
DIR=$(sed -n "${SLURM_ARRAY_TASK_ID}p" lista_directorios.txt)

# Cambia al directorio DIR
cd $DIR

# Ejecuta el programa
./programa < fichero-$SLURM_ARRAY_TASK_ID

Descargar ejemplo.

Otra forma más sencilla de hacer este caso es de la siguiente forma:

- Crear un directorio con fichero-1, fichero-2, …

- Utilizar las siguientes directivas en el script de envío:

#SBATCH --array=1-1000%5           # 1000 jobs ejecutándose 5 cada vez
#SBATCH --output=array_%A_%a.out   # STDOUT 
#SBATCH --error=array_%A_%a.err    # STDERR       

# Cambia al directorio del id de la tarea
cd $SLURM_ARRAY_TASK_ID

# Ejecuta el programa
./programa < fichero-$SLURM_ARRAY_TASK_ID

En esta última forma se utiliza la variable $SLURM_ARRAY_TASK_ID, que almacena el id de la tarea del arreglo.

Caso 3. El caso 2 pero con 5000 trabajos en vez de 1000

Es poco eficiente ejecutar 5000 trabajos en un nodo, por lo que es mejor hacer ciclos con 1000 en un nodo. De esta forma, se tendrán 5 trabajos haciendo cada uno ciclos de 1000.

Directorios: directorio1/, directorio2/, … con fichero-1, fichero-2, …

Crear el fichero lista_directorios.txt con los nombres de los directorios en columna.

En el siguiente script se combina el array task con ciclos de bash para procesar varias ejecuciones cortas.

#SBATCH --array=1-5 
#SBATCH --output=array_%A_%a.out
#SBATCH --error=array_%A_%a.err         

# Número de ejecuciones que cada tarea de Slurm debe hacer
NUMLINES=1000

# Calcula valores iniciales y finales de esta tarea basados en el task id y el número de ejecuciones
STOP=$((SLURM_ARRAY_TASK_ID*NUMLINES))
START="$(($STOP - $(($NUMLINES - 1))))"

# Ejecuta un ciclo de bash para esta tarea
for (( N = $START; N <= $STOP; N++ ))
do
    DIR=$(sed -n "${SLURM_ARRAY_TASK_ID}p" lista_directorios.txt)
    cd $DIR
endo

# Ejecuta el programa
./programa < fichero-$SLURM_ARRAY_TASK_ID

Caso 4. Diferentes opciones para un programa

Es posible pasar diferentes opciones a un programa usando el array task id.

Se escribe un fichero file.txt que contenga en cada línea los argumentos ARG1, ARG2, …

El siguiente es un ejemplo de programa Python al que se le pasan diferentes opciones:

#SBATCH --array=0-4
#SBATCH --output=array_%A_%a.out
#SBATCH --error=array_%A_%a.err         

 case $SLURM_ARRAY_TASK_ID in
    0) ARGS="-i foo.txt -o foo.out" ;;
    1) ARGS="-i bar.txt -o bar.out" ;;
    2) ARGS="-i ich.txt -o ich.txt" ;;
    3) ARGS="-i pin.txt -o pin.txt" ;;
    4) ARGS="-i lsin.txt -o lsin.txt" ;;
esac
   
python program.py $ARGS > output-$SLURM_ARRAY_TASK_ID.txt

Descargar ejemplo.

Notas importantes

Para que los programas escritos en Python y R puedan leer el array task id es necesario cargar los módulos correspondientes.

Python:

import sys
jobid = sys.getenv(´SLURM_ARRAY_TASK_ID´)

R:

task_id <- Sys.getenv(¨SLURM_ARRAY_TASK_ID¨)
hpc-script-array.txt · Última modificación: 2022/12/06 18:59 por Beatriz Valdés Díaz