Supercomputador Santos Dumont (SDumont)

  1. Características

    1. Nós SDumont Base (B700)

    2. Nós SDumont Expansão (BullSequana X)

    3. Filesystem e Armazenamento

    4. Utilização do Scratch com Striping

      1. Considerações ao utilizar o striping

      2. Considerações ao definir o stripe_size

      3. Configurando o striping para arquivos e diretórios

      4. Outros comandos do Lustre

  2. Informações sobre acesso

  3. Módulos de Ambiente

    1. Módulos para as filas sequana_*

  4. Compiladores e Implementações MPI

  5. Gerenciador de Filas

  6. Submeter Jobs

    1. Jobs paralelos (MPI)

    2. Jobs paralelos (MPI-multithreaded)

    3. Jobs paralelos (threads/OpenMP)

    4. Múltiplas tarefas simultâneas em um único job

    5. Jobs Interativos (salloc)

    6. Jobs para a fila de IA (gdl)

    7. Jobs para a fila cpu_shared

    8. Jobs para as filas sequana

    9. Jobs para as filas sequana_cpu_shared

    10. Jobs para a fila heterogênea het_scal

  7. Verificar status

    1. Status/Reason do job

    2. Informação sobre Utilização

    3. Visualizando o consumo dos recursos das filas _shared

  8. Remover jobs da fila ou em execução

  9. Comentários Finais

    1. Variáveis de ambiente do Slurm

1. Características

A primeira versão do SDumont, chamada de "SDumont Base", possuía um total de 18.424 núcleos de CPU, distribuídos em 758 nós computacionais utilizando a tecnologia BullX B700

No quarto trimestre de 2019 o SDumont recebeu uma expansão computacional, composta da tecnologia BullSequana X, que aumentou o poder computacional de 1,1 Petaflops para 5,1 Petaflops. Após essa expansão o SDumont passou a contar com um total de 36.472 núcleos de CPU, distribuídos em 1.134 nós computacionais.

Topo


1.1 Nós SDumont Base (B700)

  • 504 Nós de computação B710 ( thin node ), onde cada nó possui

    • 2 x CPU Intel Xeon E5-2695v2 Ivy Bridge, 2,4GHZ

    • 24 núcleos (12 por CPU), totalizando de 12.096 núcleos

    • 64GB DDR3 RAM

  • 198 Nós de computação B715 ( thin node ) com GPUs K40, onde cada nó possui:

    • 2 x CPU Intel Xeon E5-2695v2 Ivy Bridge, 2,4GHZ

    • 24 núcleos (12 por CPU), totalizando de 4.752 núcleos

    • 64GB DDR3 RAM

    • 2 x Nvidia K40 (dispositivo GPU)

  • 54 Nós de computação B715 ( thin node ) com coprocessadores Xeon Phi, onde cada nó possui:

    • 2 x CPU Intel Xeon E5-2695v2 Ivy Bridge, 2,4GHZ

    • 24 núcleos (12 por CPU), totalizando de 1.296 núcleos

    • 64GB DDR3 RAM

    • 2 x Xeon PHI 7120 (dispositivo MIC - atualmente inutilizável)

  • 1 Nó de computação Bull Sequana ( thin node ) com GPUs V100 (IA):

    • 2 x CPU Skylake GOLD 6148, 2,4GHZ

    • 40 núcleos (20 por CPU)

    • 384GB DDR4 RAM

    • 8 x Nvidia V100 (dispositivo GPU 16GB com NVLink)

    • 4 x portas Infiniband EDR 100Gbps

  • 1 Nó de computação MESCA2 com memória compartilhada de grande capacidade ( fat node ):

    • 16 x CPU Intel Ivy, 2,4GHZ

    • 240 núcleos (15 por CPU)

    • 6 TB de RAM

Os nós do SDumont Base são interligados por uma rede Infiniband FDR (56Gb/s)

Topo


1.2 Nós SDumont Expansão (BullSequana X)

  • 246 nós computacionais Bull Sequana X1120 (CPU)

    • 2x Intel Xeon Cascade Lake Gold 6252

    • 48 núcleos (24c por CPU)

    • 384 GB de memória RAM

  • 36 nós computacionais Bull Sequana X1120 (CPU)

    • 2x Intel Xeon Cascade Lake Gold 6252

    • 48 núcleos (24c por CPU)

    • 768 GB de memória RAM

  • 94 nós computacionais Bull Sequana X1120 (GPU)

    • 2x Intel Xeon Skylake 6252

    • 48 núcleos (24c por CPU)

    • 384 GB de memória RAM

    • 4x NVIDIA Volta V100 GPU

Os nós do SDumont Expansão são interligados por uma rede Infiniband EDR (100Gb/s).

Topo


1.3. Filesystem e Armazenamento

O SDumont conta com um Filesystem Lustre v2.12, utilizado como "Scratch", implementado através do ClusterStor 9000 v3.3 da Cray/HPE.

O "Home" dos usuários (acessível apenas no nó de login) , é fornecido através de NFS pelo storage DellEMC ISILON.

Essas áreas de armazenamento devem ser utilizadas da seguinte forma:

  • Scratch : Estrutura montada a partir do diretório /scratch . Utilizado para armazenar todos os arquivos que serão utilizados durante a execução de um job (scripts de submissão, executáveis, dados de entrada, dados de saída etc).

    • Cada projeto possui um espaço de armazenamento ( /scratch/NOME-DO-PROJETO ), cujo tamanho depende do tipo do programa de alocação e da quantidade solicitada, e é compartilhado por todos os usuários do projeto.

    • Cada usuário possui um diretório dentro dessa área ( /scratch/NOME-DO-PROJETO/USERNAME ), que pode ser acessado diretamente através da variável de ambiente $SCRATCH (configurada automaticamente durante o login).

    • IMPORTANTE: os arquivos presentes no Scratch são automaticamente removidos após 60 dias sem terem sido modificados. Por isso se sugere que, assim que um job termine sua execução, os dados relevantes que resultem do job sejam transferidos para a área de armazenamento do Home.


  • Home : Estrutura montada a partir do diretório /prj/HOME-DO-PROJETO . Utilizado para armazenar os códigos-fonte, os binários executáveis, as bibliotecas e os resultados que se queira manter durante toda a vigência do projeto.

    • Cada projeto possui um espaço de armazenamento, cujo tamanho depende do tipo do programa de alocação e da quantidade solicitada, e que é compartilhado por todos os usuários do projeto.

*IMPORTANTE: tanto o Scratch como o Home não possuem backup no LNCC. Usuários podem copiar seus arquivos de e para o SDumont usando o "scp" do SSH.

Topo


1.4. Utilização do Scratch com Striping

O Filesystem Lustre é composto de um conjunto subjacente de servidores de I/O e discos, chamados respectivamente de Object Storage Servers (OSSs) e Objetct Storage Targets (OSTs).

Um dos principais fatores que impulsionam o alto desempenho do Filesystem Lustre é a capacidade de dividir os arquivos em stripes, sendo cada stripe armazenado em um servidor diferente. Quando essa divisão ocorre, as operações de leitura e escrita acessam simultaneamente os servidores e seus discos para obter os dados do arquivo.

O número de stripes em que um único arquivo pode ser dividido é chamado de "stripe_count" , sendo 10 o limite prático máximo no SDumont.

O "stripe_size" define qual será o tamanho do stripe, sendo 4GB o limite máximo.

Os valores padrão para o "stripe_count" e "stripe_size" definidos para o Scratch são 1 e 1MB, respectivamente.

