07 ‐ Submeter Jobs - arcarneiro/teste-doc-sdumont GitHub Wiki

Table of Contents

Informações gerais

O procedimento usual para a submissão de jobs no SDumont compreende:

  1. Compilar a aplicação dentro do HOMEDIR, utilizando os compiladores desejados
  2. Criar um script de submissão, configurando os parâmetros necessários para a execução do Job
  3. Copiar os arquivos necessários (script, executável, bibliotecas, dados de entrada, etc) para dentro da área de SCRATCH, pois a área de HOMEDIR não é acessível pelos nós computacionais
  4. Submeter o script com o comando sbatch
  5. Verificar os arquivos de saída
Observações
  • Nos scripts (jobs em batch) os parâmetros do SLURM devem ser precedidos por #SBATCH como será visto mais adiante.
  • Os scripts não precisam ser executáveis e nem precisam possuir uma extensão (.sh, .bash, etc), mas precisam iniciar com a linha #!/bin/bash.
  • Ressubmissão automática de Jobs: O comportamento padrão do Slurm é de reiniciar/ressubmeter um job quando ocorre uma falha em um dos nós alocados. Para desabilitar essa funcionalidade, basta incluir o parâmetro abaixo no script:
 #SBATCH --no-requeue

Início


Exemplos de Scripts

Apresentamos abaixo alguns templantes de scripts, que podem ser utilizados como modelo e adaptados para as necessidades. A maioria dos exemplos executam o benchmark NAS Parallel Benchmarks.

OBS: Ao longo da documentação e dos scripts de exemplo, o termo "Tarefas MPI" possui a mesma conotação de "processos MPI". Como exemplo, ao iniciar a execução de uma aplicação paralela com o comando mpirun -np 4, podemos dizer que esta executará 4 tarefas MPI ou 4 processos MPI.

Jobs Seriais

Forma geral do script

#!/bin/bash
#SBATCH --nodes=1                      #Para jobs seriais, deve utilizar sempre apenas um nó!
#SBATCH --ntasks=1                     #Para jobs seriais, deve utilizar sempre apenas uma tarefa!
#SBATCH -p FILA                        #Fila (partition) a ser utilizada
#SBATCH -J JOB			       #Nome job

#Exibe os nós alocados para o Job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST
cd $SLURM_SUBMIT_DIR

#Configura os compiladores
#-------------------------#
## 1) Carregar o módulo do compilador utilizado, conforme indicado na seção "Compiladores e MPI"
module load <compilador>/<versão>

## 2) Carregar o módulo da aplicação, caso necessário
module load <aplicacao>/<versão>

#Configura o executavel
EXEC=/scratch/CAMINHO/PARA/O/EXECUTAVEL

#exibe informações sobre o executável
/usr/bin/ldd $EXEC

#Inicia a execucao
srun $EXEC

OBS: Para aplicações seriais, não é necessário utilizar o comando srun para iniciar a aplicação, podendo executá-la diretamente na última linha do script de submissão (basta apenas remover o comando srun da última linha do script acima, deixando apenas o nome do binário a ser executado: $EXEC).

Exemplo de script

#!/bin/bash
#SBATCH --nodes=1            #Numero de Nós
#SBATCH --ntasks=1           #Numero de tarefas
#SBATCH -p sequana_cpu       #Fila (partition) a ser utilizada
#SBATCH -J exemplo_1_serial  #Nome job

#Exibe os nós alocados para o Job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST
cd $SLURM_SUBMIT_DIR

#Configura os compiladores GNU, versão 9.11
module load gcc/4.9.3_sequana

#Configura o executavel
EXEC=/scratch/app/NPB3.3.1-MZ/bin/cg.C.x

#exibe informações sobre o executável
/usr/bin/ldd $EXEC

#Inicia a execucao
srun $EXEC

Para submeter o script, utilizar o comando sbatch:

 sbatch /caminho/do/script.srm

Início


Jobs Paralelos (MPI)

Forma geral do script

