User Tools

Site Tools


cluster

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
cluster [2016/11/21 13:07]
osotolongo [Enviar un email de aviso]
cluster [2020/05/04 10:23]
osotolongo [Paralelizando un archivo de ordenes]
Line 3: Line 3:
 [[https://youtu.be/q5SG7U76tls | Get it started ]] [[https://youtu.be/q5SG7U76tls | Get it started ]]
  
-El cluster (//brick//) consta de momento de tres nodos (//brick01, brick02 y brick03//). Lo que sigue describe la operativa básica para ejecutar tareas en estas maquinas de una manera ordenada+El cluster (//brick//) consta de tres nodos (//brick01, brick02 y brick03//). Lo que sigue describe la operativa básica para ejecutar tareas en estas maquinas de una manera ordenada
  
 {{ ::topologia.png?direct&300 |}} {{ ::topologia.png?direct&300 |}}
Line 188: Line 188:
  
 mas: https://wiki.fysik.dtu.dk/niflheim/SLURM#configure-slurm mas: https://wiki.fysik.dtu.dk/niflheim/SLURM#configure-slurm
-===== HPC::Runner::Slurm (AKA the hat trick) ===== 
  
-[[https://youtu.be/g03JgYdf45I|Super duper love]] 
  
-Hay una forma sencilla de lanzar una lista de scripts utilizando unwrapper escrito en Perl :[[https://metacpan.org/pod/HPC::Runner::Slurm | HPC::Runner::Slurm]]+----
  
-==== Importante: los bricks necesitan los paths ====+**Nota**Todo lo que estaba hecho en Perl, usando HPC, ha dejado de funcionar. Los modulos dan error. NO obstante, los docs estan aqui: [[oldway_cluster|HPC::Runner::Slurm (AKA the hat trick)]]
  
-Para que funcione esto hay que exportar en //detritus// los //paths// de las librerias Perl. Esto es, +----
-al principio de **todo** habria que añadir:+
  
-<code bash> +==== The real life (--multi-prog) ==== 
-export PERL5LIB=$PERL5LIB:/usr/local/perl5/lib + 
-export PATH=$PATH:/usr/local/perl5/bin+[[https://www.youtube.com/watch?v=PstrAfoMKlc|Fighter]] 
 + 
 +Vamos a intentar usar todo esto para algo util. Digamos que queremos ejecutar un programa con diferentes argumentos en los nodos del cluster. Para ello usamos **sbatch** 
 + 
 +<code> 
 +sbatch test.sh
 </code> </code>
-<del>como me ha costao el jodio</del> 
  
-O bien añadir las lineas al //.bashrc// o //.bash_profile// (el que se este usando)+El script //test.sh// no es un programa real sino que es una orden de ejecucion de las tareas.
  
-==== Generalidades ====+<code bash test.sh> 
 +#!/bin/bash 
 +#SBATCH --time=100 
 +#SBATCH --ntasks-per-node=20 
 +#SBATCH -n 50 
 +#SBATCH --mail-type=ALL 
 +#SBATCH --mail-user=osotolongo 
 +srun --exclusive --multi-prog test.conf 
 +</code>
  
-Primeramente ha de hacerse un archivo con la lista de comandos a ejecutar+Este script lo unico que hace es configurar minimamente **sbatch** y lanzar el comando **srun**.  
 +  * La directiva //time// especifica cuantos minutos dejaremos correr el trabajo. Con //--time=0// no se aplica límite de tiempo.  
 +  * Las directivas importantes aqui son //--ntasks-per-node=20// y //-n 50//. La primera dice a **sbatch** que lance 20 tareas en cada nodo, la segunda que hay un total de 50 tareas. para que todo vaya bien n/ntask-per-node < 3. Por ejemplo si ponemos //--ntasks-per-node=10//, entonces dara error porque 50/10=5. //Esto se puede quitar pero si lanzamos 50 tareas las metera todas en brick01 y el ejemplo no servira de nada//. 
 +  * Las directivas //--mail-type=ALL// y //--mail-user=osotolongo// dicen que envie por email todo lo que ocurra al usuario //osotolongo//. Si el usuario de cada uno esta bien configurado, esto deberia funcionar para cada uno con solo cambiar el nombre. 
 +  * El comando **srun** lee el archivo //test.conf// y ejecuta las ordenes que hay dentro de este archivo.
  
 +El archivo //test.conf// tiene la siguiente estructura
 <code> <code>
-job1 +0       test_runner.sh test/blah1.txt 
-job2 +1       test_runner.sh test/blah2.txt 
-job3 +2       test_runner.sh test/blah3.txt 
-job4 +3       test_runner.sh test/blah4.txt 
-# Lets tell slurmrunner.pl to execute jobs5-8 AFTER jobs1-have completed +      test_runner.sh test/blah5.txt 
-wait +5       test_runner.sh test/blah6.txt 
-job5 +. 
-job6 +. 
-job7 +. 
-job8+45      test_runner.sh test/blah46.txt 
 +46      test_runner.sh test/blah47.txt 
 +47      test_runner.sh test/blah48.txt 
 +48      test_runner.sh test/blah49.txt 
 +49      test_runner.sh test/blah50.txt
 </code> </code>
  
-Ahora se envia los comandos a slurm para que los ejecute en los nodos+La primer columna debe numerar las tareas, comenzando en **0** y terminando en **n-1**.La segunda columna no es mas que la orden a ejecutar (en el ejemplo //test_runner.sh//),con todos los argumentos correspondientes (en este caso un nombre de archivo).
  
-<code bash+=== Probando === 
-slurmrunner.pl --infile /path/to/fileofcommands --outdir slurmoutput --jobname slurmjob + 
 +<code> 
 +[osotolongo@detritus cluster]sbatch test.sh  
 +Submitted batch job 842 
 +[osotolongo@detritus cluster]$ squeue 
 +             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON) 
 +               842     debug  test.sh osotolon  R       0:03      3 brick[01-03]
 </code> </code>
  
-==== Ejemplo de paralelizacion basica ==== +El programa a ejecutar es un script sencillo que recibe como argumento un nombre de archivo,
-Supongamos que tenemos un script que ejecuta secuencialmente 22 ordenes, cada una por cada cromosoma,+
  
-<code bash+<code> 
-for i in {1..22}+[osotolongo@detritus cluster]$ cat test_runner.sh  
 +#!/bin/sh 
 +file=$1 
 +count=0 
 +while [ $count -le 10 ]
 do do
-vcftools --gzvcf /nas/marato/1KGP/ALL/chr$i.phase1_release_v3.20101123.snps_indels_svs.genotypes.refpanel.ALL.vcf.gz --snps SNPlist.txt --recode --out HapMap.vcf.chr$i +        echo $count >> $file 
-plink --vcf HapMap.vcf.chr$i.recode.vcf --make-bed --out HapMap.chr$i +        ((count++)) 
-rm HapMap.vcf.chr$i.recode.vcf+        sleep 50
 done done
 +echo Nice! >> $file
 </code> </code>
  
-Para ejecutar estas tareas en el cluster habria que hacer algo como,+y tambien me he escrito un script para que me escriba el //test.conf//,
  
-<code bash+<code> 
-for i in {1..22} +[osotolongo@detritus cluster]$ cat test_generator.sh  
-do +#!/bin/sh 
-echo "vcftools --gzvcf /nas/marato/1KGP/ALL/chr$i.phase1_release_v3.20101123.snps_indels_svs.genotypes.refpanel.ALL.vcf.gz --snps /path/to/file/SNPlist.txt --recode --out /path/to/file/HapMap.vcf.chr$i"; +count=0 
-done > dale.in +while [ $count -lt 50 ]
-echo "wait" >> dale.in +
-for i in {1..22} +
-do +
-echo "plink --vcf /path/to/file/HapMap.vcf.chr$i.recode.vcf --make-bed --out /path/to/file/HapMap.chr$i"+
-done >> dale.in +
-echo "wait" >> dale.in +
-slurmrunner.pl --infile dale.in +
-for i in {1..22}+
 do do
-rm /path/to/file/HapMap.vcf.chr$i.recode.vcf+        cn=$((count+1)) 
 +        echo "$count    test_runner.sh test/blah${cn}.txt" >> test.conf 
 +        ((count++))
 done done
 </code> </code>
-Ojo que,  
-  * <del>el ultimo //wait// lo he puesto para esperar porque termine la ejecucion de todos los //jobs// pero no es imprescindible.</del> 
-  * los //rm// probablemente no sea correcto paralelizarlos pues al ser operaciones a disco deberian ejecutarse mas rapido secuencialmente 
-  * hay que escribir los paths completos de todos los archivos. los //bricks// no tienen idea de donde esta nada! 
  
-==== Ejemplo completo de slurmrunner ==== +Luego, corro primero,
-(// pero minimo //)+
  
-Voy a empezar creando el problemaDigamos que en un directorio tengo unos cuantos archivos y quiero leer su contenido y crear unos archivos nuevos cuyo nombre dependa de ese contenido. Esto es muy basico pero puede ser un buen ejemplo.+<code> 
 +./test_generator.sh 
 +</code>
  
-Primero voy a crear los archivos de trabajo +que me hace el //test.conf// y luego, 
-<code bash> + 
-$ mkdir /nas/osotolongo/cluster +<code> 
-$ cd /nas/osotolongo/cluster +sbatch test.sh
-$ for x in {1..20}; do echo "`shuf -i1-100 -n1`" file"$x".txt; done+
 </code> </code>
  
-De forma que me quedan 20 archivos +Los archivos se generan correctamente, 
-<code bash+ 
-$ ls -l +<code> 
-total 10 +[osotolongo@detritus cluster]$ ls test 
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file10.txt +blah10.txt  blah15.txt  blah1.txt   blah24.txt  blah29.txt  blah33.txt  blah38.txt  blah42.txt  blah47.txt  blah5.txt 
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file11.txt +blah11.txt  blah16.txt  blah20.txt  blah25.txt  blah2.txt   blah34.txt  blah39.txt  blah43.txt  blah48.txt  blah6.txt 
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file12.txt +blah12.txt  blah17.txt  blah21.txt  blah26.txt  blah30.txt  blah35.txt  blah3.txt   blah44.txt  blah49.txt  blah7.txt 
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file13.txt +blah13.txt  blah18.txt  blah22.txt  blah27.txt  blah31.txt  blah36.txt  blah40.txt  blah45.txt  blah4.txt   blah8.txt 
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file14.txt +blah14.txt  blah19.txt  blah23.txt  blah28.txt  blah32.txt  blah37.txt  blah41.txt  blah46.txt  blah50.txt  blah9.txt
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file15.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file16.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file17.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file18.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file19.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file1.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file20.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file2.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file3.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file4.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file5.txt +
--rw-rw---- 1 osotolongo osotolongo 2 Nov 17 18:32 file6.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file7.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file8.txt +
--rw-rw---- 1 osotolongo osotolongo 3 Nov 17 18:32 file9.txt+
 </code> </code>
  
-que contienen cada uno un numero aleatorio entre 1 100.+el contenido es el que debe ser,
  
-<code bash+<code> 
-$ cat file* +[osotolongo@detritus cluster]$ cat test/blah1.txt 
-50 +0 
-25 +1 
-37 +2 
-88 +3 
-51 +4 
-47 +5 
-70 +6 
-84 +7
-16 +
-72 +
-45 +
-14 +
-18 +
-69 +
-29 +
-35+
 8 8
-11 +9 
-50 +10 
-40+Nice!
 </code> </code>
  
-Ahora lo que quiero es leer el contenido de cada archivo y crear un archivo que se llame numberXX.txtsiendo XX el numero que he leido, y que contenga el nombre del archivo original. +Los emails también se envian correctamente,
  
-(// esto es una chorrada pero es ilustrativo //)+{{ ::screenshot_from_2018-09-20_11-45-17.png?nolink |}}
  
-La solucion sequencial es trivial +==== Hard batching ====
-<code bash> +
-$ for x in file*; do y=$(cat ${x}); echo ${x} > number${y}.txt; done +
-</code>+
  
-Pero vamos a suponer que esta tarea consume tiempo y lo que queremos es que esto se haga en los distintos nodosAsi que creamos un archivo con las distintas ordenes+[[https://www.youtube.com/watch?v=86URGgqONvA|Run to the hills]]
  
-<code bash> +El procedimiento anterior funciona OK cuando se lanzan pocas tareas que consuman tiempoSi hemos de lanzar muchas tareas rapidas lo mejor no es usar un solo //srun// con el switch //--multi-prog// sino lanzar un //sbatch// para cada proceso.
-$ for x in file*; do echo "y=\$(cat ${x}); echo "${x}" > number\${y}.txt"; done > dale.in +
-</code>+
  
-de manera que obtengamos estas ordenes+Ahora el //test_generator// es distinto, cada proceso se ejecutara con un sbatch, que hay que construir en un bucle. Luego basta con hacer un ejecutable que lance los //sbatch// consecutivamente
-<code bash> +<code bash test_generator2.sh
-$ cat dale.in  +#!/bin/sh 
-y=$(cat file10.txt); echo file10.txt > number${y}.txt +#Creo los batch a ejecutar 
-y=$(cat file11.txt)echo file11.txt number${y}.txt +count=
-y=$(cat file12.txt); echo file12.txt number${y}.txt +while [ $count -lt 50 ] 
-y=$(cat file13.txt); echo file13.txt number${y}.txt +do 
-y=$(cat file14.txt); echo file14.txt number${y}.txt +        cn=$((count+1)) 
-y=$(cat file15.txt); echo file15.txt > number${y}.txt +        echo "#!/bin/bash" test_run_${cn}.sh 
-y=$(cat file16.txt); echo file16.txt number${y}.txt +        echo "#SBATCH -J test" >test_run_${cn}.sh 
-y=$(cat file17.txt); echo file17.txt > number${y}.txt +        echo "#SBATCH --mail-type=FAIL,TIME_LIMIT,STAGE_OUT" >> test_run_${cn}.sh 
-y=$(cat file18.txt); echo file18.txt number${y}.txt +        echo "#SBATCH --mail-user=`whoami`" >test_run_${cn}.sh 
-y=$(cat file19.txt); echo file19.txt > number${y}.txt +        echo "srun test_runner.sh test/blah${cn}.txt>> test_run_${cn}.sh 
-y=$(cat file1.txt)echo file1.txt > number${y}.txt +        ((count++)
-y=$(cat file20.txt); echo file20.txt number${y}.txt +done 
-y=$(cat file2.txt)echo file2.txt number${y}.txt +#Creo un archivo que ejecute los batch 
-y=$(cat file3.txt); echo file3.txt number${y}.txt +count=
-y=$(cat file4.txt); echo file4.txt number${y}.txt +echo "#!/bin/bash" test.sh 
-y=$(cat file5.txt); echo file5.txt number${y}.txt +while [ $count -lt 50 ] 
-y=$(cat file6.txt); echo file6.txt number${y}.txt +do 
-y=$(cat file7.txt); echo file7.txt > number${y}.txt +        cn=$((count+1)) 
-y=$(cat file8.txt); echo file8.txt number${y}.txt +        echo "sbatch test_run_${cn}.sh" >> test.sh 
-y=$(cat file9.txt); echo file9.txt > number${y}.txt+        ((count++)
 +done 
 +# Creo un script de aviso 
 +echo "#!/bin/bash" mailme.sh 
 +echo "#SBATCH -J test" >> mailme.sh 
 +echo "#SBATCH --mail-type=END" >> mailme.sh 
 +echo "#SBATCH --mail-user=`whoami`" >> mailme.sh 
 +echo "srun :" >> mailme.sh 
 +echo "sbatch --dependency=singleton mailme.sh" >> test.sh 
 +chmod +x test.sh
 </code> </code>
- +**Nota:** Cada proceso se ejecuta independientemente y solo envia emails en caso de fallo, para recibir un aviso cuando se termina la ejecucion es necesario crear y ejecutar un porceso que lo haga y que dependa especificamente de que todos los procesos previos terminen. La forma natural es ejecutarlo con el comando //sbatch --dependency=singleton//, pero ojo que esto se ejecutara cuando todos los procesos con elmismo nombre y bajo el mismo usuario hayan terminado, asi que ha de asignarse a cada proceso el mismo nombre (//swarm//)Si hay que lanzar dos //swarm// diferentes hay que hacerlo con un nombre distinto y correr porque seras condenado a la guillotina por el administrador del clusterOjoque este proceso (que aparece como Dependency bajo //squeue//) en realidad no hace nadasolo manda un email cuando se ejecuta. 
-Esto es precisamente lo que queremos, la variable //$x// se ha interpretado pero la variable //$y// no, esta la queremos averiguar en los nodosAsi, la operacion de ordenar los archivos es secuencial, pero la operacion de hacer algo con esos archivos (que supuestamente es la que consume tiempo) la paralelizamos. +Vamos a probarlo,
- +
-pues vamos a probar, +
- +
-** Primero exporto el //enviroment//, ** +
 <code bash> <code bash>
-export PERL5LIB=$PERL5LIB:/usr/local/perl5/lib +[osotolongo@detritus cluster]./test_generator2.sh  
-export PATH=$PATH:/usr/local/perl5/bin +[osotolongo@detritus cluster]$ ls 
-</code>+mailme.sh     test_run_10.sh  test_run_15.sh  test_run_1.sh   test_run_24.sh  test_run_29.sh  test_run_33.sh  test_run_38.sh  test_run_42.sh  test_run_47.sh  test_run_5.sh  test_runner.sh 
 +test     test_run_11.sh  test_run_16.sh  test_run_20.sh  test_run_25.sh  test_run_2.sh   test_run_34.sh  test_run_39.sh  test_run_43.sh  test_run_48.sh  test_run_6.sh  test.sh 
 +test.conf     test_run_12.sh  test_run_17.sh  test_run_21.sh  test_run_26.sh  test_run_30.sh  test_run_35.sh  test_run_3.sh   test_run_44.sh  test_run_49.sh  test_run_7.sh 
 +test_generator2.sh  test_run_13.sh  test_run_18.sh  test_run_22.sh  test_run_27.sh  test_run_31.sh  test_run_36.sh  test_run_40.sh  test_run_45.sh  test_run_4.sh   test_run_8.sh 
 +test_generator.sh   test_run_14.sh  test_run_19.sh  test_run_23.sh  test_run_28.sh  test_run_32.sh  test_run_37.sh  test_run_41.sh  test_run_46.sh  test_run_50.sh  test_run_9.sh 
 +[osotolongo@detritus cluster]$ cat test_run_1.sh 
 +#!/bin/bash 
 +#SBATCH -J test 
 +#SBATCH --mail-type=FAIL,TIME_LIMIT,STAGE_OUT 
 +#SBATCH --mail-user=osotolongo 
 +srun test_runner.sh test/blah1.txt 
 +[osotolongo@detritus cluster]cat test.sh 
 +#!/bin/bash 
 +sbatch test_run_1.sh 
 +sbatch test_run_2.sh 
 +sbatch test_run_3.sh 
 +sbatch test_run_4.sh 
 +sbatch test_run_5.sh 
 +................... 
 +sbatch test_run_50.sh 
 +sbatch --dependency=singleton mailme.sh
  
-y ahora lanzo los procesos+[osotolongo@detritus cluster]$ ./test.sh  
 +Submitted batch job 15262 
 +Submitted batch job 15263 
 +Submitted batch job 15264 
 +Submitted batch job 15265 
 +Submitted batch job 15266 
 +Submitted batch job 15267 
 +Submitted batch job 15268 
 +...............
  
-<code bash> +[osotolongo@detritus cluster]squeue 
-slurmrunner.pl --infile dale.in --outdir test --jobname test +             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON) 
-Submitting job /nas/osotolongo/cluster/test/001_test.sh +             15312     devel     test osotolon PD       0:00      1 (Dependency) 
- With Slurm jobid 99 +             15262     devel     test osotolon  R       0:03      1 brick01 
-Submitting job /nas/osotolongo/cluster/test/002_test.sh +             15263     devel     test osotolon  R       0:03      1 brick01 
- With Slurm jobid 100 +             15264     devel     test osotolon  R       0:03      1 brick01 
-Submitting job /nas/osotolongo/cluster/test/003_test.sh +             15265     devel     test osotolon  R       0:00      1 brick01 
- With Slurm jobid 101+             15266     devel     test osotolon  R       0:00      1 brick01 
 +....................
 </code> </code>
  
-El sistema ha repartido todos los trabajos entre los nodos y los ha lanzado.+{{::email_done.png|}}
  
-El slurmrunner ha creado el directorio //test// con todo el output. Y por supuesto ha resuelto el problema planteado: 
  
-<code bash> +===== Paralelizando un archivo de ordenes =====
-$ ls +
-dale.in     file12.txt  file15.txt  file18.txt  file20.txt  file4.txt  file7.txt  number11.txt  number18.txt  number35.txt  number45.txt  number51.txt  number72.txt  number8.txt +
-file10.txt  file13.txt  file16.txt  file19.txt  file2.txt   file5.txt  file8.txt  number14.txt  number25.txt  number37.txt  number47.txt  number69.txt  number84.txt  test +
-file11.txt  file14.txt  file17.txt  file1.txt   file3.txt   file6.txt  file9.txt  number16.txt  number29.txt  number40.txt  number50.txt  number70.txt  number88.txt+
  
-$ cat number* +Podemos abstraer todo esto en un script simple para paralelizar las ordenes escritas en un solo archivo.
-file7.txt +
-file20.txt +
-file18.txt +
-file2.txt +
-file11.txt +
-file4.txt +
-file5.txt +
-file12.txt +
-file9.txt +
-file1.txt +
-file15.txt +
-file8.txt +
-file14.txt +
-file3.txt +
-file16.txt +
-file19.txt +
-file17.txt +
-file13.txt +
-file6.txt +
-</code>+
  
-==== Enviar un email de aviso ====+Ejemplo, este script,
  
-Si los procesos que queremos enviar consumen mucho tiempo es bastante incomodo tener que estar comprobando todo el tiempo el estado en que se encuentran. Lo mas practico seria que cuando terminaran los jobs nos enviara un email. Hay una manera de configurar slurm para hacer esto cuando se lanza un //sbatch// pero no he encontrado una manera sencilla de hacerlo con //slurmrunner//. Asi que me he pensado un workaround. +<code perl slurmize.pl>
- +
-El problema es que los jobs se envian a los nodos y la unica manera que ver que esta pasando es utilizando //squeue//. Asi que lo que he hecho es monitorizar que cuando todos los jobs terminen se envíe un email. +
- +
-++++ Tambien esta hecho en bash pero no queda limpio | +
-<code bash> +
-$ cat /nas/software/mail_after_queue.sh +
-#!/bin/sh +
-ARGS='$*' +
-if [ -z "$*" ]; then +
-  ARGS='-' +
-fi +
-msg=$(cat -- $ARGS) +
-u=$(echo $USER | cut -c1-8) +
-a=$(squeue | grep -v JOBID) +
-while [ ! -z "${a// }" ]; do a=$(squeue | grep $u); done +
-if [ ! -z "${msg// }" ]; then echo "${msg}." | mail -s "jobs done" $USER; fi +
-</code> +
-++++ +
- +
-<code perl mail_after_queue.pl>+
 #!/usr/bin/perl #!/usr/bin/perl
-use strict; use warnings+use strict; 
-use Mail::Sender;+use warnings;
  
-sub achtung { +#Cambiar aqui el tiempo maximo de ejecucion 
-        my @adv = @_; +my $time '3:0:0';
-         +
-        my $sender new Mail::Sender {smtp => 'localhost',  +
-        from => "$ENV{'USER'}"}; +
-         +
-        $sender->MailMsg({to => "$ENV{'USER'}", +
-        subject => $adv[0], +
-        msg => $adv[1]}); +
-}+
  
-my @jobs; my $msg+my $ifile = $ARGV[0]; 
-my @slurp <>+my $wdir = 'slurm'; 
-foreach my $line (@slurp) { +mkdir $wdir
- if((my $jobid) = $line =~ m/With Slurm jobid (\d+)/) { +my $count 0
- push @jobs, $jobid+open IPDF, "<$ifile" or die "Could not open input file\n$!\n"; 
- } +while (<IPDF>) { 
- $msg.=$line;+        $count++; 
 +        my $ofile sprintf ("%s_%04d", 'sorder', $count); 
 +        $ofile $wdir.'/'.$ofile; 
 +        open ORD">$ofile"
 +        print ORD '#!/bin/bash'."\n"; 
 +        print ORD '#SBATCH -J '.$ifile."\n"; 
 +        print ORD '#SBATCH -c 8'."\n"; 
 +        print ORD '#SBATCH --mem-per-cpu=4G'."\n"; 
 +        print ORD '#SBATCH --time='.$time."\n"; #si no ha terminado en X horas matalo 
 +        print ORD '#SBATCH --mail-type=FAIL,TIME_LIMIT,STAGE_OUT'."\n"; #que mande email solo cuando falle 
 +        print ORD '#SBATCH --mail-user='."$ENV{'USER'}\n"; 
 +        print ORD '#SBATCH -p fast'."\n"; 
 +        print ORD '#SBATCH -o '.$wdir.'/'.$ifile.'-%j'."\n"; 
 +        print ORD "srun $_\n"; 
 +        close ORD; 
 +        system("sbatch $ofile");
 } }
- +close IPDF; 
-my $list_jobs join(\| ', @jobs)+my $orderfile $wdir.'/'.$ifile.'_end.sh'; 
-my $get_jobs = qx/squeue | grep "$list_jobs"/+open ORD, ">$orderfile"; 
-while($get_jobs)+print ORD '#!/bin/bash'."\n"; 
- $get_jobs = qx/squeue | grep "$list_jobs"/+print ORD '#SBATCH -J '.$ifile."\n"; 
- sleep 10#Esto es para que chequee cada 10 segundos +print ORD '#SBATCH --mail-type=END'."\n"; #email cuando termine 
-} +print ORD '#SBATCH --mail-user='."$ENV{'USER'}\n"; 
- +print ORD '#SBATCH -o '.$wdir.'/'.$ifile.'_end-%j'."\n"; 
-achtung "jobs done", $msg;+print ORD ":\n"
 +close ORD; 
 +my $xorder = 'sbatch --dependency=singleton'.' '.$orderfile; 
 +exec($xorder);
 </code> </code>
  
-El script se usa añadiendolo tras la salida de //slurmrunner//:+lee un archivo de entrada y ejecuta cada linea como una tarea de SLURM. Para esto basta hacer,
  
 <code bash> <code bash>
-slurmrunner.pl --infile dale.in --outdir test --jobname test | /nas/software/mail_after_queue.pl &+$ ./slurmize.pl ordenes.txt
 </code> </code>
-==== Logs y troubleshooting ==== 
  
-Todos los archivos intermedios y los logs estan (segun hemos indicado con //--outdir//) en el directorio //test//+donde //ordenes.txt// es cualquier listado de tareas.
  
-<code bash> +==== ejemplo ==== 
-test/001_test.in +  * Las ordenes deben ejecutarse dentro del directorio /naspara que el sistema de archivos sea accesible a todos los nodos
-test/001_test.sh +  * Escribo las ordenes dentro de un archivo (en este caso //test//) 
-test/002_test.in +  * Ejecuto el script dando como argumento el nombre del archivo de ordenes 
-test/002_test.sh +  * Las tareas seenvian a los nodos del cluster 
-test/003_test.in +  * El output (STDOUT & STDERR) queda dentro del directorio //slurm// en un archivo distinto para cada proceso 
-test/003_test.sh +  * Tambien pueden mirarse los scripts individuales que quedan en el mismo directorio
-test/2016-11-17-001_test/2016-11-17-CMD_001.log +
-test/2016-11-17-001_test/2016-11-17-CMD_002.log +
-test/2016-11-17-001_test/2016-11-17-CMD_003.log +
-test/2016-11-17-001_test/2016-11-17-CMD_004.log +
-test/2016-11-17-001_test/2016-11-17-CMD_005.log +
-test/2016-11-17-001_test/2016-11-17-CMD_006.log +
-test/2016-11-17-001_test/2016-11-17-CMD_007.log +
-test/2016-11-17-001_test/2016-11-17-CMD_008.log +
-test/2016-11-17-001_test/MAIN_2016-11-17.log +
-test/2016-11-17-002_test/2016-11-17-CMD_001.log +
-test/2016-11-17-002_test/2016-11-17-CMD_002.log +
-test/2016-11-17-002_test/2016-11-17-CMD_003.log +
-test/2016-11-17-002_test/2016-11-17-CMD_004.log +
-test/2016-11-17-002_test/2016-11-17-CMD_005.log +
-test/2016-11-17-002_test/2016-11-17-CMD_006.log +
-test/2016-11-17-002_test/2016-11-17-CMD_007.log +
-test/2016-11-17-002_test/2016-11-17-CMD_008.log +
-test/2016-11-17-002_test/MAIN_2016-11-17.log +
-test/2016-11-17-003_test/2016-11-17-CMD_001.log +
-test/2016-11-17-003_test/2016-11-17-CMD_002.log +
-test/2016-11-17-003_test/2016-11-17-CMD_003.log +
-test/2016-11-17-003_test/2016-11-17-CMD_004.log +
-test/2016-11-17-003_test/MAIN_2016-11-17.log +
-test/2016-11-17-slurm_logs/001_test.log +
-test/2016-11-17-slurm_logs/002_test.log +
-test/2016-11-17-slurm_logs/003_test.log +
-test/2016-11-17-slurm_logs/2016-11-17 +
-test/2016-11-17-slurm_logs/process_table.md +
-</code>+
  
-Como puede verse el wrapper ha separado las tareas en grupos que lanza en cada nodo y crea los lanzadores apropiados 
  
 <code bash> <code bash>
-cat test/001_test.in +[osotolongo@detritus slurmit]pwd 
-y=$(cat file10.txt)echo file10.txt > number${y}.txt +/nas/osotolongo/slurmit 
-y=$(cat file11.txt)echo file11.txt > number${y}.txt +[osotolongo@detritus slurmit]$ cat test 
-y=$(cat file12.txt)echo file12.txt > number${y}.txt +sleep 2000;hostname 
-y=$(cat file13.txt); echo file13.txt > number${y}.txt +sleep 2000;hostname 
-y=$(cat file14.txt); echo file14.txt > number${y}.txt +sleep 2000;hostname 
-y=$(cat file15.txt); echo file15.txt > number${y}.txt +[osotolongo@detritus slurmit]$ ./slurmize.pl test 
-y=$(cat file16.txt); echo file16.txt > number${y}.txt +Submitted batch job 129583 
-y=$(cat file17.txt); echo file17.txt > number${y}.txt +Submitted batch job 129584 
-</code>+Submitted batch job 129585 
 +Submitted batch job 129586 
 +[osotolongo@detritus slurmit]squeue | grep test 
 +            129586      fast     test osotolon PD       0:00      1 (Dependency) 
 +            129583      fast     test osotolon  R       0:06      1 brick02 
 +            129584      fast     test osotolon  R       0:06      1 brick02 
 +            129585      fast     test osotolon  R       0:06      1 brick02 
 +[osotolongo@detritus slurmit]tree 
 +
 +├── slurm 
 +│   ├── sorder_0001.sh 
 +│   ├── sorder_0002.sh 
 +│   ├── sorder_0003.sh 
 +│   ├── test-129583 
 +│   ├── test-129584 
 +│   ├── test-129585 
 +│   └── test_end.sh 
 +├── slurmize.pl 
 +└── test
  
-<code bash> +directory9 files
-$ cat test/001_test.sh +
-#!/bin/bash +
-+
-#SBATCH --share +
-#SBATCH --get-user-env +
-#SBATCH --job-name=001_test +
-#SBATCH --output=/nas/osotolongo/cluster/test/2016-11-17-slurm_logs/001_test.log +
-#SBATCH --cpus-per-task=4 +
-#SBATCH --time=04:00:00 +
-cd /nas/osotolongo/cluster +
-mcerunner.pl --procs 4 --infile /nas/osotolongo/cluster/test/001_test.in --outdir /nas/osotolongo/cluster/test --logname 001_test --process_table /nas/osotolongo/cluster/test/2016-11-17-slurm_logs/process_table.md --metastr '{"command_count":"1-8","job_batches":"1/3","batch":"1","batch_count":"1/3","commands":8,"total_batches":"3","total_processes":"20","jobname":"test"}' +
-</code>+
  
-Tambien hay una lista de los jobs enviados 
-<code bash> 
-$ cat test/2016-11-17-slurm_logs/2016-11-17 
-2016/11/17 18:50:07: DEBUG Submitted batch job 99 
- 2016/11/17 18:50:07: DEBUG Submitted batch job 100 
- 2016/11/17 18:50:07: DEBUG Submitted batch job 101 
 </code> </code>
  
-y de informacion sobre los procesos 
-<code bash> 
-$ cat test/2016-11-17-slurm_logs/process_table.md 
-### y=$(cat file10.txt); echo file10.txt > number${y}.txt 
-|122914|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 00 seconds| 
-### y=$(cat file11.txt); echo file11.txt > number${y}.txt 
-|122915|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 00 seconds| 
-### y=$(cat file12.txt); echo file12.txt > number${y}.txt 
-|122916|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 00 seconds| 
-### y=$(cat file13.txt); echo file13.txt > number${y}.txt 
-|122917|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file14.txt); echo file14.txt > number${y}.txt 
-|122926|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file15.txt); echo file15.txt > number${y}.txt 
-|122927|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file16.txt); echo file16.txt > number${y}.txt 
-|122930|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds 
-### y=$(cat file18.txt); echo file18.txt > number${y}.txt 
-|65217|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file20.txt); echo file20.txt > number${y}.txt 
-|65220|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file17.txt); echo file17.txt > number${y}.txt 
-|122931|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file2.txt); echo file2.txt > number${y}.txt 
-|65229|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file3.txt); echo file3.txt > number${y}.txt 
-|65230|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file5.txt); echo file5.txt > number${y}.txt 
-|65236|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file4.txt); echo file4.txt > number${y}.txt 
-|65233|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file9.txt); echo file9.txt > number${y}.txt 
-|122991|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file8.txt); echo file8.txt > number${y}.txt 
-|122990|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file6.txt); echo file6.txt > number${y}.txt 
-|122988|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-### y=$(cat file7.txt); echo file7.txt > number${y}.txt 
-|122989|0|0 years, 00 months, 0 days, 00 hours, 00 minutes, 01 seconds| 
-</code> 
- 
-y un monton de logs con la salida (incluyendo //warnings// y //errors//) que deberia permitir ver con una inspeccion rapida si algo ha salido mal y que es 
- 
-==== Docs ==== 
-Mas info en, 
-  * https://metacpan.org/pod/HPC::Runner::Slurm 
-  * https://metacpan.org/pod/HPC::Runner::Scheduler 
-  * https://metacpan.org/pod/distribution/HPC-Runner-Scheduler/lib/HPC/Runner/Usage.pod 
- 
-===== Ejemplo de Begonia ===== 
-<code bash> 
-[bego@detritus bego]$ cat script_GWAS.hapmap.slurm  
-#!/bin/bash 
- 
-dirFICHEROSCOMUNES=/nas/marato/ARIC2/FicherosComunes 
-db_name=SHARE_MESA_c1_LVH_founders 
-name=MESA 
-dirwork=/nas/marato/MESA/QC/bego 
- 
-### Step 1.5 PCA con HapMap (db + HapMap) 
-#Preparo lista de SNPs de DB 
-#Las selecciono por cromosoma de la referencia de HapMap de 1000G 
- 
-for i in {1..22} 
-do 
-echo "vcftools --gzvcf /nas/marato/1KGP/ALL/chr$i.phase1_release_v3.20101123.snps_indels_svs.genotypes.refpanel.ALL.vcf.gz --snps ${dirwork}/SNPlist.txt --recode --out ${dirwork}/HapMap.vcf.chr$i"; 
-done > ${dirwork}/vcftools.script 
-echo "wait" >> ${dirwork}/vcftools.script 
- 
-for i in {1..22}  
-do 
-echo "plink --vcf ${dirwork}/HapMap.vcf.chr$i.recode.vcf --make-bed --out ${dirwork}/HapMap.chr$i"; 
-done >> ${dirwork}/vcftools.script 
-echo "wait" >> ${dirwork}/vcftools.script 
- 
-for i in {1..22} 
-do 
-echo "rm ${dirwork}/HapMap.vcf.chr$i.recode.vcf"; 
-done >> ${dirwork}/vcftools.script 
-echo "wait" >> ${dirwork}/vcftools.script 
- 
-slurmrunner.pl --infile ${dirwork}/vcftools.script --outdir ${dirwork}/Slurm_Output_gwas1 -jobname gwas1_bh 
- 
-</code> 
- 
-**Esto no funcionara nunca!** 
-//jajaja// 
-<code bash> 
-for i in {2..22} 
-do 
-echo "${dirwork}/HapMap.chr$i.bed ${dirwork}/HapMap.chr$i.bim ${dirwork}/HapMap.chr$i.fam >> ${dirwork}/ListaArchivos.txt"; 
-done >> ${dirwork}/vcftools.script 
-echo "wait" >> ${dirwork}/vcftools.script 
-</code> 
- 
-==== Pendiente: Slurm templates===== 
- 
-<code> 
-#SBATCH --get-user-env 
-#SBATCH --mail-type=END,FAIL      # notifications for job done & fail 
-#SBATCH --mail-user=myemail@harvard.edu # send-to address 
-</code> 
cluster.txt · Last modified: 2020/08/04 10:58 (external edit)