Logo, por padrão, os arquivos armazenados no /scratch não são divididos em stripes.

Os usuários podem opcionalmente configurar o número de stripes e o tamanho de cada stripe para arquivos ou diretórios.

Topo


1.4.1 Considerações ao utilizar o striping

A configuração do striping depende das necessidades de cada caso.

Algumas razões para utilizar o striping incluem:

  • Fornece alta largura de banda para o acesso: Muitas aplicações necessitam de uma alta largura de banda para acessar um único arquivo, que pode ser maior que a largura de banda fornecida por um único servidor. Alguns exemplos são as aplicações que escrevem em um único arquivo a partir de centenas de nós. Nesses casos, um arquivo pode ser dividido em stripes através da quantidade servidores que for necessário para alcançar a largura de banda agregada necessária para esse arquivo. Dividir o arquivo em stripes através de um grande número de servidores deve ser usado somente quando o arquivo for muito grande e/ou é acessado por muitos nós ao mesmo tempo.

  • Fornece espaço para arquivos muito grandes: O Striping é útil quando um único servidor não possui espaço suficiente para armazenar um arquivo inteiro.

Algumas razões para minimizar ou evitar o striping:

  • Aumento do overhead: O striping resulta em mais locks e operações extras da rede.

  • Aumento do risco: Quando os arquivos são divididos em stripes através de todos os servidores, e um destes falha, uma pequena parte de cada arquivo é perdida, que pode vir a gerar corrupção de dados.

Topo


1.4.2 Considerações ao definir o stripe_size

Escolher o stripe_size é um ato de balanceamento. Algumas dicas são:

  • O stripe_size possui nenhum efeito em um arquivo que possui stripe_count igual a um.

  • O stripe_size deve ser um múltiplo de 64 KB.

  • O menor stripe_size recomendado é 512KB. Embora seja possível criar arquivos com um tamanho de stripe de 64KB, o menor stripe_size prático é 512KB porque o filesystem Lustre envia chunks de 1MB através da rede. Escolhendo um tamanho menor para o stripe_size pode resultar em I/O ineficiente e desempenho reduzido.

  • Um bom tamanho de stripe para I/O sequencial é entre 1MB e 4MB. Na maioria das situações, configurar o stripe_size com valores maiores do que 4MB pode resultar em tempos mais longos em que os locks são mantidos, assim como disputas durante o acesso a arquivos compartilhados.

  • O valor máximo para o stripe_size é de 4GB. Utilizar um tamanho grande para o stripe pode melhorar o desempenho quando acessando arquivos muito grandes. Isso permite que cada cliente tenha acesso exclusivo à sua própria parte do arquivo. Entretanto, um stripe_size grande pode ser contraprodutivo em casos onde ele não combina com o padrão das operações de I/O.

  • Escolha um padrão de stripe_size que leve em consideração os padrões de escrita da aplicação. Se o arquivo é escrito de uma maneira consistente e alinhada, o tamanho do stripe deve ser um múltiplo do tamanho da operação de escrita.

Topo


1.4.3 Configurando o striping para arquivos e diretórios

O comando "lfs setstripe" é utilizado para configurar o striping de um arquivo ou diretório.

Para alterar o tamanho e a quantidade do stripe:

lfs setstripe [--stripe-size|-S stripe_size]  [--stripe-count|-c stripe_count] filename|dirname 

Exemplos:

cd $SCRATCH


#configura o striping para diretórios
mkdir full_stripe
lfs setstripe -S 4m -c -1 full_stripe
mkdir single_stripe
lfs setstripe -S 1m -c 1 single_stripe


#configura o striping para um arquivo específico
lfs setstripe -S 4m -c 5 five_stripes_file

ATENÇÃO:

  • Configurar o stripe_count com o valor "-1" faz com que o arquivo seja dividido por todos os servidores disponíveis.

  • Configurar o striping em um diretório faz com que todos os arquivos que forem criados dentro dele herdem a sua configuração.

  • É possível alterar a configuração de striping do diretório posteriormente.

  • Para configurar o striping de um arquivo, este não pode existir previamente. O comando "lfs setstripe" criará um arquivo vazio, com a configuração de striping.

  • Após configurado o striping para um arquivo, não é possível alterá-lo.


O comando "lfs getstripe" é utilizado para obter informação sobre a configuração do striping:

lfs getstripe filename|dirname 

Exemplos:

cd $SCRATCH
lfs getstripe full_stripe
lfs getstripe single_stripe
lfs getstripe five_stripes_file

Topo


1.4.4 Outros comandos do Lustre

Para uma lista completa de todas as opções do utilitário lfs do Lustre:

lfs help
lfs help option-name

Comandos mais utilizados:

  • lfs osts - Lista todos os OSTs disponíveis no filesystem.

  • lfs find - Realiza buscas na árvore de diretório. É recomendado utilizar esse comando em vez do find comum.

  • lfs df - Exibe a utilização de espaço em disco do filesystem.

  • lfs quota /scratch/PROJETO - Exibe a utilização do espaço em disco em relação à quota

Topo


2. Informações sobre acesso e submissão

  1. O Sistema Operacional do SDumont é o RedHat Linux 7.6

  2. O SDumont utiliza o Software Stack Bull Supercomputing Cluster Suite 5

  3. O acesso ao SDumont deve ser feito por meio de SSH através do host login.sdumont.lncc.br

  4. As conexões externas deverão obrigatoriamente ser feitas através da VPN do LNCC.

  5. A submissão dos jobs deve ser feita através do gerenciador de recursos e filas Slurm

Topo


3. Módulos de Ambiente

O objetivo dos módulos é carregar as variáveis de ambiente e a inclusão no path dos programas e bibliotecas de forma modular. Para isso, o aplicativo "module" é utilizado.

Comandos

  • Listar todos os módulos disponíveis

    module avail
    

  • Obter informações sobre um módulo

    module whatis NOME-DO-MODULO 
    ou
    module help NOME-DO-MODULO
    

  • Carregar um módulo

    module load NOME-DO-MODULO
    

  • Listar todos os módulos carregados

    module list
    

  • Remover um módulo

    module unload NOME-DO-MODULO
    

Maiores informações sobre o module: "man module"

* Alguns programas e bibliotecas podem não estar configurados para serem carregados via aplicativo "module". Nesse caso, é necessário carregar as variáveis de ambiente da seguinte forma:

source /scratch/app/modulos/NOME-DO-MODULO
ou 
. /scratch/app/modulos/NOME-DO-MODULO

Exemplo

source /scratch/app/modulos/intel-psxe-2016.sh

Topo


3.1. Módulos para as filas sequana_*

Os softwares do SDumont base foram compilados visando obter a melhor performance para o conjunto de hardware e software disponíveis, entretanto esses softwares podem funcionar de forma inadequada ou ineficiente nas filas da expansão, pois os nós Sequana possuem um conjunto de hardware diferente.


Para utilizar as filas sequana_* recomendamos carregar o módulo sequana/current e verificar quais aplicações foram testadas e estão disponíveis.


Após carregado, o comando module avail listará apenas os softwares testados na nova partição.


module load sequana/current
module avail

Para voltar a configuração anterior e ter acesso apenas aos softwares do SDumont base descarregue o módulo sequana/current e carregue o módulo sdbase.


module unload sequana/current
module load sdbase

Para manter os módulos compatíveis com a expansão e também consultar os módulos do SDumont base carregue o módulo sequana/current e em seguida carregue o módulo sdbase.


module load sequana/current
module load sdbase

