IT-Bereich

Benutzung der Cluster

Für rechen- und speicherintensive Aufgaben stehen im Forschungsrechnerbereich  Cluster aus 64bit-Intel- und AMD-Rechnern zur Verfügung. Die einzelnen Rechner der Cluster sind weitestgehend kompatibel mit den Arbeitsplatzrechnern des Instituts und erlauben damit die einfache Auslagerung rechenintensiver Arbeiten vom Arbeitsplatzrechner auf die Cluster. Anderseits können durch spezifische Kompilierung von Programmen für diese Rechnerarchitektur eigene Programme deutlich beschleunigt werden, insbesondere wenn sogar die Möglichkeit der Parallelverarbeitung genutzt wird.

Weitere Möglichkeiten zur Bearbeitung rechen- und speicherintensiver Aufgaben stehen Ihnen im erweiterten Compute-Serverbereich des Institutes zur Verfügung, der dem Forschungsrechnerbereich angegliedert ist. Für diesen Bereich muss man sich gesondert anmelden. Bitte informieren Sie sie sich über die Möglichkeiten und Bedingungen auf den Dokumentationsseiten zum Computeserver-Bereich.

Im folgenden finden Sie detailierte Angaben zur Nutzung der Cluster im Forschungsrechnerbereich:

Das Batch-System wurde kürzlich auf Slurm umgestellt. Hinweise zur Übersetzung von Gridengine- in Slurm-Kommandi in folgendem PDF:

Das Batch-System wurde kürzlich auf Slurm umgestellt. Hinweise zur Übersetzung von Gridengine- in Slurm-Kommandi in folgendem PDF:

Technische Daten

Cluster 13

MerkmalWert
Anzahl Nodes (vom Forschungsnetz aus zugänglich)5
Prozessoren (je Node)2 x Intel Xeon X5650 Hexa-Core
Memory (je Node)48 GB
Netzwerk (intern)QDR Infiniband + Gigabit Ethernet
Bandbreite~3400 MB/s (MPI)
Netzwerk (nach außen)Gigabit Ethernet
  
Technische Daten

Cluster 16

MerkmalWert
Anzahl Nodes (vom Forschungsnetz aus zugänglich)4
Prozessoren (je Node)2 x Intel Xeon X2630v2 Hexa-Core
Memory (je Node)64 GB
Netzwerk (intern)QDR Infiniband + Gigabit Ethernet
Bandbreite~3700 MB/s (MPI)
Netzwerk (nach außen)Gigabit Ethernet
  
Technische Daten

Cluster 18

MerkmalWert
Anzahl Nodes (vom Forschungsnetz aus zugänglich)2
Prozessoren (je Node)2 x Intel Xeon E5-2630v4 10-Core
Memory (je Node)512 GB
Netzwerk (intern)QDR Infiniband + Gigabit Ethernet
Bandbreite~3900 MB/s (MPI)
Netzwerk (nach außen)Gigabit Ethernet
  
Technische Daten

Cluster 22

MerkmalWert
Anzahl Nodes (vom Forschungsnetz aus zugänglich)4
Prozessoren (je Node)2 x Intel Xeon Silver 4216 16-Core
Memory (je Node)192 GB
Netzwerk (intern)FDR Infiniband + Gigabit Ethernet
Bandbreite~6800 MB/s (MPI)
Netzwerk (nach außen)Gigabit Ethernet
  
Technische Daten

Cluster 23

MerkmalWert
Anzahl Nodes (vom Forschungsnetz aus zugänglich)1
Prozessoren (je Node)1 x AMD EPYC2 7302P 16-Core
Memory (je Node)128 GB
Netzwerk (intern)FDR Infiniband + Gigabit Ethernet
Bandbreite~6800 MB/s (MPI)
Netzwerk (nach außen)Gigabit Ethernet
GPUs3 x Nvidia RTX2080ti
Technische Daten

Cluster 26

MerkmalWert
Anzahl Nodes (vom Forschungsnetz aus zugänglich)8
Prozessoren (je Node)2 x AMD EPYC2 7302 16-Core
Memory (je Node)1 TB
Netzwerk (intern)FDR Infiniband + Gigabit Ethernet
Bandbreite~6800 MB/s (MPI)
Netzwerk (nach außen)Gigabit Ethernet
  
Technische Daten

Auslagerung von Programmen

Für die einfachste Nutzung des Clusters, insbesondere für interaktive Programme (d.h. mit User-Input), benutzt man am besten das srun-Kommando. Beispiele:

% srun  matlab -nosplash -nodisplay < inp
für nicht-interaktive Nutzung,oder einfach:

Zu beachten: srun benötigt die --pty Option für Programme, die I/O auf den Terminal machen, Shells z.B. :
% srun --pty bash

