J'ai un script R qui fait une évaluation comparative de méthodes l'apprentissage (RF, KNN, SVM) sur des jeux de données RNA-seq, en parallélisant les tests avec la librairie R doParallel. Les analyses prennent pas mal d'heures.
Précédemment, j'ai utilisé R sous sinteractive pour lancer les tâches une par une, et je voudrais maintenant tout lancer sur srun.
Ca tourne, mais contrairement à ce que je croyais, srun reste bloqué, et je ne sais donc pas ce qui se passera si je ferme ma session ssh, ou si je me fais éjecter.
Quelle serait la façon correcte d'envoyer un job à slurm pour pouvoir ensuite quitter la session ssh et revenir voir toutes les quelques heures où en sont les fichiers de log (error, output) ?
Je pense qu'il serait préférable d'utiliser sbatch pour ce besoin. sbatch va te permettre de soumettre l'execution d'un script au cluster et ne nécessite pas que tu maintiennes ta connexion SSH active.
Voici comment procéder :
Tout d'abord écrit un petit script pour lancer ton traitement (par exemple my_processes.sh) :
#!/bin/bash
module load r
srun misc/main_processes.R
srun te permet de marquer (et paramétrer) une étape de ton job (un job step)
A présent il te suffit de lancer ce script avec sbatch :
$ sbatch my_processes.sh
En retour tu obtiendras un numéro de job.
Slurm va automatiquement créer un fichier de sortie pour ton job de la forme slurm_xxxxx.out ou xxxxx est l'identifiant de ton job dans ton répertoire courant.
Tu peux ensuite surveiller l'activité de ton job à l'aide des commandes squeue, sacct ou sstat.
J'ai lancé la deuxième analyse séparément (en relançant sbatch sur le script bash mais avec le second cas d'étude). J'ai maintenant 2 jobs qui tournent, mais sur le même noeud (82).
(base) [jvanhelden@cpu-node-82 ~]$ squeue -u jvanhelden
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
3147815 fast srun_ana jvanheld R 40:25 1 cpu-node-82
3147822 fast srun_ana jvanheld R 10:54 1 cpu-node-82
Je devrais lancer une douzaine de cas d'étude, et chacun mobilise 26 coeurs (je parallélise avec la librairie R doParallelize). J'imagine que ce ne sera pas formidable si sbatch envoie tout sur le même noeud. Est-ce que je devrais utiliser des options quand je lance srun pour indiquer qu'il faut réserver 26 coeurs ?
Bref: comment faire pour lancer 12 jobs qui chacun mobilisent 26 coeurs ?
Je ne suis pas sûr d'avoir bien saisi si tu souhaites lancer les deux analyses en parallèle ou si les analyses sont séquentiels.
Les deux sont possibles bien entendu, mais il faudra prévoir le double de RAM si les analyses doivent être lancé en parallèle.
Quelques remarques :
sbatch permet de créer un job alors que srun va te permettre de définir un job step (une étape de ton job) en utilisant tout ou parti des ressources réservées pour le job.
par défaut srun utilise l'ensemble des ressources disponibles pour le job, ainsi si tu as besoin de toute la RAM réservée pour le job, il n'est pas nécessaire de préciser une quantité de RAM à srun
Les srun n'étant pas des jobs, tu n'obtiendras pas de numéro de jobs pour les 2 étapes de ton scripts mais uniquement un numéro d'identifiant pour l'ensemble du job. Tu peux suivre ensuite via sacct l'avancé de chaque job step (voir ci-dessous).
Il n'est pas nécessaire de créer 2 scripts. En effet, dans tout job SLURM, il existe un job step "batch" qui te permet de faire des initialisations ou des paramétrages. Il suffit de ne pas utiliser la commande srun devant tes commandes d'initialisation pour qu'elle soit associé au job step batch.
Voici un script unique qui réalise tes deux traitements de manière séquentielle :
Effectivement je désire lancer les jobs en parallèle. Ou plus précisément, je désire placer mes 12 jobs dans une queue, et qu'ils soient exécutés quand c'est possible en fonction de la disponibilité des noeuds, sachant sont complètement indépendants les uns des autres. En gros je cherche la simple fonctionnalité de qsub dans PBS ou SGE : soumettre une série de jobs indépendants à un gestionnaire de jobs, puis pouvoir suivre leur exécution.
Chacun des jobs demande pas mal de mémoire car il y fait tourner 50 répétitions d'un test sur un algo de classification supervisée (SVM, Random Forest ou KNN). Pour ne pas y passer des semaines, je parallélise les 50 répétitions avec la librairie R doParallel qui permet d'exécuter une boucle foreach en parallèle. Je ne sais pas comment il fait en pratique, j'ai l'impression que ça s'apparente à des files (threads) mais je ne suis pas sûr.
Bref, au moment d'envoyer mes jobs en queue, je voudrais m'assurer qu'ils aient suffisamment de mémoire, mais aussi qu'on leur réserve 50 coeurs (j'avais limité à 26 car les machines en ont apparemment 32).
Tu peux au choix écrire un petit script qui va lancer 12 sbatch ou alors utiliser le mécanisme des jobs array de SLURM.
Les jobs arrays permettent de lancer un même script n fois en faisant varier la valeur d'un index. On peut alors utiliser l'index pour choisir les fichiers à passer en entrée de l'analyse ou pour faire varier les paramètres.
Je te donne ci-dessous un exemple de script utilisant le mécanisme des jobs arrays à adapter à tes besoins :
#!/bin/bash
#SBATCH --array=1-12 # nous demandons ici à SLURM de créer 12 jobs (notre script sera lancé 12 fois)
#SBATCH --cpus=50 # nous demandons 50 cpus
#SBATCH --mems=32GB # nous réservons 32Go par job
#SBATCH -o analysis-%j-%a_out.txt # fichier de sortie standard du job
#SBATCH -e analysis-%j-%a_err.txt # fichier de sortie d'erreur du job
## Initiate the environment
module load conda
conda init bash
conda activate rnaseqmva
## La variable $SLURM_ARRAY_TASK_ID prendra une valeur différente (1 à 12) pour chaque job
srun Rscript --vanilla misc/main_processes.R $SLURM_ARRAY_TASK_ID
On lance le script avec sbatch qui se chargera de lancer les 12 jobs :
$ sbatch my_analysis.sh
La plupart des noeuds dispose de 52 CPUs (nous avons activé l'hyperthreading récemment), ainsi les jobs devrait occuper 12 noeuds. Cependant, la limite actuelle est de 400 CPUs par utilisateur à un instant donné, ainsi tu verras au maximum 7 jobs (364 cpus) en parallèle.
Mais comment fais-je pour fournir les paramètres qui correspondent à chaque valeur de SLURM_ARRAY_TASK_ID ? Avec ton exemple j'obtiens des valeurs de 1 à 12, alors que je voudrais pouvoir combiner deux paramètres
Tiens, l'université de Michigan a un tuto sur l'utilisation de R avec Slurm sur leur cluster. Ils ont développé un package interne pour faciliter la gestion des jobarrays à partir de R.
Ca ne répond toujours pas à ma question concernant la façon de gérer une combinaison de paramètres avec des valeurs numériques, mais ça me ramène à ma proposition de faire un tuto spécifique pour R avec Slurm sur le cluster IFB-core (échanges avec @dbenaben), avec un ou deux exemples réalistes complets (sur le site umich ils fournissent juste des morceaux de script, on doit ensuite imaginer comment combiner tout cela) qui éviterait à d'autres usagers de se casser la tête.
Mais avant cela il faut trouver la façon la plus correcte de procéder.
squeue -u $UID
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
3148928_[10-13] fast srun_job jvanheld PD 0:00 1 (QOSMaxCpuPerUserLimit)
3148928_0 fast srun_job jvanheld R 3:21 1 cpu-node-10
3148928_2 fast srun_job jvanheld R 3:21 1 cpu-node-7
3148928_4 fast srun_job jvanheld R 3:21 1 cpu-node-9
3148928_5 fast srun_job jvanheld R 3:21 1 cpu-node-11
3148928_6 fast srun_job jvanheld R 3:21 1 cpu-node-12
3148928_7 fast srun_job jvanheld R 3:21 1 cpu-node-13
3148928_9 fast srun_job jvanheld R 0:49 1 cpu-node-6
3148928_8 fast srun_job jvanheld R 0:52 1 cpu-node-8
Par contre j'ai un de mes jobs précédents qui s'est arrêté au bout de 24h car il avait dépassé le temps imparti. Est-ce que je peux lancer cela sur la queue "long" ? Comment ?
Y a-t-il une pénalité à utiliser cette queue (moins de noeuds/cpu en même temps) ?