IMPORTANTE: Não é obrigatório carregar o módulo sequana/current para utilizar as filas sequana_*.

Caso necessite de alguma aplicação que não estiver listada nos módulos de ambiente, por favor, solicite a instalação através do e-mail: helpdesk-sdumont@lncc.br

Topo


4. Compiladores e Implementações MPI

Compiladores disponíveis

  • GNU versão 4.8.5 - Compilador padrão do Sistema Operacional. Não é necessário carregar módulo!


  • GNU versão 6.5. Necessário carregar o módulo:

    module load gcc/6.5 
    

  • GNU versão 7.5. Necessário carregar o módulo:

    module load gcc/7.4
    

  • Intel Parallel Studio XE, versões 2016, 2017, 2018 e 2019. Necessário carregar o módulo:

    #PARA UTILIZAR A VERSAO 2016#
    source /scratch/app/modulos/intel-psxe-2016.sh
    
    #PARA UTILIZAR A VERSAO 2017#
    source /scratch/app/modulos/intel-psxe-2017.sh
    
    #PARA UTILIZAR A VERSAO 2018#
    source /scratch/app/modulos/intel-psxe-2018.sh
    
    #PARA UTILIZAR A VERSAO 2019#
    source /scratch/app/modulos/intel-psxe-2019.sh
    

  • PGI versão 2018.10 (Community). Necessário carregar o módulo:

    module load pgi/compilers-18.10 
    

Implementações MPI disponíveis

As opções de MPI são OpenMPI 2.0 e o Intel MPI (baseado no MPICH) - Provido pelo Intel PSXE . Para colocar os executáveis ( mpicc , mpif77 , etc) no path , execute um dos comandos abaixo.

OpenMPI

  • Utilizando compiladores GNU (gcc, g++, gfortran):  
    * É necessário carregar apenas o módulo da versão do OpenMPI desejada:

    module load openmpi/gnu/2.0.4.2
    
  • Utilizando compiladores Intel (icc, icpc, ifort):  
    * É necessário carregar o módulo do Intel Parallel Studio XE previamente:

    source /scratch/app/modulos/intel-psxe-2017.sh
    module load openmpi/icc/2.0.4.2
    


  • Para uma lista completa das versões do OpenMPI disponíveis:  

    module avail openmpi
    

Intel MPI

source /scratch/app/modulos/intel-psxe-VERSAO.sh 
  • Já configura as variáveis para utilizar o Intel MPI

  • Para compilar uma aplicação com o Intel MPI e os compiladores Intel, é necessário utilizar os seguintes comandos:   mpiicc: Compilador C   mpiicpc: Compilador C++   mpiifort: Compilador Fortran

  • Os comandos padrão (mpicc, mpic++, mpif90 etc) utilizam os compiladores GNU (gcc, g++ e gfortran).

Para mais informações sobre o Intel Parallel Studio XE: Documentação Oficial do Intel® Parallel Studio XE

Topo


5. Gerenciador de filas

Não é permitido a execução de aplicações nos nós de login. Os processos em execução contínua, nesses nós, possuem um tempo limite de 15 minutos.

O gerenciador de filas utilizado é o Slurm v17.02 . Todos os jobs devem ser submetidos através do Slurm.

As filas de execução do Slurm são:

Fila Wall-clock máximo (em horas) Número mínimo de nós (núcleos+ dispositivos) Número máximo de nós (núcleos+ dispositivos) Número máximo de tarefas em execução por usuário Número máximo de tarefas em fila por usuário Custo em Unidade de Alocação (UA)
cpu (Nós B710) 96 21 (504) 50 (1200) 4 24 1,0
nvidia (Nós B715) 48 21 (504+42) 50 (1200+100) 4 24 1,5
gdl6 (Nós Sequana IA) 48 1 (40+8) 1 (40+8) 1 6 2,0
mesca2 5 48 1 (240) 1 (240) 1 6 2,0
cpu_small 72 1 (24) 20 (480) 16 96 1,0
nvidia_small 1 1 (24+2) 20 (480+40) 4 24 1,5
cpu_dev 1 0:20 1 (24) 4 (96) 1 1 1,0
nvidia_dev 1 0:20 1 (24+2) 4 (96+8) 1 1 1,5
cpu_scal 2 18 51 (1224) 128 (3072) 1 8 1,0
nvidia_scal 2 18 51 (1224+102) 128 (3072+256) 1 8 1,5
cpu_long 3 744 (31 dias) 1 (24) 10 (240) 3 18 1,0
nvidia_long 3 744 (31 dias) 1 (24+2) 10 (240+20) 2 4 1,5
cpu_shared 7 72 1 (1) 10 (240) 16 96 1
het_scal 9 18 16 (384) 128 (3072) 1 8 1,5
Requisições especiais 4 - - - - - -
Todos os thin nodes 4 - - - - - -
Filas da expansão
sequana_cpu 96 1 (48) 50 (2400) 4 24 1,0
sequana_cpu_dev 1 0:20 1 (48) 4 (192) 1 1 1,0
sequana_cpu_long 3 744 (31 dias) 1 (48) 10 (480) 3 18 1,0
sequana_cpu_shared 8 96 (4 dias) 1 (1) 50 (2400) 4 24 1,0
sequana_cpu_bigmem 10 96 1 (48) 18 (864) 4 24 1,0
sequana_cpu_bigmem_long 10 744 (31 dias) 1 (48) 5 (240) 3 18 1,5
sequana_gpu 96 1 (48+4) 21 (1008+84) 4 24 1,5
sequana_gpu_dev 1 0:20 1 (48+4) 4 (192+16) 1 1 1,5
sequana_gpu_long 3 744 (31 dias) 1 (48+4) 10 (480+40) 3 18 1,5
sequana_gpu_shared 11 96 1 (48+4) 15 (720+60) 4 24 1,5

  • 1 : Filas de desenvolvimento e teste, com limites reduzidos. A prioridade dessas filas é maior, para que os testes possam entrar em execução mais rapidamente.

  • 2 : Filas especias para jobs que necessitam de alta escalabilidade.

  • 3 : Filas especiais para jobs que necessitam de longa duração.

  • 4 : Filas especiais, que dependem de solicitação específica pelo usuário e devem ser autorizadas pela Equipe Técnica.

  • 5 : A fila mesca2 permite o compartilhamento de jobs no nó de execução. É possível executar em modo exclusivo, utilizando o parâmetro --exclusive no script de submissão.
    Na fila mesca2, quando o usuário não especificar a quantidade de memória a ser utilizada, através dos parâmetros --mem=MB (memória total do job) ou --mem-per-cpu=MB (memória por core alocado), o SLURM requisitará para o job 23GB de memória por core solicitado. Exemplo 3

  • 6 : A fila gdl é destinada a utilizar o nó Bull Sequana, focado em Machine Learning/Deep Learning.

  • 7 : A fila cpu_shared permite o compartilhamento de jobs no nó de execução. Para garantir o melhor uso dos recursos recomendamos que o parâmetro --exclusive não seja utilizado.
    Na fila cpu_shared, quando o usuário não especificar a quantidade de memória a ser utilizada, através dos parâmetros --mem=MB (memória total do job) ou --mem-per-cpu=MB (memória por core alocado), o SLURM requisitará para o job 2,5GB de memória por core solicitado. Exemplo 1

  • 8 : A fila sequana_cpu_shared permite o uso compartilhado do nó de execução. O parâmetro --exclusive NÃO DEVE SER UTILIZADO.
    Quando o usuário não informar a quantidade de cores (parâmetros -n, --ntasks, --ntasks-per-node, --ntasks-per-socket, --tasks-per-node) desejados o SLURM reservará um core por nó solicitado.
    Quando o usuário não especificar a quantidade de memória a ser utilizada (parâmetros --mem ou --mem-per-cpu), o SLURM reservará 8GB por core solicitado.

  • 9 : A fila het_scal possui 64 nós com arquitetura CPU e 64 nós com arquitetura GPU. Os jobs submetidos a essa fila podem solicitar um conjunto de nós heterogêneos para execução. Os nós com GPU foram configurados com a feature gpu e os nós CPU foram configurados com a feature cpu. O tópico 6.10 demonstra como submeter um job e selecionar os nós de forma heterogênea.

  • 10 : As filas sequana_cpu_bigmem* estão configuradas com nós que possuem 768 GB de memória RAM. O acesso a essas filas é exclusivo para projetos Premium.

  • 11 1: Fila com aceleradores NVIDIA V100 disponível exclusivamente para projetos Standard. A partir de 10/01/2022 essa fila permitirá a alocação compartilhada dos recursos de GPU através da funcionalidade de Generic Resource (GRES) do SLURM.

  • Além dos limites das filas para cada usuário, ainda há um limite global por projeto, que é compartilhado por todos os usuários do mesmo.
    Cada projeto está limitado em 100 jobs (executando [RUNNING] ou em espera [PENDING]) por vez em todo o cluster.

  • O SLURM utiliza um mecanismo de "backfill" para realizar a alocação dos jobs e iniciar sua execução. Esse mecanismo leva em consideração o tempo de duração (WallCLock) de todos os jobs e, com base nisso, calcula o tempo esperado de quando um job iniciará (entrará em execução). O mecanismo de backfill iniciará um job de menor prioridade se o seu tempo de duração não for atrapalhar o início de um job de maior prioridade.
    Dessa forma, quanto menor for o tempo de duração de um job, maior será a sua chance de entrar em execução.

    Para as filas do SDumont base:

    Por padrão, quando não especificado, o SLURM configura o tempo de duração do job como a metade do limite da fila (conforme descrito na tabela acima). Para alterar esse valor, basta utilizar o parâmetro --time=HH:MM:SS, conforme pode ser visto no Exemplo 2

    Deve-se ter o cuidado para ajustar corretamente o tempo de duração do job de acordo com as necessidades, para que ele não seja cancelado por ultrapassar o limite de tempo de execução, gerando a mensagem abaixo no arquivo de log do job:

    *** JOB #ID ON sdumont1468 CANCELLED AT YYY-MM-DDTHH:MM:SS DUE TO TIME LIMIT ***

    Para as filas da expansão:

    É obrigatório informar o tempo estimado de execução dos jobs. Caso o parâmetro --time não seja informado o job não será adicionado a fila e apresentará o erro abaixo:

    error: Job submit/allocate failed: Requested time limit is invalid (missing or exceeds some limit)

    O Exemplo 2 demonstra a utilização do parâmetro --time.