% srun --x11 --pty matlab
für Applikationen mit Graphik

(In den obigen und den folgenden Beispielen ist % jeweils der Kommando-Prompt
der Shell)

Das srun-Kommando startet die Programme im selben Directory, in dem srun aufgerufen wurde, vorausgesetzt, das Verzeichnis ist von den Cluster-Nodes aus erreichbar. Ansonsten startet srun im $HOME-Verzeichnis.
Srun startet auch nur, wenn genügend Platz auf dem Cluster frei ist. Ggf. werden dafür Nodes eingeschaltet und gebootet. Falls dies nicht funktioniert, beendet srun mit einer entsprechenden Fehlermeldung. In solchen Fällen empfiehlt es sich, die Programme im Batch-Mode in die Queue zu stellen. Das Programm bleibt dann in einer Warteschlange und startet, wenn entsprechende Ressourcen auf dem Cluster frei werden. Für interaktive Programme wie im zweiten Beispiel oben ist dies nicht unbedingt sinnvoll, für das erste Beispiel jedoch durchaus. Wie man das macht, illustrieren die folgenden Beispiele:

Schreiben eines kleinen Job-Scripts und Abschicken desselben mit sbatch:

% cat > matlab.job <<EOF
#!/bin/bash --login
#SBATCH --job-name=matlab
#SBATCH --output=matlab.out
#SBATCH --mem=10G


matlab -nosplash -nodisplay < inp
EOF

% sbatch matlab.job

Statt 'cat' kann natürlich auch ein beliebiger Texteditor zur Erstellung des Job-Files benutzt werden.
Ein sbatch-Job läuft komplett unabhängig von der aktuellen Terminal-Session. Bei Nutzung von srun muss das Fenster offen bleiben.

Format eines Job-Scripts

Noch einmal das obige Beispiel mit Zeilennummern und ein paar mehr Parameter-Zeilen:

1#!/bin/bash --login
2#SBATCH --job-name=matlab
3#SBATCH --output=matlab.out
4#SBATCH --mem=10G
5#SBATCH --time=24:00:00
6#SBATCH --mail-user=myself@math.tu-berlin.de
7#SBATCH --mail-type=BEGIN,END
8 
9matlab -nosplash -nodisplay < inp

Erläuterung:

2) Jobname
3) Output-File
4) Memory-Bedarf
5) Angabe der maximalen Laufzeit (Format HH:MM:SS).
6) Mail-Adresse (bitte angeben, Default: <USERNAME>@math.tu-berlin.de)
7) Wann eine Mail geschickt werden soll

Die Angabe der maximalen Laufzeit wird dringend empfohlen. Der Cluster-Scheduler wird zum Einen kurze Jobs bevorzugen und zum Anderen besteht ohne weitere Angaben ein Laufzeitlimit von 12 Stunden. Des weiteren besteht eine Default-Obergrenze für die Memory-Allocation von 4GB damit die anderen CPUs und der Rest des Speichers noch für andere Jobs verwendet werden können. Die Angabe auf Zeile 5 kann entsprechend dem Bedarf angepasst werden.
Sämtliche Job-Parameter, die in einem Script benutzt werden können, dürfen auch auf der Kommandozeile von sbatch benutzt werden und haben dann höhere Priorität:

% sbatch ---job-name=test --time=36:00:00 jobscript
% srun --job-name=test2 -n 2  matlab -nosplash -nodisplay < inp

Jobs mit grossem Memory-Bedarf, Multi-Threaded Programme

Programme, die das ganze Memory von 48GB (rsp. 64GB oder 192GB etc.) nutzen wollen oder mit mehreren Threads oder Prozessen arbeiten, sollten jeweils mit geeigneten Optionen die nötige Menge Cores, Nodes und Memory reservieren, oder einen Cluster-Node mit 12 bis 32 Prozessoren komplett reservieren. Dies erreicht man mit Optionen wie:

#SBATCH --cpus-per-task=12

#SBATCH --nodes=2 --cpus-per-task=12

im Job-Script. Im ersten Falle läuft der Job auf einem 12-Core-Knoten mit 12 Prozessoren, im zweiten mit insgesamt 24 Cores verteils auf 2 Nodes.

#SBATCH --exclusive
#SBATCH --constraint=num_proc:32

Obiges Beispiel fordert einen Cluster-Node exklusiv an (d.h. keine anderen Jobs darauf) und verlangt ein über eine Randbedingung ein "Feature" namens "num_proc" an, welches die Anzahl der im Node verbauten CPUs angibt.
Features sind relativ willkürlich vergebene Attribute für Cluster-Nodes, die in 'Constraints' benutzt werden können.
Features werden allgemein mit --constraint="feature1&feature2" oder --constraint="feature1|feature2" gefordert. Die erste Form fordert beide, die 2te fordert, wie zu erwarten mindestens eines der Features. Komplexere Ausdrücke sind möglich, siehe "man sbatch" für Details.
Eine Liste der definierten Features findet man z.B. mit dem Kommando:

 sinfo -o "%15N %10c %10m %10G %f"

