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:
Merkmal | Wert |
---|---|
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 |
Merkmal | Wert |
---|---|
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 |
Merkmal | Wert |
---|---|
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 |
Merkmal | Wert |
---|---|
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 |
Merkmal | Wert |
---|---|
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 |
GPUs | 3 x Nvidia RTX2080ti |
Merkmal | Wert |
---|---|
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 |
Für die einfachste Nutzung des Clusters, insbesondere für interaktive Programme (d.h. mit User-Input), benutzt man am besten das Cluster-Kommando. Beispiele:
% Cluster -V matlab -nosplash -nodisplay < inp
oder einfach:
% Cluster -V matlab
(In den obigen und den folgenden Beispielen ist % jeweils der Kommando-Prompt
der Shell)
Anmerkung: In früheren Versionen dieser Anleitung wurde das Cluster-Kommando mit kleinem 'c' geschrieben. Wegen eines Namens-Konflikts in neueren Linux-Versionen sollte ab jetzt die großgeschriebene Variante benutzt werden.
Das Cluster-Kommando startet die Programme im selben Directory, in dem Cluster aufgerufen wurde, vorausgesetzt, dass genügend Platz auf dem Cluster frei ist. Falls dies nicht der Fall ist, beendet Cluster 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:
1. Mit der -now no Option zu Cluster:
% Cluster -now no matlab -nosplash -nodisplay < inp
2. Durch Schreiben eines kleinen Job-Scripts und Abschicken desselben mit qsub:
% cat > matlab.job <<EOF
#!/bin/bash --login
#$ -cwd
#$ -N matlab
#$ -o matlab.out
#$ -j y
matlab -nosplash -nodisplay < inp
EOF
% qsub matlab.job
Statt 'cat' kann natürlich auch ein beliebiger Texteditor zur Erstellung des Job-Files benutzt werden.
Der Unterschied zwischen beiden Methoden ist, dass im zweiten Fall der Job komplett unabhängig von der aktuellen Terminal-Session abgearbeitet wird. Im ersten Fall muss das Fenster offen bleiben.
Noch einmal das obige Beispiel mit Zeilennummern und ein paar mehr Parameter-Zeilen:
1 | #!/bin/bash --login |
2 | #$ -cwd |
3 | #$ -N matlab |
4 | #$ -o matlab.out |
5 | #$ -j y |
6 | #$ -l h_rt=86400 |
7 | #$ -m be |
8 | #$ -M myself@math.tu-berlin.de |
9 | |
10 | matlab -nosplash -nodisplay < inp |
Erläuterung:
2) Wechselt ins Verzeichnis, aus dem der Job abgeschickt wurde.
3) Jobname
4) Output-File
5) 'Join'=yes, d.h. Errors zusammen mit Output ins Output-File
6) Angabe der maximalen Laufzeit (in Sekunden).
7) Mail bei Beginn und Ende des Jobs schicken
8) Mail-Adresse (bitte angeben !!)
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 Obergrenze für die Memory-Allocation von 2GB damit der zweite Prozessor und die andere Hälfte des Speichers noch für andere Jobs verwendet werden können. Siehe unten für Möglichkeiten, mehr Memory zu nutzen.
Sämtliche Job-Parameter, die in einem Script benutzt werden können, dürfen auch auf der Kommandozeile von qsub benutzt werden und haben dann höhere Priorität:
% qsub -N test -l h_rt=80000 jobscript
% Cluster -N test2 -pe mp 2 matlab -nosplash -nodisplay < inp
Programme, die das ganze Memory von 48GB (rsp. 64GB oder 192GB etc.) nutzen wollen oder mit mehreren Threads oder Prozessen arbeiten, sollten jeweils eine Cluster-Node mit 12 oder 32 Prozessoren komplett reservieren. Dies erreicht man mit der zusätzlichen Zeile
#$ -pe mp 12 -l num_proc=12
oder
#$ -pe mp 32 -l num_proc=32
im Job-Script. Im ersten Falle läuft der Job auf einem 12-Core-Knoten mit 12 Prozessoren, im zweiten mit 32 Cores auf einem 32-Core-Rechner.
Das Kommando qstat zeigt die laufenden und wartenden Jobs an:
% qstat
job-ID prior name user state submit/start at queue slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
4636 0.50500 matlab zeppo r 08/31/2006 22:19:48 all.q@node02 2
4531 0.50500 comsol pippo r 08/25/2006 18:05:38 all.q@node04 2
4632 0.50500 meinprog blump r 08/31/2006 10:12:18 all.q@node07 2
4621 0.55500 mpitest npasched qw 09/01/2006 08:44:36 10
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 qalter. Es kennt im Wesentlichen dieselben Optionen wie qsub und setzt die entsprechenden Parameter für die angegebene Job-ID.
Jobs, die falsch aufgesetzt, abgeschickt oder sonstwie beseitigt werden sollen, werden mit dem Kommando qdel unter Angabe der Job-ID entfernt.
Beispiel:
% qstat -u npasched
job-ID prior name user state submit/start at queue slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
4621 0.55500 mpitest npasched qw 09/01/2006 08:44:36 10
% qalter -m a 4621
modified mail options of job 4621
% qdel 4621
npasched has deleted job 4621
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 qsub Kommando sieht so aus:
% qsub -t 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 ergänzt werden, so dass jede Kopie in ein eigenes File schreibt:
#$ -o job.$TASK_ID.out
2. Im Script selbst:
Hier steht die Task-Id in der Environment-Variable $SGE_TASK_ID und kann im Script selbst oder in von dort gestarteten Prozessen gelesen und genutzt werden.
#!/bin/bash --login
#$ -cwd
#$ -N matlab_run
#$ -o matlab_run.$TASK_ID.out
#$ -j y
#$ -m be
#$ -M myself@math.tu-berlin.de
matlab -nosplash -nodisplay < input.$SGE_TASK_ID.m
Hier noch ein Beispiel für einen Matlab-Input, der die Task-ID direkt liest:
task_id = str2num( getenv('SGE_TASK_ID') )
x = floor( task_id / 160 )
y = task_id - x * 160
.....
Weiter nutzbare Environment-Variablen:
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 die entsprechenden Resourcenanforderungen 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), gpu_mem, gputype und nvidia_rtx.
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.
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.
gputype fordert GPUs eines bestimmten Typs an. Derzeit mögliche Werte:
rtx2080tiNVidia GeForce RTX 2080ti
nvidia_rtx=true fordert eine GPU an, die die NVIDIA Raytracing Extensions unterstützt. Das ist normalerweise nur notwendig, wenn man die GPU tatsächlich zum Rendern von Grafik benutzen möchte.
Das folgende Jobscript fordert 1 GPU mit mindestens CUDA Compute Capability 7.5 und 2GB RAM an, lädt ein CUDA-Modul und schreibt dann den Output des deviceQuery-Tools in die Ausgabedatei
#!/bin/bash --login
#$ -cwd
#$ -N gpu_example
#$ -j y
#$ -o gpu_example.out
#$ -l h_rt=120000
#$ -l gpus=1
#$ -l gpu_mem=2G
#$ -l ccc=7.5
#$ -m e
#$ -M meine.mail@adresse
module load cuda/11.1
deviceQuery
Für paralle Programme mit MPI sollte man ein Job-Script ähnlich dem folgenden benutzen:
#!/bin/bash --login
#$ -cwd
#$ -pe ompi* 4
#$ -N mpitest
#$ -o mpitest.out
#$ -j y
#$ -m be
#$ -M myself@math.tu-berlin.de
module add ompi-1.2.2
mpirun -np $NSLOTS myprog
Die rote vier gibt hier die gewünschte Anzahl Prozessoren an. Es kann sogar ein Bereich von Prozessoren gewünscht werden:
#$ -pe ompi* 2-8
was den Job mit zwischen 2 und 8 Prozessoren startet (je nachdem was frei ist). Die tatsächlich alloziierte Anzahl ist im Script dann über die Variable $NSLOTS abrufbar.
Die sog. "Parallel Environments" ompi*, wie in den obigen Beispielen mit -pe angefordert werden, sind eine Art Gruppierung für die eigentlichen Queues. Sie bestimmen bei Anforderung von mehr als einem Queue-Slot, ob und wie die Prozesse auf die Knoten verteilt werden. Wegen der Netzwerktopologie der Cluster gibt es eine ganze Reihe dieser ompi* PEs, das '*' in der oben gezeigten Anforderung bedeutet: Nimm irgendeines dessen Name mit 'ompi' anfängt. Die Liste zeigt alle verfügbaren PEs erhält man mit dem Kommando
qconf -spl