#!/bin/bash
#SBATCH --nodes=N                      #Numero de Nós
#SBATCH --ntasks-per-node=TPN          #Numero de tarefas por Nó
#SBATCH --ntasks=T                     #Numero total de tarefas MPI
#SBATCH -p FILA                        #Fila (partition) a ser utilizada
#SBATCH -J JOB			       #Nome job

#Exibe os nós alocados para o Job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST
cd $SLURM_SUBMIT_DIR

#Configura os compiladores
#-------------------------#
## 1) Carregar o módulo do MPI utilizado, conforme indicado na seção "Compiladores e MPI"
module load <MPI>/<versão>

## 2) Carregar o módulo da aplicação, caso necessário
module load <aplicacao>/<versão>

#Configura o executavel
EXEC=/scratch/CAMINHO/PARA/O/EXECUTAVEL

#exibe informações sobre o executável
/usr/bin/ldd $EXEC

#Inicia a execucao
srun $EXEC

Exemplo 1 de script MPI

Utilizando o OpenMPI 4.1.4, alocando 4 nós, utilizando 24 tarefas MPI por nó, totalizando 96 tarefas, e alterando o limite de tempo.

*OBS: Por padrão, quando não especificado, o Slurm configura o WallCLock do job como a metade do limite da fila. Para alterar esse valor, basta utilizar o parâmetro --time=HH:MM:SS

Script rodarmpi.srm

#!/bin/bash
#SBATCH --nodes=4                      #Numero de Nós
#SBATCH --ntasks-per-node=24           #Numero de tarefas por Nó
#SBATCH --ntasks=96                    #Numero total de tarefas MPI
#SBATCH -p sequana_cpu                 #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-sp-intelmpi-24       #Nome job
#SBATCH --time=01:00:00		       #Altera o tempo limite para 1 hora

#Exibe os nós alocados para o Job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST

cd $SLURM_SUBMIT_DIR

#Configura os compiladores
module load openmpi/gnu/4.1.4_sequana

#Configura o executavel
EXEC=/scratch/app/NPB3.3.1-MZ/bin/bt-mz.C.x

#exibe informações sobre o executável
/usr/bin/ldd $EXEC

srun $EXEC

Submeter o job através do comando:

 sbatch rodarmpi.srm

Início


Jobs paralelos (threads/OpenMP)

Exemplos de script para aplicações que possuem paralelismo apenas através de Threads OpenMP, sem a capacidade de se dividir e utilizar múltiplos nós.

Exemplo 1 de script OpenMP

Utilizando os compiladores Intel e executando 48 threads. Para configurar o número de threads, é necessário configurar o parâmetro --cpus-per-task do SLURM no script de submissão.

O número nós e o número total de tarefas deve ser igual a 1.

Script rodaropenmp.srm

#!/bin/bash
#SBATCH --nodes=1                      #Numero de Nós deve ser igual a 1
#SBATCH --ntasks-per-node=1            #Numero de tarefas por Nó deve ser igual a 1
#SBATCH --ntasks=1                     #Numero total de tarefas deve ser igual a 1
#SBATCH --cpus-per-task=48             #Numero de threads
#SBATCH -p sequana_cpu_dev             #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-sp-openmp-intel      #Nome job

#Exibe os nós alocados para o Job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST

cd $SLURM_SUBMIT_DIR

#Configura os compiladores
module load intel_psxe/2020_sequana

#exibe informações sobre o executável
EXEC=/scratch/app/NPB3.3.1-MZ/bin/sp-mz.C.openmp-intel.x
/usr/bin/ldd  $EXEC

#Configura o numero de threads OpenMP com o valor passado para a variavel --cpus-per-task
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK

srun -c $SLURM_CPUS_PER_TASK $EXEC

Submeter o job através do comando:

 sbatch rodaropenmp.srm

Início


Jobs paralelos (MPI-multithreaded)

Scripts para aplicações que utilizam dois níveis de paralelismo: MPI + OpenMP.

Exemplo 1 de script

