Diferencia entre revisiones de «SISTEMA GESTOR DE RECURSOS»

De NLHPC
Sin resumen de edición
 
(No se muestran 107 ediciones intermedias de 3 usuarios)
Línea 28: Línea 28:
<td><b>RAM</b></td>
<td><b>RAM</b></td>
<td><b>Descripción</b>
<td><b>Descripción</b>
</td></tr>
<tr>
<td>main</td>
<td>27</td>
<td>256</td>
<td>768GB</td>
<td>
</td></tr>
</td></tr>
<tr>
<tr>
Línea 44: Línea 51:
</td></tr>
</td></tr>
<tr>
<tr>
<td>gpus</td>
<td>v100</td>
<td>2</td>
<td>2</td>
<td>44</td>
<td>44</td>
Línea 51: Línea 58:
</td></tr>
</td></tr>
<tr>
<tr>
<td>slims</td>
<td>mi100</td>
<td>132</td>
<td>1</td>
<td>20</td>
<td>128</td>
<td>46GB</td>
<td>502GB</td>
<td>
<td>2 GPUs AMD Instinct MI100.
</td></tr>
<tr>
<td>mi210</td>
<td>2</td>
<td>24</td>
<td>1457GB</td>
<td>6 GPUs AMD Instinct MI210.
</td></tr>
</td></tr>
<tr>
<tr>
<td>debug</td>
<td>debug</td>
<td>4</td>
<td>2</td>
<td>20</td>
<td>48</td>
<td>59GB</td>
<td>768GB</td>
<td>Destinados a pruebas de máximo 30 minutos.
<td>Destinados a pruebas de máximo 30 minutos.
</td></tr></table>
</td></tr></table>
Línea 67: Línea 81:
== Introducción a los comandos slurm ==
== Introducción a los comandos slurm ==
<table class="wikitable" style="width: 60%;">
<table class="wikitable" style="width: 60%;">
<tbody><tr>
<td><b>Comando SLURM</b></td>
<td><b>Comando SLURM</b></td>
<td><b>Descripción</b>
<td><b>Descripción</b>
Línea 90: Línea 103:
<td>sinfo</td>
<td>sinfo</td>
<td>Muestra el estado de los nodos de cómputo.
<td>Muestra el estado de los nodos de cómputo.
</td></tr></tbody></table>
</td></tr></table>
Estos son los comandos básicos utilizados para realizar la mayoría de las operaciones básicas con SLURM.
Estos son los comandos básicos utilizados para realizar la mayoría de las operaciones básicas con SLURM.


== Estado de nodos ==
=== Estado de nodos ===
Para consultar el uso de nuestra infraestructura y qué particiones están más libres, le recomendamos el comando sinfo:
Para consultar el uso de nuestra infraestructura y qué particiones están más libres, le recomendamos el comando sinfo:


<pre># sinfo
<pre># sinfo<small>
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
all          up  infinite    24   mix cn[001,003,005-006,010,034-035,037,041,043,045,050,057,070,079,085,095,098,108,121],sn[012,016,037,042]
main*        up  infinite      1  idle mn[016,018]
all          up  infinite   134 alloc           cn[002,004,007-009,011-033,036,038-040,042,044,046-049,051-056,058-069,071-078,080-084,086-094,096-097,099-107,109-120,122-128],cnf[001-004],sn[001-011,013-015,017,036,038-041,043-044]
main*        up  infinite    21   mix mn[001-003,005,007-011,013,015,017,019-027]
all          up  infinite    33  idle fn[001-009],gn[001-002],sn[018-035,045-048]
main*        up  infinite     4 alloc mn[004,006,012,014]
slims*      up  infinite     20   mix cn[001,003,005-006,010,034-035,037,041,043,045,050,057,070,079,085,095,098,108,121]
general      up  infinite      1  drain sn041
slims*      up  infinite   112 alloc cn[002,004,007-009,011-033,036,038-040,042,044,046-049,051-056,058-069,071-078,080-084,086-094,096-097,099-107,109-120,122-128],cnf[001-004]
general      up  infinite    16    mix sn[005-007,012-015,019-021,030-031,043-048]
debug        up  infinite      4   idle leftraru[1-4]
general      up  infinite    31  alloc sn[001-004,008-011,016-018,022-029,032-040]
general      up  infinite      4   mix sn[012,016,037,042]
largemem    up  infinite     1   mix fn006
general      up  infinite    22  alloc sn[001-011,013-015,017,036,038-041,043-044]
largemem    up  infinite     8 alloc fn[001-005,007-009]
general      up  infinite     22   idle sn[018-035,045-048]
debug        up  infinite      2   idle leftraru[1-2]
largemem    up  infinite      9  idle fn[001-009]
v100        up  infinite      2   mix gn[001-002]
gpus        up  infinite      2   idle gn[001-002]
mi100        up  infinite     1   idle gn003
mi210        up  infinite      1    mix gn004
mi210        up  infinite      1   idle gn005</small>
</pre>
</pre>


Fijándose en el texto resaltado de la salida del comando sinfo, se puede comprobar que en la partición main hay 20 nodos que están completamente ocupados (estado alloc), 7 nodos que están libres (idle); por otro lado, en la partición general hay 22 nodos completamente ocupados, 4 parcialmente ocupados y 22 libres. Dado este escenario, está claro que debería de lanzar sus ejecuciones en los nodos de la partición general, por las razones anteriormente expuestas.


 
Para lanzar en la partición general, debe tener en cuenta que tiene que indicar en su script que se use dicha partición en vez de, probablemente, main. Por supuesto, en esta partición cambian las características técnicas, se pasan a tener 44 cores por nodo (en vez de 256 en main) y una capacidad RAM de 187GB (en vez de 768GB en main). Puede ver más información de las particiones en este link(agregar link), donde podrá revisar que con la inclusión de Guacolda hemos añadido nodos con hasta 765GB de memoria RAM y nodos con GPUs Nvidia Tesla V100 y AMD Instinct MI100 .
 
 
# sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
all          up  infinite    24    mix cn[001,003,005-006,010,034-035,037,041,043,045,050,057,070,079,085,095,098,108,121],sn[012,016,037,042]
all          up  infinite    134  alloc          cn[002,004,007-009,011-033,036,038-040,042,044,046-049,051-056,058-069,071-078,080-084,086-094,096-097,099-107,109-120,122-128],cnf[001-004],sn[001-011,013-015,017,036,038-041,043-044]
all          up  infinite    33  idle fn[001-009],gn[001-002],sn[018-035,045-048]
slims*      up  infinite    20    mix cn[001,003,005-006,010,034-035,037,041,043,045,050,057,070,079,085,095,098,108,121]
slims*      up  infinite    112  alloc cn[002,004,007-009,011-033,036,038-040,042,044,046-049,051-056,058-069,071-078,080-084,086-094,096-097,099-107,109-120,122-128],cnf[001-004]
debug        up  infinite      4  idle leftraru[1-4]
general      up  infinite      4    mix sn[012,016,037,042]
general      up  infinite    22  alloc sn[001-011,013-015,017,036,038-041,043-044]
general      up  infinite    22  idle sn[018-035,045-048]
largemem    up  infinite      9  idle fn[001-009]
gpus        up  infinite      2  idle gn[001-002]
Fijándose en el texto resaltado de la salida del comando sinfo, se puede comprobar que en la partición slims hay 112 nodos que están completamente ocupados (estado alloc), 20 nodos que están parcialmente ocupados (mix) y ninguno libre (idle); por otro lado, en la partición general hay 22 nodos completamente ocupados, 4 parcialmente ocupados y 22 libres. Dado este escenario, está claro que debería de lanzar sus ejecuciones en los nodos de la partición general, por las razones anteriormente expuestas.
 
Para lanzar en la partición general, debe tener en cuenta que tiene que indicar en su script que se use dicha partición en vez de, probablemente, slims. Por supuesto, en esta partición cambian las características técnicas, se pasan a tener 44 cores por nodo (en vez de 20 en slims) y una capacidad RAM de 187GB (en vez de 46GB en slims). Puede ver más información de las particiones en este link(agregar link), donde podrá revisar que con la inclusión de Guacolda hemos añadido nodos con hasta 765GB de memoria RAM y nodos con GPUs Nvidia Tesla V100.


Para ver los nodos disponibles y poder determinar en que partición lanzar los trabajos se recomienda utilizar el siguiente comando.
Para ver los nodos disponibles y poder determinar en que partición lanzar los trabajos se recomienda utilizar el siguiente comando.


[prueba@leftraru1 ~]$ sinfo -o "%10P %6D %10t %10m %c" -t idle| egrep "PARTITION|slims|general|largemem|gpus"
<pre>[prueba@leftraru1 ~]$ sinfo -o "%10P %6D %10t %10m %c" -t idle| egrep "PARTITION|main|general|largemem|v100|mi100|mi210"
PARTITION  NODES  STATE      MEMORY    CPUS
PARTITION  NODES  STATE      MEMORY    CPUS
PARTITION  NODES  STATE      MEMORY    CPUS
slims*     32    idle      46000      20
main*     2      idle      727000    256
general    2     idle      187000    44
general    0     n/a        0          0
largemem  7     idle      765000     44
largemem  0      n/a        0          0
gpus      1      idle      187000    44
v100      0      n/a        0          0
El comando anterior muestra que slims tiene 32 nodos libres, en este caso es recomendado lanzar en en slims para evitar que el trabajo quede en cola por falta de recursos en otros nodos.
mi100      1     idle      485000     128
mi210      1      idle      1457000    48
</pre>
El comando anterior muestra que main tiene 27 nodos libres, en este caso es recomendado lanzar en en main para evitar que el trabajo quede en cola por falta de recursos en otros nodos.


Otro Ejemplo, se muestra sólo una partición específica
Otro Ejemplo, se muestra sólo una partición específica


[prueba@leftraru1 ~]$ sinfo -p slims
<pre>[prueba@leftraru1 ~]$ sinfo -p main
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
slims*       up  infinite    24   mix cn[015,033,036-038,041-050,053-054,075-080,104]
main*       up  infinite    15   mix mn[001-008,014-020]
slims*       up  infinite    76    alloc   cn[001-009,019-032,039-040,051-090,093-094,097-099],cnf[001-004]
main*       up  infinite    12   idle mn[009-013,021-027]
slims*      up  infinite    32    idle cn[010-014,016-018,034-035,056-058,073-074,091-100,120-122,125-127]
</pre>
Comprobación del estado de tareas
 
=== Comprobación del estado de tareas ===
squeue - Muestra el estatus de los trabajos
squeue - Muestra el estatus de los trabajos


squeue                  # tus trabajos
<pre>squeue                  # tus trabajos
squeue -u <username>   # trabajos por usuario <username>
squeue -u &lt;username&gt;   # trabajos por usuario &lt;username&gt;
</pre>
 
squeue: Comprobar estados de los trabajos
squeue: Comprobar estados de los trabajos


      JOBID PARTITION    NAME    USER ST      TIME  NODES NODELIST(REASON)
<div style="" class="mw-highlight mw-content-ltr" dir="ltr">
13951858_1    general       test1    test1     R 1-18:35:14      2    cn[009-010]
<pre>
13951857_2    general      test2    test1     R 1-18:36:11      2    cn[099-100]
  JOBID       PARTITION    NAME    USER   ST      TIME  NODES NODELIST(REASON)
13956453      gpu          test3    test3     R 1-03:42:08      1    cn039
13951858_1    general     test1    test1   R   1-18:35:14      2    cn[009-010]
13956449      largemem      test4    test4     R 1-05:42:08      1    cn044
13951857_2    general      test2    test1   R   1-18:36:11      2    cn[099-100]
13956453      gpu          test3    test3   R   1-03:42:08      1    cn039
13956449      largemem      test4    test4   R   1-05:42:08      1    cn044
</pre>
 
Puede utilizar squeue para saber el estado de una o varias de sus tareas
Puede utilizar squeue para saber el estado de una o varias de sus tareas


$ squeue -o "%.15i %.6P %.8j %.20S %.11M %.11L %.20V %.10Q %.4C %.2D %.6m" -S -t,-Q
<pre>
          JOBID PARTIT    NAME           START_TIME       TIME   TIME_LEFT         SUBMIT_TIME   PRIORITY CPUS NO MIN_ME
$ squeue -o "%.15i %.6P %.8j %.20S %.11M %.11L %.20V %.10Q %.4C %.2D %.6m" -S -t,-Q
      10837561 general  TEST1     2018-06-18T18:51:01    19:00:31  2-04:59:29  2018-06-18T18:51:01     119972    1  1  1000M
JOBID   PARTIT    NAME     START_TIME         TIME     TIME_LEFT     SUBMIT_TIME       PRIORITY CPUS NO MIN_ME
      10838562 general  TEST2     2018-06-19T11:30:47    2:20:45 2-21:39:15  2018-06-19T11:30:46     119946    1  1  1000M