Topo


6. Submeter Jobs

  1. Compilar a aplicação dentro do HOMEDIR, utilizando os compiladores desejados

  2. Copiar os arquivos necessários (executável, bibliotecas, dados de entrada) para dentro da área de SCRATCH, pois a área de HOMEDIR não é acessível pelos nós computacionais

  3. Criar um script de submissão, configurando os parâmetros necessários para a execução do Job

  4. Submeter o script com o comando sbatch

  5. Verificar os arquivos de saída

Informações gerais

  • 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.

  • Para fins de contabilização de UAs, o Slurm considera a alocação de todos os cores de um nó quando este é alocado para um job, mesmo que só tenha sido solicitado 1 core. Ex: No caso de um job MPI, utilizando 2 nós e solicitando 4 cores em cada nó, o Slurm contabilizará um total de 48 cores para o job.

  • O ideal é sempre utilizar o máximo possível de cores nos nós alocados.

  • 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. Para desabilitar essa funcionalidade, basta incluir o parâmetro abaixo no script
    #SBATCH --no-requeue

Topo


6.1. Jobs paralelos (MPI)

Forma Geral de um Script 1) Utilizando o OpenMPI 2.0 e os compiladores GNU ou Intel

#!/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 --exclusive                    #Utilização exclusiva dos nós durante a execução do 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) Utilizando o OpenMPI com Intel PSXE (2016, 2017, 2018 ou 2019)
source /scratch/app/modulos/intel-psxe-2016.sh
##########    ou    ##########
source /scratch/app/modulos/intel-psxe-2017.sh
##########    ou    ##########
source /scratch/app/modulos/intel-psxe-2018.sh
##########    ou    ##########
source /scratch/app/modulos/intel-psxe-2019.sh
module load openmpi/icc/2.0.4.2

##########    ou    ##########
## 2) Utilizando o OpenMPI com GNU
module load openmpi/gnu/2.0.4.2


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

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

srun -n $SLURM_NTASKS $EXEC

*A ordem de carregar os módulos é importante! Primeiro carregar o módulo do Intel PSXE e depois o módulo do OpenMPI.


Forma Geral de um Script 2) Utilizando os compiladores Intel e o Intel MPI

#!/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 --exclusive                    #Utilização exclusiva dos nós durante a execução do 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 com intel MPI PSXE (2016, 2017, 2018 ou 2019)
source /scratch/app/modulos/intel-psxe-2016.sh
##########    ou    ##########
source /scratch/app/modulos/intel-psxe-2017.sh
##########    ou    ##########
source /scratch/app/modulos/intel-psxe-2018.sh
##########    ou    ##########
source /scratch/app/modulos/intel-psxe-2019.sh
export I_MPI_PMI_LIBRARY=/usr/lib64/libpmi.so

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

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

srun -n $SLURM_NTASKS $EXEC


Exemplo 1: - Utilizando OpenMPI 2.0 com Intel. Vai alocar 2 nós e distribuir 12 processos MPI por nó.

Script rodarmpi.srm
#!/bin/bash
#SBATCH --nodes=2                      #Numero de Nós
#SBATCH --ntasks-per-node=12           #Numero de tarefas por Nó
#SBATCH --ntasks=24                    #Numero total de tarefas MPI
#SBATCH -p cpu_dev                     #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-sp-openmpi-24       #Nome job
#SBATCH --exclusive                    #Utilização exclusiva dos nós durante a execução do 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
source /scratch/app/modulos/intel-psxe-2016.sh
module load openmpi/icc/2.0.4.2

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

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

srun --resv-ports -n $SLURM_NTASKS $EXEC

Submeter o job através do comando:
sbatch rodarmpi.srm



Exemplo 2: Utilizando o Intel MPI, alocando 8 nós, utilizando 3 processos MPI por nó e alterando o limite de tempo

* Por padrão, quando não especificado, o Slurm configura o WallCLock do job como o limite da fila (conforme descrito no 5. Gerenciador de Filas ). Para alterar esse valor, basta utilizar o parâmetro --time=HH:MM:SS

Script rodarmpi.srm
#!/bin/bash
#SBATCH --nodes=8                      #Numero de Nós
#SBATCH --ntasks-per-node=3            #Numero de tarefas por Nó
#SBATCH --ntasks=24                    #Numero total de tarefas MPI
#SBATCH -p cpu_small                   #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-sp-intelmpi-24       #Nome job
#SBATCH --time=00:05:00		       #Altera o tempo limite para 5 minutos
#SBATCH --exclusive                    #Utilização exclusiva dos nós durante a execução do 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
source /scratch/app/modulos/intel-psxe-2016.sh