Utilizando os compiladores e MPI Intel, alocando 4 nós, distribuindo 1 processo MPI por nó, que abrirá 48 threads cada um.

  • Número de máquinas = 4 -> configurado através do parâmetro --nodes.
  • Número de tarefas MPI por Nó = 1 -> configurado através do parâmetro --ntasks-per-node.
  • Número total de tarefas MPI = 4 -> configurado através do parâmetro --ntasks, representando nodes * ntasks-per-node.
  • Número de threads que cada mpi abrirá = 48 -> configurado através do parâmetro --cpus-per-task.
No total, a aplicação executará com 192 processos (ou 192 threads), representando ntasks * cpus-per-task..

Script rodarmpi+openmp.srm

#!/bin/bash
#SBATCH --nodes=4                     #Numero de Nós
#SBATCH --ntasks-per-node=1           #Numero de tarefas por Nó
#SBATCH --ntasks=4                    #Numero total de tarefas MPI
#SBATCH --cpus-per-task=48            #Numero de threads por tarefa MPI
#SBATCH -p sequana_cpu_dev            #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-sp-intel-hybrid-4 #Nome job

#Exibe os nos alocados para o Job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST

cd $SLURM_SUBMIT_DIR

#Configura os compiladores
module load intel_psxe/2020_sequana

#exibe informaçoes sobre o executavel
EXEC=/scratch/app/NPB3.3.1-MZ/bin/sp-mz.C.intelmpi-hybrid.4
/usr/bin/ldd  $EXEC

#configura o numero de threads, de acordo com o parametro definido no SLURM
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK

srun -c $SLURM_CPUS_PER_TASK $EXEC

Submeter o job através do comando:

 sbatch rodarmpi+openmp.srm

Início


Múltiplas execuções simultâneas em um único job

É possível, dentro de um único job (script) executar múltiplas instâncias de uma mesma aplicação ou múltiplas aplicações distintas.

Dentro do conjunto solicitado de recursos (número de nós e de cores), é possível fazer uma divisão e iniciar a execução simultânea.

Por exemplo, solicitar 4 nós e executar:

  1. Uma aplicação em cada nó distinto
  2. Duas aplicações, cada uma executando em 2 nós
  3. Três aplicações, uma executando em dois nós e as outras duas executando em um nó cada
O importante é se atentar à quantidade de recursos solicitada e à divisão destes entre as aplicações.

Exemplo 1 de script

Alocando 4 nós, mas executando duas instâncias de uma mesma aplicação MPI, de forma independente e simultânea. Cada execução utilizará 2 nós e um total de 96 processos.

Script rodar.srm

#!/bin/bash
#SBATCH --nodes=4                   #Numero de Nós
#SBATCH --ntasks-per-node=48        #Numero de tarefas por Nó
#SBATCH --ntasks=192                #Numero total de tarefas MPI
#SBATCH -p sequana_cpu_dev          #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-bt-Multi          #Nome job

#Exibe os nos alocados para o Job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST

cd $SLURM_SUBMIT_DIR

#Configura os compiladores
module load openmpi/gnu/4.1.4_sequana

#Configura o executavel
EXEC=/scratch/app/NPB3.3.1-MZ/bin/bt-mz.C.x

/usr/bin/ldd  $EXEC

#configura o numero de threads como 1
export OMP_NUM_THREADS=1

srun --nodes=2 --ntasks=96 $EXEC > out.exec.1.txt 2>&1 &
srun --nodes=2 --ntasks=96 $EXEC > out.exec.2.txt 2>&1 &
wait

Submeter o job através do comando:

 sbatch rodar.srm

OBS:

  1. Necessário a inclusão do & ao final da linha de execução da aplicação, para poder iniciar em segundo plano.
  2. Necessário a inclusão do comando wait ao final do script, para aguardar a finalização da execução das aplicações em segundo plano. Do contrário, o script finalizaria a execução do job antes de obter os resultados.
  3. Necessário ajustar os parâmetros --nodes e --ntasks, na linha do srun, para poder dividir os recursos alocados (4 nós e um total de 192 tarefas) entre as execuções das aplicações.
