Cómo Ejecutar Trabajos en Slurm#
Lanzar una Ejecución#
Existen tres métodos principales para lanzar trabajos en Slurm: sesiones interactivas, ejecución de trabajos en tiempo real, y envío de trabajos mediante scripts. Cada método requiere especificar los recursos necesarios.
Ejecución de Sesión Interactiva#
Usando el comando salloc
, Slurm proporcionará al usuario un nodo de cálculo donde, de manera interactiva, el usuario puede trabajar y ejecutar cualquier software necesario. Esta es una opción muy útil para probar nuevo software o nuevos datos para trabajar, sin la necesidad de lanzar trabajos a la cola, con el riesgo de que fallen tan pronto como comiencen.
Solicitar un único núcleo:
Aviso
Los parámetros predeterminados asignados por slurm son:
Solicitar múltiples núcleos:
En este comando, estamos solicitando acceso exclusivo a un nodo entero, asumiendo que el nodo dispone de 16 núcleos. Este tipo de solicitud es particularmente útil para tareas que requieren una gran cantidad de memoria y recursos de CPU, permitiendo que la aplicación aproveche completamente los núcleos del nodo sin compartirlos con otros trabajos. Esta configuración maximiza el rendimiento para cargas de trabajo intensivas en cálculo o memoria.
Solicitar un nodo de una partición particular, con un nombre de trabajo y una duración determinada:
Información
Después de asegurar los recursos, podrías ver un mensaje como:
Y cuando el trabajo comienza:
Toma nota!
Una vez que tenemos un nodo vía `salloc`, podemos, desde otro terminal, acceder a ese nodo vía **SSH** para tener varias sesiones abiertas en el mismo nodo y trabajar en múltiples cosas al mismo tiempo.
Saliendo de la sesión:
Una vez que salimos del nodo desde el terminal donde hicimos salloc
, Slurm liberará el nodo y el trabajo se marcará como completado. Obviamente, una vez que salimos, todas las sesiones adicionales que hayamos abierto vía SSH se cerrarán automáticamente.
Ejecutando un Trabajo en Tiempo Real#
Usa el comando srun
para lanzar un trabajo directamente en la cola:
Este comando envía directamente un trabajo solicitando 16 núcleos, lo cual es útil para aplicaciones que necesitan procesamiento paralelo.
Más opciones disponibles:
Nombre | Dirección IP |
---|---|
-p <partition> | partición en la que se ejecutarán los trabajos |
-N <nodes> | número de nodos |
-n=<num_tasks> | número de tarea |
--tasks-per-node=<number> | tarea por nodo (considerar -N) |
-J <job_name> | nombre del trabajo |
-t <days-HH:MM:SS> | tiempo esperado |
-d=<type:job_id[:job_id]> | tipo de dependencia del trabajo y id de dependencia (opcional) |
-o </path/to/file.out> | archivo para stdout (flujo de salida estándar) |
-e </path/to/file.out> | archivo para sterr (flujo de error estándar) |
-D <directory> | directorio predeterminado para ejecución |
--mail-user=<email> | email para notificaciones de slurm |
--mail-type=<eventos> | lista de eventos para notificaciones |
Ejecutar en SLURM vía un script#
El comando sbatch
envía un trabajo a la cola para ser ejecutado por uno o más nodos, dependiendo de los recursos que se hayan especificado.
La estructura más básica para un script es la siguiente:
#!/bin/bash
#SBATCH -J <job_name>
#SBATCH -p <partition>
#SBATCH -N <nodes>
#SBATCH --tasks=<number>
#SBATCH --cpus-per-task=<number>
#SBATCH --constraints=<node architecture> # sandy, ilk (icelake)... architecture
#SBATCH -t <days-HH:MM:SS>
#SBATCH -o <file.out>
#SBATCH -D .
#SBATCH --mail-user=<email_account>
#SBATCH --mail-type=BEGIN,END,FAIL,TIME_LIMIT_50,TIME_LIMIT_80,TIME_LIMIT_90
##########################################################
module purge
module load <modules>
srun <application>
Diferencia Entre los Parámetros de CPU#
--cpus-per-task: Especifica el número de CPUs (núcleos) que se asignarán a cada tarea. Se utiliza cuando una tarea requiere más de un CPU para funcionar, como en aplicaciones que pueden utilizar multihilo o paralelismo a nivel de hilo.
--ntasks: Define el número total de tareas que se ejecutarán en el trabajo. Cada tarea es una instancia separada del programa que estás ejecutando. Se usa principalmente para la paralelización a nivel de tareas, como en programas que utilizan MPI (Interfaz de Paso de Mensajes).
--ntasks-per-node: Determina cuántas tareas se ejecutarán en cada nodo. Esto es útil cuando se desea controlar cómo se distribuyen las tareas entre los nodos asignados. A menudo se usa en conjunto con ntasks para asegurar una distribución específica de tareas por nodo.
Ejemplo#
Objetivo#
Deseas ejecutar un total de 8 tareas de tu aplicación, donde cada tarea utilizará 4 núcleos. Quieres distribuir estas tareas en 2 nodos.
Script de Slurm#
Este script configura Slurm para ejecutar un programa que se beneficia de la paralelización tanto a nivel de tarea como a nivel de hilo:
#!/bin/bash
#SBATCH -J ejemplo_paralelismo
#SBATCH -p batch # Partición batch
#SBATCH -N 2 # Solicitando 2 nodos
#SBATCH --ntasks=8 # Total de 8 tareas a ejecutar
#SBATCH --ntasks-per-node=4 # Distribuir 4 tareas por nodo
#SBATCH --cpus-per-task=4 # Cada tarea utilizará 4 CPUs (núcleos)
#SBATCH --time=01:00:00 # Límite de tiempo de una hora
#SBATCH -o resultado_%j.out # Salida estándar
#SBATCH -e errores_%j.err # Errores estándar
module load mi_modulo # Cargar los módulos necesarios
srun mi_aplicacion # Ejecutar la aplicación
Explicación del Script#
--ntasks=8: Este parámetro establece que el trabajo consistirá en 8 tareas independientes. En el contexto de MPI, podrías pensar en esto como lanzar 8 procesos distintos.
--ntasks-per-node=4: Indica que cada nodo asignado al trabajo deberá ejecutar 4 de estas tareas. Dado que has solicitado 2 nodos y quieres ejecutar 8 tareas en total, cada nodo manejará 4 tareas.
--cpus-per-task=4: Especifica que cada tarea debe utilizar 4 núcleos. Esto es útil para tareas que pueden ejecutar hilos de manera concurrente, aprovechando la paralelización a nivel de hilo dentro de cada tarea.
Resultado Esperado#
Con esta configuración, el sistema de Slurm distribuirá el trabajo en los 2 nodos disponibles, colocando 4 tareas en cada uno, y cada tarea utilizará 4 núcleos de CPU en el nodo asignado. Esto puede resultar en un uso eficiente del hardware disponible, maximizando el rendimiento del programa que se beneficia tanto de la paralelización a nivel de tarea como de hilo.