Comment optimiser les ressources pour aligner des génomes humain?

Bonjour à tous,

C'est la première fois que je vais faire les alignements de génomes sur un nombre important de génomes et du coup je ne sais pas trop comment optimiser les ressources demandées pour que ça ne prenne pas un temps fou...

Précision: je travaille sur le cluster de l'igbmc @team.igbmc

J'ai 74 génomes humains à aligner. Chaque génome à été séquencés sur 4 lignes différentes et en paired end donc je me retrouve avec 74 * 4 * 2 = 592 fastq. J'ai également 296 petits fastq correspondants au reads unpaired quand l'un des read d'une paire à passer le contrôle qualité et pas l'autre.

J'utilise BWA mem.

Normalement je pipe directement le résultat de BWA mem dans samtools view puis dans samtools sort pour obtenir le bam trié.

Pour paralléliser les taches, je fais normalement un script sbatch dans lequel je mets une boucle avec un srun.

Par exemple, pour fastq_screen ça donne quelque chose de ce genre :

for i in $(ls $FASTQ_DIR/*fastq*)
do
srun --ntasks=1 fastq_screen --conf $fastq_screen_dir_script/FastQ_Screen_Genomes/fastq_screen.conf --outdir $fastq_screen_outdir/ $i &
done

wait

avec dans les options sbatch --ntasks=8 et --cpus-per-task=8 ce qui permettait de traiter 8 fichiers d'un coup avec 8 cpus par traitement.

Sauf que dans cet exemple tout tient sur un seul noeud. Pour des alignements de génomes, il va falloir utiliser plusieurs noeuds, je pense.

En résumé: si quelqu'un peut me dire la meilleure combinaison nombre de cpu, quantité de ram, nombre de taches en parallèles, nombre de noeuds, pour que ça puisse tourner de manière raisonnable.
Merci :slight_smile:

On m'a conseillé de faire une boucle qui lance un sbatch par alignment pour laisser slurm gérer. Mais je me demande si je fais ça, ça ne risque pas de bloquer toutes les ressources disponibles jusqu'à ce que mes alignments soient finis ? Slurm gère l'allocation par ordre chronologique? Si c'est le cas il va devoir traiter tous mes sbatch en attente avant de pouvoir traiter les jobs de gens qui auraient lancé après ?

Bonjour Quentin,

Comme souvent, il y a plusieurs façon de faire.

J'aurais aussi tendance à réaliser un job par alignement.

D'une manière très générale, je privilégie toujours les "petits" jobs (en termes de CPU, RAM ou temps d’exécution). Plus les jobs sont "petits" plus les jobs partiront facilement.

On peut tout à fait imaginer une boucle qui lance un sbatch par alignement (juste faire un "sleep 1s" entre chaque lancement pour ne pas saturer).

Mais il est aussi possible d'utiliser un "Job Array" pour lancer tous ses jobs.
Plus d'information ici: Slurm advanced guide - IFB Core Cluster Documentation
Exemple avec plusieurs fichiers fastq: Slurm Cookbook - IFB Core Cluster Documentation
Le job array permets de plus de lancer tous ses jobs d'un seul coup mais de limiter le nombre de job exécuté simultanément (option %).

Slurm gère les jobs et leurs priorités.
Suivant la configuration du cluster, plusieurs paramètres peuvent rentrer en jeu: le nombre de CPU demandé, le temps d'attente déjà écoulé, le nombre d'heures CPU déjà consommés, le "backfilling", etc.
Ainsi, l'ordre de lancement des jobs n'est pas forcément l'ordre d'arrivé chronologique.

Slurm modère ainsi l'usage du cluster.
Il existe par exemple une limite pour éviter qu'un seul utilisateur lance simultanément des milliers de jobs et sature le cluster.
Au-delà de cette limite, les jobs sont mis en attente et envoyé dès qu'un autre de ses jobs se termine (pour rester dans la limite).
On peut avoir cette limite avec la commande sacctmgr list qos. Elle est de "500" (MaxSubmitJobsPerUser) sur l'IFB Core Cluster.

Exemple (commande sacctmgr)
$ sacctmgr list qos format=name,Description,MaxSubmitJobsPerUser
      Name                Descr MaxSubmitPU 
---------- -------------------- ----------- 
    normal   Normal QOS default         500 
    bigmem               bigmem             
    galaxy               galaxy             
 unlimited            unlimited

Il y a donc peu de risque de saturer un cluster (un cluster est par essence fait pour être "saturé").
Mais il est évidemment préférable de connaître la politique et la configuration du site.

N'hésitez pas à nous indiquer ici même votre solution.

Bon après-midi

Bonjour,

Au final après reflexion ce week end je pense partir sur un array du genre #SBATCH --array 1-296%10

Et mettre un fichier avec par exemple deux colonnes, une colonne avec le chemin du read1 et une colonne avec le chemin du read2 et faire:

samplesheet=name_of_file_with_fastq_path.txt
r1=`sed -n "$SLURM_ARRAY_TASK_ID"p $samplesheet |  awk '{print $1}'` 
r2=`sed -n "$SLURM_ARRAY_TASK_ID"p $samplesheet |  awk '{print $2}'`

bwa mem -t 10 ref.fa $r1 $r2 | samtools sort -@ 4 > .bam

De cette manière il sera très facile de relancer les éventuels jobs qui n'aurait pas marché
(Pour plus de clarté je n'ai pas mis le code entier avec les read groups et autres options).

1 J'aime