Início

Jobs Interativos (salloc)

Para submeter jobs interativos no SDumont, é necessário utilizar o comando salloc, solicitando os recursos a serem utilizados. Quando o salloc consegue alocar os recursos solicitados para o job, ele inicia uma nova sessão, que permite ao usuário executar a aplicação diretamente (através do srun), ou acessar o nó via ssh, realizar as suas tarefas localmente e executar a aplicação (através do mpirun/mpiexec).

Quando a aplicação iniciar a execução, a saída será mostrada no STDOUT, que geralmente é a tela/terminal.

  • IMPORTANTE: Se não houver recurso disponível para iniciar o JOB, o prompt do terminal ficará bloqueado, aguardando os recursos ficarem disponíveis.
  • IMPORTANTE: Sempre executar o comando exit para finalizar a sessão e terminar o job.

Exemplo 1

Submetendo um job interativo, utilizando o Intel MPI.

salloc --nodes=2 --ntasks-per-node=12 --ntasks=24 -p sequana_cpu_dev -J NPB-MZ-interativo

#SLURM exibirá informações sobre a alocação dos recursos
salloc: Pending job allocation NNNNNNNNN
salloc: job NNNNNNNNN queued and waiting for resources
salloc: job NNNNNNNNN has been allocated resources
salloc: Granted job allocation NNNNNNNNN
salloc: Waiting for resource configuration
salloc: Nodes sdumont[YYYYY-ZZZZZ] are ready for job

#verificar quais nós foram alocados para o job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST

#carregar as bibliotecas
module load intel_psxe/2016

#executa a aplicação
srun -n 24 /scratch/app/NPB3.3.1-MZ/bin/sp-mz.C.intelmpi.24 

#encerra a sessão interativa e termina o job
exit

Exemplo 2

Submetendo um job interativo, alocando 4 nós e acessando diretamente o nó. Será utilizado o OpenMPI 2.0.

Nesse exemplo, vamos supor que o Slurm alocou para o job os nós sdumont6000, sdumont6001, sdumont6002 e sdumont6003.

salloc --nodes=4 --ntasks-per-node=6   --ntasks=24  -p sequana_cpu_dev   -J Interativo
#SLURM exibirá informações sobre a alocação dos recursos
salloc: Pending job allocation NNNNNNNNN
salloc: job NNNNNNNNN queued and waiting for resources
salloc: job NNNNNNNNN has been allocated resources
salloc: Granted job allocation NNNNNNNNN
salloc: Waiting for resource configuration
salloc: Nodes sdumont[6000-6003] are ready for job

#verificar quais nós foram alocados para o job
echo $SLURM_JOB_NODELIST
#retornará algo como sdumont[6000-6003]

nodeset -e $SLURM_JOB_NODELIST
#retornará algo como sdumont6000 sdumont6001 sdumont6002 sdumont6003
                  

#acessar o primeiro nó alocado
ssh sdumont6000

#carregar as bibliotecas
[usuario@sdumont6000 ~]$ module load openmpi/2.0.4.2
[usuario@sdumont6000 ~]$ module load gcc/6.5

#pode realizar a compilação da aplicação
[usuario@sdumont6000 ~]$ cd $SCRATCH/CODIGO
[usuario@sdumont6000 CODIGO]$ make ....

#executa a aplicação, utilizando o mpiexec
[usuario@sdumont6000 CODIGO]$ mpiexec -x LD_LIBRARY_PATH \
 --host sdumont6000,sdumont6001,sdumont6002,sdumont6003 -np 24 -npernode 6  ${PWD}/executavel

#encerra a sessão no nó sdumont6000
[usuario@sdumont6000 ~]$ exit

#encerra a sessão interativa e termina o job
exit

Início


Jobs para as filas GPU

