07 ‐ Submeter Jobs - lncc-sered/manual-sdumont2nd GitHub Wiki
O SDumont2nd não possui um HOMEDIR em sistema de armazenamento dedicado, nos moldes do SDumont (HOMEDIR -> /prj). Desse forma, tanto a variável $HOME quando a $SCRATCH apontam para a área de armazenamento do Lustre (/scratch ou /petrobr).
IMPORTANTE: Os dados armazenado no SDumont2nd NÃO POSSUEM BACKUP. Os usuários são responsáveis por manter uma copia dos seus dados.
O procedimento usual para a submissão de jobs no SDumont compreende:
- Compilar a aplicação utilizando os compiladores desejados;
- Criar um script de submissão, configurando os parâmetros necessários para a execução do Job;
- Submeter o script com o comando sbatch
- Verificar os arquivos de saída
- 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, .srm, 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 a seguinte linha no script: #SBATCH --no-requeue
- Exemplos de scripts de submissão para aplicaçãoes conhecidas estão disponíveis neste link.
É obrigatório informar o tempo estimado de execução dos jobs. Essa configuração é feita através do parâmetro --time=HH:MM:SS. Caso o parâmetro --time não seja informado, ocorrerá o erro: error: Job submit/allocate failed: Requested time limit is invalid (missing or exceeds some limit)
Os usuários de projetos PETROBRAS e Parceiros/ICTs podem fazer parte de vários projetos com apenas uma conta/login. Dessa forma, é obrigatório informar o account (projeto) no momento da submissão de um job ou quando for alocar um só.
Para obter a lista de projetos (coluna Account) e filas (coluna Partition) em que um usuário está associado:
sacctmgr list user $USER -s format=User,Partition%20,Account
Na hora de submeter o job, informar o account a ser utilizado:
srun -N 1 -n 1 -p <NOME-DA-FILA> --time=hh:mm:ss --account=<NOME-DO-ACCOUNT>
ou
Inserindo a linha '#SBATCH --account=<NOME-DO-ACCOUNT>' dentro do script de submissão
Do contrário, ocorrerá o erro descrito abaixo:
sbatch: error: Batch job submission failed: Job violates accounting/QOS policy (job submit limit, user's size and/or time limits)
Para submeter os jobs para as filas que possuem aceleradores é obrigatório especificar a quantidade de aceleradores desejados (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. Caso seja submido com srun ou salloc o terminal exibirá a mensagem "queued and waiting for resources" e o job não será executado.
srun -N 1 -n 1 -p <NOME-DA-FILA> --time=hh:mm:ss --account=<NOME-DO-ACCOUNT> --gpus=N
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.
#!/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
#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
#-------------------------#
## 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 é obrigató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).
Usando o benchmark BT, compilado com o GNU/GCC (sem a necessidade de carregar módulo adicional).
#!/bin/bash
#SBATCH --nodes=1 #Numero de Nós
#SBATCH --ntasks=1 #Numero de tarefas
#SBATCH -p lncc-cpu_amd_dev #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 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
#!/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
#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
#-------------------------#
## 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
Usando o benchmark BT, utilizando o OpenMPI 4.1.6 com compiladores AMD, alocando 2 nós, utilizando 32 tarefas MPI por nó, totalizando 64 tarefas, e alterando o limite de tempo.
Script rodarmpi.srm
#!/bin/bash
#SBATCH --nodes=2 #Numero de Nós
#SBATCH --ntasks-per-node=32 #Numero de tarefas por Nó
#SBATCH --ntasks=64 #Numero total de tarefas MPI
#SBATCH -p lncc-cpu_amd_dev #Fila (partition) a ser utilizada
#SBATCH -J NPB-bt #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 amd-compilers
module load openmpi/amd/4.1.6.15.1
#Configura o executavel
EXEC=/scratch/app/npb/MPI/bt.C.64_ompi4_amd
#exibe informações sobre o executável
/usr/bin/ldd $EXEC
srun $EXEC
Submeter o job através do comando:
sbatch rodarmpi.srm
Usando o benchmark BT, utilizando o OpenMPI 5.0.5 com compiladores GNU/GCC, alocando 4 nós, utilizando 16 tarefas MPI por nó, totalizando 64 tarefas.
Script rodarmpi.srm
#!/bin/bash
#SBATCH --nodes=4 #Numero de Nós
#SBATCH --ntasks-per-node=16 #Numero de tarefas por Nó
#SBATCH --ntasks=64 #Numero total de tarefas MPI
#SBATCH -p lncc-cpu_amd_dev #Fila (partition) a ser utilizada
#SBATCH -J NPB-bt #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 openmpi/gnu/5.0.5.1.0
#EVITAR AVISO SOBRE O COMPOMENTE PSEC/MUNGE DO PMIX
export PMIX_MCA_psec=^munge
#Configura o executavel
EXEC=/scratch/app/npb/MPI/bt.C.64_ompi5_gcc
#exibe informações sobre o executável
/usr/bin/ldd $EXEC
srun $EXEC
Submeter o job através do comando:
sbatch rodarmpi.srm
OBS: A configuração da variável de ambiente PMIX_MCA_psec=^munge é necessária para evitar a exibição do aviso abaixo:
A requested component was not found, or was unable to be opened. This
means that this component is either not installed or is unable to be
used on your system (e.g., sometimes this means that shared libraries
that the component requires are unable to be found/loaded). Note that
PMIx stopped checking at the first component that it did not find.
Host: sdumont2ndXXXX
Framework: psec
Component: munge
Apesar desse aviso, o teste descrito acima funcionou corretamente.
- Intel OneAPI + Intel MPI
...
module load intel_oneapi/2025.1
EXEC="/scratch/app/npb/MPI/cg.D.64_intel1api"
srun $EXEC
- Intel OneAPI + OpenMPI 4
...
module load intel_oneapi/2025.1
module load openmpi/intel1api/4.1.6.15.1
EXEC="/scratch/app/npb/MPI/cg.D.64_ompi4_intel1api"
srun --mpi=pmi2 $EXEC
- Intel OneAPI + OpenMPI 5
...
module load intel_oneapi/2025.1
module load openmpi/intel1api/5.0.5.1.0
EXEC="/scratch/app/npb/MPI/cg.D.64_ompi5_intel1api"
#EVITAR AVISO SOBRE O COMPOMENTE PSEC/MUNGE DO PMIX
export PMIX_MCA_psec=^munge
srun $EXEC
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.
Usando o benchmark SP-MZ, utilizando os compiladores GNU/CC e executando 96 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=96 #Numero de threads
#SBATCH -p lncc-cpu_amd_dev #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-sp-openmp #Nome job
#Exibe os nós alocados para o Job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST
cd $SLURM_SUBMIT_DIR
#exibe informações sobre o executável
EXEC=/scratch/app/npb/THREADS/sp-mz.C.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
Scripts para aplicações que utilizam dois níveis de paralelismo: MPI + OpenMP.
Usando o benchmark SP-MZ, utilizando os compiladores OpenMPI 4.1.6 e GNU/GCC, 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.
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 lncc-cpu_amd_dev #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-sp-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 openmpi/gnu/4.1.6.15.1
#exibe informaçoes sobre o executavel
EXEC=/scratch/app/npb/MPI+THREADS/sp-mz.D.x_ompi4_gcc
/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
É 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:
- Uma aplicação em cada nó distinto
- Duas aplicações, cada uma executando em 2 nós
- Três aplicações, uma executando em dois nós e as outras duas executando em um nó cada
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=32 #Numero de tarefas por Nó
#SBATCH --ntasks=128 #Numero total de tarefas MPI
#SBATCH -p lncc-cpu_amd_dev #Fila (partition) a ser utilizada
#SBATCH -J NPB-bt #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 amd-compilers
module load openmpi/amd/4.1.6.15.1
#Configura o executavel
EXEC=/scratch/app/npb/MPI/bt.C.64_ompi4_amd
#exibe informações sobre o executável
/usr/bin/ldd $EXEC
srun --nodes=2 --ntasks=64 $EXEC > out.exec.1.txt 2>&1 &
srun --nodes=2 --ntasks=64 $EXEC > out.exec.2.txt 2>&1 &
wait
Submeter o job através do comando:
sbatch rodar.srm
OBS:
- Necessário a inclusão do & ao final da linha de execução da aplicação, para poder iniciar em segundo plano.
- 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.
- 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.
Para submeter jobs interativos no SDumont2nd, é 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.
Submetendo um job interativo, utilizando o OpenMPI 4.1.6.
salloc --nodes=2 --ntasks-per-node=12 --ntasks=24 -p lncc-cpu_amd_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 sdumont2nd[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 openmpi/gnu/4.1.6.15.1
#executa a aplicação
srun -n 24 /scratch/app/npb/MPI+THREADS/sp-mz.D.x_ompi4_gcc
#encerra a sessão interativa e termina o job
exit
Submetendo um job interativo, alocando 1 nó e acessando diretamente o nó.
Nesse exemplo, vamos supor que o Slurm alocou para o job os nós sdumont2nd1000 e sdumont2nd1001.
salloc --nodes=2 --ntasks-per-node=48 --ntasks=96 -p lncc-cpu_amd_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 sdumont2nd[1000-1001] are ready for job
#verificar quais nós foram alocados para o job
echo $SLURM_JOB_NODELIST
#retornará algo como sdumont2nd[1000-1001]
nodeset -e $SLURM_JOB_NODELIST
#retornará algo como sdumont2nd1000 sdumont2nd1001
#acessar o nó alocado
ssh sdumont2nd1000
#carregar as bibliotecas
[usuario@sdumont2nd1000 ~]$ module load openmpi/gnu/4.1.6.15.1
#pode realizar a compilação da aplicação
[usuario@sdumont2nd1000 ~]$ cd /DIRETORIO/DO/CODIGO
[usuario@sdumont2nd1000 CODIGO]$ make ....
#executa a aplicação, utilizando o mpiexec
[usuario@sdumont2nd1000 CODIGO]$ run -N 2 -n 96 --ntasks-per-node=48 ${PWD}/executavel
#encerra a sessão no nó sdumont2nd1000
[usuario@sdumont2nd1000 ~]$ exit
#encerra a sessão interativa e termina o job
exit
Conforme descrito na seção "06 ‐ Gerenciador de filas", as filas das arquiteturas H100, GH200 e MI300A 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! Caso seja utilizado, o job ficará pendente, com o REASON QOSMaxGRESPerUser.
- Embora os nós sejam de uso compartilhado, os recursos alocados para o job são de uso exclusivo (processadores, memória e GPU)
- A configuração (recursos disponíveis) de cada nó computacional do SDumont2nd está descrito aqui.
- 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á 1/4 cores do nó 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á 1/4 da RAM do nó por GPU solicitada.
- 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: 1/4 das CPUs para cada GPU alocada)
- --mem-per-gpu=n: Memória RAM solicitada para cada GPU alocada (Valor padrão: 1/4 da RAM 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 H100 do SDumont2nd 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 H100 do SDumont2nd possuem 96 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=96 totalizando 192 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 H100 do SDumont2nd possuem 1024 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=500G, totalizando 2000 GB), ocorrerá o erro “Invalid generic resource (gres) specification” ou “Requested node configuration is not available” ao tentar realizar a submissão.
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.
#!/bin/bash
#SBATCH --nodes=2 #Numero de Nos
#SBATCH -p lncc-h100_dev #Fila (partition) a ser utilizada
#SBATCH -J simpleMultiGPU #Nome job
#SBATCH --gpus=2 #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
#Exibe as GPUs disponiveis
nvidia-smi
#Configura o executavel
EXEC=/scratch/app/gpu/cuda-samples/12.5/simpleMultiGPU
#exibe informações sobre o executável
/usr/bin/ldd $EXEC
srun $EXEC
Saída esperada:
sdumont2nd2038 sdumont2nd2039
Mon May 26 14:42:57 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 560.35.03 Driver Version: 560.35.03 CUDA Version: 12.6 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA H100 80GB HBM3 On | 00000000:9D:00.0 Off | 0 |
| N/A 34C P0 71W / 700W | 1MiB / 81559MiB | 0% Default |
| | | Disabled |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| No running processes found |
+-----------------------------------------------------------------------------------------+
linux-vdso.so.1 (0x00007ffd221d4000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x0000147e76400000)
libm.so.6 => /lib64/libm.so.6 (0x0000147e7666e000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000147e76653000)
libc.so.6 => /lib64/libc.so.6 (0x0000147e76000000)
/lib64/ld-linux-x86-64.so.2 (0x0000147e76756000)
Starting simpleMultiGPU
CUDA-capable device count: 1
Generating input data...
Computing with 1 GPUs...
GPU Processing time: 3.640000 (ms)
Computing with Host CPU...
Comparing GPU and Host CPU results...
GPU sum: 16777296.000000
CPU sum: 16777294.395033
Relative difference: 9.566307E-08
Starting simpleMultiGPU
CUDA-capable device count: 1
Generating input data...
Computing with 1 GPUs...
GPU Processing time: 3.661000 (ms)
Computing with Host CPU...
Comparing GPU and Host CPU results...
GPU sum: 16777296.000000
CPU sum: 16777294.395033
Relative difference: 9.566307E-08
OBS: O SLURM realizou uma execução do simpleMultiGPU em cada nó (foi solicito 2 nós), e cada execução utilizou 1 GPU do nó.
Submetendo um job, alocando 2 nós e 2 GPU em cada nó.
#!/bin/bash
#SBATCH --nodes=2 #Numero de Nos
#SBATCH -p lncc-h100_dev #Fila (partition) a ser utilizada
#SBATCH -J simpleMultiGPU #Nome job
#SBATCH --gpus-per-node=2 #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
#Exibe as GPUs disponiveis
nvidia-smi
#Configura o executavel
EXEC=/scratch/app/gpu/cuda-samples/12.5/simpleMultiGPU
#exibe informações sobre o executável
/usr/bin/ldd $EXEC
srun $EXEC
Saída esperada:
sdumont2nd2038 sdumont2nd2039
Mon May 26 14:49:12 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 560.35.03 Driver Version: 560.35.03 CUDA Version: 12.6 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA H100 80GB HBM3 On | 00000000:9D:00.0 Off | 0 |
| N/A 33C P0 71W / 700W | 1MiB / 81559MiB | 0% Default |
| | | Disabled |
+-----------------------------------------+------------------------+----------------------+
| 1 NVIDIA H100 80GB HBM3 On | 00000000:AD:00.0 Off | 0 |
| N/A 34C P0 72W / 700W | 1MiB / 81559MiB | 0% Default |
| | | Disabled |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| No running processes found |
+-----------------------------------------------------------------------------------------+
linux-vdso.so.1 (0x00007ffe89581000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x000014b326800000)
libm.so.6 => /lib64/libm.so.6 (0x000014b326a8c000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000014b326a71000)
libc.so.6 => /lib64/libc.so.6 (0x000014b326400000)
/lib64/ld-linux-x86-64.so.2 (0x000014b326b74000)
Starting simpleMultiGPU
CUDA-capable device count: 2
Generating input data...
Computing with 2 GPUs...
GPU Processing time: 4.087000 (ms)
Computing with Host CPU...
Comparing GPU and Host CPU results...
GPU sum: 16777280.000000
CPU sum: 16777294.395033
Relative difference: 8.580068E-07
Starting simpleMultiGPU
CUDA-capable device count: 2
Generating input data...
Computing with 2 GPUs...
GPU Processing time: 4.108000 (ms)
Computing with Host CPU...
Comparing GPU and Host CPU results...
GPU sum: 16777280.000000
CPU sum: 16777294.395033
Relative difference: 8.580068E-07
OBS: O SLURM realizou uma execução do simpleMultiGPU em cada nó (foi solicito 2 nós), e cada execução utilizou 2 GPUs do nó.
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.
#!/bin/bash
#SBATCH --nodes=2 #Numero de Nos
#SBATCH -p lncc-h100_dev #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
#Exibe as GPUs disponiveis
nvidia-smi
#Configura o executavel
EXEC=/scratch/app/gpu/cuda-samples/12.5/cudaOpenMP
#exibe informações sobre o executável
/usr/bin/ldd $EXEC
srun $EXEC
Saída esperada:
sdumont2nd[2038-2039]
sdumont2nd2038 sdumont2nd2039
Mon May 26 14:53:25 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 560.35.03 Driver Version: 560.35.03 CUDA Version: 12.6 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA H100 80GB HBM3 On | 00000000:9D:00.0 Off | 0 |
| N/A 33C P0 71W / 700W | 1MiB / 81559MiB | 0% Default |
| | | Disabled |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| No running processes found |
+-----------------------------------------------------------------------------------------+
linux-vdso.so.1 (0x00007ffd063bf000)
libgomp.so.1 => /lib64/libgomp.so.1 (0x000014c585f91000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x000014c585c00000)
libm.so.6 => /lib64/libm.so.6 (0x000014c585eb6000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000014c585e9b000)
libc.so.6 => /lib64/libc.so.6 (0x000014c585800000)
/lib64/ld-linux-x86-64.so.2 (0x000014c585fe5000)
/scratch/app/gpu/cuda-samples/12.5/cudaOpenMP Starting...
number of host CPUs: 4
number of CUDA devices: 1
0: NVIDIA H100 80GB HBM3
---------------------------
CPU thread 0 (of 1) uses CUDA device 0
---------------------------
/scratch/app/gpu/cuda-samples/12.5/cudaOpenMP Starting...
number of host CPUs: 4
number of CUDA devices: 1
0: NVIDIA H100 80GB HBM3
---------------------------
CPU thread 0 (of 1) uses CUDA device 0
---------------------------
Algumas aplicações não conseguem fazer o uso correto, ou de forma satisfatória, de execução utilizando múltiplas GPUs ao mesmo tempo.
Dessa forma, visando fazer um bom uso dos recursos alocados (em especial as filas lncc-h100 e lncc-gh200, que possuem alocação exclusiva dos recursos, alocando nós inteiros para a execução do job), é possível realizar múltiplas execuções dentro de um único job, usando como base o descrito neste item.
Essa filas não possuem o GRES configurado. Dessa forma, não devem utilizar os parâmetros --gpus, --gpus-per-node, --gpus-per-socket, --gpus-per-task.
Abaixo um exemplo alocando um nó inteiro e disparando uma execução para cada GPU.
#!/bin/bash
#SBATCH --nodes=1 #Numero de Nos
#SBATCH --tasks-per-node=4 #Numero de Nos
#SBATCH --cpus-per-task=24 #Numero de Nos
#SBATCH -p lncc-h100 #Fila (partition) a ser utilizada
#SBATCH -J multi-exec #Nome job
#SBATCH --time=00:10:00
#Exibe os nós alocados para o Job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST
cd $SLURM_SUBMIT_DIR
#Exibe as GPUs disponiveis
nvidia-smi
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
#Configura o primeiro executavel para executar na GPU 0
EXEC=/scratch/app/gpu/cuda-samples/12.5/cudaTensorCoreGemm
export CUDA_VISIBLE_DEVICES=0
#Realiza a primeira execucao
$EXEC > out.exec.1.txt 2>&1 &
#Configura o segundo executavel para executar na GPU 1
EXEC=/scratch/app/gpu/cuda-samples/12.5/cudaOpenMP
export CUDA_VISIBLE_DEVICES=1
#Realiza a segunda execucao
$EXEC > out.exec.2.txt 2>&1 &
#Configura o terceiro executavel para executar na GPU 2
EXEC=/scratch/app/gpu/cuda-samples/12.5/FDTD3d
export CUDA_VISIBLE_DEVICES=2
#Realiza a terceira execucao
$EXEC > out.exec.3.txt 2>&1 &
#Configura o quarto executavel para executar na GPU 3
EXEC=/scratch/app/gpu/cuda-samples/12.5/BlackScholes
export CUDA_VISIBLE_DEVICES=3
#Realiza a quarta execucao
$EXEC > out.exec.4.txt 2>&1 &
wait
Também é possível fazer esse tipo de submissão para as filas que possuem o compartilhamento de recursos, conforme abaixo. Nesse caso, [e]obrigatório especificar as GPUs através de um dos parâmetros --gpus, --gpus-per-node, --gpus-per-socket, --gpus-per-task:
#!/bin/bash
#SBATCH --nodes=2 #Numero de Nos
#SBATCH --tasks-per-node=2 #Numero de Nos
#SBATCH --cpus-per-task=24 #Numero de Nos
#SBATCH --gpus-per-node=2 #Numero de Nos
#SBATCH -p lncc-h100_shared #Fila (partition) a ser utilizada
#SBATCH -J multi-exec #Nome job
#SBATCH --time=00:10:00
#Exibe os nós alocados para o Job
echo $SLURM_JOB_NODELIST
nodeset -e $SLURM_JOB_NODELIST
cd $SLURM_SUBMIT_DIR
#Exibe as GPUs disponiveis
nvidia-smi
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
#Configura o primeiro executavel
EXEC=/scratch/app/gpu/cuda-samples/12.5/cudaTensorCoreGemm
#Realiza a primeira execucao
srun --nodes=1 --tasks-per-node=1 --gpus-per-node=1 $EXEC > out.exec.1.txt 2>&1 &
#Configura o segundo executavel
EXEC=/scratch/app/gpu/cuda-samples/12.5/cudaOpenMP
#Realiza a segunda execucao
srun --nodes=1 --tasks-per-node=1 --gpus-per-node=1 $EXEC > out.exec.2.txt 2>&1 &
#Configura o terceiro executavel
EXEC=/scratch/app/gpu/cuda-samples/12.5/FDTD3d
#Realiza a terceira execucao
srun --nodes=1 --tasks-per-node=1 --gpus-per-node=1 $EXEC > out.exec.3.txt 2>&1 &
#Configura o quarto executavel
EXEC=/scratch/app/gpu/cuda-samples/12.5/BlackScholes
#Realiza a quarta execucao
srun --nodes=1 --tasks-per-node=1 --gpus-per-node=1 $EXEC > out.exec.4.txt 2>&1 &
wait
O parâmetro --dependecy (-d) permite adiar o início do job até que a dependência especificada seja satisfeita.
Tipos de dependências:
after:jobid[:jobid...] job pode iniciar depois que os jobs especificados tiverem começado. afterany:jobid[:jobid...] job pode iniciar após o termino dos jobs especificados independente do status da conclusão. afternotok:jobid[:jobid...] job pode iniciar depois que os jobs especificados falharem afterok:jobid[:jobid...] job pode iniciar somente se os jobs especificados forem finalizados sem erros. singleton job pode começar a ser executado após o término de todos os jobs iniciados anteriormente
A dependência entre os jobs poderá ser configurada para qualquer tipo de submissão via sbatch. Como a dependencia entre os jobs necessita indicar explicitamente o JOBID, você poderá incluir o parâmetro -d ou --dependency no momento que executar o comando sbatch.
Submtendo o primeiro job da série:
$ sbatch meujob.sh Submitted batch job 105558
O primeiro job da série tem o JOBID=105558, os próximo job precisará ser configurado informando a dependência.
$ sbatch -d afterany:105558 meujob.sh Submitted batch job 105559
O segundo job por sua vez tem o JOBID=105559, caso existam novas dependencias, basta encadear os comandos de forma que toda sua sequencia de trabalho seja executada respeitando o limite de 30 jobs submetidos à fila.
$ squeue -u $USER JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON) 105559 lncc-h100 JOBNAME USUARIO PD 0:00 1 (Dependency) 105558 lncc-h100 JOBNAME USUARIO R 0:26 1 sdumont2nd2001
Para mais detalhes sobre o configuração de dependência acesso o manual do sbatch (https://slurm.schedmd.com/sbatch.html)