10837561 general  TEST1   2018-06-18T18:51:01    19:00:31  2-04:59:29  2018-06-18T18:51:01 119972    1  1  1000M
para mas opciones puede revisar con el comando man squeue las opciones restantes.
10838562 general  TEST2   2018-06-19T11:30:47    2:20:45   2-21:39:15  2018-06-19T11:30:46 119946    1  1  1000M
</pre>
 
 
para mas opciones puede revisar con el comando [https://slurm.schedmd.com/squeue.html man squeue] las opciones restantes.
 
=== Códigos de ESTADO de los trabajos ===
 
Los trabajos suelen pasar por varios estados durante su ejecución. Los estados típicos son PENDIENTE, EN EJECUCIÓN, SUSPENDIDO, FINALIZANDO y TERMINADO. A continuación se explica cada estado.
 
'''BF''' BOOT_FAIL
    Trabajo finalizado debido a un fallo de arranque, normalmente debido a un fallo de hardware (por ejemplo, no se puede arrancar el nodo o bloque y el trabajo no se puede volver a poner en cola).
 
'''CA''' CANCELADO
    El trabajo ha sido cancelado explícitamente por el usuario o el administrador del sistema. El trabajo puede haberse iniciado o no.
 
'''CD''' TERMINADO
    El trabajo ha terminado todos los procesos en todos los nodos con un código de salida de cero.
 
'''CF''' CONFIGURANDO
    Al trabajo se le han asignado recursos, pero están esperando a que estén listos para su uso (por ejemplo, arrancando).
 
'''CG''' COMPLETANDO
    El trabajo está en proceso de finalización. Algunos procesos en algunos nodos pueden estar aún activos.  


Cancelar un trabajo
'''DL''' FECHA LÍMITE
    El trabajo ha finalizado en la fecha límite.
 
'''F''' FALLÓ
    Trabajo finalizado con un código de salida distinto de cero u otra condición de fallo.
 
'''NF''' NODO_FAIL
    Trabajo finalizado debido al fallo de uno o más nodos asignados.
 
'''OOM''' OUT_OF_MEMORY
    El trabajo ha experimentado un error de memoria insuficiente.
 
'''PD''' PENDIENTE
    El trabajo está pendiente de asignación de recursos.
 
'''PR''' PREEMPTED
    El trabajo ha finalizado debido a una espera.
 
'''R''' EN MARCHA
    El trabajo tiene actualmente una asignación.
 
'''RD''' RESV_DEL_HOLD
    El trabajo se está reteniendo después de que se eliminara la reserva solicitada.
 
'''RF''' REQUEUE_FED
    El trabajo está siendo solicitado por una federación.
 
'''RH''' REQUEUE_HOLD
    Se está volviendo a poner en cola un trabajo retenido.
 
'''RQ''' REQUEUED
    Se está poniendo en cola un trabajo que se está completando.
 
'''RS''' CAMBIO DE TAMAÑO
    El trabajo está a punto de cambiar de tamaño.
 
'''RV''' REVOCADO
    El trabajo se ha retirado del clúster debido a que otro clúster ha iniciado el trabajo.
 
'''SI''' SEÑALANDO
    El trabajo está siendo señalizado.
 
'''SE''' SPECIAL_EXIT
    El trabajo se ha puesto en cola en un estado especial. Este estado puede ser establecido por los usuarios, normalmente en EpilogSlurmctld, si el trabajo ha terminado con un valor de salida particular.
 
'''SO''' STAGE_OUT
    El trabajo está preparando los archivos.
 
'''ST''' PARADO
    El trabajo tiene una asignación, pero la ejecución se ha detenido con la señal SIGSTOP. Los CPUS han sido retenidos por este trabajo.
 
'''S''' SUSPENDIDO
    El trabajo tiene una asignación, pero se ha suspendido la ejecución y se han liberado CPUs para otros trabajos.
 
'''TO''' TIMEOUT
    El trabajo ha finalizado al alcanzar su límite de tiempo.
 
=== Cancelar un trabajo ===
Con scancel se puede cancelar un trabajo en ejecución
Con scancel se puede cancelar un trabajo en ejecución
 
<pre>scancel &lt;jobID&gt;         # Matar proceso &lt;jobID&gt;. (puede obtener el ID del job con "squeue")
scancel <jobID>         # Matar proceso <jobID>. (puede obtener el ID del job con "squeue")
scancel -u &lt;username&gt;   # Matar proceso por usuario &lt;username&gt;.
scancel -u <username>   # Matar proceso por usuario <username>.
</pre>
[prueba@leftraru1 ~]$ squeue -u prueba
<pre>[prueba@leftraru1 ~]$ squeue -u prueba
            JOBID PARTITION     NAME    USER ST       TIME  NODES NODELIST(REASON)
JOBID PARTITION   NAME    USER   ST   TIME  NODES NODELIST(REASON)
            45594     slims    TEST  prueba  R       0:59    20 cn[001-020]
45594   main      TEST   prueba   R   0:59   3     mn[001-003]
[prueba@leftraru1 ~]$ scancel 45594
</pre>
<pre>[prueba@leftraru1 ~]$ scancel 45594
[prueba@leftraru1 ~]$ squeue -u prueba
[prueba@leftraru1 ~]$ squeue -u prueba
            JOBID PARTITION    NAME    USER ST      TIME  NODES NODELIST(REASON)
JOBID PARTITION    NAME    USER ST      TIME  NODES NODELIST(REASON)
[prueba@leftraru1 ~]$
[prueba@leftraru1 ~]$
Ver estado de trabajos
</pre>
 
=== Ver estado de trabajos ===
Para revisar el detalle de las opciones de un trabajo: scontrol show job
Para revisar el detalle de las opciones de un trabajo: scontrol show job


<pre>
$ scontrol show job 10837561
$ scontrol show job 10837561
JobId=10837561 JobName=TEST1
JobId=10837561 JobName=TEST1
Línea 195: Línea 289:
   StartTime=2018-06-18T18:51:01 EndTime=2018-06-21T18:51:01 Deadline=N/A
   StartTime=2018-06-18T18:51:01 EndTime=2018-06-21T18:51:01 Deadline=N/A
   PreemptTime=None SuspendTime=None SecsPreSuspend=0
   PreemptTime=None SuspendTime=None SecsPreSuspend=0
   Partition=slims AllocNode:Sid=leftraru2:5471
   Partition=main AllocNode:Sid=leftraru2:5471
   ReqNodeList=(null) ExcNodeList=(null)
   ReqNodeList=(null) ExcNodeList=(null)
   NodeList=cn021
   NodeList=cn021
Línea 214: Línea 308:
   Power=
   Power=
   BatchScript=
   BatchScript=
</pre>
Para ver el script asociado a un trabajo: scontrol write batch_script <job_id> -
Para ver el script asociado a un trabajo: scontrol write batch_script <job_id> -


<pre>
$ scontrol write batch_script 10837561 -
$ scontrol write batch_script 10837561 -
#!/bin/bash
#!/bin/bash
#SBATCH -J nombre_del_trabajo
#SBATCH -J nombre_del_trabajo
#SBATCH -p slims
#SBATCH -p main
#SBATCH -n 1
#SBATCH -n 1
#SBATCH --ntasks-per-node=1
#SBATCH --ntasks-per-node=1
Línea 231: Línea 328:


matlab -nodisplay -nosplash -nodesktop < programa.m
matlab -nodisplay -nosplash -nodesktop < programa.m
Ejecutando trabajos
</pre>
Actualmente contamos con 2 metodos de enviar trabajos bajo SLURM: sbatch and srun. A veces puede ser ventajoso ejecutar un solo comando en el clúster como prueba o realizar rápidamente una operación con recursos adicionales. 'srun' permite a los usuarios hacer esto, y comparte las mismas variables que 'sbatch' . STDOUT y STDERR para un trabajo 'srun' serán redirigidos a la pantalla del usuario. Ctrl-C cancelará un trabajo srun. sbatch enviará un script de trabajo para que lo ejecute el clúster. Los scripts de trabajo bajo SLURM son simplemente scripts de shell (* .sh) con un conjunto de solicitudes de recursos en la parte superior del script.
 
== Ejecutando trabajos ==
Actualmente contamos con 2 metodos de enviar trabajos bajo SLURM: '''sbatch''' and '''srun'''. A veces puede ser ventajoso ejecutar un solo comando en el clúster como prueba o realizar rápidamente una operación con recursos adicionales. 'srun' permite a los usuarios hacer esto, y comparte las mismas variables que 'sbatch' . STDOUT y STDERR para un trabajo 'srun' serán redirigidos a la pantalla del usuario. Ctrl-C cancelará un trabajo srun. '''sbatch''' enviará un script de trabajo para que lo ejecute el clúster. Los scripts de trabajo bajo SLURM son simplemente scripts de shell (* .sh) con un conjunto de solicitudes de recursos en la parte superior del script.




Uso básico de srun:
Uso básico de srun:


srun <algúnComando>    
<pre>
srun <algúnComando>
</pre>
 
 
Ejemplo de salida (ejecutando el comando "hostname" para saber en que nodo se está ejecutando):
Ejemplo de salida (ejecutando el comando "hostname" para saber en que nodo se está ejecutando):
<pre> $ srun hostname
  cn003
</pre>


$ srun hostname
cn003
Para enviar un script de trabajo a SLURM:
Para enviar un script de trabajo a SLURM:
<pre>sbatch nombreScript.sh</pre>


sbatch nombreScript.sh
Example output:
Example output:
<pre>$ sbatch test-job.sh
Submitted batch job 1169</pre>


$ sbatch test-job.sh
=== Variables Slurm ===
Submitted batch job 1169
Variables Slurm
Las variables en esta sección son obligatorias, y SLURM las determina para determinar dónde y cuándo se ejecutarán sus trabajos. Si no asigna un valor para estos, el planificador asignará a sus trabajos el valor predeterminado. Si no solicita específicamente recursos para un trabajo, se le asignará un conjunto de recursos predeterminados. Para obtener una lista de todas las variables disponibles, consulte la documentación de SLURM en http://slurm.schedmd.com/sbatch.html. Las variables de este artículo estaban cubiertas porque eran las más relevantes para los casos de uso típicos.
Las variables en esta sección son obligatorias, y SLURM las determina para determinar dónde y cuándo se ejecutarán sus trabajos. Si no asigna un valor para estos, el planificador asignará a sus trabajos el valor predeterminado. Si no solicita específicamente recursos para un trabajo, se le asignará un conjunto de recursos predeterminados. Para obtener una lista de todas las variables disponibles, consulte la documentación de SLURM en http://slurm.schedmd.com/sbatch.html. Las variables de este artículo estaban cubiertas porque eran las más relevantes para los casos de uso típicos.
<table class="wikitable" style="width: 100%;">
<tr>
<td><b>Comando SLURM</b></td>
<td><b>Descripción</b>
</td></tr>
<tr>
<td>--mem-per-cpu=&lt;megabytes&gt;</td>
<td>Memoria requerida para el trabajo por CPU (en MegaBytes). El valor predeterminado es 1024 MB.
</td></tr>
<tr>
<td>-p &lt;partition&gt;, --partition=&lt;partition&gt;</td>
<td>Enviar un trabajo a una partición específica.
</td></tr>
<tr>
<td>-n, --ntasks=&lt;cantidad de tareas&gt;</td>
<td>Número de tareas que serán asignadas para el trabajo.
</td></tr>
<tr>
<td>-c &lt;cpus&gt;</td>
<td>Esta es la cantidad de CPU que necesita su trabajo. Tenga en cuenta que SLURM es relativamente generoso con las CPU, y el valor especificado aquí es el número "mínimo" de CPU que se asignará a su trabajo. Si hay CPU adicionales disponibles en un nodo más allá de lo solicitado, su trabajo recibirá esas CPU hasta que otros trabajos las necesiten. El valor predeterminado es 1 CPU. Intentar usar más CPU de las que se le asignaron dará como resultado que sus procesos adicionales se turnen en la misma CPU (ralentizando su trabajo).
</td></tr>
<tr>
<td>-J &lt;name&gt;, --jobname=&lt;name&gt;</td>
<td>Especifica un nombre a tu trabajo.
</td></tr>
<tr>
<td>--mail-type=BEGIN,END,FAIL,ALL<b> and </b>--mail-user=&lt;emailAddress&gt;</td>
<td>Enviar por correo electrónico cuando su trabajo comienza / termina / falla. Puede especificar varios valores para esto (separados por comas) si es necesario.
</td></tr>
<tr>
<td>-o &lt;STDOUT_log&gt;, --output=&lt;STDOUT_log&gt;</td>
<td>Redirija la salida a los archivos de registro que especifique. Por defecto, ambos, STDOUT and STDERR son enviados a este archivo. Puedes especificar %j como parte del nombre de archivo de registro para indicar la ID del trabajo (como ejemplo, "#SBATCH -o ouptut_%j.o" redirigiría la salida a "output_123456.o").
</td></tr>
<tr>
<td>-e &lt;STDERR_log&gt;, --error=&lt;STDERR_log&gt;</td>
<td>Redireccionar STDERR a un archivo separado. Funciona exactamente igual que "-o".
</td></tr>
<tr>
<td>-t &lt;days-hours:minutes:seconds&gt;</td>
<td>Walltime para tu trabajo. La duración del Walltime es el tiempo que espera que su trabajo se ejecute.
</td></tr>
<tr>
<td>-a, --array=&lt;índices&gt;</td>
<td>Envía una lista (arreglo) de trabajos identicos. Solo aplica para sbatch.
</td></tr></table>




Comando SLURM Descripción
--mem-per-cpu=<megabytes> Memoria requerida para el trabajo por CPU (en MegaBytes). El valor predeterminado es 1024 MB.
-p <partition>, --partition=<partition> Enviar un trabajo a una partición específica.
-n, --ntasks=<cantidad de tareas> Número de tareas que serán asignadas para el trabajo.
-c <cpus> Esta es la cantidad de CPU que necesita su trabajo. Tenga en cuenta que SLURM es relativamente generoso con las CPU, y el valor especificado aquí es el número "mínimo" de CPU que se asignará a su trabajo. Si hay CPU adicionales disponibles en un nodo más allá de lo solicitado, su trabajo recibirá esas CPU hasta que otros trabajos las necesiten. El valor predeterminado es 1 CPU. Intentar usar más CPU de las que se le asignaron dará como resultado que sus procesos adicionales se turnen en la misma CPU (ralentizando su trabajo).
-J <name>, --jobname=<name> Especifica un nombre a tu trabajo.
--mail-type=BEGIN,END,FAIL,ALL and --mail-user=<emailAddress> Enviar por correo electrónico cuando su trabajo comienza / termina / falla. Puede especificar varios valores para esto (separados por comas) si es necesario.
-o <STDOUT_log>, --output=<STDOUT_log> Redirija la salida a los archivos de registro que especifique. Por defecto, ambos, STDOUT and STDERR son enviados a este archivo. Puedes especificar %j como parte del nombre de archivo de registro para indicar la ID del trabajo (como ejemplo, "#SBATCH -o ouptut_%j.o" redirigiría la salida a "output_123456.o").
-e <STDERR_log>, --error=<STDERR_log> Redireccionar STDERR a un archivo separado. Funciona exactamente igual que "-o".
-t <days-hours:minutes:seconds> Walltime para tu trabajo. La duración del Walltime es el tiempo que espera que su trabajo se ejecute.
-a, --array=<índices> Envía una lista (arreglo) de trabajos identicos. Solo aplica para sbatch.
Los scripts de trabajo especifican los recursos solicitados y otras consideraciones especiales con comentarios especiales "#SBATCH" en la parte superior de un script de trabajo. Aunque muchas de estas opciones son opcionales, las varibles que se ocupan de solicitudes de recursos (CPU, memoria y tiempo) son obligatorias. Todas las variables deben agregarse a sus scripts de la siguiente manera:
Los scripts de trabajo especifican los recursos solicitados y otras consideraciones especiales con comentarios especiales "#SBATCH" en la parte superior de un script de trabajo. Aunque muchas de estas opciones son opcionales, las varibles que se ocupan de solicitudes de recursos (CPU, memoria y tiempo) son obligatorias. Todas las variables deben agregarse a sus scripts de la siguiente manera:


#SBATCH <variable>
<pre>#SBATCH <variable></pre>
Para especificar un nombre al job, por ejemplo, debe agregar lo siguiente a su secuencia de comandos:
Para especificar un nombre al job, por ejemplo, debe agregar lo siguiente a su secuencia de comandos:


#SBATCH --job-name=nombreDeTrabajo
<pre>#SBATCH --job-name=nombreDeTrabajo</pre>
Enviar un script
 
===Enviar un script===
<pre>
  #!/bin/bash
  #!/bin/bash
  #SBATCH -J example
  #SBATCH -J example
Línea 279: Línea 422:
  #SBATCH --mail-user=user@example.com
  #SBATCH --mail-user=user@example.com
  #SBATCH --mail-type=ALL
  #SBATCH --mail-type=ALL
</pre>


Como debe comenzar un script en Linux:
Como debe comenzar un script en Linux:
<pre>
#!/bin/bash
</pre>


#!/bin/bash
Nombre del trabajo:
Nombre del trabajo:
<pre>
#SBATCH -J example
</pre>


#SBATCH -J example
Nombre la particion donde desea ejecutar el Job:


Nombre la partición donde desea ejecutar el Job:
<pre>
#SBATCH -p general
#SBATCH -p general
</pre>
Número de tareas:
Número de tareas:
<pre>
#SBATCH -n 1
</pre>


#SBATCH -n 1
Log de salida:
Log de salida:
<pre>
#SBATCH -o example_%j.out
</pre>


#SBATCH -o example_%j.out
Log de error:
Log de error:
<pre>
#SBATCH -e example_%j.err
</pre>


#SBATCH -e example_%j.err
Correo para notificaciones:
Correo para notificaciones:
<pre>
#SBATCH --mail-user=user@example.com
</pre>


#SBATCH --mail-user=user@example.com
Enviar correo en todos casos (verificar opciones arriba):
Enviar correo en todos casos (verificar opciones arriba):
<pre>
#SBATCH --mail-type=ALL
</pre>


#SBATCH --mail-type=ALL
=== Programar tarea (uso de scrontab) ===
Programar tarea (uso de scrontab)
'''scrontab''' es una implementación del clásico planificador de tareas de linux '''crontab''' donde se guarda un listado de comandos a ejecutar en un tiempo determinado por el usuario.
scrontab es una implementación del clásico planificador de tareas de linux crontab donde se guarda un listado de comandos a ejecutar en un tiempo determinado por el usuario.


Para acceder a scrontab utilice el siguiente comando:
Para acceder a scrontab utilice el siguiente comando:
 
<pre>
[prueba@leftraru1 ~]$ scrontab -e
[prueba@leftraru1 ~]$ scrontab -e
Esto le permitirá editar su archivo scrontab, la estructura base es la siguiente:
</pre>


Esto le permitirá editar su archivo scrontab, asignando recursos como también el momento en que desea ejecutar su tarea. La estructura base a utilizar es la siguiente:
<pre>
#SCRON -J mi_tarea
#SCRON -p main
#SCRON -n 1
#SCRON -c 1
#SCRON --mem-per-cpu=2300
#SCRON --mail-user=foo@bar.com
#SCRON --mail-type=ALL
#SCRON -o mi_tarea_%j.out
#SCRON -e mi_tarea_%j.err
# Example of job definition:
# Example of job definition:
# .---------------- minute (0 - 59)
# .---------------- minute (0 - 59)
Línea 320: Línea 498:
# |  |  |  |  |
# |  |  |  |  |
# *  *  *  *  *    command to be executed
# *  *  *  *  *    command to be executed
minute - Corresponde al minuto en que se va a ejecutar el script, valor de 0 a 59.
</pre>
hour - Hora de ejecución, formato 24 horas, valor de 0 a 23, donde 0 son las 12:00 AM.
 
day of month - Día del mes, la tarea se puede ejecutar cada x día, valor de 1 a 31.
* '''minute''' - Corresponde al minuto en que se va a ejecutar el script, valor de 0 a 59.
month - La tarea se puede ejecutar cada x mes, valor de 1 a 12.
* '''hour''' - Hora de ejecución, formato 24 horas, valor de 0 a 23, donde 0 son las 12:00 AM.
day of week - Día de la semana, valor de 0 a 6, donde 0 es Domingo.
* '''day of month''' - Día del mes, la tarea se puede ejecutar cada x día, valor de 1 a 31.
command to be executed - Script a ejecutar por el usuario.
* '''month''' - La tarea se puede ejecutar cada x mes, valor de 1 a 12.
* '''day of week''' - Día de la semana, valor de 0 a 6, donde 0 es Domingo.
* '''command to be executed''' - Script a ejecutar por el usuario.
Ejemplo envío de trabajo slurm:
Ejemplo envío de trabajo slurm:


Primero debemos especificar el tiempo, en este caso la tarea será ejecutada todos los días cada 20 minutos, luego debemos indicar el script enviado por el usuario y guardamos los cambios en el archivo.
Para la asignación de recursos, utilizaremos la directriz '''#SCRON''', que utiliza los mismos parámetros usados por '''#SBATCH'''.
 
Luego de asignar los recursos debemos especificar el tiempo, en este caso la tarea será ejecutada todos los días cada 20 minutos, luego debemos indicar el script enviado por el usuario y guardamos los cambios en el archivo.


<pre>
*/20 * * * * /home/prueba/ejemplo/script.sh
*/20 * * * * /home/prueba/ejemplo/script.sh
</pre>
Es importante destacar que el script a lanzar '''/home/prueba/ejemplo/script.sh''' debe tener permisos de ejecución.
Para revisar el listado de tareas existentes en nuestro scrontab, ejecutamos el comando:
Para revisar el listado de tareas existentes en nuestro scrontab, ejecutamos el comando:
 
<pre>
[prueba@leftraru1 ~]$ scrontab -l
[prueba@leftraru1 ~]$ scrontab -l
*/20 * * * * /home/prueba/ejemplo/script.sh
*/20 * * * * /home/prueba/ejemplo/script.sh
</pre>
Para borrar el contenido de nuestro scrontab:
Para borrar el contenido de nuestro scrontab:
<pre>
[prueba@leftraru1 ~]$ scrontab -r
</pre>
'''Información a considerar:'''


[prueba@leftraru1 ~]$ scrontab -r
* Generar archivos de salida correctamente
Información a considerar:
** Para que el archivo error y out de tu script se generen en el directorio solicitado, ejemplo, /home/prueba/ejemplo/ en tu script debe estar presente el comando cd “/home/prueba/ejemplo”, esto hará que scrontab se posicione dentro del directorio de salida.
* Es distinto el tiempo de programar el envío de una tarea (scrontab) a que una tarea inicie en el clúster (running), ya que esto dependerá de los recursos libres que existan en ese momento en el clúster.
* Para revisar las tareas programadas debe ejecutar en cualquier nodo login el comando '''scrontab -l''' o revisar con el comando '''squeue''':


Generar archivos de salida correctamente
<pre>
Para que el archivo error y out de tu script se generen en el directorio solicitado, ejemplo, /home/prueba/ejemplo/ en tu script debe estar presente el comando cd “/home/prueba/ejemplo”, esto hará que scrontab se posicione dentro del directorio de salida.
Es distinto el tiempo de programar el envío de una tarea (scrontab) a que una tarea inicie en el clúster (running), ya que esto dependerá de los recursos libres que existan en ese momento en el clúster.
Para revisar las tareas programadas debe ejecutar en cualquier nodo login el comando scrontab -l o revisar con el comando squeue:
[prueba@leftraru1 ~]$ squeue
[prueba@leftraru1 ~]$ squeue
24293471    slims /home/eg  prueba PD      0:00      1 (BeginTime)
24293471    main /home/eg  prueba PD      0:00      1 (BeginTime)
Checkpointing
</pre>
 
== Checkpointing ==
Es la acción de guardar el estado de un proceso en ejecución en un archivo de imagen de punto de control. Este proceso se puede reiniciar más tarde desde el archivo del punto de control, continuando la ejecución desde donde se detuvo, en la misma computadora o en una diferente.
Es la acción de guardar el estado de un proceso en ejecución en un archivo de imagen de punto de control. Este proceso se puede reiniciar más tarde desde el archivo del punto de control, continuando la ejecución desde donde se detuvo, en la misma computadora o en una diferente.


¿Por qué utilizarlo?
=== ¿Por qué utilizarlo? ===
Permite ejecuciones de tarea largas que superen el tiempo de ejecución permitido en el cluster (30 días)
* Permite ejecuciones de tarea largas que superen el tiempo de ejecución permitido en el cluster (30 días)
Estar preparados ante fallas del sistema que nos puedan hacer perder resultados de nuestras simulaciones
* Estar preparados ante fallas del sistema que nos puedan hacer perder resultados de nuestras simulaciones
Utilización
 
=== Utilización ===
Lo primero que debemos hacer en nuestro script es cargar el módulo de Mana:
Lo primero que debemos hacer en nuestro script es cargar el módulo de Mana:
 
<pre>
ml mana/3.0.0
ml mana/3.0.0
</pre>
Este módulo provee 3 ejecutables que necesitaremos:
Este módulo provee 3 ejecutables que necesitaremos:


mana_coordinator: Coordina los checkpoints entre los distintos procesos
* '''mana_coordinator:''' Coordina los checkpoints entre los distintos procesos
mana_launch: Inicia un proceso con checkpoint
* '''mana_launch:''' Inicia un proceso con checkpoint
mana_restart: Reinicia la ejecución desde una imagen del checkpoint
* '''mana_restart:''' Reinicia la ejecución desde una imagen del checkpoint
 
Necesitaremos 2 scripts para trabajar con checkpoints: Inicio y reinicio
Necesitaremos 2 scripts para trabajar con checkpoints: Inicio y reinicio


Script de inicio (inicio.sh)
=== Script de inicio (inicio.sh) ===
<pre>
#!/bin/bash
#!/bin/bash
##---------------SLURM Parameters - NLHPC ----------------
##---------------SLURM Parameters - NLHPC ----------------
Línea 383: Línea 584:
#Ejecutamos nuestra tarea con checkpointing
#Ejecutamos nuestra tarea con checkpointing
srun mana_launch ./ejecutable
srun mana_launch ./ejecutable
</pre>


Script de reinicio (reinicio.sh)
=== Script de reinicio (reinicio.sh) ===
<pre>
#!/bin/bash
#!/bin/bash
##---------------SLURM Parameters - NLHPC ----------------
##---------------SLURM Parameters - NLHPC ----------------
Línea 403: Línea 606:
mana_cooridinator -i3600
mana_cooridinator -i3600
#Reiniciar nuestra tarea desde los archivos de checkpoint
#Reiniciar nuestra tarea desde los archivos de checkpoint
srun mana_restart  
srun mana_restart
</pre>
 
 
Para correr estos scripts se puede hacer utilizando la funcionalidad de dependencias de SLURM:
Para correr estos scripts se puede hacer utilizando la funcionalidad de dependencias de SLURM:
<pre>
[test@leftraru2 test]$ sbatch inicio.sh
Submitted batch job 23574685
[test@leftraru2 test]$ sbatch --dependency=afterok:23574685 reinicio.sh
</pre>


[test@leftraru3 test]$ sbatch inicio.sh
== Trabajos ==
Submitted batch job 23574685
=== Trabajos paralelos ===
[test@leftraru3 test]$ sbatch --dependency=afterok:23574685 reinicio.sh
Trabajos
Trabajos paralelos
Muchos de los trabajos que se ejecutan en un clúster de producción implicarán más de un procesador (CPU, núcleo). Dichos trabajos paralelos deben solicitar la cantidad de recursos necesarios a través de opciones adicionales. Los más comunes son:
Muchos de los trabajos que se ejecutan en un clúster de producción implicarán más de un procesador (CPU, núcleo). Dichos trabajos paralelos deben solicitar la cantidad de recursos necesarios a través de opciones adicionales. Los más comunes son:


Para diferentes tipos de trabajos paralelos, se especificarán diferentes opciones. Los trabajos paralelos más comunes son trabajos de MPI (memoria distribuida), trabajos de subprocesos múltiples (memoria compartida) y los llamados híbridos que son una combinación de los dos. Analicemos por separado con un n ejemplo para cada uno.
Para diferentes tipos de trabajos paralelos, se especificarán diferentes opciones. Los trabajos paralelos más comunes son trabajos de MPI (memoria distribuida), trabajos de subprocesos múltiples (memoria compartida) y los llamados híbridos que son una combinación de los dos. Analicemos por separado con un n ejemplo para cada uno.


Ejecución de programas con MPI
=== Ejecución de programas con MPI ===
MPI (interfaz de paso de mensajes) es la API de comunicación estándar para trabajos paralelos de memoria distribuida capaz de implementarse en un clúster. Para programar dicho trabajo, es necesario especificar la cantidad de nodos del clúster que se utilizarán y la cantidad de procesos (tareas) que se ejecutarán en cada nodo.
MPI (interfaz de paso de mensajes) es la API de comunicación estándar para trabajos paralelos de memoria distribuida capaz de implementarse en un clúster. Para programar dicho trabajo, es necesario especificar la cantidad de nodos del clúster que se utilizarán y la cantidad de procesos (tareas) que se ejecutarán en cada nodo.


Línea 434: Línea 642:


Como empieza un shell script en Linux:
Como empieza un shell script en Linux:
<pre>
#!/bin/bash
</pre>


#!/bin/bash
Nombre del Job:
Nombre del Job:
<pre>
#SBATCH -J example_mpi
</pre>


#SBATCH -J example_mpi
Nombre la particion donde se desea ejecutar el trabajo:
Nombre la particion donde se desea ejecutar el trabajo:
<pre>
#SBATCH -p general
</pre>


#SBATCH -p general
Número de tareas. Debe de ser un número múltiplo del número de CPUs máximo que tenga un node de la partición donde se lanza:
Número de tareas. Debe de ser un número múltiplo del número de CPUs máximo que tenga un node de la partición donde se lanza:
<pre>
#SBATCH -n 264
</pre>


#SBATCH -n 264
Con esto se fuerza a que se lancen 44 tareas MPI en cada uno de los nodos, ocupando de este modo nodos completos. En este caso 6 nodos completos:
Con esto se fuerza a que se lancen 44 tareas MPI en cada uno de los nodos, ocupando de este modo nodos completos. En este caso 6 nodos completos:
<pre>
#SBATCH --ntasks-per-node=44
</pre>


#SBATCH --ntasks-per-node=44
Log de salida:
Log de salida:
<pre>
#SBATCH -o example_%j.out
</pre>


#SBATCH -o example_%j.out
Log de error:
Log de error:
<pre>
#SBATCH -e example_%j.err
</pre>


#SBATCH -e example_%j.err
Correo para notificaciones:
Correo para notificaciones:
<pre>
#SBATCH --mail-user=user@example.com
</pre>


#SBATCH --mail-user=user@example.com
Envía correo en todos los casos:
Envía correo en todos los casos:
<pre>
#SBATCH --mail-type=ALL
</pre>


#SBATCH --mail-type=ALL
Programa para ejecutar:
Programa para ejecutar:
<pre>
srun ./mpi_test
</pre>


srun ./mpi_test
'''Nota''': no se carga específicamente el módulo "mpi" ya que se carga siempre por defecto.
Nota: no se carga específica el módulo "mpi" ya que se carga siempre por defecto.


Para enviarlo al clúster debe ejecutar el comando: sbatch script.sh. El ejemplo anterior ejecutará una tarea OpenMPI con 264 procesos reservando 264 cores para ello.
Para enviarlo al clúster debe ejecutar el comando: ''sbatch script.sh''. El ejemplo anterior ejecutará una tarea OpenMPI con 264 procesos reservando 264 cores para ello.


Trabajos multiproceso OpenMP
=== Trabajos multiproceso OpenMP ===
Los trabajos paralelos diseñados para ejecutarse en un sistema multi-core (shared-memory) suelen ser "multi-threaded". La programación de un job de este tipo requiere especificar el número de núcleos que se utilizan para acomodar los subprocesos.
Los trabajos paralelos diseñados para ejecutarse en un sistema multi-core (shared-memory) suelen ser "multi-threaded". La programación de un job de este tipo requiere especificar el número de núcleos que se utilizan para acomodar los subprocesos.


OpenMP es el conjunto común de variables de compilación para facilitar el desarrollo de programas multi-threaded. Un script típico de SLURM para un programa de este tipo se ve así:
OpenMP es el conjunto común de variables de compilación para facilitar el desarrollo de programas multi-threaded. Un script típico de SLURM para un programa de este tipo se ve así:
 
<pre>
  #!/bin/bash
  #!/bin/bash
  #SBATCH -J OMPtest
  #SBATCH -J OMPtest
Línea 485: Línea 722:


  OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK time ./omp-program
  OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK time ./omp-program
</pre>
Como debe comenzar un script en Linux:
Como debe comenzar un script en Linux:
<pre>
#!/bin/bash
</pre>


#!/bin/bash
Nombre del Job:
Nombre del Job:
<pre>
#SBATCH -J OMPtest
</pre>


#SBATCH -J OMPtest
Nombre la particion donde desea ejecutar el Job:
Nombre la particion donde desea ejecutar el Job:
<pre>
#SBATCH -p general
</pre>


#SBATCH -p general
Número de trabajos:
Número de trabajos:
<pre>
#SBATCH -n 1
</pre>


#SBATCH -n 1
Número de tareas:
Número de tareas:
<pre>
#SBATCH -c 44
</pre>


#SBATCH -c 44
Con esto se fuerza a que se agrupen las 44 tareas en un nodo (en OpenMP no hay comunicación entre nodos, por lo que todas las tareas deben estar en el mismo nodo o no funcionaría):
Con esto se fuerza a que se agrupen las 44 tareas en un nodo (en OpenMP no hay comunicación entre nodos, por lo que todas las tareas deben estar en el mismo nodo o no funcionaría):
<pre>
#SBATCH --ntasks-per-node=44
</pre>


#SBATCH --ntasks-per-node=44
Memoria por core (MBytes):
Memoria por core (MBytes):
<pre>
#SBATCH --mem-per-cpu=1024
</pre>


#SBATCH --mem-per-cpu=1024
Log de salida:
Log de salida:
<pre>
#SBATCH -o example_%j.out
</pre>


#SBATCH -o example_%j.out
Log de error:
Log de error:
<pre>
#SBATCH -e example_%j.err
</pre>


#SBATCH -e example_%j.err
Correo para notificaciones:
Correo para notificaciones:
<pre>
#SBATCH --mail-user=user@example.com
</pre>


#SBATCH --mail-user=user@example.com
Enviar correo en todos los casos:
Enviar correo en todos los casos:
<pre>
#SBATCH --mail-type=ALL
</pre>


#SBATCH --mail-type=ALL
Programa para ejecutar:
Programa para ejecutar:
<pre>
OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK time ./omp-program
</pre>


OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK time ./omp-program
Cuando se utiliza un programa OpenMP, el número de subprocesos (y, por lo tanto, el número requerido de núcleos) se especifica a través de la variable de entorno OMP_NUM_THREADS que, por lo tanto, aparece en el script frente a la llamada al programa. Lo estamos configurando en la variable interna SLURM_CPUS_PER_TASK que se establece a través de la opción "-c" (a 44 en nuestro ejemplo, que sería el número total de cores de un nodo de la partición "general").
Cuando se utiliza un programa OpenMP, el número de subprocesos (y, por lo tanto, el número requerido de núcleos) se especifica a través de la variable de entorno OMP_NUM_THREADS que, por lo tanto, aparece en el script frente a la llamada al programa. Lo estamos configurando en la variable interna SLURM_CPUS_PER_TASK que se establece a través de la opción "-c" (a 44 en nuestro ejemplo, que sería el número total de cores de un nodo de la partición "general").


La opción "-n" se mantiene en 1 para indicar un único trabajo principal que tiene 44 tareas. Para asegurarnos que todas las tareas se ejecutan en el mismo nodo, se añade la opción "--ntasks-per-node" con el máximo número de cores que tiene un nodo de la partición donde se está lanzando el trabajo.
La opción "-n" se mantiene en 1 para indicar un único trabajo principal que tiene 44 tareas. Para asegurarnos que todas las tareas se ejecutan en el mismo nodo, se añade la opción "--ntasks-per-node" con el máximo número de cores que tiene un nodo de la partición donde se está lanzando el trabajo.


Ejecución de tareas en GPUs
=== Ejecución de tareas en GPUs ===
<pre>
#!/bin/bash
#!/bin/bash
#SBATCH -J ejemplo_gpus
#SBATCH -J ejemplo_gpus
#SBATCH -p gpus
#SBATCH -p v100
#SBATCH -n 1
#SBATCH -n 1
#SBATCH -o ejemplo_%j.out
#SBATCH -o ejemplo_%j.out
Línea 538: Línea 815:


./programa
./programa
</pre>


Inicio de un bash script en Linux:
Inicio de un bash script en Linux:
<pre>
#!/bin/bash
</pre>


#!/bin/bash
Nombre del trabajo:
Nombre del trabajo:
<pre>
#SBATCH -J ejemplo_gpus
</pre>


#SBATCH -J ejemplo_gpus
Nombre la partición donde se ejecuta el trabajo:
Nombre la partición donde se ejecuta el trabajo:
<pre>
#SBATCH --partition=v100
</pre>


#SBATCH --partition=gpus
Número de tareas:
Número de tareas:
<pre>
#SBATCH -n 1
</pre>


#SBATCH -n 1
Log de salida:
Log de salida:
<pre>
#SBATCH -o ejemplo_%j.out
</pre>


#SBATCH -o ejemplo_%j.out
Log de error:
Log de error:
<pre>
#SBATCH -e ejemplo_%j.err
</pre>


#SBATCH -e ejemplo_%j.err
Correo para notificaciones:
Correo para notificaciones:
<pre>
#SBATCH --mail-user=user@example.com
</pre>


#SBATCH --mail-user=user@example.com
Enviar correo en todos los casos:
Enviar correo en todos los casos:
<pre>
#SBATCH --mail-type=ALL
</pre>


#SBATCH --mail-type=ALL
Memoria por CPU (MB):
Memoria por CPU (MB):
<pre>
#SBATCH --mem-per-cpu=4365
</pre>


#SBATCH --mem-per-cpu=4365
Cantidad utilizada de GPUs. El parámetro gpu:1 indica la cantidad de tarjetas a utilizar (cada nodo tiene 2 GPUs):
Cantidad utilizada de GPUs. El parámetro gpu:1 indica la cantidad de tarjetas a utilizar (cada nodo tiene 2 GPUs):
<pre>
#SBATCH --gres=gpu:1
</pre>


#SBATCH --gres=gpu:1


Programa para ejecutar:
Programa para ejecutar:
<pre>
./programa
</pre>


./programa
=== Job Arrays ===
Job Arrays
Cuando se ejecutan cientos o miles de simulaciones que utilizan la misma cantidad de recursos, puede ser una ventaja ejecutar estas simulaciones como un "job array". Los job array le permiten enviar miles de dichos trabajos (llamados "job steps") con un solo script. A cada simulación se le asignará un valor único para la variable de entorno SLURM_ARRAY_TASK_ID. Puede usar esta variable para leer parámetros para pasos individuales de una línea dada de un archivo.
Cuando se ejecutan cientos o miles de simulaciones que utilizan la misma cantidad de recursos, puede ser una ventaja ejecutar estas simulaciones como un "job array". Los job array le permiten enviar miles de dichos trabajos (llamados "job steps") con un solo script. A cada simulación se le asignará un valor único para la variable de entorno SLURM_ARRAY_TASK_ID. Puede usar esta variable para leer parámetros para pasos individuales de una línea dada de un archivo.


Caso de uso de un Script Job Array (Gaussian)
=== Caso de uso de un Script Job Array (Gaussian) ===
Tenemos usuarios que actualmente envían varias simulaciones al clúster que son similares en cuanto al uso de recursos, pero, la diferencia es que solo cambia la entrada que le entregan al programa. Para esta situación, recomendamos hacer uso de un script Job Array.
Tenemos usuarios que actualmente envían varias simulaciones al clúster que son similares en cuanto al uso de recursos, pero, la diferencia es que solo cambia la entrada que le entregan al programa. Para esta situación, recomendamos hacer uso de un script Job Array.


Línea 582: Línea 892:


Script:
Script:
 
<pre>
#!/bin/bash
#!/bin/bash
# ----------------SLURM Parameters----------------
# ----------------SLURM Parameters----------------
Línea 603: Línea 913:
file=$(ls Child_10_*.com | sed -n ${SLURM_ARRAY_TASK_ID}p)
file=$(ls Child_10_*.com | sed -n ${SLURM_ARRAY_TASK_ID}p)
srun g16 $file
srun g16 $file
Descripción de comandos utilizados en script:
</pre>
 
'''
Descripción de comandos utilizados en script:'''


Inicio de un bash script en Linux:
Inicio de un bash script en Linux:
<pre>
#!/bin/bash
</pre>


#!/bin/bash
Nombre de la simulación:
Nombre de la simulación:
<pre>
#SBATCH -J prueba
</pre>


#SBATCH -J prueba
Nombre la partición donde se ejecuta la simulación:
Nombre la partición donde se ejecuta la simulación:
<pre>
#SBATCH -p slims
</pre>


#SBATCH -p slims
Número de tareas (1 tarea va a ejecutar 63 simulaciones):
Número de tareas (1 tarea va a ejecutar 63 simulaciones):
<pre>
#SBATCH -n 1
</pre>


#SBATCH -n 1
Core’s por tareas (cada tarea utilizará un máximo 8 cores):
Core’s por tareas (cada tarea utilizará un máximo 8 cores):
<pre>
#SBATCH -c 8
</pre>


#SBATCH -c 8
Memoria ram por cpu (cada tarea utilizará un máximo 8 Gb de ram):
Memoria ram por cpu (cada tarea utilizará un máximo 8 Gb de ram):
<pre>
#SBATCH –mem-per-cpu=1000
</pre>


#SBATCH –mem-per-cpu=1000
Correo para activar el envío de notificaciones:
Correo para activar el envío de notificaciones:
<pre>
#SBATCH --mail-user=prueba@nlhpc.cl
</pre>


#SBATCH --mail-user=prueba@nlhpc.cl
Permitir envío de notificaciones:
Permitir envío de notificaciones:
<pre>
#SBATCH --mail-type=ALL
</pre>


#SBATCH --mail-type=ALL
Se generan 63 simulaciones diferentes:
Se generan 63 simulaciones diferentes:
<pre>
#SBATCH --array=1-63
</pre>


#SBATCH --array=1-63
Log de salida: (ejemplo: prueba_18455017_1.out)
Log de salida: (ejemplo: prueba_18455017_1.out)


%A corresponde al Job ID de nuestra tarea que le asignará Slurm → 18455017.
* %A corresponde al Job ID de nuestra tarea que le asignará Slurm → 18455017.
* %a corresponde a la simulación X de nuestra tarea que le asignará Slurm → 1.
<pre>
#SBATCH -o prueba_%A_%a.out
</pre>


%a corresponde a la simulación X de nuestra tarea que le asignará Slurm → 1.


#SBATCH -o prueba_%A_%a.out
Log de errores: (ejemplo: prueba_18455017_1.err)
Log de errores: (ejemplo: prueba_18455017_1.err)


%A corresponde al Job ID de nuestra tarea que le asignará Slurm → 18455017.
* %A corresponde al Job ID de nuestra tarea que le asignará Slurm → 18455017.
 
* %a corresponde a la simulación X de nuestra tarea que le asignará Slurm → 1.
%a corresponde a la simulación X de nuestra tarea que le asignará Slurm → 1.


<pre>
#SBATCH -e prueba_%A_%a.err
#SBATCH -e prueba_%A_%a.err
Toolchain: en este apartado, limpiaremos nuestro entorno de software no deseados y luego escogemos la herramienta informática con la cual está compilado el software Gaussian (nosotros utilizamos el compilador Intel/2019b).
Toolchain: en este apartado, limpiaremos nuestro entorno de software no deseados y luego escogemos la herramienta informática con la cual está compilado el software Gaussian (nosotros utilizamos el compilador Intel/2019b).
Línea 660: Línea 1002:
file=$(ls Child_10_*.com | sed -n ${SLURM_ARRAY_TASK_ID}p)
file=$(ls Child_10_*.com | sed -n ${SLURM_ARRAY_TASK_ID}p)
srun g16 $file
srun g16 $file
</pre>
file= variable que va a listar los archivos de entrada que comiencen por Child_10_ y terminen en .com
file= variable que va a listar los archivos de entrada que comiencen por Child_10_ y terminen en .com


Child.png
[[Archivo:Child.png|no]]
 


sed -n ${SLURM_ARRAY_TASK_ID}p) ← Sed imprimirá las líneas de cada archivo de entrada y la variable $SLURM_ARRAY_TASK_ID asumirá estas entradas como matriz de simulación en nuestro job array, en este ejemplo tenemos 63 archivos de entrada.
sed -n ${SLURM_ARRAY_TASK_ID}p) ← Sed imprimirá las líneas de cada archivo de entrada y la variable $SLURM_ARRAY_TASK_ID asumirá estas entradas como matriz de simulación en nuestro job array, en este ejemplo tenemos 63 archivos de entrada.
Línea 671: Línea 1015:


