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.