#Configura I_MPI_PMI_LIBRARY para apontar para a biblioteca "Process Management Interface" do Slurm
export I_MPI_PMI_LIBRARY=/usr/lib64/libpmi.so


#Configura o executavel
EXEC=/scratch/app/NPB3.3.1-MZ/bin/sp-mz.C.intelmpi.24

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

srun -n $SLURM_NTASKS $EXEC

Submeter o job através do comando:
sbatch rodarmpi.srm


Exemplo 3: Submetendo um job para a fila mesca2, utilizando OpenMPI 2.0 com GNU, alterando a quantidade de memória alocada por core.
No total será alocado 120GB (24 cores * 5GB de memória por core)

* Esse exemplo utiliza um programa compilado com o GCC 6.5, por isso a necessidade do comando "module load gcc/6.5"

#!/bin/bash
#SBATCH --nodes=1                    #Numero de Nós
#SBATCH --ntasks=24                  #Numero total de tarefas MPI
#SBATCH -p mesca2                    #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-sp-openmpi+gnu-24 #Nome job
#SBATCH --mem-per-cpu=5000           #Altera a quantidade de memoria 

#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 gcc/6.5
module load openmpi/gnu/2.0.4.2

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

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

srun --resv-ports -n $SLURM_NTASKS $EXEC

Submeter o job através do comando:
sbatch rodarmpi.srm

Topo


6.2. Jobs paralelos (MPI-multithreaded)

Forma Geral de um 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 --cpus-per-task=CPT            #Numero de threads por tarefa MPI
#SBATCH -p FILA                        #Fila (partition) a ser utilizada
#SBATCH -J JOB                         #Nome job
#SBATCH --exclusive                    #Utilização exclusiva dos nós durante a execução do 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
#OpenMPI com Intel
source /scratch/app/modulos/intel-psxe-2016.sh
module load openmpi/icc/2.0.4.2

#ou
#OpenMPI com GNU
module load gcc/6.5
module load openmpi/gcc/2.0.4.2

#ou
#intel MPI
source /scratch/app/modulos/intel-psxe-2016.sh
export I_MPI_PMI_LIBRARY=/usr/lib64/libpmi.so


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

#exibe informaçoes sobre o executavel
/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  -n $SLURM_NTASKS -c $SLURM_CPUS_PER_TASK $EXEC

O número máximo de threads (cpus-per-task=) é 24

Exemplo 1: Utilizando O OpenMPI 2.0 com GNU, alocando 4 nós e distribuindo 1 processo MPI por nó, que abrirá 24 threads cada um.

Número de threads que cada mpi abrirá = 24

Número de máquinas = 4

Número de tarefas MPI por Nó = 1

Número total de tarefas MPI = 4

Script rodarmpi.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=24 #Numero de threads por tarefa MPI
#SBATCH -p cpu_dev #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-sp-openmpi-hybrid-4 #Nome job
#SBATCH --exclusive #Utilização exclusiva dos nós durante a execução do 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/2.0.4.2
module load gcc/6.5

#exibe informaçoes sobre o executavel
EXEC=/scratch/app/NPB3.3.1-MZ/bin/sp-mz.C.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 --resv-ports -n $SLURM_NTASKS -c $SLURM_CPUS_PER_TASK $EXEC

Submeter o job através do comando:
sbatch rodarmpi.srm

Topo


6.3. Jobs paralelos (threads/OpenMP)

Forma Geral de um Script

#!/bin/bash
#SBATCH --nodes=1                      #Numero de Nós
#SBATCH --ntasks-per-node=1            #Numero de tarefas por Nó
#SBATCH --ntasks=1                     #Numero total de tarefas MPI
#SBATCH --cpus-per-task=CPT            #Numero de threads
#SBATCH -p FILA                        #Fila (partition) a ser utilizada
#SBATCH -J JOB                         #Nome job
#SBATCH --exclusive                    #Utilização exclusiva dos nós durante a execução do 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
#Intel
source /scratch/app/modulos/intel-psxe-2016.sh

#ou
#GNU
module load gcc/6.5

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

#exibe informaçoes sobre o executavel
/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  -N 1 -c $SLURM_CPUS_PER_TASK $EXEC

O número máximo de threads (cpus-per-task=) é 24

Exemplo: Utilizando os compiladores intel e abrindo 24 threads.

Script rodarthread.srm
#!/bin/bash
#SBATCH --nodes=1                      #Numero de Nós
#SBATCH --ntasks-per-node=1            #Numero de tarefas por Nó
#SBATCH --ntasks=1                     #Numero total de tarefas MPI
#SBATCH --cpus-per-task=24             #Numero de threads
#SBATCH -p cpu_dev                     #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-sp-openmp-intel      #Nome job
#SBATCH --exclusive                    #Utilização exclusiva dos nós durante a execução do 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
source /scratch/app/modulos/intel-psxe-2016.sh

#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

export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK

srun  -N 1 -c $SLURM_CPUS_PER_TASK $EXEC

Submeter o job através do comando:
sbatch rodarthread.srm

Topo


6.4. Múltiplas tarefas simultâneas em um único job

É possível executar várias tarefas simultâneas em um único job, utilizando o ambiente que foi alocado.

Essas tarefas podem ser mistas, sendo puramente MPI, puramente Thread/OpenMP ou híbridas.

Exemplo 1: Alocando 20 nós, mas executando duas aplicações MPI independentes e simultâneas.

Script rodar.srm

#!/bin/bash
#SBATCH --nodes=20                     #Numero de Nós
#SBATCH --ntasks-per-node=24           #Numero de tarefas por Nó
#SBATCH --ntasks=480                   #Numero total de tarefas MPI
#SBATCH -p cpu_small                   #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-sp-Multi       #Nome job
#SBATCH --exclusive                    #Utilização exclusiva dos nós durante a execução do 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
source /scratch/app/modulos/intel-psxe-2016.sh
module load openmpi/icc/2.0.4.2

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

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

srun --resv-ports --nodes 10 --ntasks=240 $EXEC &
srun --resv-ports --nodes 10 --ntasks=240 $EXEC &
wait

Submeter o job através do comando:
sbatch rodar.srm


Exemplo 2: Alocando 10 nós e executando 10 aplicações OpenMP independentes e simultâneas.

Script rodar.srm

#!/bin/bash
#SBATCH --nodes=10           #Numero de Nós
#SBATCH --ntasks-per-node=1  #Numero de tarefas por Nó
#SBATCH --cpus-per-task=24   #Numero de threads por tarefa MPI
#SBATCH -p cpu_small         #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-sp-Multi   #Nome job
#SBATCH --exclusive          #Utilização exclusiva dos nós durante a execução do 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 gcc/6.5

#exibe informaçoes sobre o executavel
EXEC=/scratch/app/NPB3.3.1-MZ/bin/sp-mz.C.openmp-gnu.x
/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 -N 1 -n 1 -c $SLURM_CPUS_PER_TASK $EXEC &
srun -N 1 -n 1 -c $SLURM_CPUS_PER_TASK $EXEC &
srun -N 1 -n 1 -c $SLURM_CPUS_PER_TASK $EXEC &
srun -N 1 -n 1 -c $SLURM_CPUS_PER_TASK $EXEC &
srun -N 1 -n 1 -c $SLURM_CPUS_PER_TASK $EXEC &
srun -N 1 -n 1 -c $SLURM_CPUS_PER_TASK $EXEC &
srun -N 1 -n 1 -c $SLURM_CPUS_PER_TASK $EXEC &
srun -N 1 -n 1 -c $SLURM_CPUS_PER_TASK $EXEC &
srun -N 1 -n 1 -c $SLURM_CPUS_PER_TASK $EXEC &
srun -N 1 -n 1 -c $SLURM_CPUS_PER_TASK $EXEC &
wait