Enviar el script:
Enviar el script:
<pre>
[prueba@leftraru1 ~]$ sbatch prueba.sh
</pre>


[prueba@leftraru1 ~]$ sbatch prueba.sh
=== Ejecución de una tarea que ocupa mucha RAM por CPU ===
Ejecución de una tarea que ocupa mucha RAM por CPU
Debemos tener en cuenta que la RAM que SLURM reserva por defecto son 1000 MB. Un típico error de cancelación de tarea por falta de memoria es el siguiente:
Debemos tener en cuenta que la RAM que SLURM reserva por defecto son 1000 MB. Un típico error de cancelación de tarea por falta de memoria es el siguiente:
 
<pre>
/tmp/slurmd/job136839939/slurm_script: line 15: 23547 Killed                  ./programa.sh
/tmp/slurmd/job136839939/slurm_script: line 15: 23547 Killed                  ./programa.sh
slurmstepd: error: Detected 1 oom-kill event(s) in step 136839939.batch cgroup. Some of your processes  
slurmstepd: error: Detected 1 oom-kill event(s) in step 136839939.batch cgroup. Some of your processes  
may have been killed by the cgroup out-of-memory handler.
may have been killed by the cgroup out-of-memory handler.
</pre>
Si su tarea ocupa más de la memoria por defecto, puede utilizar el siguiente parámetro:
Si su tarea ocupa más de la memoria por defecto, puede utilizar el siguiente parámetro:
 
