Job Array
Uma outra forma de paralelismo é conhecida como bag-of-tasks (ou DAG). Ela ocorre quando são executadas diversas simulações completamente independentes umas das outras. Esse caso aparece com frequência quando se trabalha com um modelo parametrizado e são feitas simulações varrendo esses parâmetros, ou em simulações repetidas para ganhar significância estatística, como em modelos de Monte Carlo.
Diferentemente de paralelizações com memória distribuída ou compartilhada, no caso de bag-of-tasks não é necessário nenhuma alteração de código.
Com o Slurm é possível criar apenas um único script de execução de jobs que iniciará programas com diferentes parâmetros ou arquivos de entrada. Isso é chamado de Job Array.
A opção --array
permite que o usuário especifique uma sequência de valores que serão substituídos na variável de ambiente SLURM_ARRAY_TASK_ID. É possível passar uma lista de números (1,2,3,4), um intervalo (1-4) ou um intervalo com incrementos diferentes de 1, como em 1-10:3, que resulta em 1,4,7,10.
Essa variável pode ser usada como parâmetro na linha de comando. Em casos mais sofisticados, pode ser um índice em uma lista que contém o nome dos arquivos de entrada, quando esses não seguem uma regra simples.
Script de execução
#!/bin/bash
#SBATCH --array=1-7:2
# comentario: isso ee equivalente a --array=1,3,5,7
echo my ID is ${SLURM_ARRAY_TASK_ID}
Nota
Considerando a configuração atual do cluster, são permitidos, no máximo, 1000 jobs dentro de um único job array.
Dependência entre jobs
Em muitos casos é necessário fazer algum pós processamento quando todos os jobs do Job Array terminarem. Por exemplo, gerar alguma estatística ou selecionar o caso com o melhor resultado.
Isso pode ser obtido com a opção --depend
. Por exemplo:
sbatch --depend=after:<job_id> submit_job.sh
Exemplo
Vamos supor que que o usuário fulano queira executar uma aplicação científica (hipotética) chamada runCovid para simular a quantidade de pessoas infectadas e de óbitos condiderando 100 combinações distintas da probabilidade de contaminação e da porcentagem da população em isolamento social. Cada uma dessas combinações é acompanhada de uma miríade de outros parâmetros correlacionados contidos em 100 versões diferentes dos arquivos de input contam-XXX.in e isol-XXX.in (em que XXX varia de 1 a 100). Além disso, após estudos de optimização, vamos supor também que cada simulação terá duração máxima de 2 dias (-t 2-00
). O script de submissão hipotético seria algo como:
#!/bin/bash
#SBATCH -t 2-00 --array=1-100
export INPUT="contam-${SLURM_ARRAY_TASK_ID}.in isol-${SLURM_ARRAY_TASK_ID}.in"
export OUTPUT="casos-positivos.out obitos.out"
module load anaconda3
source activate sarscov2
job-nanny runCovid -in=contam-${SLURM_ARRAY_TASK_ID}.in,isol-${SLURM_ARRAY_TASK_ID}.in \
-out=casos-positivos.out,obitos.out
Supondo que o nome dado ao script acima seja submit_job_array.sh, ao executar o comando
sbatch submit_job_array.sh
o resultado na tela seria algo como
2940077_99 medium submit_j fulano PD 0:00 1 (Priority)
2940077_98 medium submit_j fulano PD 0:00 1 (Priority)
2940077_97 medium submit_j fulano PD 0:00 1 (Priority)
...
2940077_3 medium submit_j fulano R 2-03:48:25 1 node040
2940077_2 medium submit_j fulano R 2-04:31:51 1 node050
2940077_1 medium submit_j fulano R 2-06:11:48 1 node032
2940077_0 medium submit_j fulano R 2-08:41:52 1 node037
Nesse caso hipotético, algumas das simulações do job array já estão sendo executas, enquanto outras aguardam pela liberação de recursos.