Das Batch-System legt für alle Jobs eine Limite für den nutzbaren Haupspeicher fest. Per Default ist diese (lokal) auf 4GB festegelegt (pro reservierter CPU).
Für Jobs mit grösserem Memory-Bedarf sollte die Option
   --mem=<size>
oder
   --mem-per-cpu=<size>
angegeben werden (<size> in MB).

 

Überprüfen der Queues und der Clusternutzung

Das Kommando squeue zeigt die laufenden und wartenden Jobs an:

% squeue
             JOBID PARTITION     NAME     USER      ST       TIME  NODES NODELIST(REASON)
              2409    ompi17       mpitasks     npasched CF       0:17     2         node[546-547]
              2408       smp            s445          habicht     R          2:34     1         node545
 

Ändern und Löschen von Jobs

Einige der Job-Parameter können auch nach dem Abschicken des Jobs noch geändert werden, teilweise sogar noch wenn der Job schon läuft. Hierzu dient das Kommando scontrol. Das Kommando kann (wie squeue) auch Details eines Jobs anzeigen und diese auch ändern.
Jobs, die falsch aufgesetzt, abgeschickt oder sonstwie beseitigt werden sollen, werden mit dem Kommando scancel unter Angabe der Job-ID entfernt.
Beispiel:

% squeue -u npasched
 JOBID PARTITION     NAME     USER        ST       TIME  NODES  NODELIST(REASON)
  2520       smp               sjob         npasched    R       1:52                1  node545

% scontrol show job 2520 | grep JobName
JobId=2520 JobName=sjob
% scontrol update job 2520 JobName=test
% squeue  -u  npasched
 JOBID PARTITION     NAME     USER        ST       TIME  NODES  NODELIST(REASON)
  2520       smp               test         npasched    R       1:55                1  node545
% scancel  2520

 

Array Jobs

Es kommt ab und zu vor, dass ein Job-Script mit einer grossen Anzahl Datensätzen laufen soll und dies im Prinzip auch parallel tun könnte. Die offensichtliche Methode, nämlich einfach n nur leicht differierende Job-Scripts zu schreiben und abzuschicken, ist sicherlich ab n > 3 eher lästig.
Eine elegantere Lösung sind sog. Job-Arrays, wo ein einziges Job-Script abgeschickt wird, versehen mit der Weisung in n Kopien zu starten.
Ein entsprechendes sbatch Kommando sieht so aus:

% sbatch --array 10-30:2 jobscript

Das obige Kommando schickt das Script jobscript ins Batch-System und erzeugt dort 11 Kopien, die jeweils eine sog. TASK_ID zugewiesen bekommen im Bereich [10..30] mit Abstand 2, also 10 12 14 16 ....
Im Job-Script steht die Task-ID an zwei Stellen zur Verfügung:

1. Im Script-Header:
Hier können z.B. die Namen der Output-Files um die Task-ID (%a) ergänzt werden, so dass jede Kopie in ein eigenes File schreibt:

#SBATCH --output=job.%a.out

2. Im Script selbst:

Hier steht die Task-Id in der Environment-Variable $SLURM_ARRAY_TASK_ID und kann im Script selbst oder in von dort gestarteten Prozessen gelesen und genutzt werden.

#!/bin/bash --login 
#SBATCH --array=10-30:2 
#SBATCH -J matlab_run 
#SBATCH -o matlab_run.%a.out 
#SBATCH --mail-type=end 
#SBATCH --mail-user=myself@math.tu-berlin.de 
  
matlab -nosplash -nodisplay < input.$SLURM_ARRAY_TASK_ID.m 

Hier noch ein Beispiel für einen Matlab-Input, der die Task-ID direkt liest:

task_id = str2num( getenv('SLURM_ARRAY_TASK_ID') )

x = floor( task_id / 160 )
y = task_id - x * 160

.....

Weiter nutzbare Environment-Variablen:

    $SLURM_ARRAY_TASK_MIN : Die erste Task-ID
    $SLURM_ARRAY_TASK_MAX : Die letzte Task-ID
    $SLURM_ARRAY_TASK_STEP : Der angegebene Step-Size.

GPU-Jobs

Um GPUs benutzen zu können, müssen Jobs eine oder mehrere GPUs reservieren. Dem Job stehen diese GPUs dann exklusiv zur Verfügung.