Submeter o job através do comando:
sbatch rodar.srm

Topo


6.5. 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ó, realizar as suas tarefas localmente e executar a aplicação (através do mpirun/mpiexec ).

* 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 cpu_dev -J NPB-MZ-interativo --exclusive

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

#carregar as bibliotecas
source /scratch/app/modulos/intel-psxe-2016.sh

#executa a aplicação
export I_MPI_PMI_LIBRARY=/usr/lib64/libpmi.so
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 sdumont1000, sdumont1001, sdumont1002 e sdumont1003.

salloc --nodes=4 --ntasks-per-node=6   --ntasks=24  -p cpu_dev   -J Interativo   --exclusive

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

nodeset -e $SLURM_JOB_NODELIST
#retornará algo como sdumont1000 sdumont1001 sdumont1002 sdumont1003
                  

#acessar o primeiro nó alocado
ssh sdumont1000

#carregar as bibliotecas

[usuario@sdumont1000 ~]$ module load openmpi/2.0.4.2

[usuario@sdumont1000 ~]$ module load gcc/6.5

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

#executa a aplicação, utilizando o mpiexec
[usuario@sdumont1000 CODIGO]$ mpiexec -x LD_LIBRARY_PATH \
 --host sdumont1000,sdumont1001,sdumont1002,sdumont1003 -np 24 -npernode 6  ${PWD}/executavel

#* Será necessário digitar a senha para poder iniciar a execução 
# da aplicação nos outros nós (ex: sdumont1001, sdumont1002 e sdumont1003)

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

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

Topo


6.6. 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).

Para utilizar os frameworks disponíveis (TensorFlow 1.13, Keras, PyTorch) é necessário carregar o módulo:

module load deepl/deeplearn-py3.7

* IMPORTANTE: Esse módulo está disponível apenas dentro do nó da fila gdl!

A utilização da fila gdl segue o mesmo padrão das outras filas, podendo ser através de jobs interativos (Exemplo 1) ou através de scripts de submissão (Exemplo 2).

Exemplo 1: Submetendo um job interativo, acessando diretamente o nó.

salloc --nodes=1 -p gdl -J GDL-teste --exclusive

salloc: Granted job allocation 123456

#verificar quais nós foram alocados para o job
squeue -j 123456
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
            123456       gdl     bash usuario1  R       5:28      1 sdumont4000

#acessa o nó
ssh sdumont4000

#carrega o módulo e executa a aplicação 
[usuario1@sdumont4000 ~]$ cd /scratch/projeto/usuario1/teste-gdl
[usuario1@sdumont4000 teste-gdl]$ module load deepl/deeplearn-py3.7
[usuario1@sdumont4000 teste-gdl]$ python script.py 

#encerra a conexão com o nó
[usuario1@sdumont4000 teste-gdl]$ exit

#encerra a sessão interativa e termina o job
exit
salloc: Relinquishing job allocation 123456


Exemplo 2: Submetendo um job através de um script para executar o python diretamente.

#!/bin/bash
#SBATCH --nodes=1           #Numero de Nós
#SBATCH --ntasks-per-node=1 #Numero de tarefas por Nó
#SBATCH --ntasks=1          #Numero de tarefas
#SBATCH -p gdl              #Fila (partition) a ser utilizada
#SBATCH -J GDL-teste-script #Nome job
#SBATCH --exclusive         #Utilização exclusiva dos nós durante a execução do job

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

cd $SLURM_SUBMIT_DIR

#Configura o módulo de Deep Learning
module load deepl/deeplearn-py3.7

#acessa o diretório onde o script está localizado 
cd /scratch/projeto/usuario1/teste-gdl

#executa o script
python script.py 


Submeter o job através do comando:

sbatch rodar.srm

*Nesse exemplo não é necessário utilizar o comando srun. A execução pode ser iniciada diretamente através do python

Topo


6.7. Jobs para a fila cpu_shared

A fila cpu_shared permite o uso compartilhado dos nodes. Para fazer o melhor uso dos recusos recomendamos que o parâmetro --exclusive não seja utilizado nos scripts de submissão.

Exemplo 1: Submetendo um job serial para a fila cpu_small, alterando a quantidade de memória alocada por core.

Esse exemplo utiliza um programa compilado com o GCC 6.5, por isso a necessidade do comando "module load gcc/6.5"

#!/bin/bash
#SBATCH --nodes=1                    #Numero de Nós
#SBATCH --ntasks=1                   #Numero total de tarefas MPI
#SBATCH -p cpu_shared                #Fila (partition) a ser utilizada
#SBATCH -J NPB-MZ-serial             #Nome job
#SBATCH --mem-per-cpu=4000           #Altera a quantidade de memoria 

#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 gcc/6.5

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

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

$EXEC


Para a submissão de jobs paralelos consulte os exemplos anteriores: MPI-multithreaded e Threads/OpenMP.

* IMPORTANTE: Não utilize o parâmetro --exclusive nessa fila.

Topo


6.8. Jobs para as filas sequana

Todos os exemplos acima se aplicam para a submissão de jobs às filas da expansão.

Os usuários que compilaram suas aplicações para o SDumont base podem encontrar problemas ao tentar executá-las nos nós da expansão.

Um dos possíveis motivos é que o conjunto de hardware dos nós das filas sequana_* é diferente dos nós do SDumont base e a compilação pode ter utilizado algum parâmetro que não seja compatível com a nova arquitetura. Caso isso aconteça, você deverá acessar o nó sdumont18 (que possui o mesmo conjunto de hardware dos nós sequana) e recompilar sua aplicação.

Após se conectar ao login.sdumont.lncc.br, execute o comando ssh sdumont18.

$ ssh nome.sobrenome@login.sdumont.lncc.br
$ ssh sdumont18
sdumont18 ~$

Se você precisar rodar sua aplicação nas duas arquiteturas, recomendamos que você mantenha uma versão compatível com cada uma.

Para as aplicações compiladas pela equipe do Helpdesk basta carregar o módulo correspondente conforme demonstrado no item 3.1.

IMPORTANTE 1: A submissão dos jobs para as filas sequana_* pode ser feita a partir de qualquer nó de login.

IMPORTANTE 2: É obrigatório informar o parâmetro --time na submissão dos jobs.

Exemplo de job para a fila sequana

#!/bin/bash
#SBATCH --nodes=N                #Número de Nós
#SBATCH --ntasks-per-node=TPN    #Número 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          #Obrigatório

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

cd  $SLURM_SUBMIT_DIR

## 1) Carrega o módulo sequana
module load sequana/current

## 2) Carrega o OpenMPI com GNU
module load openmpi/gnu/2.0.4.14_sequana

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

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

srun -n $SLURM_NTASKS $EXEC

Topo


6.9. Jobs para a fila sequana_cpu_shared

O número máximo de threads (cpus-per-task) é 48.

A fila sequana_cpu_shared permite o uso compartilhado do nó de execução. O parâmetro --exclusive NÃO DEVE SER UTILIZADO.

Quando o usuário não informar a quantidade de cores (parâmetros -n, --ntasks, --ntasks-per-node, --ntasks-per-socket, --tasks-per-node) desejados o SLURM reservará um core por nó solicitado.

