SLURM en COYOTE
- Actualmente el cluster COYOTE cuenta con el administrador de trabajos SLURM para ejecutar las aplicaciones en paralelo en el mismo.
- En SLURM el usuario requiere un número de cores para una aplicación, y el sistema los asigna apenas tenga disponibilidad de recursos
- Ya que el hardware de COYOTE no es heterogeneo, sino que está compuesto por distintos tipos de equipamiento, se debe tener en cuenta a la hora de solicitar cores las siguientes features:
- node[2-7] 2 CPU de 4 cores (Xeon E5420), 8GB RAM Feature=E5420,RAM8
- node[8-24] 1 CPU de 6 cores (Xeon W3690), 16GB RAM Feature=W3690,RAM16
- node[1,25-32] 1 CPU de 6 cores (Xeon E5-1660), 16GB RAM Feature=1660,RAM16
Además los nodos 25 a 32 tienen placas GPU:
- node25 Feature=1660,RAM16,gpu,T2050
- node[26,27] Feature=1660,RAM16,gpu,T1060
- node[31,32] Feature=1660,RAM16,gpu,G580
- Para enviar trabajos a COYOTE mediante SLURM, se pueden usar dos comandos:
sbatch
y srun
. Se recomienda el uso del primer comando, ya que permite una mejor configuración a pesar de tener que usar un archivo de configuración.
- La sintaxis del comando sbatch es la siguiente:
sbatch [opciones] script
Las opciones pueden especificarse en la consola, en un archivo de configuración o en variables de entorno.
- En el caso de usar un script de configuración, se deben definir algunas variables:
Si se especifican dentro del script, Slurm lee las líneas que comienzan con #SBATCH e ignora el resto, y permite agregar comentarios después de las opciones. Por ejemplo "trabajo.sh" contiene:
#!/bin/bash
#SBATCH --job-name=prueba4 # nombre para identificar el trabajo. Por defecto es el nombre del script
#SBATCH --ntasks=10 # cantidad de cores pedidos
# la linea siguiente es ignorada por Slurm porque empieza con ##
##SBATCH --tasks-per-node=1 # cantidad de cores por nodo, para que distribuya entre varios nodos
#SBATCH --constraint=E5420 # sólo ejecutar en nodos con Xeon E5420 (los valores válidos son los definidos con "Feature")
#SBATCH --output=myjob.output # la salida y error estandar van a este archivo. Si no es especifca es slurm-%j.out (donde %j es el Job ID)
#SBATCH --error=myjob.error # si se especifica, la salida de error va por separado a este archivo
# aqui comienzan los comandos
mpirun /u/alquien/programa/programa_mpi
El script pide 10 cores en nodos Xeon E5420, por lo que se asignan 2 nodos de forma exclusiva (por más que en un nodo queden 6 cores libres).
Para lanzarlo (no es necesario que el script tenga permiso de ejecución):
sbatch trabajo.sh
y devuelve un texto similar a
Submitted batch job 101
Luego con squeue -l
se puede ver el estado:
JOBID | PARTITION | NAME | USER | STATE | TIME | TIME_LIMI | NODES | NODELIST(REASON) |
101 | work | prueba4 | alguien | PENDING | 0:00 | UNLIMITED | 1 | (Resources) |
100 | work | mpi-slur | alguien | RUNNING | 0:44 | UNLIMITED | 5 | node[2-7] |
El trabajo prueba4
ha quedado en espera (PENDING
) hasta que haya nodos suficientes/adecuados (Resources
) para que se ejecute.
El mismo script "trabajo.sh" se puede enviar con otras opciones (tienen precedencia sobre las variables SBATCH
):
sbatch --ntasks=4 --constraint=RAM16 --job-name=parte2 trabajo.sh
De este modo no es necesario crea o modificar un script por cada trabajo.
- Se pueden encadenar trabajos independientes para que se ejecuten al terminar el anterior:
sbatch --dependency=afterany:110 segunda_parte.sh
Las opciones posibles para --dependency
son:
afterany:job_id[:job_id...]
Este trabajo comienza cuando la ejecución del trabajo con id job_id
haya finalizado.
afternotok:job_id[:job_id...]
Este trabajo comienza su ejecución luego de que el trabajo especificado en job_id
haya finalizado con algún estado de error (código de sálida distinto de cero, fallo de nodo, timeout, etc.)
afterok:job_id[:job_id...]
Este trabajo comienza su ejecución luego de que el trabajo especificado en job_id
haya finalizado correctamente.
Para los programas con MPI:
Los paquetes de MPI incluyen soporte para la API PMI/PMI2 (Process Management Interface), diseñada para coordinar trabajos con sistemas como SLURM. Esta API permite que mpirun/mpiexec detecte los nodos asignados y no sea necesario pasar opcines -machinefile, -f o -n.
MPICH ya incluye este soporte en la compilación por defecto, por lo que no es necesario recompilarlo. Fue probado con la compilación instalada en /usr/local/mpich
(v3.1.4). No hay que especificar una lista de hosts (-f) en mpirun porque queda en espera permanente.
Para OpenMPI es necesario activar el soporte para PMI, la instalación en /usr/local/openmpi-1.8.7 ya lo tiene. Para los usuarios que compilen sus propias versiones se recomienda una configuración similar a
./configure --prefix=/u/alguien/openmpi --enable-static --disable-java --without-x --without-loadleveler --with-slurm --with-pmi=/usr/local/include/slurm --with-pmi-libdir=/usr/local/lib --with-cuda=/usr/local/cuda
Importante:
- El orden de precedencia de las opciones es el siguiente (de mayor a menor): en línea de comando, variable de entorno, dentro del script.
Hay pocas opciones potencialmente útiles en las variables de entorno: SBATCH_EXCLUSIVE, SBATCH_JOB_NAME (listado completo en info sbatch / man sbatch)
- Los comandos (sbatch, squeue), atributos (E5420) y opciones (--ntasks, --job-name) son sensibles a mayúsculas.
- Los comandos se utilizan desde Coyote, no es necesario ingresar a los nodos para lanzar el trabajo.
Comandos útiles:
squeue -l # lista los trabajos en ejecución y espera
sinfo # muestra estado de los nodos
scancel JOB_ID # cancela un trabajo