Conforme descrito na seção "06 ‐ Gerenciador de filas", as filas sequana_gpu* permitem o compartilhamento do nó por múltiplos jobs (até 4). Para submeter jobs para essas filas, é necessário fazer utilização do GRES do SLURM.

  • Para garantir o melhor uso dos recursos, o parâmetro --exclusive não deve ser utilizado!
  • Embora os nós sejam de uso compartilhado, os recursos alocados para o job são de uso exclusivo (processadores, memória e GPU)
  • Cada nó computacional do SDumont expansão (Sequana X1120) possui 4 aceleradores NVIDIA V100, 48 núcleos CPU e 384GB de memória RAM. Em cada nó, é possível executar até 4 jobs simultaneamente, cada um usando os recursos solicitados de forma independente.
  • Para alocar uma ou mais GPUs, é obrigatório especificar a quantidade de aceleradores (parâmetros --gpus, --gpus-per-node, --gpus-per-socket, --gpus-per-task).
    • Caso não seja informada a quantidade de GPU's, o job não entrará em execução e ficará pendente em fila com a REASON QOSMinGRES.
  • Quando não for informado a quantidade de cores desejados (parâmetros --cpus-per-gpu, -n, --ntasks, --ntasks-per-node, --ntasks-per-socket, --tasks-per-node), o SLURM reservará 12 cores por GPU solicitada.
  • Quando o usuário não especificar a quantidade de memória a ser utilizada (parâmetros --mem-per-gpu, --mem, --mem-per-cpu), o SLURM reservará 8GB por core solicitado.
  • Por padrão, se não for especificada a quantidade de cores e memória, para cada GPU solicitada serão alocados 12 cores e 96GB de memória RAM.
  • A GPU (unidade) não é compartilhável, portanto ao ser alocada para um job, nenhum outro job conseguirá utilizá-la.
  • Parâmetros do slurm para alocações referentes a GPU
    • --gpus=n: Número total de GPUs solicitadas para o job
    • --gpus-per-node=n: Número de GPUs solicitadas para cada nó alocado
    • --gres=gpu:n: Número de GPUs solicitadas por nó (o mesmo que a combinação de --gpus=n --gpus-per-node=n)
    • --gpus-per-socket=n: Número de GPUs solicitadas para cada socket alocada
    • --gpus-per-task=n: Número de GPUs solicitadas para cada tarefa alocada
    • --cpus-per-gpu=n: Número de CPUs solicitadas para cada GPU alocada (Valor padrão: 12 CPUs para cada GPU alocada)
    • --mem-per-gpu=n: Memória RAM solicitada para cada GPU alocada (Valor padrão: 8GB para cada CPU alocada)
  • O número total de GPUs não é necessariamente dividido em partes iguais entre os nós alocados. Por exemplo, 8 GPUs solicitadas. O SLURM pode alocar 4 GPUs em um nó, 3 GPUs em outro nó e 1 GPU em um terceiro nó, a depender dos recursos e nós disponíveis. Para definir quantas GPUs devem ser alocadas por nó, deve-se utilizar o parâmetro --gpus-per-node=n ou --gres=gpu:n.
  • ATENÇÃO: Ao utilizar os parâmetros para solicitar os recursos, observar se os valores solicitados estão em conformidade com os recursos disponíveis no(s) nó(s), para não ocorrer incompatibilidade e erro de submissão. Por exemplo, para os parâmetros abaixo:
    • --gpus-per-node: Os nós do SDumont expansão possuem 4 GPUs. Ao configurar este parâmetro, se for especificado um número que seja maior do que o disponível nos nós solicitados, ocorrerá o erro “Invalid generic resource (gres) specification” ou “Requested node configuration is not available” ao tentar realizar a submissão.
    • --cpus-per-gpu: Os nós do SDumont expansão possuem 48 cores. Ao configurar este parâmetro, deve-se atentar para a quantidade solicitada vs quantidade disponível. Se for especificado um número que seja maior do que o disponível no nó (ex: --gpus-per-node=2 e --cpus-per-gpu=48 totalizando 96 cores), ocorrerá o erro “Invalid generic resource (gres) specification” ou “Requested node configuration is not available” ao tentar realizar a submissão.
    • --mem-per-gpu: Os nós do SDumont expansão possuem 384 GB de RAM. Ao configurar este parâmetro, deve-se atentar para a quantidade solicitada vs quantidade disponível. Se for especificado um número que seja maior do que o disponível no nó (ex: --gpus-per-node=4 e --mem-per-gpu=99000, totalizando 396 GB), ocorrerá o erro “Invalid generic resource (gres) specification” ou “Requested node configuration is not available” ao tentar realizar a submissão.