Im Jobscript muss die Anzahl und die Fähigkeiten der GPUs durch Anforderung sogenannter 'generic resources' spezifiziert werden. Die Anzahl wird mit der Resource gpu ausgewählt, für die Fähigkeiten gibt es die Resourcen cuda_compute_capabilty (kurz: ccc), und gpu_mem.
Der GPU-Typ kann zusammen mit der Anzahl GPUs angegeben werden und fordert GPUs eines bestimmten Typs an. Derzeit mögliche Werte:

rtx2080ti     :     NVidia GeForce RTX 2080ti

Allgemeine Form von 'gres'-Ausdrücken:

    --gres=<resource>[:<typ>]:<menge>

Beispiele:
     --gres=gpu:1
     --gres=gpu:rtx2080ti:2
     --gres=gpu:1,gpu_mem:4000M,ccc:70

Die cuda_compute_capability ist ein numerischer Wert in Form einer Versionnummer, z.B. 3.1 oder 7.5. Sie wird von NVIDIA festgelegt und beschreibt die von der GPU untertützten CUDA-Features. Das Batchsystem interpretiert die Resource als Mindestanforderung, d.h. es wird eine GPU mit mindestens diesen Fähigkeiten zur Verfügung gestellt, allerdings unterstützt SLURM hier lediglich Integer-Werte, d.h. der gewünschte Wert ist mit 10 zu multiplizieren.

gpu_mem fordert eine GPU mit mindestens der angegebenen Menge an benutzbarem RAM an. Das kann relevant sein, wenn es mehrere GPU-Typen mit dem gleichen Chipsatz, aber verschieden viel RAM gibt, z.B. RTX6000 und RTX2080Ti.

Das folgende Jobscript fordert 1 GPU mit mindestens CUDA Compute Capability 7.5 und 10GB RAM an, lädt ein CUDA-Modul und schreibt dann den Output des deviceQuery-Tools in die Ausgabedatei

#!/bin/bash --login 
#SBATCH --job-name=gpu_example 
#SBATCH --output=gpu_example.out 
#SBATCH --time=2000 
#SBATCH --gres=gpu:1,gpu_mem:10G,ccc:75 
#SBATCH --mail-type=end 
#SBATCH --mail-user=meine.mail@adresse 
module load cuda/11.1 
deviceQuery 

Zu beachten ist hier, dass alle 'gres'-Anforderungen zusammengefasst werden müssen, bei mehreren '--gres'-Ausdrücken wird
nur der letzte beachtet.

Parallele Programme mit MPI

Für paralle Programme mit MPI sollte man ein Job-Script ähnlich dem folgenden benutzen

#!/bin/bash --loginDie ausführende Shell. Bei 'bash' bitte immer '--login' verwenden.
#SBATCH -J my_jobDer Job-Name
#SBATCH -o %x.%j.%N.outDas Output-File, verschiedene Platzhalter sind erlaubt und werden ersetzt durch den Job-Namen (%x), den Node-Namen (%N) oder die Job-Id (%j).
#SBATCH --partition=*Die 'Partition' in der der Job laufen soll. Wenn unsicher, kann man den Wildcard '*' benutzen.
#SBATCH --nodes=4Anzahl der benötigten Clusterknoten.
#SBATCH --ntasks-per-node=8Pro Clusterknoten werden 8 MPI-Tasks gestartet
#SBATCH --mail-type=begin,endDas Batch-System sendet eine Mail bei Start und Ende des Jobs ...
#SBATCH --mail-user=my@email.address.. an diese Mail-Adresse
#SBATCH --time=08:00:00Maximale Laufzeit
#SBATCH --memory=4GMemory-Bedarf pro Clusterknoten (!)
module rm ompiEnt-lädt das Default-MPI-Modul
module add ompi/gcc/4.1.1Lädt benötigte MPI-Module
mpirun -np $NSLOTS myprogStartet das MPI-Programm

Slurm erlaubt sehr detaillierte Angaben, wie und wo die Prozesse auf Clusternodes verteilt werden. Hier ein paar Beispiele:

--nodes=44 Clusterknoten, 1 Task mit je 1 CPU-Core pro Knoten
--nodes=4 --ntasks-per-node=24 Clusterknoten, 2 Tasks mit je 1 CPU-Core pro Knoten
--nodes=4 --cpus-per-task=24 Clusterknoten, 1 Task mit je 2 CPU-Cores pro Node
--nodes=4 --ntasks-per-node=2 --cpus-per-task=34 Clusterknoten, 2 Tasks mit je 3 CPU-Cores pro Knoten
--ntasks=2020 Tasks in beliebiger Verteilung

Zu bemerken ist, dass für Jobs mit mehr als 1 Node immer eine Partition angegeben werden muss (ggf. als '*'), die Default-Partition erlaubt lediglich paralelle Jobs auf einem Node.