Melhorando o Script de Submissão
Esta seção tem o intuito de detalhar a construção de um script de submissão de job. Para isso, vários exemplos e opções de parâmetros serão mostrados.
Opções do SBATCH
O SBATCH
é uma instrução necessária do Slurm. Eis algumas referências:
A tabela abaixo mostra alguns dos parâmetros do sbatch.
Parâmetro |
Abreviação |
Significado |
–time |
-t |
Tempo máximo de execução (min, min:seg, horas:min:seg, dias-horas) |
–cpus-per-task |
-c |
Número de CPUs por processo |
–ntasks |
-n |
Número total de processos |
–nodes |
-N |
Número mínimo de worker nodes |
–output |
-o |
Arquivo com o stdout (mensagens de saída) |
–error |
-e |
Arquivo com o stderr (mensagens de erro) |
–mem |
Memória por nó em MB |
|
–mem-per-cpu |
Memória por CPU em MB |
Script job-nanny
Vamos supor que que um usuário chamado Spock (cujo login no GridUnesp seja spock) queira, adaptar seu script (denominado vulcano.sh) para começar a processar simulações de seu projeto de pesquisa. Para isso, ele precisa conhecer mais opções sobre o comando SBATCH
e como construir um script de maneira adequada.
Digamos ainda que Spock pretenda executar um script em linguagem Python que denominou de dobra_4.py, o qual lê os arquivos de input energia.in e combustivel.in, e produz o arquivo light-speed.data como resultado. Seu script de submissão tem então o seguinte conteúdo:
#!/bin/bash
#SBATCH -t 24:00:00 -c 4
python dobra_4.py --input=energia.in,combustivel.in
Algumas observações sobre esse script:
Como sabe que a execução do script dobra_4.py não deverá demorar mais do que 1 dia, requistou o tempo máximo de processamento de 24 horas (
-t 24:00:00
).Solicitou ainda a alocação de 4 CPUs (
-c 4
) para realizar o processamento desse job.Ao fim, resolveu utilizar uma versão do Python que ele próprio instalou (
/home/spock/installations/bin/python
).
Perigo
Aqui já é possível identificar alguns problemas no script de submissão:
Não foram informados os arquivos de input nem de output.
Também não foi informado o script
job-nanny
.Também não foram informadas as variáveis de ambiente para o Python a ser usado.
O script job-nanny
serve para evitar que as aplicações científicas façam leitura e escrita diretamente na partição /home/
. Uma vez que o job é submetido (a partir do /home/
) e começa a ser processado pelos worker nodes (nós de processamento), a leitura e escrita em disco deve ser feita em uma partição distinta do /home/
. Cabe ao scritp job-nanny
escolher qual será essa partição (a depender das configurações do script de submissão). Do contrário, os worker node realizarão leitura e escrita diretamente no disco do /home/
, levando a uma sobrecarga na rede devido à grande transferência de arquivos entre esta partição e os nós.
Além disso, o job-nanny
também verifica outros parâmetros como INPUT e OUTPUT. A importância de informar quais são os arquivos/pastas de input reside no fato de evitar que todos os arquivos do diretório (da pasta) corrente sejam transferidos para a partição escolhida. Não se deve transferir arquivos desnecessários, que não farão parte da execução da simulação. Bem como é também importante informar quais são os arquivos/pastas de output pois, a depender da aplicação científica utilizada, muito “lixo” é produzido durante o processamento, não sendo de interesse do usuário ter esses arquivos e, ademais, ao garantir que a menor quantidade de dados possível seja transferida, evita degradar a rede.
Por fim, ao usar um pacote instalado no próprio /home/
, é preciso informar ao sistema onde encontrar os binários, libs e/ou headers da instalação. Geralmente isso é feito passando o caminho de variáveis como PATH, LD_LIBRARY_PATY e INCLUDE. Mas pode ser necessário informar várias outras variáveis de ambiente. É preciso verificar as instruções do manual de instalação do pacote.
Com base nas observações acima, um script vulcano.sh ideal para Spock seria:
#!/bin/bash
#SBATCH -t 24:00:00 -c 4
export INPUT="energia.in combustivel.in dobra_4.py"
export OUTPUT="light-speed.data"
export PATH=/home/spock/installations/bin:$PATH
export LD_LIBRARY_PATY=/home/spock/installations/lib:$LD_LIBRARY_PATY
export INCLUDE=/home/spock/installations/include:$INCLUDE
job-nanny python dobra_4.py --input=energia.in,combustivel.in
Neste exemplo, estão sendo passados os arquivos energia.in, combustivel.in e dobra_4.py como INPUT, e light-speed.data como OUTPUT dentro das aspas dupla. Havendo mais de um arquivo de input/output, deve-se separar os nomes por espaço em branco.
Digamos agora que Spock tenha decidido usar o pacote Python que instalou num ambiente Conda (veja a Seção Instalação via comandos Conda). Neste caso, o script de submissão teria o seguinte conteúdo:
#!/bin/bash
#SBATCH -t 24:00:00 -c 4
#SBATCH --mail-user=spock.vulcano@unesp.br ---mail-type=END,FAIL
export INPUT="energia.in combustivel.in dobra_4.py"
export OUTPUT="light-speed.data"
module load anaconda3
source activate startrek
job-nanny python dobra_4.py --input=energia.in,combustivel.in
Note que não houve necessidade de informar as variáveis de ambiente já que bastou ativar o ambiente Conda anteriormente criado.
Note também que, desta vez, Spock decidiu incluir seu e-mail (spock.vulcano@unesp.br) para ser informado quando a simulação finalizar com sucesso (END) ou caso seja cancelado devido a alguma falha (FAIL).
Dica
Caso queira saber mais opções do parâmetro ---mail-type
, consulte a página do SBATCH.
Parâmetros do job-nanny
O script job-nanny
identifica os seguintes parâmetros:
Parâmetro |
Valor padrão |
Significado |
INPUT |
“*” |
Arquivos copiados para a área temporária para iniciar a simulação. |
OUTPUT |
“*” |
Arquivos copiados de volta para a pasta
inicial (no |
CHECKPOINT |
“$OUTPUT” |
Arquivos copiados sistematicamente para a pasta inicial. |
WAIT_CHECKPOINT |
“10800” = 3horas |
Intervalo entre a cópia dos arquivos de checkpoint, em segundos. |
VERBOSE |
“0” = False |
Controla se informações sobre as operações do próprio script devem ser impressas no stdout |
CHECKPOINT_FUNC |
Avançado: Usado apenas em casos específicos onde é necessário realizar alguma operação antes do checkpoint. Consule VASP |
|
LARGE_FILES |
“false” |
Suporte a arquivos grandes.
Para ponto de montagem no |
SHARED_FS |
Utiliza um sistema de arquivos compartilhado
(útil para aplicações MPI).
Se SHARED_FS=”true”, é utilizado o ponto de
montagem no |
Sempre que a simulação utilizar MPI com Memória Distribuída entre 2 ou mais nós, ou LARGE_FILES=”true”, ou SHARED_FS=”true”, os jobs serão executados a partir da partição /store/
. Para informações sobre a utilização das partições /home/
, /tmp/
ou /store/
, consulte a seção Informações sobre o Storage.
Supondo que o usuário queira informar no parâmetro INPUT apenas 5 arquivos denominados
input_01.txt
input_02.txt
process.dat
file_a.csv
file_b.csv
e que não se importe em receber todos os arquivos de output e, ainda, gostaria que os resultados da simulação fossem sincronizados com seu /home/
a cada hora (em vez do padrão de 3 horas), o script de submissão poderia então ser configurado assim:
export INPUT="input_*.txt process.dat file*"
export OUTPUT="*"
export WAIT_CHECKPOINT="3600"
Sistema de Filas
O cluster está dividido em filas, de forma a organizar os processos e equilibrar o tempo de espera com o tempo de execução. Cada fila significa que o job não ficará processando por um tempo maior do que aquele que foi solicitado. A tabela a seguir mostra o tempo máximo de processamento em cada fila.
Fila |
Limite de execução |
short |
24 horas (padrão) |
medium |
7 dias |
long |
30 dias |
Nenhum processo poderá alocar um recurso por mais de 30 dias.
Importante
Cabe ao usuário informar o tempo máximo de processamento do seu job. Caso não informe, a simulação será executada até atingir o prazo padrão (24 horas). E caso o prazo limite seja atingido e o processamento não tenha finalizado, o job é automaticamente CANCELADO por TIMEOUT.
Eis alguns exemplos:
Job será processado na fila short por até 50 minutos
#SBATCH -t 50:00
Job será processado na fila short por até 23 horas
#SBATCH -t 23:00:00
Job será processado na fila medium por até 50 horas (2 dias e 2 horas)
#SBATCH -t 50:00:00
Job será processado na fila medium por até 5 dias e 10 horas
#SBATCH -t 5-10
Job será processado na fila long por até 12 dias
#SBATCH -t 12-00
Job será processado na fila long por até 30 dias
#SBATCH -t 30-00
Não serão alocados recursos pois solicitou mais do que 30 dias (45 dias, na verdade). A execução desse job nunca será inicializada pelo Slurm.
#SBATCH -t 45-00
Recomenda-se que processos nas filas medium e long tenham sistemas de checkpoint pois a possibilidade de falha aumenta proporcionalmente ao tempo necessário para a execução. Também recomenda-se que essas simulações sejam testadas antes com processos na fila short (veja seção Otimizando o Desempenho).
Nota
Talvez algum usuáro poderia se perguntar se não seria suficiente informar o tempo máximo permitido em cada fila, ou seja, 24 horas, 7 dias ou 30 dias, em vez de se preocupar com o tempo máximo que acredita que seja necessário.
Contudo, vale ressaltar que quantos mais recursos são solicitados, maior o tempo que o job do usuário poderá ficar esperando até que esses recursos sejam finalmente disponibilizados. E TEMPO também é um recurso.
Sendo assim, podemos concluir que há uma certa “beleza” em fazer uma otimização do tempo necessário a ser alocado para o job.
Informações sobre o Storage
O GridUnesp possui vários storages (partições) para “armazenar” os arquivos dos usuários, sejam eles de entrada, saída ou temporários (gerados durante o processamento do job). Durante o processamento, o programa em exeução poderá manipular arquivos localizados em diferentes pontos de montagem. É fundamental que o usuário entenda cada um deles.
Perigo
A palavra armazenar acima está entre aspas porque o usuário não deve pensar que pode usar o cluster do GridUnesp como lugar para guardar dados. A capacidade em disco das partições, apesar de significativamente grande, é limitada. Assim, apenas arquivos/pastas estritamente necessários à realização de novas simulação é que podem ser mantidos. Os resultados devem ser movidos para um computador local. Veja mais informações na Seção Manutenção dos Dados.
Abaixo está a lista dos pontos de montagen seguido do seu tamanho e escopo de acesso.
Ponto de Montagem |
Tamanho |
Escopo |
---|---|---|
/tmp/ |
120 GB |
Job usando apenas 1 nó e arquivos pequenos |
/store/ |
32 TB |
Job usando mais de 1 nó e/ou arquivos grandes |
/home/ |
40 TB |
Preparação dos jobs para submissão |
A partir daqui, vamos entender em detalhes o uso de cada partição.
Partição: /home/
Este é o único ponto de montagem acessível pelo servidor de acesso (access2.grid.unesp.br). O usuário deve colocar aqui seus arquivos de entrada, assim como é onde serão depositados os arquivos produzidos nas simulações.
Partição: /tmp/
Utilizado para salvar arquivos temporários durante a execução do job. Este diretório é o menor de todos (120 GB) e é um disco localizado dentro do nó de processamento (worker node). Ou seja, se 2 jobs estão sendo executos em nós diferentes, cada processo irá acessar um /tmp/
diferente. Não há compartilhamento entre os /tmp/
de diferentes nós. Nos casos em que o job utiliza apenas 1 nó e, além disso, os arquivos de input e output são relativamente poucos e pequenos (não mais do que unidades de GB), então a partição /tmp/
é a melhor opção.
O vídeo abaixo ilustra o que ocorre com o fluxo de dados ao usar a partição /tmp/.
Vamos supor então que que um usuário queira executar um aplicação científica (hipotética) chamada test-Covid que seja capaz de trabalhar com várias threads em um único nó. Além disso, após estudos de optimização, vamos supor que o usuário saiba que a simulação possa ter maior performance alocando 6 CPUs para cada processo (-c 6
) e que terá duração máxima de 5 dias (-t 5-00
). O script de submissão hipotético seria algo como:
#!/bin/bash
#SBATCH -t 5-00 -c 6
export INPUT="teste-pcr.in teste-sangue.in"
export OUTPUT="casos-positivos.out obitos.out"
module load anaconda3
source activate sarscov2
job-nanny test-Covid -in=teste-pcr.in,teste-sangue.in -out=casos-positivos.out,obitos.out
Analiando em detalhes o que ocorre com o fluxo de dados, sabemos ao menos que o script job-nanny
irá copiar os arquivos de input para a partição /tmp/
de um dos nós que foi alocado ao job, sendo lidos pelo programa test-Covid (instalado no /home/
do usuário via ambiente Conda) e cujo processamento será feito nesse worker node especifico. Os outpus serão temporariamente escritos na partição /tmp/
e copiados para o /home/
a cada 3 horas.
Já em caso de processos com múltiplos nós (ex: MPI), o usuário deve utilizar a partição /store/
.
Partição: /store/
Caso a partição /tmp/
não seja suficiente (devido ao seu tamanho limitado ou ao escopo do trabalho), então a alternativa é que os arquivos temporários utilizem a partição /store/
. Ela possui um escopo maior, sendo visível por todos os nós em que o job está em sendo executado. Seu espaço também é maior, contendo atualmente 32 TB. Assim, caso o script de submissão contenha instruções para uso de vários processos ou de vários nós, o programa em execução irá usar a partição /store/
.
O vídeo abaixo ilustra o que ocorre com o fluxo de dados ao usar a partição /store/.
Vamos supor então que que um usuário queira executar um aplicação científica (hipotética) chamada test-Covid que seja capaz de trabalhar com vários processos espalhados por vários nós. Digamos ainda que o usuário queira, para isso, usar 12 processos (-n 12
) espalhados em 3 nós (-N 3
). Além disso, após estudos de optimização, vamos supor que o usuário saiba que a simulação possa ter maior performance alocando 2 CPUs para cada processo (-c 2
) e que terá duração máxima de 3 dias (-t 3-00
). O script de submissão hipotético seria algo como:
#!/bin/bash
#SBATCH -t 3-00 -n 12 -N 3 -c 2
export INPUT="teste-pcr.in teste-sangue.in"
export OUTPUT="casos-positivos.out obitos.out"
export WAIT_CHECKPOINT="5400"
module load intel/compilers/2017
module load intel/mpi/2017
module load anaconda3
source activate sarscov2
job-nanny test-Covid -in=teste-pcr.in,teste-sangue.in -out=casos-positivos.out,obitos.out
Analiando em detalhes o que ocorrerá com o fluxo de dados, sabemos ao menos que o script job-nanny
irá copiar os arquivos de input para a partição /store/
, sendo lidos pelo programa test-Covid (instalado no /home/
do usuário via ambiente Conda) e cujo processamento será feito por 3 worker nodes. Os outpus serão temporariamente escritos na partição /store/
e copiados para o /home/
a cada 1 hora e meia (5400 segundos). Ademais, para os processos serem espalhados em vários nós a partir do conceito de Memória Distribuída, foram usadas as ferramentas MPI da Intel através dos módulos.
Por fim, é válido ainda informar que os 12 processos não serão espalhados igualmente para cada nó (4 processos por nó). Isto é, a maneira do Slurm distribuir os processos nos 3 worker nodes poderia ser 4,4,4, assim como: 2,6,4; 3,3,6; 1,7,4; 8,2,2; etc. E como foram solicitadas 2 CPUs para cada processo, o Slurm alocou um total de 24 CPUs para essa simulação (2 CPUs para cada um dos 12 processos).
Nota
Em algumas situações (como quando a fila de jobs está consideravelmente grande), pode ser mais interessante ao usuário não especificar uma quantidade exata de worker nodes, mas delimitar quantidades mínima e máxima, deixando a decisão para o escalonadador do sistema (Slurm). Como exemplo, digamos que o usuário deseje espalhar 18 processos entre 2 e 4 nós. Isso poderia ser feito da seguinte maneira:
#!/bin/bash
#SBATCH -n 18 -N 2-4
Quando apenas um único valor é especificado, o sistema identifica as quantidades mínima e máxima de nós como sendo as mesmas: -N 4
, por exemplo, é equivalente a -N 4-4
.