Exemplo 1

Submetendo um job para fila, alocando 2 nós e 4 GPUs.

Se não informado, por padrão são alocadas 12 CPUs para cada GPU solicitada e 8GB me memória para cada CPU alocada. Neste exemplo, serão alocados 2 nós, 4 GPUs, 48 CPUs e 384GB de memória.

IMPORTANTE: O número total de GPUs não é necessariamente dividido em partes iguais entre os nós alocados. Das quatro GPUs solicitadas, o escalonador pode alocar uma GPU em um nó e 3 GPUs em outro nó. Basta ter recurso disponível na fila. Para definir quantas GPUs devem ser alocadas por nó, utilize o parâmetro --gpus-per-node.

Esse script utiliza um exemplo cuda, compilado com o cuda/11.2_sequana.

#!/bin/bash
#SBATCH --nodes=2         #Numero de Nos
#SBATCH -p sequana_gpu_dev    #Fila (partition) a ser utilizada
#SBATCH -J simpleMultiGPU #Nome job
#SBATCH --gpus=4          #Numero total de GPUS

#Exibe os nós alocados para o Job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST

cd $SLURM_SUBMIT_DIR

#Configura os Módulos
module load cuda/11.2_sequana

#Exibe as GPUs disponiveis 
nvidia-smi

#Configura o executavel
EXEC=/scratch/app/cuda-samples/cuda-11.2-samples/bin/x86_64/linux/release/simpleMultiGPU

#exibe informações sobre o executável
/usr/bin/ldd $EXEC

srun $EXEC

Exemplo 2

Submetendo um job, alocando 2 nós e 1 GPU em cada nó.

Foram solicitadas 4 cores e 32GB de memória para cada GPU alocada.

Esse script utiliza um exemplo cuda, compilado com openmpi/gnu/4.1.2+cuda-11.2_sequana

#!/bin/bash
#SBATCH --nodes=2            #Numero de Nos
#SBATCH -p sequana_gpu       #Fila (partition) a ser utilizada
#SBATCH -J cudaOpenMP        #Nome job
#SBATCH --gpus=2             #Numero total de GPUS
#SBATCH --gpus-per-node=1    #Numero de GPUS por no
#SBATCH --cpus-per-gpu=4     #Numero de CPUs por GPU
#SBATCH --mem-per-gpu=32000  #Memoria em GB por GPU

#Exibe os nós alocados para o Job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST

cd $SLURM_SUBMIT_DIR

#Configura os Módulos
module load openmpi/gnu/4.1.2+cuda-11.2_sequana

#Exibe as GPUs disponiveis 
nvidia-smi


#Configura o executavel
EXEC=/scratch/app/cuda-samples/cuda-11.2-samples/bin/x86_64/linux/release/cudaOpenMP

#exibe informações sobre o executável
/usr/bin/ldd $EXEC

srun $EXEC

Início


Jobs para a fila de IA (gdl)

A fila gdl utiliza um nó com uma arquitetura especialmente projetada para processamento em Aprendizagem Profunda (Deep Learning), contendo 8 GPUs NVIDIA Tesla V100-16GB com NVLink (total de 40.960 CUDA-core e 5.120 Tensor-core), além de 2 CPUs Intel Xeon Skylake Gold 6148 (20 CPU-core cada) e um total de 384GB de memória RAM (DDR4).

A utilização da fila gdl segue o mesmo padrão das outras filas GPU, podendo ser através de jobs interativos ou através de scripts de submissão, sendo necessário especificar o número de GPU a ser utilizado.

Início


⚠️ **GitHub.com Fallback** ⚠️