Você está na página 1de 19

Tutorial de Slurm

David da Silva Pires

2 de março de 2021
Capı́tulo 1

Introdução

Os recursos computacionais de um servidor dedicado à computação cientı́fica


geralmente são organizados por um programa chamado gerenciador de recur-
sos ou escalonador de serviços. Os usuários submetem serviços, os quais são
agendados para execução. Quando executados, o escalonador de serviços aloca
recursos computacionais, como quantidade e tempo de CPU e memória, para
uso exclusivo dos serviços em questão.
O gerenciador de recursos usado no servidor vital é o Slurm, que também é
usado pela maioria dos supercomputadores listados no Top500 [1].
Os usuários interagem com o SLURM através de cinco utilitários de linha
de comando: srun para submeter um serviço para execução e opcionalmente
controlá-lo interativamente, sbatch para submeter um serviço para execução
em modo lote, sem controle interativo, scancel para cancelar um serviço que
esteja pendente ou rodando, squeue para monitorar a fila de serviços e sinfo
para monitorar o estado das partições e de todo o sistema em geral.

1.1 Inı́cio rápido


Esta seção serve como uma rápida introdução à submissão e ao gerenciamento
de serviços usando o Slurm no servidor vital.
Para exemplificar o uso do servidor será usado o comando stress com a
opção --cpu 8, que faz uso intensivo de 8 núcleos dos processadores.

1.1.1 Execução de processos


Para executar um processo sem submissão ao Slurm basta usar a linha de co-
mando normalmente:

$> stress --cpu 8

Esse comando fará uso apenas dos oito últimos núcleos do servidor, numerados
de 217 a 224. É bastante instrutivo visualizar esse uso por meio do comando
htop. No caso de não conseguir visualizar todos os núcleos mesmo maximizando
a tela, use o atalho <Ctrl> + - para diminuir o tamanho da fonte.
Para fazer uso dos 216 núcleos restantes, é preciso submeter o processo como
um serviço ao Slurm.

1
1.1.2 Submissão de serviços
Para submeter um processo como um serviço ao Slurm, basta escrever um script
bash que contenha o comando como conteúdo:
$> cat > stress.slurm << EOI
#!/usr/bin/env bash

stress --cpu 8
EOI
A submissão é feita por meio do uso do comando sbatch:
$> sbatch -n8 --mem=100G stress.slurm
A opção -n8 indica que oito núcleos devem ser alocados para o serviço. A opção
--mem=100G indica que devem ser alocados 100 gigabytes para esse serviço.

1.1.3 Consulta da fila de execução


O comando squeue permite consultar a fila de execução e verificar quais pro-
cessos ainda estão na fila de espera, geralmente por exigirem mais recursos do
que os que estão disponı́veis:
$> squeue

1.1.4 Consulta de serviço submetido


Para consultar metadados sobre um processo submetido, esteja ele em execução
ou não, basta usar o comando scontrol com a opção show job e passar como
argumento o identificador do serviço, o qual é indicado na coluna JOBID do
comando squeue:
$> scontrol show job 1000

1.1.5 Cancelamento de serviço submetido


Para cancelar um serviço submetido, esteja ele sendo executado ou apenas na
fila de espera, basta usar o comando scancel e passar como argumento o iden-
tificador do serviço:
$> scancel <JOBID>

1.2 Obtenção de informações


O Slurm possui muitos comandos para interagir com o sistema. Por exemplo,
o comando sinfo fornece uma visão geral dos recursos oferecidos pelo cluster,
enquanto que o comando squeue mostra para quais serviços estes recursos estão
atualmente alocados.
Por padrão, o comando sinfo lista as partições que estão disponı́veis. Uma
partição é um conjunto de nós de computação (computadores dedicados ao
processamento de dados) agrupados logicamente. Exemplos tı́picos incluem
partições dedicadas a processamento em lote, depuração de programas, pós-
processamento ou visualização.
$> sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
batch* up infinite 1 idle vital

No exemplo acima vemos uma única partição, nomeada batch. Por ser única,
ela também é a partição padrão e por isso é marcada com um asterisco. A
partição batch é composta por um único nó, chamado vital, o qual está livre.
O comando sinfo também lista o tempo limite (coluna TIMELIMIT) aos
quais os serviços estão sujeitos. Em todo cluster, os serviços são limitados a
um valor máximo de tempo de execução, de modo a permitir rotação entre os
serviços e dar a cada usuário a chance de seus serviços serem iniciados. Geral-
mente, quanto maior o cluster, menor o tempo máximo permitido.
O comando sinfo pode fornecer informações em um modo orientado a nó:
basta usar a opção -N:

$> sinfo -N
NODELIST NODES PARTITION STATE
vital 1 batch* mix
Observe que com a opção -l mais informações sobre cada nó é fornecida:
número de CPUs, soquetes, núcleos por soquete, threads por núcleo, memória,
além do motivo, se for aplicável, de um nó estar caı́do.
$> sinfo -Nl
Mon Aug 17 17:32:15 2020
NODELIST NODES PARTITION STATE CPUS S:C:T MEMORY TMP_DISK WEIGHT AVAIL_FE REASON
vital 1 batch* mixed 224 4:28:2 103151 0 1 (null) none

Para visualizar a lista de serviços que estão atualmente rodando (no estado
RUNNING, indicado como “R”) ou que estão esperando por recursos (indicados
como “PD”, abreviação de PENDING), use o comando squeue:

[12:04:53] pires@vital:~ :( $ squeue


JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
596 batch python gestrela R 1-19:16:57 1 vital

A saı́da acima mostra que há um serviço rodando, cujo nome é “python” e
cujo identificador é 596. O identificador de serviço é único e é usado por vários
comandos do Slurm quando ações precisam ser tomadas para um serviço em
particular. Por exemplo, para cancelar o serviço “python”, você poderia execu-
tar

$> scancel 596

A coluna entitulada “TIME” exibe há quanto tempo o serviço está rodando.
“NODE” é o número de nós que foram alocados para o serviço, enquanto que a
coluna “NODELIST” lista os nomes dos nós que foram alocados. Para serviços
pendentes, esta coluna fornece a razão do porquê este serviço estar pendente.
A prioridade de serviços pendentes pode ser obtida através do comando sprio.
O comando sinfo, ao ser usado com algumas opções, pode ter sua saı́da
filtrada por usuário (“--user”), por partição (“--partition”) e por estado
(“--state”).
Para visualizar a fila para um usuário especı́fico (${USER} neste caso), use
a opção -u:
[12:10:19] pires@vital:~ :) $ squeue -u $USER
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)

Para visualizar informações detalhadas sobre um serviço especı́fico, use seu


identificador (<jobid>) com o comando scontrol show job:

[12:13:04] pires@vital:~ :( $ scontrol show job 596


JobId=596 JobName=python
UserId=gestrela(10005) GroupId=gestrela(10005) MCS_label=N/A
Priority=1001 Nice=0 Account=(null) QOS=(null)
JobState=RUNNING Reason=None Dependency=(null)
Requeue=1 Restarts=0 BatchFlag=0 Reboot=0 ExitCode=0:0
RunTime=1-19:23:23 TimeLimit=UNLIMITED TimeMin=N/A
SubmitTime=2019-11-19T16:51:05 EligibleTime=2019-11-19T16:51:05
StartTime=2019-11-19T16:51:05 EndTime=Unknown Deadline=N/A
PreemptTime=None SuspendTime=None SecsPreSuspend=0
LastSchedEval=2019-11-19T16:51:05
Partition=batch AllocNode:Sid=vital:66496
ReqNodeList=(null) ExcNodeList=(null)
NodeList=vital
BatchHost=vital
NumNodes=1 NumCPUs=220 NumTasks=1 CPUs/Task=220 ReqB:S:C:T=0:0:*:*
TRES=cpu=220,mem=10G,node=1,billing=220
Socks/Node=* NtasksPerN:B:S:C=0:0:*:* CoreSpec=*
MinCPUsNode=220 MinMemoryNode=10G MinTmpDiskNode=0
Features=(null) DelayBoot=00:00:00
Gres=(null) Reservation=(null)
OverSubscribe=OK Contiguous=0 Licenses=(null) Network=(null)
Command=python
WorkDir=/mnt/project1/msreis/modelSelection/users/gestrela/my_masters_scripts/walk
Power=

Lista de serviços pendentes na mesma ordem que é considerada pelo Slurm


para agendamento:

[12:17:45] pires@vital:~ :) $ squeue --priority --sort=-p,i --states=PD


JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)

É possı́vel alterar os campos exibidos por padrão pelo comando squeue por
meio da variável SQUEUE_FORMAT:

[09:20:56] localadmin@vital:~ :( $ squeue


JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
[10:15:08] localadmin@vital:~ :) $ export SQUEUE_FORMAT="%.18i %.9P %.8j %.8u %.10T %
[10:15:13] localadmin@vital:~ :) $ squeue
JOBID PARTITION NAME USER STATE PRIORITY TIME TIME_L

Para alterar o formato em que o tempo é exibido, altere o valor da variável


SLURM_TIME_FORMAT:

[10:15:13] localadmin@vital:~ :) $ squeue


JOBID PARTITION NAME USER STATE PRIORITY TIME TIME_L
[10:15:15] localadmin@vital:~ :) $ export SLURM_TIME_FORMAT="%a %T"
[10:19:24] localadmin@vital:~ :) $ squeue
JOBID PARTITION NAME USER STATE PRIORITY TIME TIME_LIMI NODES

Status of all jobs of user: squeue -u user


Status of all jobs: squeue
Capı́tulo 2