<pre>
#SBATCH --mem-per-cpu=2300 #Máxima RAM por CPU
#SBATCH --mem-per-cpu=2300 #Máxima RAM por CPU
</pre>
Esto hará que SLURM reserve más RAM por CPU para sus tareas.
Esto hará que SLURM reserve más RAM por CPU para sus tareas.


Tenga en cuenta que nuestros nodos tienen 46 GB de memoria RAM (Partición slims), 187 GB (Partición general) y 765 GB (Partición largemem) por nodo. Más información.
Tenga en cuenta que nuestros nodos tienen 46 GB de memoria RAM (Partición slims), 187 GB (Partición general) y 765 GB (Partición largemem) por nodo. [https://wiki.nlhpc.cl/Hardware_Disponible Más información].


Otra forma de reservar memoria es utilizando el siguiente parámetro:
Otra forma de reservar memoria es utilizando el siguiente parámetro:


<pre>
#SBATCH --mem=2300
#SBATCH --mem=2300
</pre>
En este caso SLURM realizará una reserva de memoria de 2300 MB pero por la totalidad del trabajo.
En este caso SLURM realizará una reserva de memoria de 2300 MB pero por la totalidad del trabajo.


Los parámetros anteriores al igual que el número de CPUs que se van a usar, hay que afinarlos lo mejor posible. Para ello lo que se puede hacer es hacer pruebas en los nodos logins, sin lanzar en las colas, y así estudiar el uso de RAM y CPU por parte de sus procesos.
Los parámetros anteriores al igual que el número de CPUs que se van a usar, hay que afinarlos lo mejor posible. Para ello lo que se puede hacer es hacer pruebas en los nodos logins, sin lanzar en las colas, y así estudiar el uso de RAM y CPU por parte de sus procesos.


Ejecución de una tarea con Dependencias
=== Ejecución de una tarea con Dependencias ===
Las dependencias de trabajos se utilizan para aplazar el inicio de un trabajo hasta que se satisfagan las dependencias especificadas. Se especifican con la opción --dependency en el siguiente formato:
Las dependencias de trabajos se utilizan para aplazar el inicio de un trabajo hasta que se satisfagan las dependencias especificadas. Se especifican con la opción --dependency en el siguiente formato:
 
<pre>
sbatch --dependency=<type:job_id[:job_id][,type:job_id[:job_id]]> ...
sbatch --dependency=<type:job_id[:job_id][,type:job_id[:job_id]]> ...
</pre>
Los tipos de dependencias son las siguientes:
Los tipos de dependencias son las siguientes:


after:jobid[:jobid...] - el trabajo puede empezar después de que los trabajos especificados comiencen
* '''after''':jobid[:jobid...] - el trabajo puede empezar después de que los trabajos especificados comiencen
afterany:jobid[:jobid...] - el trabajo puede empezar después de que los trabajos especificados terminen
* '''afterany''':jobid[:jobid...] - el trabajo puede empezar después de que los trabajos especificados terminen
afternotok:jobid[:jobid...] - el trabajo puede empezar después que los trabajos especificados terminan fallidamente
* '''afternotok''':jobid[:jobid...] - el trabajo puede empezar después que los trabajos especificados terminan fallidamente
afterok:jobid[:jobid...] - el trabajo puede empezar después que los trabajos especificados terminan exitósamente
* '''afterok''':jobid[:jobid...] - el trabajo puede empezar después que los trabajos especificados terminan exitósamente


La manera más simple de usar una dependencia del tipo afterok:
La manera más simple de usar una dependencia del tipo afterok:
 
<pre>
[prueba@leftraru1 ~]$ sbatch job1.sh
[prueba@leftraru1 ~]$ sbatch job1.sh
Submitted batch job 21363626
Submitted batch job 21363626
[prueba@leftraru1 ~]$ sbatch --dependency=afterok:21363626 job2.sh
[prueba@leftraru1 ~]$ sbatch --dependency=afterok:21363626 job2.sh
</pre>
Ahora cuando job1.sh termine correctamente, el job2.sh entrará en ejecución. Si job1.sh termina fallidamente, job2.sh no entrará en ejecución nunca pero sí quedará en cola (debe cancelarse manualmente el trabajo).
Ahora cuando job1.sh termine correctamente, el job2.sh entrará en ejecución. Si job1.sh termina fallidamente, job2.sh no entrará en ejecución nunca pero sí quedará en cola (debe cancelarse manualmente el trabajo).


==== Capturando el Job ID para facilitar la ejecución de varias tareas con dependencias ====
Es posible capturar en una variable el Job ID de cada tarea para poder lanzar varias tareas sin conocer el Job ID previamente.
Por ejemplo, si se desea lanzar 4 tareas que sean dependientes con la anterior, se comenzará lanzando la primera tarea y capturando en la variable '''$JOB1''', el que será utilizado como dependencia en la tarea '''$JOB2''', y así sucesivamente.
<pre>
JOB1=$(sbatch job_1.sbatch 2>&1 | awk '{print $4}')
JOB2=$(sbatch --dependency=afterok:$JOB1 job_2.sbatch 2>&1 | awk '{print $4}')
JOB3=$(sbatch --dependency=afterok:$JOB2 job_3.sbatch 2>&1 | awk '{print $4}')
JOB4=$(sbatch --dependency=afterok:$JOB3 job_4.sbatch 2>&1 | awk '{print $4}')
</pre>


Prioridad de tarea
== Prioridad de tarea ==
Cómo ver la prioridad del trabajo. Los factores que determinan la prioridad del trabajo, incluyendo la fórmula y pesos.
Cómo ver la prioridad del trabajo. Los factores que determinan la prioridad del trabajo, incluyendo la fórmula y pesos.


Factores que determinan prioridad de tarea
=== Factores que determinan prioridad de tarea ===
Comando SLURM Descripción
<table class="wikitable" style="width: 60%;">
Edad la cantidad de tiempo que el trabajo ha estado esperando en la cola.
<tr>
Tamaño de la tarea número de nodos solicitados por el trabajo.
<td><b>Comando SLURM</b></td>
Partición prioridad para una partición determinada.
<td><b>Descripción</b>
Prioridad Baja Mientras más tareas se ejecuten en el cluster, menor será la prioridad.
</td></tr>
Prioridad Alta Mientras menos tareas se ejecuten en el clúster, más alta es la prioridad.
<tr>
Prioridad de tarea
<td>Edad</td>
<td>la cantidad de tiempo que el trabajo ha estado esperando en la cola.
</td></tr>
<tr>
<td>Tamaño de la tarea</td>
<td>número de nodos solicitados por el trabajo.
</td></tr>
<tr>
<td>Partición</td>
<td>prioridad para una partición determinada.
</td></tr>
<tr>
<td>Prioridad Baja</td>
<td>Mientras más tareas se ejecuten en el cluster, menor será la prioridad.
</td></tr>
<tr>
<td>Prioridad Alta</td>
<td>Mientras menos tareas se ejecuten en el clúster, más alta es la prioridad.
</td></tr></table>
 
== Prioridad de tarea ==
Cómo ver la prioridad del trabajo. Los factores que determinan la prioridad del trabajo, incluyendo la fórmula y pesos.
Cómo ver la prioridad del trabajo. Los factores que determinan la prioridad del trabajo, incluyendo la fórmula y pesos.


Factores que determinan prioridad de tarea
=== Factores que determinan prioridad de tarea ===
Edad - la cantidad de tiempo que el trabajo ha estado esperando en la cola
* Edad - la cantidad de tiempo que el trabajo ha estado esperando en la cola
Tamaño Oficio - número de nodos solicitados por el trabajo
* Tamaño Oficio - número de nodos solicitados por el trabajo
Partición - prioridad para una partición determinada
* Partición - prioridad para una partición determinada
Contribución de prioridades basada en los recursos informáticos utilizados por los miembros de un grupo de investigación en los últimos 30 días - Fairshare.
* Contribución de prioridades basada en los recursos informáticos utilizados por los miembros de un grupo de investigación en los últimos 30 días - Fairshare.
Mientras más tareas se ejecuten en el cluster, menor será la prioridad.
* Mientras más tareas se ejecuten en el cluster, menor será la prioridad.
Mientras menos tareas se ejecuten en el clúster, más alta es la prioridad.
* Mientras menos tareas se ejecuten en el clúster, más alta es la prioridad.
Fórmula Prioridad de tarea
Fórmula Prioridad de tarea
<pre>
Job_priority =
Job_priority =
   (PriorityWeightAge) * (age_factor) +
   (PriorityWeightAge) * (age_factor) +
Línea 739: Línea 1126:
   (PriorityWeightPartition) * (partition_factor) +
   (PriorityWeightPartition) * (partition_factor) +
   (PriorityWeightQOS) * (QOS_factor)
   (PriorityWeightQOS) * (QOS_factor)
Visualización de sus Tareas
</pre>
 
== Visualización de sus Tareas ==
Si Ud. necesita visualizar información acerca de sus tareas de forma interactiva, puede utilizar el comando smap:
Si Ud. necesita visualizar información acerca de sus tareas de forma interactiva, puede utilizar el comando smap:


smap -i 3
smap -i 3
Smap.png
 
[[Archivo:Smap.png|no|700px]]




De esta forma, tendrá una actualización cada 3 segundos de sus tareas en ejecución incluyendo los nodos en los cuales se encuentran ejecutándose.
De esta forma, tendrá una actualización cada 3 segundos de sus tareas en ejecución incluyendo los nodos en los cuales se encuentran ejecutándose.


Bibliografía
== Bibliografía ==
Manual Oficial de Slurm
[http://slurm.schedmd.com/documentation.html Manual Oficial de Slurm]


Documentación scrontab
[https://slurm.schedmd.com/scrontab.html Documentación scrontab]

Revisión actual - 15:07 20 nov 2024

SLURM Workload Manager

Es un sistema de programación de trabajos y gestión de clústeres de código abierto, tolerante a fallas y altamente escalable para clústeres Linux grandes y pequeños.

Como administrador de carga de trabajo de clúster, Slurm tiene tres funciones clave. Primero, asigna acceso exclusivo y / o no exclusivo a los recursos (nodos de cómputo) a los usuarios durante un período de tiempo para que puedan realizar el trabajo. En segundo lugar, proporciona un marco para iniciar, ejecutar y monitorear el trabajo (normalmente un trabajo paralelo) en el conjunto de nodos asignados. Finalmente, arbitra la contención de recursos mediante la gestión de una cola de trabajo pendiente.

SLURM es el gestor de colas instalado en muchos de los súper computadores del TOP500, y también en el clúster del NLHPC. Si Ud. quiere lanzar tareas dentro de Leftaru, debe hacerlo a través de Slurm.

Conceptos clave

SLURM gestiona trabajos de usuario que tienen las siguientes características clave:

  • Conjunto de recursos solicitados:
    • Número de recursos informáticos: nodos (incluidas todas sus CPUs y núcleos) o CPUs (incluidos todos sus núcleos) o solo núcleos
    • Cantidad de memoria: por nodo o por CPU (lógica)
    • Tiempo necesario para que las tareas del usuario completen su trabajo
  • Una partición de nodo solicitada (cola de trabajos)
  • Un nivel de calidad de servicio (QoS) solicitado que otorga a los usuarios accesos específicos
  • Una cuenta solicitada con recursos limitados

De manera predeterminada, los usuarios envían trabajos a una partición particular (marcada como tal para todos los usuarios) y bajo una cuenta particular (preestablecida por usuario).

Particiones SLURM

Nombre Particion Nodos CPUs RAM Descripción
main 27 256 768GB
general 48 44 187GB
largemem 9 44 765GB
v100 2 44 187GB 4 GPUs Nvidia Tesla V100.
mi100 1 128 502GB 2 GPUs AMD Instinct MI100.
mi210 2 24 1457GB 6 GPUs AMD Instinct MI210.
debug 2 48 768GB Destinados a pruebas de máximo 30 minutos.

Introducción a los comandos slurm

Comando SLURM Descripción
srun ejecutar un comando en nodos de cómputo asignados.
sbatch presentar un script de trabajo
squeue Mostrar estado de los trabajos en la cola.
scancel eliminar un trabajo.
sinfo Muestra el estado de los nodos de cómputo.

Estos son los comandos básicos utilizados para realizar la mayoría de las operaciones básicas con SLURM.

Estado de nodos

Para consultar el uso de nuestra infraestructura y qué particiones están más libres, le recomendamos el comando sinfo:

# sinfo<small>
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
main*        up   infinite      1  idle mn[016,018]
main*        up   infinite     21    mix mn[001-003,005,007-011,013,015,017,019-027]
main*        up   infinite      4  alloc mn[004,006,012,014]
general      up   infinite      1  drain sn041
general      up   infinite     16    mix sn[005-007,012-015,019-021,030-031,043-048]
general      up   infinite     31  alloc sn[001-004,008-011,016-018,022-029,032-040]
largemem     up   infinite      1    mix fn006
largemem     up   infinite      8  alloc fn[001-005,007-009]
debug        up   infinite      2   idle leftraru[1-2]
v100         up   infinite      2    mix gn[001-002]
mi100        up   infinite      1   idle gn003
mi210        up   infinite      1    mix gn004
mi210        up   infinite      1   idle gn005</small>

Fijándose en el texto resaltado de la salida del comando sinfo, se puede comprobar que en la partición main hay 20 nodos que están completamente ocupados (estado alloc), 7 nodos que están libres (idle); por otro lado, en la partición general hay 22 nodos completamente ocupados, 4 parcialmente ocupados y 22 libres. Dado este escenario, está claro que debería de lanzar sus ejecuciones en los nodos de la partición general, por las razones anteriormente expuestas.

Para lanzar en la partición general, debe tener en cuenta que tiene que indicar en su script que se use dicha partición en vez de, probablemente, main. Por supuesto, en esta partición cambian las características técnicas, se pasan a tener 44 cores por nodo (en vez de 256 en main) y una capacidad RAM de 187GB (en vez de 768GB en main). Puede ver más información de las particiones en este link(agregar link), donde podrá revisar que con la inclusión de Guacolda hemos añadido nodos con hasta 765GB de memoria RAM y nodos con GPUs Nvidia Tesla V100 y AMD Instinct MI100 .

Para ver los nodos disponibles y poder determinar en que partición lanzar los trabajos se recomienda utilizar el siguiente comando.

[prueba@leftraru1 ~]$ sinfo -o "%10P %6D %10t %10m %c" -t idle| egrep "PARTITION|main|general|largemem|v100|mi100|mi210"
PARTITION  NODES  STATE      MEMORY     CPUS
PARTITION  NODES  STATE      MEMORY     CPUS
main*      2      idle       727000     256
general    0      n/a        0          0
largemem   0      n/a        0          0
v100       0      n/a        0          0
mi100      1      idle       485000     128
mi210      1      idle       1457000    48

El comando anterior muestra que main tiene 27 nodos libres, en este caso es recomendado lanzar en en main para evitar que el trabajo quede en cola por falta de recursos en otros nodos.

Otro Ejemplo, se muestra sólo una partición específica

[prueba@leftraru1 ~]$ sinfo -p main
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
main*        up   infinite     15    mix mn[001-008,014-020]
main*        up   infinite     12   idle mn[009-013,021-027]

Comprobación del estado de tareas

squeue - Muestra el estatus de los trabajos

squeue                  # tus trabajos
squeue -u <username>    # trabajos por usuario <username>

squeue: Comprobar estados de los trabajos

  JOBID        PARTITION     NAME     USER    ST       TIME  	NODES 	NODELIST(REASON)
13951858_1     general	     test1    test1    R   1-18:35:14      2    cn[009-010]
13951857_2     general       test2    test1    R   1-18:36:11      2    cn[099-100]
13956453       gpu           test3    test3    R   1-03:42:08      1    cn039
13956449       largemem      test4    test4    R   1-05:42:08      1    cn044

Puede utilizar squeue para saber el estado de una o varias de sus tareas

$ squeue -o "%.15i %.6P %.8j %.20S %.11M %.11L %.20V %.10Q %.4C %.2D %.6m" -S -t,-Q
 JOBID   PARTIT     NAME      START_TIME          TIME      TIME_LEFT     SUBMIT_TIME       PRIORITY CPUS NO MIN_ME
10837561 general   TEST1   2018-06-18T18:51:01    19:00:31  2-04:59:29  2018-06-18T18:51:01  119972    1  1  1000M
10838562 general   TEST2   2018-06-19T11:30:47    2:20:45   2-21:39:15  2018-06-19T11:30:46  119946    1  1  1000M


para mas opciones puede revisar con el comando man squeue las opciones restantes.

Códigos de ESTADO de los trabajos

Los trabajos suelen pasar por varios estados durante su ejecución. Los estados típicos son PENDIENTE, EN EJECUCIÓN, SUSPENDIDO, FINALIZANDO y TERMINADO. A continuación se explica cada estado.

BF BOOT_FAIL

   Trabajo finalizado debido a un fallo de arranque, normalmente debido a un fallo de hardware (por ejemplo, no se puede arrancar el nodo o bloque y el trabajo no se puede volver a poner en cola). 

CA CANCELADO

   El trabajo ha sido cancelado explícitamente por el usuario o el administrador del sistema. El trabajo puede haberse iniciado o no. 

CD TERMINADO

   El trabajo ha terminado todos los procesos en todos los nodos con un código de salida de cero. 

CF CONFIGURANDO

   Al trabajo se le han asignado recursos, pero están esperando a que estén listos para su uso (por ejemplo, arrancando). 

CG COMPLETANDO

   El trabajo está en proceso de finalización. Algunos procesos en algunos nodos pueden estar aún activos. 

DL FECHA LÍMITE

   El trabajo ha finalizado en la fecha límite. 

F FALLÓ

   Trabajo finalizado con un código de salida distinto de cero u otra condición de fallo. 

NF NODO_FAIL

   Trabajo finalizado debido al fallo de uno o más nodos asignados. 

OOM OUT_OF_MEMORY

   El trabajo ha experimentado un error de memoria insuficiente. 

PD PENDIENTE

   El trabajo está pendiente de asignación de recursos. 

PR PREEMPTED

   El trabajo ha finalizado debido a una espera. 

R EN MARCHA

   El trabajo tiene actualmente una asignación. 

RD RESV_DEL_HOLD

   El trabajo se está reteniendo después de que se eliminara la reserva solicitada. 

RF REQUEUE_FED

   El trabajo está siendo solicitado por una federación. 

RH REQUEUE_HOLD

   Se está volviendo a poner en cola un trabajo retenido. 

RQ REQUEUED

   Se está poniendo en cola un trabajo que se está completando. 

RS CAMBIO DE TAMAÑO

   El trabajo está a punto de cambiar de tamaño. 

RV REVOCADO

   El trabajo se ha retirado del clúster debido a que otro clúster ha iniciado el trabajo. 

SI SEÑALANDO

   El trabajo está siendo señalizado. 

SE SPECIAL_EXIT

   El trabajo se ha puesto en cola en un estado especial. Este estado puede ser establecido por los usuarios, normalmente en EpilogSlurmctld, si el trabajo ha terminado con un valor de salida particular. 

SO STAGE_OUT

   El trabajo está preparando los archivos. 

ST PARADO

   El trabajo tiene una asignación, pero la ejecución se ha detenido con la señal SIGSTOP. Los CPUS han sido retenidos por este trabajo. 

S SUSPENDIDO

   El trabajo tiene una asignación, pero se ha suspendido la ejecución y se han liberado CPUs para otros trabajos. 

TO TIMEOUT

   El trabajo ha finalizado al alcanzar su límite de tiempo.

Cancelar un trabajo

Con scancel se puede cancelar un trabajo en ejecución

scancel <jobID>         # Matar proceso <jobID>. (puede obtener el ID del job con "squeue")
scancel -u <username>   # Matar proceso por usuario <username>. 
[prueba@leftraru1 ~]$ squeue -u prueba
 JOBID  PARTITION    NAME     USER    ST   TIME  NODES  NODELIST(REASON)
 45594    main       TEST    prueba   R    0:59   3     mn[001-003]
[prueba@leftraru1 ~]$ scancel 45594
[prueba@leftraru1 ~]$ squeue -u prueba
JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
[prueba@leftraru1 ~]$

Ver estado de trabajos

Para revisar el detalle de las opciones de un trabajo: scontrol show job

$ scontrol show job 10837561
JobId=10837561 JobName=TEST1
   UserId=usuario(1000) GroupId=group(1000) MCS_label=N/A
   Priority=1100 Nice=0 Account=account QOS=120
   JobState=RUNNING Reason=None Dependency=(null)
   Requeue=0 Restarts=0 BatchFlag=1 Reboot=0 ExitCode=0:0
   DerivedExitCode=0:0
   RunTime=19:03:08 TimeLimit=3-00:00:00 TimeMin=N/A
   SubmitTime=2018-06-18T18:51:01 EligibleTime=2018-06-18T18:51:01
   StartTime=2018-06-18T18:51:01 EndTime=2018-06-21T18:51:01 Deadline=N/A
   PreemptTime=None SuspendTime=None SecsPreSuspend=0
   Partition=main AllocNode:Sid=leftraru2:5471
   ReqNodeList=(null) ExcNodeList=(null)
   NodeList=cn021
   BatchHost=cn021
   NumNodes=1 NumCPUs=1 NumTasks=1 CPUs/Task=1 ReqB:S:C:T=0:0:*:*
   TRES=cpu=1,mem=1000M,node=1
   Socks/Node=* NtasksPerN:B:S:C=1:0:*:* CoreSpec=*
     Nodes=cn021 CPU_IDs=1 Mem=1000 GRES_IDX=
   MinCPUsNode=1 MinMemoryCPU=1000M MinTmpDiskNode=0
   Features=(null) DelayBoot=00:00:00
   Gres=(null) Reservation=(null)
   OverSubscribe=OK Contiguous=0 Licenses=matlab Network=(null)
   Command=/home/usuario/script.sh
   WorkDir=/home/usuario/
   StdErr=/home/usuario/10837561_%x.err
   StdIn=/dev/null
   StdOut=/home/usuario/10837561_%x.out
   Power=
   BatchScript=

Para ver el script asociado a un trabajo: scontrol write batch_script <job_id> -

$ scontrol write batch_script 10837561 -
#!/bin/bash
#SBATCH -J nombre_del_trabajo
#SBATCH -p main
#SBATCH -n 1
#SBATCH --ntasks-per-node=1
#SBATCH --mail-user=usaurio@correo.cl
#SBATCH --mail-type=ALL
#SBATCH -o nombre_del_trabajo%j_%x.out
#SBATCH -e nombre_del_trabajo%j_%x.err
#SBATCH --license=matlab 
 
ml MATLAB/2017a

matlab -nodisplay -nosplash -nodesktop < programa.m

Ejecutando trabajos

Actualmente contamos con 2 metodos de enviar trabajos bajo SLURM: sbatch and srun. A veces puede ser ventajoso ejecutar un solo comando en el clúster como prueba o realizar rápidamente una operación con recursos adicionales. 'srun' permite a los usuarios hacer esto, y comparte las mismas variables que 'sbatch' . STDOUT y STDERR para un trabajo 'srun' serán redirigidos a la pantalla del usuario. Ctrl-C cancelará un trabajo srun. sbatch enviará un script de trabajo para que lo ejecute el clúster. Los scripts de trabajo bajo SLURM son simplemente scripts de shell (* .sh) con un conjunto de solicitudes de recursos en la parte superior del script.


Uso básico de srun:

srun <algúnComando>


Ejemplo de salida (ejecutando el comando "hostname" para saber en que nodo se está ejecutando):

 $ srun hostname
  cn003


Para enviar un script de trabajo a SLURM:

sbatch nombreScript.sh


Example output:

$ sbatch test-job.sh
Submitted batch job 1169

Variables Slurm

Las variables en esta sección son obligatorias, y SLURM las determina para determinar dónde y cuándo se ejecutarán sus trabajos. Si no asigna un valor para estos, el planificador asignará a sus trabajos el valor predeterminado. Si no solicita específicamente recursos para un trabajo, se le asignará un conjunto de recursos predeterminados. Para obtener una lista de todas las variables disponibles, consulte la documentación de SLURM en http://slurm.schedmd.com/sbatch.html. Las variables de este artículo estaban cubiertas porque eran las más relevantes para los casos de uso típicos.

Comando SLURM Descripción
--mem-per-cpu=<megabytes> Memoria requerida para el trabajo por CPU (en MegaBytes). El valor predeterminado es 1024 MB.
-p <partition>, --partition=<partition> Enviar un trabajo a una partición específica.
-n, --ntasks=<cantidad de tareas> Número de tareas que serán asignadas para el trabajo.
-c <cpus> Esta es la cantidad de CPU que necesita su trabajo. Tenga en cuenta que SLURM es relativamente generoso con las CPU, y el valor especificado aquí es el número "mínimo" de CPU que se asignará a su trabajo. Si hay CPU adicionales disponibles en un nodo más allá de lo solicitado, su trabajo recibirá esas CPU hasta que otros trabajos las necesiten. El valor predeterminado es 1 CPU. Intentar usar más CPU de las que se le asignaron dará como resultado que sus procesos adicionales se turnen en la misma CPU (ralentizando su trabajo).
-J <name>, --jobname=<name> Especifica un nombre a tu trabajo.
--mail-type=BEGIN,END,FAIL,ALL and --mail-user=<emailAddress> Enviar por correo electrónico cuando su trabajo comienza / termina / falla. Puede especificar varios valores para esto (separados por comas) si es necesario.
-o <STDOUT_log>, --output=<STDOUT_log> Redirija la salida a los archivos de registro que especifique. Por defecto, ambos, STDOUT and STDERR son enviados a este archivo. Puedes especificar %j como parte del nombre de archivo de registro para indicar la ID del trabajo (como ejemplo, "#SBATCH -o ouptut_%j.o" redirigiría la salida a "output_123456.o").
-e <STDERR_log>, --error=<STDERR_log> Redireccionar STDERR a un archivo separado. Funciona exactamente igual que "-o".
-t <days-hours:minutes:seconds> Walltime para tu trabajo. La duración del Walltime es el tiempo que espera que su trabajo se ejecute.
-a, --array=<índices> Envía una lista (arreglo) de trabajos identicos. Solo aplica para sbatch.


Los scripts de trabajo especifican los recursos solicitados y otras consideraciones especiales con comentarios especiales "#SBATCH" en la parte superior de un script de trabajo. Aunque muchas de estas opciones son opcionales, las varibles que se ocupan de solicitudes de recursos (CPU, memoria y tiempo) son obligatorias. Todas las variables deben agregarse a sus scripts de la siguiente manera:

#SBATCH <variable>

Para especificar un nombre al job, por ejemplo, debe agregar lo siguiente a su secuencia de comandos:

#SBATCH --job-name=nombreDeTrabajo

Enviar un script

 
 #!/bin/bash
 #SBATCH -J example
 #SBATCH -p general
 #SBATCH -n 1
 #SBATCH --output=example_%j.out
 #SBATCH --error=example_%j.err
 #SBATCH --mail-user=user@example.com
 #SBATCH --mail-type=ALL

Como debe comenzar un script en Linux:

#!/bin/bash


Nombre del trabajo:

#SBATCH -J example


Nombre la partición donde desea ejecutar el Job:

#SBATCH -p general


Número de tareas:

#SBATCH -n 1


Log de salida:

#SBATCH -o example_%j.out


Log de error:

#SBATCH -e example_%j.err


Correo para notificaciones:

#SBATCH --mail-user=user@example.com


Enviar correo en todos casos (verificar opciones arriba):

#SBATCH --mail-type=ALL

Programar tarea (uso de scrontab)

scrontab es una implementación del clásico planificador de tareas de linux crontab donde se guarda un listado de comandos a ejecutar en un tiempo determinado por el usuario.

Para acceder a scrontab utilice el siguiente comando:

[prueba@leftraru1 ~]$ scrontab -e

Esto le permitirá editar su archivo scrontab, asignando recursos como también el momento en que desea ejecutar su tarea. La estructura base a utilizar es la siguiente:

#SCRON -J mi_tarea
#SCRON -p main
#SCRON -n 1
#SCRON -c 1
#SCRON --mem-per-cpu=2300
#SCRON --mail-user=foo@bar.com
#SCRON --mail-type=ALL
#SCRON -o mi_tarea_%j.out
#SCRON -e mi_tarea_%j.err
# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  *     command to be executed
  • minute - Corresponde al minuto en que se va a ejecutar el script, valor de 0 a 59.
  • hour - Hora de ejecución, formato 24 horas, valor de 0 a 23, donde 0 son las 12:00 AM.
  • day of month - Día del mes, la tarea se puede ejecutar cada x día, valor de 1 a 31.
  • month - La tarea se puede ejecutar cada x mes, valor de 1 a 12.
  • day of week - Día de la semana, valor de 0 a 6, donde 0 es Domingo.
  • command to be executed - Script a ejecutar por el usuario.

Ejemplo envío de trabajo slurm:

Para la asignación de recursos, utilizaremos la directriz #SCRON, que utiliza los mismos parámetros usados por #SBATCH.

Luego de asignar los recursos debemos especificar el tiempo, en este caso la tarea será ejecutada todos los días cada 20 minutos, luego debemos indicar el script enviado por el usuario y guardamos los cambios en el archivo.

*/20 * * * * /home/prueba/ejemplo/script.sh

Es importante destacar que el script a lanzar /home/prueba/ejemplo/script.sh debe tener permisos de ejecución.

Para revisar el listado de tareas existentes en nuestro scrontab, ejecutamos el comando:

[prueba@leftraru1 ~]$ scrontab -l
*/20 * * * * /home/prueba/ejemplo/script.sh


Para borrar el contenido de nuestro scrontab:

[prueba@leftraru1 ~]$ scrontab -r

Información a considerar:

  • Generar archivos de salida correctamente
    • Para que el archivo error y out de tu script se generen en el directorio solicitado, ejemplo, /home/prueba/ejemplo/ en tu script debe estar presente el comando cd “/home/prueba/ejemplo”, esto hará que scrontab se posicione dentro del directorio de salida.
  • Es distinto el tiempo de programar el envío de una tarea (scrontab) a que una tarea inicie en el clúster (running), ya que esto dependerá de los recursos libres que existan en ese momento en el clúster.
  • Para revisar las tareas programadas debe ejecutar en cualquier nodo login el comando scrontab -l o revisar con el comando squeue:
[prueba@leftraru1 ~]$ squeue
24293471     main /home/eg  prueba PD       0:00      1 (BeginTime)

Checkpointing

Es la acción de guardar el estado de un proceso en ejecución en un archivo de imagen de punto de control. Este proceso se puede reiniciar más tarde desde el archivo del punto de control, continuando la ejecución desde donde se detuvo, en la misma computadora o en una diferente.

¿Por qué utilizarlo?

  • Permite ejecuciones de tarea largas que superen el tiempo de ejecución permitido en el cluster (30 días)
  • Estar preparados ante fallas del sistema que nos puedan hacer perder resultados de nuestras simulaciones

Utilización

Lo primero que debemos hacer en nuestro script es cargar el módulo de Mana:

ml mana/3.0.0

Este módulo provee 3 ejecutables que necesitaremos:

  • mana_coordinator: Coordina los checkpoints entre los distintos procesos
  • mana_launch: Inicia un proceso con checkpoint
  • mana_restart: Reinicia la ejecución desde una imagen del checkpoint

Necesitaremos 2 scripts para trabajar con checkpoints: Inicio y reinicio

Script de inicio (inicio.sh)

#!/bin/bash
##---------------SLURM Parameters - NLHPC ----------------
#SBATCH -J Testcheckpoint
#SBATCH -p general
#SBATCH -n 44
#SBATCH --ntasks-per-node=44
#SBATCH --mem-per-cpu=4363
#SBATCH --mail-user=test@nlhpc.cl
#SBATCH --mail-type=ALL
#SBATCH -o Testcheckpoint_%j.out
#SBATCH -e Testcheckpoint_%j.err

# ----------------Modules----------------------------
ml mana/3.0.0
# ----------------Command--------------------------
#Checkpointing cada 1 hora
mana_cooridinator -i3600
#Ejecutamos nuestra tarea con checkpointing
srun mana_launch ./ejecutable

Script de reinicio (reinicio.sh)

#!/bin/bash
##---------------SLURM Parameters - NLHPC ----------------
#SBATCH -J Testcheckpoint
#SBATCH -p general
#SBATCH -n 44
#SBATCH --ntasks-per-node=44
#SBATCH --mem-per-cpu=4363
#SBATCH --mail-user=test@nlhpc.cl
#SBATCH --mail-type=ALL
#SBATCH -o Testcheckpoint_%j.out
#SBATCH -e Testcheckpoint_%j.err

# ----------------Modules----------------------------
ml mana/3.0.0
# ----------------Command--------------------------
#Checkpointing cada 1 hora
mana_cooridinator -i3600
#Reiniciar nuestra tarea desde los archivos de checkpoint
srun mana_restart


Para correr estos scripts se puede hacer utilizando la funcionalidad de dependencias de SLURM:

[test@leftraru2 test]$ sbatch inicio.sh
Submitted batch job 23574685
[test@leftraru2 test]$ sbatch --dependency=afterok:23574685 reinicio.sh

Trabajos

Trabajos paralelos

Muchos de los trabajos que se ejecutan en un clúster de producción implicarán más de un procesador (CPU, núcleo). Dichos trabajos paralelos deben solicitar la cantidad de recursos necesarios a través de opciones adicionales. Los más comunes son:

Para diferentes tipos de trabajos paralelos, se especificarán diferentes opciones. Los trabajos paralelos más comunes son trabajos de MPI (memoria distribuida), trabajos de subprocesos múltiples (memoria compartida) y los llamados híbridos que son una combinación de los dos. Analicemos por separado con un n ejemplo para cada uno.

Ejecución de programas con MPI

MPI (interfaz de paso de mensajes) es la API de comunicación estándar para trabajos paralelos de memoria distribuida capaz de implementarse en un clúster. Para programar dicho trabajo, es necesario especificar la cantidad de nodos del clúster que se utilizarán y la cantidad de procesos (tareas) que se ejecutarán en cada nodo.

El siguiente es un ejemplo de ejecución de un programa compilado con Open MPI:

#!/bin/bash
#SBATCH -J example_mpi
#SBATCH -p general
#SBATCH -n 264
#SBATCH --ntasks-per-node=44
#SBATCH --output=example_%j.out
#SBATCH --error=example_%j.err
#SBATCH --mail-user=user@example.com
#SBATCH --mail-type=ALL

srun ./mpi_test

A continuacion se explica línea por líneael script.

Como empieza un shell script en Linux:

#!/bin/bash


Nombre del Job:

#SBATCH -J example_mpi


Nombre la particion donde se desea ejecutar el trabajo:

#SBATCH -p general


Número de tareas. Debe de ser un número múltiplo del número de CPUs máximo que tenga un node de la partición donde se lanza:

#SBATCH -n 264


Con esto se fuerza a que se lancen 44 tareas MPI en cada uno de los nodos, ocupando de este modo nodos completos. En este caso 6 nodos completos:

#SBATCH --ntasks-per-node=44


Log de salida:

#SBATCH -o example_%j.out


Log de error:

#SBATCH -e example_%j.err


Correo para notificaciones:

#SBATCH --mail-user=user@example.com


Envía correo en todos los casos:

#SBATCH --mail-type=ALL


Programa para ejecutar:

srun ./mpi_test

Nota: no se carga específicamente el módulo "mpi" ya que se carga siempre por defecto.

Para enviarlo al clúster debe ejecutar el comando: sbatch script.sh. El ejemplo anterior ejecutará una tarea OpenMPI con 264 procesos reservando 264 cores para ello.

Trabajos multiproceso OpenMP

Los trabajos paralelos diseñados para ejecutarse en un sistema multi-core (shared-memory) suelen ser "multi-threaded". La programación de un job de este tipo requiere especificar el número de núcleos que se utilizan para acomodar los subprocesos.

OpenMP es el conjunto común de variables de compilación para facilitar el desarrollo de programas multi-threaded. Un script típico de SLURM para un programa de este tipo se ve así:

 #!/bin/bash
 #SBATCH -J OMPtest
 #SBATCH -p general
 #SBATCH -n 1
 #SBATCH -c 44
 #SBATCH --ntasks-per-node=44
 #SBATCH --mem-per-cpu=1024
 #SBATCH -o example_%j.out
 #SBATCH -e example_%j.err
 #SBATCH --mail-user=user@example.com
 #SBATCH --mail-type=ALL

 OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK time ./omp-program


Como debe comenzar un script en Linux:

#!/bin/bash


Nombre del Job:

#SBATCH -J OMPtest


Nombre la particion donde desea ejecutar el Job:

#SBATCH -p general


Número de trabajos:

#SBATCH -n 1


Número de tareas:

#SBATCH -c 44


Con esto se fuerza a que se agrupen las 44 tareas en un nodo (en OpenMP no hay comunicación entre nodos, por lo que todas las tareas deben estar en el mismo nodo o no funcionaría):

#SBATCH --ntasks-per-node=44


Memoria por core (MBytes):

#SBATCH --mem-per-cpu=1024


Log de salida:

#SBATCH -o example_%j.out


Log de error:

#SBATCH -e example_%j.err


Correo para notificaciones:

#SBATCH --mail-user=user@example.com


Enviar correo en todos los casos:

#SBATCH --mail-type=ALL


Programa para ejecutar:

OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK time ./omp-program 


Cuando se utiliza un programa OpenMP, el número de subprocesos (y, por lo tanto, el número requerido de núcleos) se especifica a través de la variable de entorno OMP_NUM_THREADS que, por lo tanto, aparece en el script frente a la llamada al programa. Lo estamos configurando en la variable interna SLURM_CPUS_PER_TASK que se establece a través de la opción "-c" (a 44 en nuestro ejemplo, que sería el número total de cores de un nodo de la partición "general").

La opción "-n" se mantiene en 1 para indicar un único trabajo principal que tiene 44 tareas. Para asegurarnos que todas las tareas se ejecutan en el mismo nodo, se añade la opción "--ntasks-per-node" con el máximo número de cores que tiene un nodo de la partición donde se está lanzando el trabajo.

Ejecución de tareas en GPUs

#!/bin/bash
#SBATCH -J ejemplo_gpus
#SBATCH -p v100
#SBATCH -n 1
#SBATCH -o ejemplo_%j.out
#SBATCH -e ejemplo_%j.err
#SBATCH --mail-user=correo@gmail.com
#SBATCH --mail-type=ALL
#SBATCH --mem-per-cpu=4300
#SBATCH --gres=gpu:1

./programa


Inicio de un bash script en Linux:

#!/bin/bash


Nombre del trabajo:

#SBATCH -J ejemplo_gpus


Nombre la partición donde se ejecuta el trabajo:

#SBATCH --partition=v100


Número de tareas:

#SBATCH -n 1


Log de salida:

#SBATCH -o ejemplo_%j.out


Log de error:

#SBATCH -e ejemplo_%j.err


Correo para notificaciones:

#SBATCH --mail-user=user@example.com


Enviar correo en todos los casos:

#SBATCH --mail-type=ALL


Memoria por CPU (MB):

#SBATCH --mem-per-cpu=4365


Cantidad utilizada de GPUs. El parámetro gpu:1 indica la cantidad de tarjetas a utilizar (cada nodo tiene 2 GPUs):

#SBATCH --gres=gpu:1


Programa para ejecutar:

./programa

Job Arrays

Cuando se ejecutan cientos o miles de simulaciones que utilizan la misma cantidad de recursos, puede ser una ventaja ejecutar estas simulaciones como un "job array". Los job array le permiten enviar miles de dichos trabajos (llamados "job steps") con un solo script. A cada simulación se le asignará un valor único para la variable de entorno SLURM_ARRAY_TASK_ID. Puede usar esta variable para leer parámetros para pasos individuales de una línea dada de un archivo.

Caso de uso de un Script Job Array (Gaussian)

Tenemos usuarios que actualmente envían varias simulaciones al clúster que son similares en cuanto al uso de recursos, pero, la diferencia es que solo cambia la entrada que le entregan al programa. Para esta situación, recomendamos hacer uso de un script Job Array.

En este ejemplo crearemos un script job array para el software Gaussian, el cual, realizará 63 simulaciones, cada una de estas utilizará 8 cores y podrá alcanzar un uso máximo de 8 Gb de memoria ram. Para este caso utilizaremos la partición slims donde cada nodo tiene 46 Gb de memoria ram y 20 cores.

Script:

#!/bin/bash
# ----------------SLURM Parameters----------------
#SBATCH -J prueba
#SBATCH -p slims
#SBATCH -n 1
#SBATCH -c 8
#SBATCH --mem-per-cpu=1000
#SBATCH --mail-user=prueba@nlhpc.cl
#SBATCH --mail-type=ALL
#SBATCH --array=1-63
#SBATCH -o prueba_%A_%a.out
#SBATCH -e prueba_%A_%a.err
#-----------------Toolchain---------------------------
ml purge
ml intel/2019b
# ----------------Módulos-----------------------------
ml g16/B.01
# ----------------Comandos--------------------------
file=$(ls Child_10_*.com | sed -n ${SLURM_ARRAY_TASK_ID}p)
srun g16 $file

Descripción de comandos utilizados en script:

Inicio de un bash script en Linux:

#!/bin/bash


Nombre de la simulación:

#SBATCH -J prueba


Nombre la partición donde se ejecuta la simulación:

#SBATCH -p slims


Número de tareas (1 tarea va a ejecutar 63 simulaciones):

#SBATCH -n 1


Core’s por tareas (cada tarea utilizará un máximo 8 cores):

#SBATCH -c 8


Memoria ram por cpu (cada tarea utilizará un máximo 8 Gb de ram):

#SBATCH –mem-per-cpu=1000


Correo para activar el envío de notificaciones:

#SBATCH --mail-user=prueba@nlhpc.cl


Permitir envío de notificaciones:

#SBATCH --mail-type=ALL


Se generan 63 simulaciones diferentes:

#SBATCH --array=1-63


Log de salida: (ejemplo: prueba_18455017_1.out)

  • %A corresponde al Job ID de nuestra tarea que le asignará Slurm → 18455017.
  • %a corresponde a la simulación X de nuestra tarea que le asignará Slurm → 1.
#SBATCH -o prueba_%A_%a.out


Log de errores: (ejemplo: prueba_18455017_1.err)

  • %A corresponde al Job ID de nuestra tarea que le asignará Slurm → 18455017.
  • %a corresponde a la simulación X de nuestra tarea que le asignará Slurm → 1.
#SBATCH -e prueba_%A_%a.err
Toolchain: en este apartado, limpiaremos nuestro entorno de software no deseados y luego escogemos la herramienta informática con la cual está compilado el software Gaussian (nosotros utilizamos el compilador Intel/2019b).

#-----------------Toolchain---------------------------
ml purge
ml intel/2019b
Módulos: cargamos el software Gaussian versión 16/B.0.

# ----------------Módulos-----------------------------
ml g16/B.01
Comandos: aquí definimos los comandos a ejecutar.

# ----------------Comandos--------------------------
file=$(ls Child_10_*.com | sed -n ${SLURM_ARRAY_TASK_ID}p)
srun g16 $file

file= variable que va a listar los archivos de entrada que comiencen por Child_10_ y terminen en .com

Child.png


sed -n ${SLURM_ARRAY_TASK_ID}p) ← Sed imprimirá las líneas de cada archivo de entrada y la variable $SLURM_ARRAY_TASK_ID asumirá estas entradas como matriz de simulación en nuestro job array, en este ejemplo tenemos 63 archivos de entrada.

Para más detalles sobre los archivos stdin, stdout y stderr de una simulación % A será reemplazado por el valor de SLURM_ARRAY_JOB_ID que es el Job ID de nuestra tarea y %a será reemplazado por el valor de SLURM_ARRAY_TASK_ID que corresponde a la simulación X de nuestra tarea.

Srun g16 $file: ejecutará el comando gaussian g16 interpretando la variable $file en los nodos de cómputo asignados.

Enviar el script:

[prueba@leftraru1 ~]$ sbatch prueba.sh

Ejecución de una tarea que ocupa mucha RAM por CPU

Debemos tener en cuenta que la RAM que SLURM reserva por defecto son 1000 MB. Un típico error de cancelación de tarea por falta de memoria es el siguiente:

/tmp/slurmd/job136839939/slurm_script: line 15: 23547 Killed                  ./programa.sh
slurmstepd: error: Detected 1 oom-kill event(s) in step 136839939.batch cgroup. Some of your processes 
may have been killed by the cgroup out-of-memory handler.


Si su tarea ocupa más de la memoria por defecto, puede utilizar el siguiente parámetro:

#SBATCH --mem-per-cpu=2300 #Máxima RAM por CPU

Esto hará que SLURM reserve más RAM por CPU para sus tareas.

Tenga en cuenta que nuestros nodos tienen 46 GB de memoria RAM (Partición slims), 187 GB (Partición general) y 765 GB (Partición largemem) por nodo. Más información.

Otra forma de reservar memoria es utilizando el siguiente parámetro:

#SBATCH --mem=2300

En este caso SLURM realizará una reserva de memoria de 2300 MB pero por la totalidad del trabajo.

Los parámetros anteriores al igual que el número de CPUs que se van a usar, hay que afinarlos lo mejor posible. Para ello lo que se puede hacer es hacer pruebas en los nodos logins, sin lanzar en las colas, y así estudiar el uso de RAM y CPU por parte de sus procesos.

Ejecución de una tarea con Dependencias

Las dependencias de trabajos se utilizan para aplazar el inicio de un trabajo hasta que se satisfagan las dependencias especificadas. Se especifican con la opción --dependency en el siguiente formato:

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

Los tipos de dependencias son las siguientes:

  • after:jobid[:jobid...] - el trabajo puede empezar después de que los trabajos especificados comiencen
  • afterany:jobid[:jobid...] - el trabajo puede empezar después de que los trabajos especificados terminen
  • afternotok:jobid[:jobid...] - el trabajo puede empezar después que los trabajos especificados terminan fallidamente
  • afterok:jobid[:jobid...] - el trabajo puede empezar después que los trabajos especificados terminan exitósamente

La manera más simple de usar una dependencia del tipo afterok:

[prueba@leftraru1 ~]$ sbatch job1.sh
Submitted batch job 21363626
[prueba@leftraru1 ~]$ sbatch --dependency=afterok:21363626 job2.sh

Ahora cuando job1.sh termine correctamente, el job2.sh entrará en ejecución. Si job1.sh termina fallidamente, job2.sh no entrará en ejecución nunca pero sí quedará en cola (debe cancelarse manualmente el trabajo).

Capturando el Job ID para facilitar la ejecución de varias tareas con dependencias

Es posible capturar en una variable el Job ID de cada tarea para poder lanzar varias tareas sin conocer el Job ID previamente.

Por ejemplo, si se desea lanzar 4 tareas que sean dependientes con la anterior, se comenzará lanzando la primera tarea y capturando en la variable $JOB1, el que será utilizado como dependencia en la tarea $JOB2, y así sucesivamente.

JOB1=$(sbatch job_1.sbatch 2>&1 | awk '{print $4}')
JOB2=$(sbatch --dependency=afterok:$JOB1 job_2.sbatch 2>&1 | awk '{print $4}')
JOB3=$(sbatch --dependency=afterok:$JOB2 job_3.sbatch 2>&1 | awk '{print $4}')
JOB4=$(sbatch --dependency=afterok:$JOB3 job_4.sbatch 2>&1 | awk '{print $4}')

Prioridad de tarea

Cómo ver la prioridad del trabajo. Los factores que determinan la prioridad del trabajo, incluyendo la fórmula y pesos.

Factores que determinan prioridad de tarea

Comando SLURM Descripción
Edad la cantidad de tiempo que el trabajo ha estado esperando en la cola.
Tamaño de la tarea número de nodos solicitados por el trabajo.
Partición prioridad para una partición determinada.
Prioridad Baja Mientras más tareas se ejecuten en el cluster, menor será la prioridad.
Prioridad Alta Mientras menos tareas se ejecuten en el clúster, más alta es la prioridad.

Prioridad de tarea

Cómo ver la prioridad del trabajo. Los factores que determinan la prioridad del trabajo, incluyendo la fórmula y pesos.

Factores que determinan prioridad de tarea

  • Edad - la cantidad de tiempo que el trabajo ha estado esperando en la cola
  • Tamaño Oficio - número de nodos solicitados por el trabajo
  • Partición - prioridad para una partición determinada
  • Contribución de prioridades basada en los recursos informáticos utilizados por los miembros de un grupo de investigación en los últimos 30 días - Fairshare.
  • Mientras más tareas se ejecuten en el cluster, menor será la prioridad.
  • Mientras menos tareas se ejecuten en el clúster, más alta es la prioridad.

Fórmula Prioridad de tarea

Job_priority =
  (PriorityWeightAge) * (age_factor) +
  (PriorityWeightFairshare) * (fair-share_factor) +
  (PriorityWeightJobSize) * (job_size_factor) +
  (PriorityWeightPartition) * (partition_factor) +
  (PriorityWeightQOS) * (QOS_factor)

Visualización de sus Tareas

Si Ud. necesita visualizar información acerca de sus tareas de forma interactiva, puede utilizar el comando smap:

smap -i 3

Smap.png


De esta forma, tendrá una actualización cada 3 segundos de sus tareas en ejecución incluyendo los nodos en los cuales se encuentran ejecutándose.

Bibliografía

Manual Oficial de Slurm

Documentación scrontab