.. _job_array: ========= Job Array ========= .. contents:: Nesta seção: :local: :depth: 2 Job Array é uma funcionalidade do SLURM que permite submeter múltiplos jobs similares com um único script. É ideal para **High Throughput Computing (HTC)**. Conceito ======== Um job array é um conjunto de jobs independentes, cada um com seu próprio índice. Todos compartilham o mesmo script de submissão, mas podem processar dados diferentes baseados no índice. **Analogia:** Você contrata uma empresa de confecções (o Cluster HPC) e entrega um único molde (o script de job) e uma lista de parâmetros (os nomes das cores ou um intervalo de números, como 0 a 10). A empresa (Slurm) analisa o molde e disponibiliza 8 costureiras/os (CPUs) para trabalhar (processar) simultaneamente, cada costureira/o pegando um parâmetro (cor) diferente da lista usando o ``$SLURM_ARRAY_TASK_ID``. Quando Usar Job Array ===================== ✅ **Ideal para:** - Processamento de muitos arquivos independentes - Varredura de parâmetros (sweep) - Simulações de Monte Carlo - Análise de dados embaralhável (embarrassingly parallel) - Bootstrapping e validação cruzada ❌ **Não recomendado para:** - Jobs com dependência simultânea entre si - Comunicação entre jobs - Problemas que exigem sincronização Sintaxe Básica ============== .. code-block:: bash #!/bin/bash #SBATCH --array=1-100 #SBATCH -n 1 #SBATCH -t 01:00:00 echo "Meu índice é $SLURM_ARRAY_TASK_ID" Formatos de Array ================= 1. **Intervalo simples:** ``--array=1-100`` (índices 1 a 100) 2. **Lista específica:** ``--array=1,5,10,20,50`` 3. **Com passo:** ``--array=1-100:5`` (1,6,11,...,96) 4. **Com limite de simultâneos:** ``--array=1-1000%50`` (máximo de 50 jobs rodando ao mesmo tempo) Exemplos Práticos ================= Exemplo 1: Processamento de Múltiplos Arquivos ----------------------------------------------- Suponha que você tem 100 arquivos de entrada nomeados ``dados_1.dat``, ``dados_2.dat``, ..., ``dados_100.dat``. .. code-block:: bash :caption: processa_array.sh #!/bin/bash #SBATCH -J processa_dados #SBATCH --array=1-100 #SBATCH -n 1 #SBATCH -t 02:00:00 #SBATCH --mem=4G #SBATCH --output=logs/array_%A_%a.out #SBATCH --error=logs/array_%A_%a.err # Variáveis do job array # %A = Job ID do array # %a = Task ID (índice) mkdir -p resultados/ export INPUT="dados_${SLURM_ARRAY_TASK_ID}.dat" export OUTPUT="resultados/resultado_${SLURM_ARRAY_TASK_ID}.dat" module load python/3.9 job-nanny python processa.py $INPUT -o $OUTPUT Exemplo 2: Varredura de Parâmetros ----------------------------------- Para testar diferentes combinações de parâmetros: .. code-block:: bash :caption: sweep_array.sh #!/bin/bash #SBATCH -J sweep #SBATCH --array=1-27 #SBATCH -n 1 #SBATCH -t 04:00:00 # Definir combinações de parâmetros temperatura=(300 310 320 330 340 350 360 370 380) pressao=(1.0 1.5 2.0) catalisador=("Fe" "Ni" "Co") # Calcular índices i_temp=$(( ($SLURM_ARRAY_TASK_ID - 1) / 3 / 3 )) i_press=$(( ($SLURM_ARRAY_TASK_ID - 1) / 3 % 3 )) i_cat=$(( ($SLURM_ARRAY_TASK_ID - 1) % 3 )) T=${temperatura[$i_temp]} P=${pressao[$i_press]} CAT=${catalisador[$i_cat]} export INPUT="template.in" export OUTPUT="resultados/T${T}_P${P}_${CAT}/" # Substituir parâmetros no arquivo de entrada sed -e "s/TEMPERATURA/$T/g" \ -e "s/PRESSAO/$P/g" \ -e "s/CATALISADOR/$CAT/g" \ template.in > input_${SLURM_ARRAY_TASK_ID}.in job-nanny ./simular input_${SLURM_ARRAY_TASK_ID}.in Exemplo 3: Job Array com Limite de Simultâneos ----------------------------------------------- Para não sobrecarregar o sistema: .. code-block:: bash :caption: array_limitado.sh #!/bin/bash #SBATCH -J limitado #SBATCH --array=1-1000%50 # Máximo 50 jobs simultâneos #SBATCH -n 1 #SBATCH -t 01:00:00 # Processamento aqui ./meu_programa input_${SLURM_ARRAY_TASK_ID}.dat Exemplo 4: Job Array com Dependências -------------------------------------- Processamento em duas etapas: .. code-block:: bash # Submeter o array de processamento JOBID=$(sbatch --parsable --array=1-100 processa_array.sh) # Submeter job de pós-processamento (só após todos terminarem) sbatch --dependency=afterok:$JOBID pos_processamento.sh **pos_processamento.sh:** .. code-block:: bash :caption: pos_processamento.sh #!/bin/bash #SBATCH -J pos #SBATCH -n 1 #SBATCH -t 01:00:00 # Coletar todos os resultados e gerar sumário cat resultados/resultado_*.dat > todos_resultados.dat python gera_estatisticas.py todos_resultados.dat Variáveis de Ambiente ===================== =========================== ======================= ======= Variável Descrição Exemplo --------------------------- ----------------------- ------- ``$SLURM_ARRAY_JOB_ID`` ID do job array 123456 ``$SLURM_ARRAY_TASK_ID`` Índice da tarefa atual 42 ``$SLURM_ARRAY_TASK_COUNT`` Número total de tarefas 100 ``$SLURM_ARRAY_TASK_MIN`` Índice mínimo 1 ``$SLURM_ARRAY_TASK_MAX`` Índice máximo 100 =========================== ======================= ======= Monitoramento de Job Arrays =========================== Ver todos os jobs do array -------------------------- .. code-block:: bash squeue -u $USER -t PD,R -o "%.18i %.9P %.8j %.8u %.2t %.10M %.6D %R" **Exemplo de saída:** .. code-block:: text JOBID PARTITION NAME USER ST TIME NODES NODELIST 2940077_1 medium submit_job joao R 2-06:11:48 1 node032 2940077_2 medium submit_job joao R 2-04:31:51 1 node050 2940077_3 medium submit_job joao R 2-03:48:25 1 node040 2940077_4 medium submit_job joao PD 0:00 1 (Priority) 2940077_5 medium submit_job joao PD 0:00 1 (Priority) Cancelar um job array --------------------- .. code-block:: bash # Cancelar tarefa específica scancel 2940077_42 # Cancelar todo o array scancel 2940077 # Cancelar todas as tarefas pendentes do array scancel -t PD 2940077 Ver detalhes de uma tarefa -------------------------- .. code-block:: bash scontrol show job 2940077_42 Limitações ========== - **Máximo de jobs por array:** 1000 (configuração atual do GridUnesp) - **Máximo de jobs simultâneos:** Controlado por ``%N`` no array - **Recursos por job:** Cada tarefa do array pode ter suas próprias requisições - **Nomes de arquivos:** Use ``%A`` (job array ID) e ``%a`` (task ID) para evitar conflitos .. attention:: Atualmente o GridUnesp está configurado para aceitar no **máximo 1000 jobs por array**. Boas Práticas ============= 1. **Organize os arquivos de saída** .. code-block:: bash #SBATCH --output=logs/array_%A_%a.out #SBATCH --error=logs/array_%A_%a.err mkdir -p logs resultados 2. **Limite de jobs simultâneos** .. code-block:: bash #SBATCH --array=1-1000%50 # Não sobrecarrega o sistema 3. **Teste com um subconjunto primeiro** .. code-block:: bash #SBATCH --array=1-10 # Teste com 10 jobs antes de 1000 4. **Use nomes significativos** .. code-block:: bash #SBATCH -J sweep_temp_pressao 5. **Monitore o progresso** .. code-block:: bash squeue -u $USER | grep "seu_job" | wc -l # Contar jobs ativos Comparação: Job Array vs Jobs Individuais =========================================== .. list-table:: Comparação: Job Array vs Jobs Individuais :header-rows: 1 :widths: 30 35 35 * - Aspecto - Job Array - Jobs Individuais * - Submissão - 1 comando - N comandos * - Gerenciamento - Centralizado - Disperso * - Dependências - Fácil (afterok:JOBID) - Complexo * - Cancelamento - 1 comando ou seletivo - N comandos * - Limite de jobs - 1000 por array - 10000 no total * - Organização - Automática - Manual .. seealso:: - :ref:`processando_simulacoes` - Conceitos básicos de submissão - :ref:`otimizando_o_desempenho` - Estratégias HTC vs HPC - :ref:`melhorando_o_script_de_submissao` - Mais opções de script - :ref:`slurm_referencia` - Referência completa SLURM