SLURM (Simple Linux Utility for Resurce Management) es el software de gestión de particiones utilizado en Drago.
Al lanzar un trabajo será SLURM quien nos asigne lo recursos que necesitamos.
Para ello disponemos de varios comandos y algunos aspectos a tener en cuenta.
Básico
Información
Trabajos
Referencias
Para lanzar un trabajo lo podemos hacer con el comando sbatch y los siguientes parámetros:
sbatch -p generic -N 1 -n 1 script.sh
-p : Indica el nombre de la partición, en este caso generic
-N : Indica el numero de nodos a usar, en este caso 1
-n : Indica el numero de tareas a usar, en este caso 1
Para enviar trabajos a la partición de gpu es muy importante indicar el numero de gpus que se necesita de esta forma #SBATCH --gres=gpu:1
En la sección trabajos tenemos un ejemplo de script.
Por defecto, para SLURM,
1 tarea = 1 procesador
1 procesador = 1 core
Es decir, que si no se le especifica lo contrario, cuando le asignamos el número de tareas (-n), será lo mismo que procesadores a usar. Pero existen trabajos en los que las tareas requieren más procesadores, cómo por ejemplo los binarios multithreading.
Por ejemplo, si mi binario utiliza OpenMP para paralelizar, que lo que hace es crear threads, tendré que especificarle el número de threads/cores a usar. Imaginamos que quiero crear 4 threads, entonces tendré que reservar 4 cores de la siguiente forma:
sbatch -p generic -n 1 --cpus-per-task=4 script.sh
Le estoy diciendo que reserve para 1 tarea 4 cores.
Otro ejemplo, tengo un binario híbrido con OpenMP y MPI. Quiero reservar 4 cores entre 2 nodos diferentes, de esta forma:
sbatch -p special -N 2 -n 2 --tasks-per-node=1 --cpus-per-task=2 script.sh
En este caso le estoy especificando que me reserve 2 Nodos y 2 tareas en total (procesos MPI), que en cada nodo me asigne 1 tarea y aparte que me reserve 2 cores por tarea.
Si tenemos el mismo binario que sólo hace uso de MPI para paralelizar, pues para obtener el mismo resultado tendría que mandarlo de la siguiente forma:
sbatch -p special -N 2 -n 4 --tasks-per-node=2 --cpus-per-task=1 script.sh
Lo importante en estos casos, es entender bien, el concepto de tareas (MPI) y threads (OpenMP) y cómo se reservan correctamente los cores.
Memoria total vs memoria por CPU/core:
Por defecto por cada core una cantidad de memoria. Ver tabla en particiones
Si nuestros trabajos requieren más memoria hay que especificarlo, con las opciones --mem y --mem-per-cpu hasta un máximo 16GB por core, de lo contrario, el trabajo fallará porque no tiene memoria suficiente.
Por ejemplo, si mi trabajo no paraleliza y sé que requiere hasta 6GB de memoria lo tendré que especificar de la siguiente forma:
sbatch -p generic -n 1 --mem=6GB script.sh
Imaginemos que mi trabajo en serie requiere más de los 16GB por core que se puede reservar, si yo pido más memoria, pongamos por ejemplo 32GB:
sbatch -p generic -n 1 --mem=32GB script.sh
Lo que hará es reservar 2 cores ( 32GB/16GBcore= 2 cores) para mi trabajo, que sólo tiene 1 tarea.
Lo mismo pasará si se especifica con --mem-per-cpu, si pido:
sbatch -p generic -n 2 --mem-per-cpu=20GB script.sh
Me reservará 2 tareas/cores con 20GB de memoria para cada uno.
Pero si lo que quiero es 1 tarea con 2 cores y 20 GB (40GB) de memoria por core, sería:
sbatch -p generic -n 1 --cpus-per-task=2 --mem-per-cpu=20GB script.sh
Información de una partición
$ sinfo -p [partition]
Muestra la información a intervalos de 60 segundos
$ sinfo -i60
Información sobre los nodos caídos y su motivo
$ sinfo -R
En esta tabla podemos ver las particiones que hay, los límites de cada tipo de partición y la orientación de cada una de ellas.
Tiempo | Nodos | Memoria por cpu | Descripción | |
---|---|---|---|---|
express | 10 horas | 1-2 | 4 GB | Trabajos sean cortos o pruebas. |
generic | 15 días | 1 | 4 GB | Trabajos que no paralelizan entre nodos. |
special | 7 días | 2-8 | 4 GB | Trabajos que paralelizan entre nodos |
long | 30 días | 8-112 | 4 GB | Trabajos que necesitan mas recursos. |
GPU | 7 días | 1-2 | 8 GB | Trabajos que usen GPUs. |
compile | 10 horas | 1 CPU + 1 GPU | 4(8 GB) | Trabajos de compilación |
Estos son los comandos más utilizados, que sirven de introducción a este sistema de particiones (también llamadas colas).
A la hora del envío de un trabajo, existen dos maneras de ejecutar un trabajo:
Con el comando sbatch (envío de un trabajo a una partición para esperar a su ejecución)
Con el comando srun (envío de un trabajo a una partición en tiempo real).
Antes de enviar un trabajo, en cualquier editor de texto plano, tendremos que crear un fichero (script) con datos del trabajo a ejecutar. Ejemplo:
$ vi ejemplo.sh
#!/bin/bash
#SBATCH -p generic # Partición (cola)
#SBATCH -N 1 # Numero de nodos
#SBATCH -n 1 # Numero de cores(CPUs)
#SBATCH --gres=gpu:1 # SOLO en particion gpu
#SBATCH --mem 100 # Bloque de memoria para todos los nodos
#SBATCH -t 0-02:00 # Duración (D-HH:MM)
#SBATCH -o slurm.%N,%j.out #STDOUT
#SBATCH -e slurm.%N,%j.err #STDERR
#SBATCH --mail-type=BEGIN,END,FAIL # Notificación cuando el trabajo empieza,termina o falla
#SBATCH --mail-user=micorreo@csic.es # Enviar correo a la dirección
for i in {1..1000}; do
echo $RANDOM >> SomeRandomNumbers.txt
done
sort SomeRandomNumbers.txt
No tenemos que poner todo, si no vamos a usar una opcion podemos comentar la linea o eliminarla.
La mayoría de estas opciones del script se pueden incluir en la línea de comando de sbatch.
Enviar trabajos
$ sbatch -p generic ejemplo.sh
$ sbatch -p generic -N1 -n1 --mem=6Gb
$ sbatch -p special -N2 -n4 --men-per-cpu=8Gb
Envío en tiempo real de un trabajo
Con el comando srun, podemos enviar trabajos en tiempo real a una partición o ejecutar un trabajo interactivo.
Para más información:
$ man srun
Ejemplos de envío de trabajos en tiempo real con srun
srun -p generic -N1 -n1 <programa/orden>
srun -p special -N2 -n2 <orden/programa>
salloc xterm (abre un terminal x)
Trabajo interactivo
srun -p generic -N1 -n1 --pty $SHELL -i
Asignar recursos para la ejecución de un trabajo
salloc -N5 srun -n10 myprogram
exit (salir de los recursos asignados)
Ver la hora y fecha de entrada a ejecución de los trabajos pendientes
$ squeue --start
Ver trabajos de un usuario
$ squeue -u <username>
Listar todos los trabajos en ejecución de un usuario
$ squeue -t RUNNING
Ver todos los trabajos en espera de un usuario
$ squeue -t PENDING
Ver todos los trabajos de un usuario en una partición
$ squeue -u <nombreusuario> -p generic
Ver información detallada de un trabajo (útil para la solución de problemas)
$ scontrol show jobid -dd <jobid>
Una vez terminado el trabajo, se puede solicitar información sobre los recursos consumidos
$ sacct -j <jobid> --format=JobID,JobName,MaxRSS,Elapsed
Para visualizar toda la información de todos los trabajos del usuario
$ sacct -u <nombreusuario> --format=JobID,JobName,MaxRSS,Elapsed
Para recibir un pequeño informe de rendimiento una vez finalizado el trabajo
$ seff <jobid>
Cancelar un trabajo
$ scancel <jobid>
Cancelar los trabajos de un usuario
$ scancel -u <nombreusuario>
Cancelar todos los trabajos pendientes de un usuario
$ scancel -t PENDING -u <nombreusuario>
Cancelar uno o más trabajos por su nombre
$ scancel --name <nombretrabajo>
Detener un trabajo en particular
$ scontrol hold <jobid>
Reanudar un trabajo retenido
$ scontrol resume <jobid>
Volver a encolar un trabajo en particular (cancel y ejecutar)
$ scontrol requeue <jobid>
Para una información más detallada, se puede consultar, a través del comando man de Linux o en internet.