Exemples de soumission

Script de soumission

Il est possible de spécifier des options de soumission directement dans un script utilisant la syntaxe suivante :

#!/bin/sh

# SLURM options:

#SBATCH --job-name=serial_job_test    # Job name
#SBATCH --output=serial_test_%j.log   # Standard output and error log

#SBATCH --partition=htc               # Partition choice
#SBATCH --ntasks=1                    # Run a single task (by default tasks == CPU)
#SBATCH --mem=3000                    # Memory in MB per default
#SBATCH --time=1-00:00:00             # 7 days by default on htc partition

#SBATCH --mail-user=<email address>   # Where to send mail
#SBATCH --mail-type=END,FAIL          # Mail events (NONE, BEGIN, END, FAIL, ALL)

# Commands to be submitted:

module load python
python my_python_script.py

Dans cet exemple, on met en place un environnement Python via modules afin d’exécuter my_python_script.py. L’ensemble des options Slurm sont passées via des directives #SBATCH, et ce script pourra simplement être soumis comme suit :

% sbatch my_script.sh

Script à tâches multiples

Des tâches de calcul en srun peuvent aussi être lancées de l’intérieur du script, pourvu que les ressources déclarées par les lignes #SBATCH se soient pas dépassées. Par exemple :

#!/bin/sh

#SBATCH --job-name=mulitple_jobs

#SBATCH --ntasks=2
#SBATCH --output=mulitple_jobs_%j.log
#SBATCH --licenses=sps

####################################
srun -n 1 --exclusive -L sps script_sps.sh &
srun -n 1 --exclusive script_software.sh &
srun -n 1 --cpus-per-task 2 script_software.sh
wait

L’option --exclusive permet à la tâche de ne pas partager la ressource. La syntaxe bash permet de:

  • & : lancer les tâches en parallèle; si une tâche ne trouve pas de ressource disponible, elle reste en attente et un message de warning est écrit sur le output,
  • wait : attendre que toutes les tâches soient terminées avant de sortir du script.

Dans le cas où la tâche soumise est un script exécutant des processus en paralèlle, alors il faut préciser le nombre de cpus par tâches :

#! /bin/bash

#SBATCH --ntasks=4 #run max 4 parallel tasks and allocate 4 CPUs
#SBATCH --cpus-per-task=4

my_parallel_script.sh

sinon, tous les sous-processus lancés par my_parallel_scirpt.sh ne s’exécuteront que sur un seul CPU.

Job mono-cœur

La soumission d’un job monocœur se fait simplement avec la commande suivante :

% sbatch my_script.sh

Le job sera alors exécuté dans la partition définie par défaut, i.e. htc et avec la QoS par défaut, i.e. normal.

Si l’on souhaite accèder à une ressource nécessitant la déclaration, on utilisera l’option -L :

% sbatch -L sps my_script.sh

Job multi-cœurs

La soumission d’un job multi-cœurs se fait comme précédemment, mais en précisant le nombre de cœurs requis à la ligne de commande :

% sbatch -n 8 my_script.sh
-n <nombre>
spécifie le nombre de coeurs alloués pour my_script.sh.

Job interactif

La soumission d’un job interactif se fait via la commande srun et l’on doit préciser la partition adéquate.

% srun -p htc_interactive --pty bash -i         # mono-cœur

% srun -p htc_interactive -c <N> --pty bash -i  # multi-cœurs (N taches)

% srun -p gpu_interactive --gres=gpu:[type]:1 --pty bash -i        # GPU
-p
sélectionne la partition
--gres=
permet de spécifier l’utilisation d’une ressource GPU, et de la définir.
--pty
autorise l’interactivité avec la session ouverte (voir note précédente).

Afin de quitter sa session interactive, faire :

% exit

Job parallèle (MPI)

Il s’agit de jobs qui exécutent des opérations en parallèle, possiblement sur des serveurs de calcul différents, en utilisant une interface de type MPI à travers une connectique InfiniBand. Il faut préciser la partition hpc :

% sbatch -p hpc -n 8 -N 2 my_script.sh
-N <nombre>
spécifie le nombre de serveurs de calcul requis

Note

Dans le cas où le nombre de serveurs de calcul (option -N) est 1, il n’est pas nécessaire de l’indiquer, ni de spécifier la partition.

Job GPU

Ce sont des jobs qui s’exécutent sur des serveurs de calcul équipés de GPUs. Ils peuvent être multi-cœurs, parallèles, et interactifs. La soumission de tels jobs doit se faire sur la partition dédiée, i.e. gpu :

% sbatch -p gpu --gres=gpu:1 my_script.sh

Ici, on demande l’allocation d’un seul GPU, mais il est possible d’en utiliser plusieurs.

Un seul type de GPUs est disponible actuellement au CC-IN2P3 : Nvidia V100, identifié par le mot clé v100. Le type peut etre demandé en paramètre de --gres :

--gres=gpu:v100:1

Utiliser CUDA

Si vous devez utiliser des bibliothèques CUDA spécifiques, précisez dans votre script:

  • bash

    if! echo $ {LD_LIBRARY_PATH} | /bin/grep -q /usr/local/cuda-11.3/lib64 ; then
           LD_LIBRARY_PATH=/usr/local/cuda-11.3/lib64:${LD_LIBRARY_PATH}
    fi
    
  • csh

    if ($?LD_LIBRARY_PATH) then
           setenv LD_LIBRARY_PATH /usr/local/cuda-11.3/lib64:${LD_LIBRARY_PATH}
    else
           setenv LD_LIBRARY_PATH /usr/local/cuda-11.3/lib64
    endif
    

Important

Plusieurs environnements CUDA sont disponibles, et sont régulièrement mis-à-jour. La version courante des pilotes Nvidia est 465.19.01 ; la version CUDA par défaut est 11.3 et cudnn est 8.2.0.

Pour compiler votre code CUDA, vous devriez vous connecter sur un serveur GPU interactif et utiliser le compilateur nvcc :

% /usr/local/cuda-11.3/bin/nvcc

Une fois le code compilé, nous vous conseillons de sortir du serveur interactif et soumettre vos jobs avec sbatch.

Job récursif

Pour les jobs de longue durée à petite consommation de ressources (type job démon), la limite de 7 jours peut être contournée avec un job récursif qui se re-soumet lui-même et reste en queue tant que le premier job ne disparait pas. La ligne de commande ci-dessous doit être écrite à l’intérieur du script du job lui-même, de préférence au début du script.

sbatch --dependency=afterany:$SLURM_JOBID job.sh

$SLURM_JOBID étant l’identifiant du job en cours depuis lequel le job est lancé.

Enchaînement de jobs

Il est possible d’utiliser la notion de dépendance de Slurm pour bâtir un enchaînement (pipeline) de jobs basé sur la réalisation de conditions spécifiques :

% sbatch --dependency=<type:job_id[:job_id][,type:job_id[:job_id]]> my_script.sh

Avec les types de dépendances suivants :

after:jobid[:jobid...]
exécution possible après qu’un ou plusieurs jobs donnés (identifiés par leurs identifiants) aient été démarrés
afterany:jobid[:jobid...]
exécution possible après qu’un ou plusieurs jobs donnés soient terminés
afternotok:jobid[:jobid...]
exécution possible après qu’un ou plusieurs jobs donnés aient échoués
afterok:jobid[:jobid...]
exécution possible après qu’un ou plusieurs jobs donnés se soient terminés avec succès (code retour de 0)
singleton
exécution possible après que tous les jobs d’un même nom appartenant au même utilisateur se soient terminés.

Un exemple de construction d’un tel enchaînement est donné sur cette page.