Quando o usuário não especificar a quantidade de memória a ser utilizada (parâmetros --mem ou --mem-per-cpu), o SLURM reservará 8GB por core solicitado.

Solicitando 1 nó e 24 núcleos (equivalente a um nó do sdumont base)

#!/bin/bash
#SBATCH --nodes=1                #Número de Nós
#SBATCH --ntasks-per-node=24     #Número de tarefas por Nó
#SBATCH -p sequana_cpu_shared    #Fila (partition) a ser utilizada
#SBATCH -J JOB   		    	      #Nome job
#SBATCH --time=01:00:00          #Obrigatório

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

cd  $SLURM_SUBMIT_DIR

## 1) Carrega o módulo sequana
module load sequana/current

## 2) Carrega os módulos desejados
module load nome_do_modulo1/compilador/versao_sequana
module load nome_do_modulo2/compilador/versao_sequana

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

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

srun -n $SLURM_NTASKS $EXEC

Solicitando 2 nós e 24 núcleos por nó (equivalente a dois nós do sdumont base):

#!/bin/bash
#SBATCH --nodes=2                #Número de Nós
#SBATCH --ntasks-per-node=24     #Número de tarefas por Nó
#SBATCH --ntasks=48              #Número de tarefas por Nó
#SBATCH -p sequana_cpu_shared    #Fila (partition) a ser utilizada
#SBATCH -J JOB   		    	      #Nome job
#SBATCH --time=01:00:00          #Obrigatório

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

cd  $SLURM_SUBMIT_DIR

## 1) Carrega o módulo sequana
module load sequana/current

## 2) Carrega os módulos desejados
module load nome_do_modulo1/compilador/versao_sequana
module load nome_do_modulo2/compilador/versao_sequana

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

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

srun -n $SLURM_NTASKS $EXEC

Por padrão, o SLURM vai reservar 8GB de memória do nó para cada core requisitado. É possível solicitar uma quantidade de memória diferente utilizando as opções --mem (define o total de memória utilizada pelo job) ou --mem-per-cpu (permite definir o limite de memória que será reservado para cada core)

Solicitando 1 nó, 12 núcleos e um total de 128GB de memória RAM para o job

#!/bin/bash
#SBATCH --nodes=1                #Número de Nós
#SBATCH --ntasks-per-node=12     #Número de tarefas por Nó
#SBATCH --mem=128G               #Total de memória do job
#SBATCH -p sequana_cpu_shared    #Fila (partition) a ser utilizada
#SBATCH -J JOB   		    	      #Nome job
#SBATCH --time=01:00:00          #Obrigatório

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

cd  $SLURM_SUBMIT_DIR

## 1) Carrega o módulo sequana
module load sequana/current

## 2) Carrega os módulos desejados
module load nome_do_modulo1/compilador/versao_sequana
module load nome_do_modulo2/compilador/versao_sequana

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

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

srun -n $SLURM_NTASKS $EXEC

Para a submissão de jobs paralelos consulte os exemplos anteriores: MPI-multithreaded e Threads/OpenMP.

Topo


6.10. Jobs para a fila heterogênea het_scal

A fila het_scal está configurada com 128 nós B700, dividido em 64 nós CPU e 64 nós com aceleradores NVIDIA K40. Essa fila permite que o usuário solicite um conjunto heterogêneo de recursos para realizar suas simulações. Os nós CPU foram configurados com a feature cpu e os nós GPU foram configurados com a feature gpu.

Para especificar o tipo de nó deve ser utilizado o parâmetro -C ou –constraint.

IMPORTANTE: Se o tipo de nó não for especificado o SLURM vai alocar o nó que estiver disponível, independente do seu tipo.

Solicitando 8 nós CPU e 8 nós GPU

#!/bin/bash
#SBATCH --nodes=8 -C cpu
#SBATCH packjob
#SBATCH --nodes=8 -C gpu

##Executando a aplicação nos nós CPU
srun --pack-group=0 $EXEC1

#Executando a aplicação nos nós GPU
srun --pack-group=1 $EXEC2


A separação dos grupos é feita pela linha #SBATCH packjob Para submeter diretamente pela linha de comando utilize o caractere “:” para separar os grupos de nós, veja os exemplos abaixo:

$ salloc -N 8 -C cpu : -N 8 -C gpu
$ sbatch -N 8 -C cpu : -N 8 -C gpu meuprograma

Os grupos de nós ficam armazenados nas variáveis de ambiente do SLURM. Para consultar a lista de nós de cada grupo utilize o comando: env | grep SLURM_JOB. Será criada uma variável de ambiente SLURM_JOB_NODELIST_PACK_GROUP_Nº, onde Nº corresponde ao índice do grupo de nós.

SLURM_JOB_NODELIST_PACK_GROUP_0 = lista de nós alocados com a feature cpu
SLURM_JOB_NODELIST_PACK_GROUP_1 = lista de nós alocados com a feature gpu

Mais detalhes sobre a submissão de jobs heterogêneos podem ser encontrados na documentação do SLURM. https://slurm.schedmd.com/SLUG17/HeterogeneousJobs.pdf

Topo


7. Verificando status

Comando: squeue [parametros] - Exibe informações sobre os jobs e o escalonamento

Comando: squeue --start - Exibe o tempo esperado de quando um job entrará em execução (coluna START_TIME)

Comando: sinfo [parametros] - Exibe informações sobre as filas/partições e os nós.

Comando: scontrol show jobid #NUMERO-DO-JOB -dd - Exibe informações detalhadas sobre um job.

Topo


7.1. Status/Reason do job

Ao executar o comando squeue ou sacct, o job pode estar em um dos seguintes estados (coluna "ST"):

CA - CANCELLED: O job foi explicitamente cancelado pelo usuário ou pelo administrador.

CD - COMPLETED: O job foi terminou normalmente, finalizando todos os seus processos em todos os nós.

CG - COMPLETING: O job está no processo de finalização. Alguns dos processos ainda podem estar em execução em um dos nós.

F - FAILED: O job terminou com um código de saída diferente de zero, indicando falha na execução/finalização.

NF - NODE_FAIL: O job terminou devido a uma falha em um ou mais nós.

PD - PENDING: O job está aguardando em fila pela alocação/liberação de recursos.

R - RUNNING: O job em execução.

TO - TIMEOUT: O job foi terminado por ter alcançado o seu limite de tempo.


Ao executar o comando squeue, a coluna REASON (Razão) explica porque um job está aguardando na fila, com o status PD - PENDING. As razões mais comuns são:

AssociationJobLimit: Foi atingido o limite máximo do número de jobs.

PartitionNodeLimit: O número de nós solicitado pelo job está fora do limite da Fila.

AssocMaxNodesPerJobLimit: O job solicitou um número de nós acima do permitido.

AssocMaxJobsLimit: Geralmente ocorre quando excedeu o número de jobs em execução da fila.

AssocMaxWallDurationPerJobLimit : O job solicitou um tempo de execução maior do que o permitido pela fila

BeginTime: O job possui um horário determinado para iniciar, que ainda não foi atingido.

Dependency: O job está aguardando a finalização de uma dependência para poder iniciar.

JobHeldAdmin: O job foi suspenso pelo administrador.

JobHeldUser: O job foi suspenso pelo usuário.

NodeDown: Um ou mais nós necessários para o job está "Down".

PartitionDown: A fila (partição) solicitada pelo job está "Down".

PartitionInactive: A fila (partição) solicitada pelo job está Inativa.

Priority: Um ou mais jobs de maior prioridade estão à frente na fila, aguardando a execução.

