Cos'è un job?
Le basi per lanciare le proprie computazioni
Nei sistemi HPC, l'esecuzione dei programmi non avviene in modo interattivo o immediato. I job (lavori di calcolo) vengono gestiti da un sistema batch (o gestore di code), un software centralizzato che organizza le richieste degli utenti in base alle risorse hardware disponibili e alle politiche del centro di calcolo.
Flusso di lavoro tipico
-
Accesso: L'utente si connette a un nodo di login. Questo nodo serve esclusivamente per l'accesso, la gestione dei file e la preparazione dei job; è vietato utilizzarlo per eseguire calcoli pesanti.
-
Configurazione: Si predispone uno script di job, ovvero un file di testo contenente le direttive per il sistema batch (risorse richieste) e i comandi shell per l'esecuzione del programma.
-
Accodamento: Il sistema batch inserisce il job in una coda divisa generalmente in tre stati: in esecuzione (running), in attesa (idle), o bloccato (blocked).
-
Uscita: Al termine dell'esecuzione, il sistema rilascia i nodi e salva i risultati in file di output e di errore nella directory dell'utente.
Tipologie di Calcolo e Parallelizzazione
Per sfruttare l'architettura di un cluster, un problema computazionale deve essere parallelizzabile, ossia scomponibile in operazioni indipendenti.
1. Job Seriali Multipli (High-Throughput Computing)
Consiste nell'eseguire lo stesso programma seriale (che usa un solo core) centinaia di volte simultaneamente su dati di input differenti (es. uno screening parametrico).
-
Vantaggi: Non richiede modifiche al codice del programma.
-
Funzionamento: Uno script automatico inserisce le diverse varianti del job nella coda. Il sistema batch le esegue in parallelo man mano che si liberano i singoli core del cluster, riducendo linearmente il tempo totale di elaborazione complessivo.
2. Parallelismo MPI (Message Passing Interface)
Per distribuire un unico job su più nodi computazionali, si utilizza il protocollo MPI. Si tratta di uno standard di comunicazione che permette a processi in esecuzione su macchine fisiche distinte di scambiarsi dati attraverso la rete interna del cluster.
-
Modello Master/Slave: Un processo principale (master) coordina il lavoro, suddivide i dati e li distribuisce ai processi di calcolo (slave), per poi raccogliere e combinare i risultati finali.
-
Applicazioni tipiche: Algoritmi di ordinamento di grandi moli di dati, rendering grafico distribuito, simulazioni fluidodinamiche o modelli climatici e moltiplicazioni di matrici complesse.
Memoria Condivisa vs. Memoria Distribuita
-
Memoria Condivisa (OpenMP): I thread del programma accedono alla stessa RAM. È un approccio limitato ai confini del singolo nodo hardware. I moderni chip multi-core rendono comunque efficiente l'uso combinato di OpenMP all'interno del nodo e MPI tra i nodi.
-
Memoria Distribuita (MPI): Ogni processo ha la propria memoria riservata. Le informazioni vengono scambiate esplicitamente tramite la rete del cluster. È l'approccio ideale per scalare su un numero elevato di nodi hardware standard.
Accelerazione Hardware: CPU vs. GPU
I cluster moderni integrano nei propri nodi sia processori tradizionali (CPU) sia acceleratori grafici (GPU) per ottimizzare diverse tipologie di carico di lavoro.
| CPU (Central Processing Unit) | GPU (Graphics Processing Unit) | |
| Ottimizzazione | Ottimizzata per la latenza. | Ottimizzata per il throughput (portata dei dati). |
| Architettura | Pochi core potenti progettati per l'esecuzione sequenziale di compiti complessi. | Migliaia di core semplici progettati per l'esecuzione simultanea di calcoli matematici uniformi. |
| Ambiti d'uso | Logica di controllo, calcolo seriale, operazioni di sistema. | Machine Learning, modellazione scientifica molecolare, algebra lineare. |
Requisiti per l'uso delle GPU
I programmi devono essere scritti specificamente per interfacciarsi con l'hardware delle GPU utilizzando framework dedicati come CUDA, OpenCL, OpenACC o HIP. In alternativa, è possibile utilizzare software scientifico o librerie di programmazione (es. pacchetti Python avanzati) in cui il supporto GPU è già integrato nativamente.
Gestione dei Job con SLURM
SLURM (Simple Linux Utility for Resource Management) è il gestore di risorse open source utilizzato sul cluster Copernico e in molte delle principali infrastrutture HPC globali. I suoi compiti principali sono l'allocazione esclusiva o condivisa dei nodi, l'avvio del lavoro parallelo e la gestione della coda di attesa.
Struttura di uno script SLURM
Le direttive destinate al gestore delle code devono essere inserite all'inizio dello script e precedute dal prefisso #SBATCH. I commenti testuali normali usano il carattere #.
Esempio di script di invio (submit_file.sh)
#!/bin/bash
# Nome identificativo del job nelle code
#SBATCH -J Job_Parallelo
# Numero di task (in configurazione standard corrisponde al numero di core richiesti)
#SBATCH -n 1
# Tempo massimo stimato di esecuzione (Ore:Minuti:Secondi)
#SBATCH --time=00:30:00
# Caricamento dell'ambiente software richiesto (specifico del cluster)
ml foss/2021b
# Esecuzione dell'eseguibile (usare srun prima del comando se il programma è parallelo)
./my_program
Comandi Principali di Gestione
-
Invio del job:
sbatch submit_file.sh -
Verifica dello stato delle code:
-
Mostra tutti i job del sistema:
squeue -
Mostra solo i propri job:
squeue -u USERNAME -
Mostra i dettagli di un singolo job:
squeue -j JOBID
-
-
Analisi approfondita e stima dell'avvio:
scontrol show job JOBID -
Annullamento o interruzione di un job in corso/attesa:
scancel JOBID