Criando serviços

Um serviço consiste em duas partes:


Requisição de recursos: corresponde ao número de CPUs, duração estimada
da computação, quantidade de memória RAM ou espaço em disco, etc.
Passos do serviço: descrevem tarefas que precisam ser executadas, programas
que precisam ser rodados.
A forma tı́pica de criação de um serviço é por meio da escrita de um script de
submissão. Um script de submissão é um script de shell (e. g., um script Bash)
cujos comentários, quando precedidos da palavra “SBATCH”, são entendidos pelo
Slurm como parâmetros descrevendo as solicitações de recursos e outras opções
de submissão.
As chamadas diretivas SBATCH precisam aparecer no topo do arquivo de sub-
missão, antes de qualquer outra linha, exceto a primeira linha que opcionalmente
pode conter o denominado shebang (e. g., #!/bin/bash).
O script consiste nos passos do serviço. Outros passos podem ser criados
com o comando srun.
Por exemplo, o script seguinte, ao qual podemos chamar de submit.sh,
#!/bin/bash
#
#SBATCH --job-name=test
#SBATCH --outpu=res.txt
#
#SBATCH --ntasks=1
#SBATCH --time=10:00
#SBATCH --mem-per-cpu=100

srun hostname
srun sleep 60
solicita o uso de uma CPU por 10 minutos em conjunto com 100 MB de memória
RAM na fila padrão. Quando iniciado, o serviço rodará como primeiro passo
o comando srun hostname, o qual executará o comando hostname no nó em
que a CPU requisitada foi alocada. Na sequência, um segundo passo do serviço
executará o comando sleep. Note que o parâmetro --job-name nos permite

7
fornecer um nome significativo ao serviço e o parâmetro --output define o
arquivo para o qual a saı́da do serviço deve ser enviada.
Capı́tulo 3

Submissão de serviços

Uma vez que o script de submissão é corretamente criado, é necessário sub-


metê-lo ao slurm por meio do comando sbatch, o qual, quando corretamente
executado, exibe o identificador atribuı́do ao serviço.

sbatch submit.sh
sbatch: Submitted batch job 570

O serviço entra então na fila no estado PENDING. Tão logo os recursos se tor-
nam disponı́veis e o serviço possui a mais alta prioridade, uma alocação é criada
para ele e seu estado passa a ser RUNNING. Se o serviço termina corretamente,
seu estado é alterado para COMPLETED; caso contrário, para FAILED.
Após o término do serviço, o arquivo de saı́da indicado no script do serviço
contém o resultado dos comandos executados. No exemplo dado no capı́tulo
anterior, o arquivo chama-se res.txt, o qual pode ser visualizado com os co-
mandos a seguir:
$> cat res.txt
$> less res.txt
Você pode obter informações sobre os seus serviços que estão rodando com
o comando sstat, passando o identificador do serviço como argumento para o
parâmetro -j.

$> sstat -j 570


O exemplo dado ilustra um serviço serial que roda em uma única CPU em
um único nó. Ele não tira vantagem de nós multi-processados ou dos vários nós
de computação que podem estar disponı́veis em um cluster. O capı́tulo seguinte
explica como criar serviços paralelos.

9
Capı́tulo 4

Cancelamento de serviços

Delete a job: scancel jobID


Delete all jobs of user: scancel -u user

11
Capı́tulo 5

Execução paralela de
serviços

Um serviço paralelo é aquele cujas tarefas são executadas simultaneamente. Há


muitas formas de um serviço paralelo ser criado:
• rodando um programa multi-processo, que segue o paradigma SPMD (do
inglês Single Program, Multiple Data);

• rodando um programa multi-tarefa, que segue o paradigma de memória


compartilhada;
• rodando várias instâncias de um programa composto por apenas uma
tarefa, que segue o paradigma chamado embarassingly parallel, também
conhecido como job array ou vetor de serviços;

• rodando um programa mestre que controla vários programas escravos, que


segue o paradigma mestre/escravo.
Para o Slurm, uma tarefa é entendida como um processo. Assim, um pro-
grama multi-processo é composto por várias tarefas. Por outro lado, um pro-
grama multi-tarefa é composto por apenas uma tarefa, a qual usa diversas CPUs.
Tarefas são requisitadas/criadas com a opção --ntasks, ao passo que CPUs,
para programas multi-tarefas, são requisitadas com a opção --cpus-per-task.

13
Capı́tulo 6

Referências

• Slurm documentation: https://slurm.schedmd.com


• C.E.C.I “Slurm Quick Start Tutorial”: https://bit.ly/2GETVCZ
• OzSTAR Documentation: supercomputing.swin.edu.au/docs

• Wikipedia: https://en.wikipedia.org/wiki/Embarassingly parallel

15
Referências Bibliográficas

[1] Top500. url = https://www.top500.org. Accessed: 2020-08-27.

17

Você também pode gostar