ReqNodeNotAvail: Um ou mais nós solicitados pelo job não estão disponíveis.

Resources: O job está aguardando os recursos solicitados ficarem disponíveis, geralmente relacionado ao número de nós.

Topo


7.2. Informações sobre a Utilização

Para obter informações sobre a utilização dos recursos do SDumont por um projeto, é possível utilizar um dos comandos abaixo:

Comando: sacct -lj #NUMERO-DO-JOB - Exibe informações de accounting do job.

Comando: sacct -S AAAA-MM-DD -E AAAA-MM-DD -X -A PROJETO - Exibe a lista dos jobs que foram executados pelo projeto em um determinado período.

Comando: sreport -t hours job SizesByAccount start=AAAA-MM-DD end=AAAA-MM-DD Users=USUARIO FlatView Grouping=12001 - Exibe o total (em horas) utilizado durante o período, delimitado pelos parâmetros start e end.

Comando: sreport -t hours cluster AccountUtilizationByUser start=AAAA-MM-DD end=AAAA-MM-DD Accounts=PROJETO - Exibe a quantidade de horas utilizada pelo projeto durante um período, delimitado pelos parâmetros start e end.

Essa informação sobre a utilização também está disponível na intranet do SDumont, acessível apenas para o coordenador de cada projeto.

Topo


7.3. Visualizando o consumo dos recursos das filas _shared

É possível utilizar o comando sinfo para exibir uma visualização personalizada das informações das filas.

Visualizando os recursos (CPUS) da fila:

$ sinfo -p sequana_cpu_shared -o "%P %.5a %.10l %.6D %C"
PARTITION AVAIL TIMELIMIT NODES CPUS(A/I/O/T)
sequana_cpu_shared up infinite 80 12/3828/0/3840

No exemplo acima visualizamos que temos 12 cores ocupados (A), 3828 disponíveis (I), nenhum nó offline (O) e um total de 3840 cores disponíveis (T) na fila.

Visualizando os recursos de cada nó da fila:

Para visualizar o consumo dos cores de cada nó, devemos acrescentar o parâmentro -N e adicionar o cabeçalho %N ao comando:

$ sinfo -N -p sequana_cpu_shared -o "%N %.5a %.10l %.6D %C"
NODELIST AVAIL TIMELIMIT NODES CPUS(A/I/O/T)
sdumont6085 up infinite 1 12/36/0/48
sdumont6086 up infinite 1 0/48/0/48
sdumont6087 up infinite 1 0/48/0/48
sdumont6088 up infinite 1 0/48/0/48
sdumont6089 up infinite 1 0/48/0/48
...

O resultado apresenta que todos os 12 cores foram alocados no nó sdumont6085. Os demais nós da fila estão totalmente livres.

Topo


8. Remover jobs da fila ou em execução

Comando: scancel [parametros] #NUMERO-DO-JOB

Topo


9. Comentários Finais

Para mais detalhes, consulte os manuais dos comandos:

  • man sbatch

  • man srun

  • man squeue

  • man sinfo

  • man scancel

  • man sacct

  • man sreport

Topo


9.1. Variáveis de ambiente do Slurm

O Slurm configura as seguintes variáveis no ambiente do Job (acessíveis dentro do script de submissão, por exemplo):

SLURM_ARRAY_TASK_ID

  • Job array ID (index) number.

SLURM_ARRAY_JOB_ID

  • Job array's master job ID number.

SLURM_CHECKPOINT_IMAGE_DIR

  • Directory into which checkpoint images should be written if specified on the execute line.

SLURM_CLUSTER_NAME

  • Name of the cluster on which the job is executing.

SLURM_CPUS_ON_NODE

  • Number of CPUS on the allocated node.

SLURM_CPUS_PER_TASK

  • Number of cpus requested per task. Only set if the --cpus-per-task option is specified.

SLURM_DISTRIBUTION

  • Same as -m, --distribution

SLURM_GTIDS

  • Global task IDs running on this node. Zero origin and comma separated.

SLURM_JOB_ID (and SLURM_JOBID for backwards compatibility)

  • The ID of the job allocation.

SLURM_JOB_CPUS_PER_NODE

  • Count of processors available to the job on this node. Note the select/linear plugin allocates entire nodes to jobs, so the value indicates the total count of CPUs on the node. The select/cons_res plugin allocates individual processors to jobs, so this number indicates the number of processors on this node allocated to the job.

SLURM_JOB_DEPENDENCY

  • Set to value of the --dependency option.

SLURM_JOB_NAME

  • Name of the job.

SLURM_JOB_NODELIST (and SLURM_NODELIST for backwards compatibility)

  • List of nodes allocated to the job.

SLURM_JOB_NUM_NODES (and SLURM_NNODES for backwards compatibility)

  • Total number of nodes in the job's resource allocation.

SLURM_JOB_PARTITION

  • Name of the partition in which the job is running.

SLURM_LOCALID

  • Node local task ID for the process within a job.

SLURM_MEM_BIND

  • Set to value of the --mem_bind option.

SLURM_NODE_ALIASES

  • Sets of node name, communication address and hostname for nodes allocated to the job from the cloud. Each element in the set if colon separated and each set is comma sepa rated. For example: SLURM_NODE_ALIASES=ec0:1.2.3.4:foo,ec1:1.2.3.5:bar

SLURM_NODEID

  • ID of the nodes allocated.

SLURMD_NODENAME

  • Names of all the allocated nodes.

SLURM_NTASKS (and SLURM_NPROCS for backwards compatibility)

  • Same as -n, --ntasks

SLURM_NTASKS_PER_CORE

  • Number of tasks requested per core. Only set if the --ntasks-per-core option is specified.

SLURM_NTASKS_PER_NODE

  • Number of tasks requested per node. Only set if the --ntasks-per-node option is specified.

SLURM_NTASKS_PER_SOCKET

  • Number of tasks requested per socket. Only set if the --ntasks-per-socket option is specified.

SLURM_PRIO_PROCESS

  • The scheduling priority (nice value) at the time of job submission. This value is propagated to the spawned processes.

SLURM_PROCID

  • The MPI rank (or relative process ID) of the current process

SLURM_PROFILE

  • Same as --profile

SLURM_RESTART_COUNT

  • If the job has been restarted due to system failure or has been explicitly requeued, this will be sent to the number of times the job has been restarted.

SLURM_SUBMIT_DIR

  • The directory from which sbatch was invoked.

SLURM_SUBMIT_HOST

  • The hostname of the computer from which sbatch was invoked.

SLURM_TASKS_PER_NODE

  • Number of tasks to be initiated on each node. Values are comma separated and in the same order as SLURM_NODELIST. If two or more consecutive nodes are to have the same task count, that count is followed by "(x#)" where "#" is the repetition count. For example, "SLURM_TASKS_PER_NODE=2(x3),1" indicates that the first three nodes will each execute three tasks and the fourth node will execute one task.

SLURM_TASK_PID

  • The process ID of the task being started.

SLURM_TOPOLOGY_ADDR

  • This is set only if the system has the topology/tree plugin configured. The value will be set to the names network switches which may be involved in the job's communications from the system's top level switch down to the leaf switch and ending with node name. A period is used to separate each hardware component name.

SLURM_TOPOLOGY_ADDR_PATTERN

  • This is set only if the system has the topology/tree plugin configured. The value will be set component types listed in SLURM_TOPOLOGY_ADDR. Each component will be identified as either "switch" or "node". A period is used to separate each hardware component type.

Topo