Rechenjobs und Batchsystem

Das Rechnen im Cluster wird über das SLURM-Batchsystem organisiert. SLURM berechnet, wann und auf welchen der Rechenknoten der Auftrag gestartet wird. Dabei werden unter anderem der Bedarf an Ressourcen, die Wartezeit des Auftrags und die Priorität des zugeordneten Projektes berücksichtigt.

FAQ zum Batchsystem

Mit der aktuellen Cluster-Konfiguration müssen im Regelfall keine Partitionen (oder Queues) beim Abschicken* eines neuen Jobs angegeben werden – das erledigt Slurm weitestgehend automatisch anhand allgemeiner Job-Eigenschaften (z.B. max. Laufzeit und spezieller Ressourcen-Anforderung wie Akzeleratoren).

Nutzer mit mehreren Projekten müssen darauf achten, dass beim Abschicken neuer Rechenjobs die Projektzugehörigkeit korrekt spezifiziert wurde (z.B. mittels des Parameters -A <Projekt-Name>).

  • sbatch <Job-Script>
    Stellt einen neuen Job in eine Queue (Warteschlange) ein. Weitere wichtige Parameter des Kommandos und für die Job-Scripte findet man im folgenden Abschnitt Parameter des Kommandos „sbatch“.
    Verschiedene ausführliche Beispiele für Job-Scripte findet man in den folgenden Abschnitten.
  • squeue
    Zeigt den Stand und die Job-IDs aller Ihrer wartenden und aktiven Jobs.
  • sjobs <Job-ID>
    Das ist ein spezielles TU Darmstadt Script und zeigt detaillierte Informationen über alle Jobs bzw. über den Job (Job-ID) an.
  • scancel <Job-ID<
    Löscht einen Job aus der Warteschlange oder beendet einen aktiven Job.
    • scancel -u <TU-ID>
      Löscht/beendet alle eigenen Jobs.
  • csreport
    Das ist ein spezielles TU Darmstadt Script und zeigt für die vergangenen Monate und für alle ihre Projekte den Gesamtverbrauch (im Vergleich zu den beantragten Ressourcen) in Core*Stunden pro Monat an. Für den aktuellen Monat wird zusätzlich auch ihr eigener Nutzeranteil gezeigt (für Projekte mit mehreren Nutzern wichtig).
    • sreport
      Das ist das Slurm-Standardkommando zum Anzeigen des Ressourcen-Verbrauchs zu jedem ihrer Projekte.
      Achtung: ohne „-t hours“ erfolgt die Ausgabe in Core*Minuten.
      • Mit diesem Standardkommando kann man auch selektiv für einen bestimmten Zeitraum die Werte anzeigen.
        Dazu müssen die Parameter cluster Account, sowie der Start- und Ende-Zeitpunkt angegeben werden. Nachfolgendes Beispiel zeigt die Core-Hours für den Monat April 2016:
        sreport cluster Account Start=2016-04-01 End=2016-05-01 -t hours
  • csum
    Das ist ein spezielles TU Darmstadt Script und zeigt für alle ihre Projekte den aktuellen Gesamtverbrauch (im Vergleich zu den genehmigten Ressourcen) an Core*Stunden an.

* außer Nutzer in Kursen oder Lehrveranstaltungen

Zur besseren Nachvollziehbarkeit empfehlen wir, alle Parameter/Pragmas im Job-Script explizit aufzuführen (anstatt sie sbatch als Kommandozeilenparameter zu übergeben). Auf diese Weise ist auch viel später noch nachvollziehbar, mit welchen Einstellungen ein Job gelaufen ist.

Beispiele für Job-Scripts (MPI, OpenMP, MPI+OpenMP) finden Sie weiter unten auf dieser Seite.

Hier sind nur die wichtigsten Pragmas des sbatch-Kommandos angeführt. Eine vollständige Parameterliste liefert das Kommando ''man sbatch'' auf den Login-Knoten .

-A Projekt-Bezeichnung
Für das Accounting kann man hiermit eins der eigenen Projekte auswählen, auf das die verwendeten Core-Stunden gebucht/abgerechnet werden. Die Projektnamen bestehen im Allgemeinen aus dem Wort „project“, gefolgt von einer 5stelligen Zahl, also z.B. „project12345“.
Achtung: Jeder Nutzer hat ein default-Projekt (meist sein erstes angemeldetes), auf das automatisch gebucht wird, wenn man diese Option nicht angibt!

-J Job_Name
Weist dem Job einen frei wählbaren, beschreibenden Namen zu.
Referenzierbar als %x (in #SBATCH … pragmas) und als $SLURM_JOB_NAME (im Rest des Scripts).

--mail-type=BEGIN
Sendet eine E-Mail beim Start des Jobs.
--mail-type=END
Sendet eine E-Mail beim Ende des Jobs.
--mail-type=ALL
Sendet Mails bei beiden Vorgängen (und in einigen weiteren Fällen).

Bitte beachten: wenn man sehr viele Jobs einzeln abschickt, werden dementsprechend sehr viele Mails erzeugt. Das hat in der Vergangenheit dazu geführt, dass diverse eMail- bzw. Internet Service Provider die Mailserver der TU als „spammer“ auf ihre Blacklisten gesetzt haben. Das Mail- und Groupware-Team des HRZ hatte dann sehr viel Mühe, dieses Blacklisting rückgängig zu machen.

Vermeiden Sie dies bitte mittels

  • job arrays (#SBATCH -a 1-100 für 100 gleichartige Jobs)
  • --mail-type=NONE – stattdessen mittels „squeue“ prüfen, welche Jobs noch laufen und welche fertig sind

Bitte vermeiden Sie auch, Ihre Mailadresse mittels „--mail-user=“ selbst zu spezifizieren – die leider nicht seltenen Tippfehler bei diesem Parameter kosten uns unnötigen Arbeitsaufwand. Unser Setup ermittelt auch ohne diese Angabe automatisch Ihre Mailadresse aus Ihrer TU-ID.

-o /pfad/zu/AusgabeDatei_Name (besser mit vollständigem Pfad)
Schreibt die Standard-Ausgabe STDOUT des gesamten Jobs-Scripts in die genannte Datei.
-e /pfad/zu/FehlerDatei_Name (besser mit vollständigem Pfad)
Schreibt den Fehler-Kanal STDERR in die genannte Datei.

Bei beiden Optionen empfehlen wir, den vollen Pfadnamen und/oder "%. „-Dateinamen-Variablen anzugeben, um versehentliches Überschreiben anderer Job-Ausgaben und -Fehlerdateien zu vermeiden.

-n Task_Zahl
Gibt die Anzahl an Tasks (separate Prozesse) für diesen Job an. Sofern nicht anders spezifiziert, stimmt dies mit der Gesamtanzahl der benötigten Rechenkerne überein, die der Job nutzen soll.

Prozesse kann der Scheduler auf verschiedene Rechenknoten verteilen (wofür Ihr Programm MPI-fähig sein muss).

MPI-Programme müssen unter der Kontrolle von “mpirun„ oder “srun„ (bevorzugt) gestartet werden, also z.B.

srun /path/to/my/MPIprogram …

-c Anzahl_Kerne_pro_Prozess
Gibt die Anzahl der Rechenkerne pro Task an. Für reine MultiThreading/OpenMP-Programme sollte man -n auf 1 setzen und -c auf die Anzahl der OpenMP-Threads. Voreinstellung: 1

Threads werden nie auf verschiedene Rechenknoten verteilt.

Programme, die nur mittels MultiThreading/OpenMP parallelisiert sind, brauchen nicht mittels “srun" gestartet zu werden!

--mem-per-cpu=Speicher
Definiert den maximalen Hauptspeicher-Bedarf pro angefordertem Rechenkern in MByte. Zur Ermittlung dieses Werts für Ihr Programm finden Sie in den FAQs zum Batchsystem unter „Wie bestimme ich die Laufzeit-Parameter meines Jobs?“. Als problemloser Standard kann auf LB2 der Wert 3800 verwendet werden.

-t Laufzeit
Setzt das Laufzeit-Limit für den Job. Ein Job, der sich innerhalb dieser Zeit nicht selbst beendet, wird vom Batchsystem automatisch abgebrochen.
Die Zeit kann als einfache Zahl in Minuten oder auch in Form 00:00:00 (Stunden:Minuten:Sekunden) spezifiziert werden.

-C feature
Fordert spezielle Features (Eigenschaften) für die Rechenknoten an, z.B. AVX512 oder größeren Hauptspeicher. Features dürfen mittels „&“ verknüpft werden. Erlaubte Features sind u.a.:

  • avx512
  • mem oder mem1536g
  • mpi (Standard)

-d Dependency
Hiermit lassen sich Abhängigkeiten zwischen verschiedenen Jobs definieren. Details liefert das Kommando ''man sbatch''.

--exclusive
Fordert die Rechen-Knoten job-exklusiv an. Diese Option kann wichtig sein, wenn man weniger Rechenkerne pro Knoten anfordert als vorhanden sind (96 auf den Rechenknoten des LB2 Phase I). In so einem Fall könnte Slurm weitere Jobs (desselben Nutzers) auf denselben Knoten schicken. Da das das Laufzeitverhalten des ersten Jobs beeinflussen (und so möglicherweise Zeit- oder Performancemessungen verfälschen) könnte, stellt diese Option sicher, dass der damit gestartete Job allein auf dem Knoten ist.

Jobs anderer Benutzer dürfen sowieso nicht auf einen bereits benutzten Knoten – unsere Konfiguration ist per se user-exklusiv.

--gres=Klasse:Typ:# Beschleuniger-Anforderung, z.B. GPUs
(wenn nicht angegeben: Typ=any und #=1)

  • --gres=gpu – fordert 1 GPU beliebigen Typs an
  • --gres=gpu:v100 – fordert 1 NVidia „Volta 100“-Karte an
  • --gres=gpu:a100:3 – fordert 3 NVidia „Ampere 100“-Karten an

Um Ihre Job-Scripts nicht immer für wechselnde Anzahlen an GPUs umschreiben zu müssen, können Sie überall dort, wo Ihre Programme die Zahl der zu nutzenden GPUs erwarten, die Variable $SLURM_GPUS_ON_NODE verwenden. Beispiel: … --num-devices=$SLURM_GPUS_ON_NODE.

Wenn Sie für verteiltes Machine/Deep Learning mehrere GPU-Nodes benötigen (z.B. mit „horovod“), müssen Sie mit -N # (und dann -n >=#) explizit mehrere Nodes anfordern (# = 2-8).
Da „GRes“ immer pro Node gelten, darf --gres=gpu:4 nicht überschritten werden, selbst wenn mehrere 4-GPU-Knoten angefordert werden.

MPI-Script

#!/bin/bash

#SBATCH -J <Job_Name>
#SBATCH --mail-type=END
# Bitte achten Sie auf korrekte Pfad-Angaben (Vz. müssen bereits vorher existieren):
#SBATCH -e /scratch/<TU-ID>/<yourWorkingDirectory>/%x.err.%j
#SBATCH -o /scratch/<TU-ID>/<yourWorkingDirectory>/%x.out.%j
#
#SBATCH -n 192               # Anzahl der Prozesse (= zu nutzende Rechenkerne, hier 2 Nodes à 96 Kerne)
#SBATCH --mem-per-cpu=1750   # Hauptspeicher in MByte pro MPI-Task
#SBATCH -t 01:30:00          # in Stunden, Minuten und Sekunden, oder '#SBATCH -t 10' - nur Minuten

# -------------------------------
# Anschließend schreiben Sie Ihre eigenen Befehle zum Start der Berechnung, wie z.B.
module purge
module load gcc openmpi
cd /scratch/<TU-ID>/<yourWorkingDirectory>
srun  <MPI-Programm>  <Parameter>
EXITCODE=$?

# Aufräum- und Kopierbefehle:
...
# JobScript mit dem Status des wiss. Programms beenden
exit $EXITCODE
alle Parameter in <…> bitte durch eigene Werte ersetzen! Dieses Script startet ein MPI-fähiges Programm, dass Knoten-übergreifend rechnen kann.

Multi-Threading/OpenMP-Script

#!/bin/bash

#SBATCH -J <job_name>
#SBATCH --mail-type=END
# Bitte achten Sie auf korrekte Pfad-Angaben (Vz. müssen bereits vorher existieren):
#SBATCH -e /home/<TU-ID>/<project_name>/%x.err.%j
#SBATCH -o /home/<TU-ID>/<project_name>/%x.out.%j
#
#SBATCH -n 1                  # nur 1 Prozess
#SBATCH -c 24                 # Anzahl der Prozessorkerne pro Prozess
#                               kann unten als $SLURM_CPUS_PER_TASK abgerufen werden​
#SBATCH --mem-per-cpu=1750    # Hauptspeicher in MByte pro Prozessorkern
#SBATCH -t 01:30:00           #  in Stunden, Minuten und Sekunden, oder '#SBATCH -t 10' - nur Minuten

# -------------------------------
# Anschließend schreiben Sie Ihre eigenen Befehle zum Start der Berechnung, wie z.B.
module purge
module load gcc
cd /scratch/<TU-ID>/<yourWorkingDirectory>

# falls Ihr Programm $OMP_NUM_THREADS beachtet/berücksichtigt:
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK​

/home/<TU-ID>/<path/to/programm>  <Parameter>
EXITCODE=$?

#  Aufräum- und Kopierbefehle:
...
# JobScript mit dem Status des wiss. Programms beenden
exit $EXITCODE
alle Parameter in <…> bitte durch eigene Werte ersetzen! Dieses Script eignet sich für ein nicht-MPI-fähiges Programm, das dennoch Multithreading bzw. Open MultiProcessing nutzen kann.

Hybrid: MPI + OpenMP-Script

#!/bin/bash

#SBATCH -J <Job_Name>
#SBATCH --mail-type=END
# Bitte achten Sie auf korrekte Pfad-Angaben (Vz. müssen bereits vorher existieren):
#SBATCH -e /home/<TU-ID>/<Projekt_Name>/%x.err.%j
#SBATCH -o /home/<TU-ID>/<Projekt_Name>/%x.out.%j
#
#SBATCH -n 4                 # Anzahl der MPI-Prozesse/Tasks (vier Prozesse, aber - siehe nächste Zeile - jeder mit 96 Kernen)
#SBATCH -c 96                # Anzahl der Rechenkerne (OpenMP-Threads) pro MPI-Prozess
#                              ist unten als $SLURM_CPUS_PER_TASK​ abrufbar
#SBATCH --mem-per-cpu=1750   # Hauptspeicher pro Rechenkern in MByte
#SBATCH -t 01:30:00          # in Stunden, Minuten und Sekunden, oder '#SBATCH -t 10' - nur Minuten

# -------------------------------
# Anschließend schreiben Sie Ihre eigenen Befehle zum Start der Berechnung, wie z.B.
module purge
module load gcc openmpi
cd /home/<TU-ID>/<yourWorkingDirectory>

# falls Ihr Programm $OMP_NUM_THREADS beachtet/berücksichtigt:
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK​

srun  <Programm>  <Parameter>
EXITCODE=$?

#  Aufräum- und Kopierbefehle:
...

# JobScript mit dem Status des wiss. Programms beenden
exit $EXITCODE
alle Parameter in <…> bitte durch eigene Werte ersetzen! Dieses Beispiel startet 4 MPI-Prozesse, die je 96 CPU-Kerne per MultiThreading nutzen.

GPU/GRes

#!/bin/bash

#SBATCH -J <Job_Name>
#SBATCH --mail-type=END
# Bitte achten Sie auf korrekte Pfad-Angaben (Vz. müssen bereits vorher existieren):
#SBATCH -e /home/<TU-ID>/<Projekt_Name>/%x.err.%j
#SBATCH -o /home/<TU-ID>/<Projekt_Name>/%x.out.%j
#
# CPU-Anforderung
#SBATCH -n 1                  # nur 1 MPI-Prozess/Task
#SBATCH -c 24                 # Anzahl der Rechenkerne (OpenMP-Threads) pro MPI-Prozess 
#                               ist unten als $SLURM_CPUS_PER_TASK​ abrufbar
#SBATCH --mem-per-cpu=1750    # Hauptspeicher in MByte pro Rechenkern
#SBATCH -t 01:30:00           # in Stunden, Minuten und Sekunden, oder '#SBATCH -t 10' - nur Minuten

# GPU-Anforderung 
#SBATCH --gres=gpu:v100:2     # 2 GPUs des Typs NVidia "Volta 100"

# -------------------------------
# Anschließend schreiben Sie Ihre eigenen Befehle zum Start der Berechnung, wie z.B.
module purge
module load gcc cuda
cd /scratch/<TU-ID>/<yourWorkingDirectory>

# falls Ihr Programm $OMP_NUM_THREADS beachtet/berücksichtigt:
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
​
# nur zur Prüfung, ob und welche GPUs tatsächlich zugeteilt wurden
# (Ausgabe erscheint in der oben als "#SBATCH -e" definierten Datei):
nvidia-smi 1>&2

./<Programm>  -<Parameter> 
EXITCODE=$?

#  Aufräum- und Kopierbefehle:
...

# JobScript mit dem Status des wiss. Programms beenden
exit $EXITCODE
alle Parameter in <…> bitte durch eigene Werte ersetzen! Falls Ihr Programm einen Parameter kennt, wieviele GPUs es nutzen soll, können Sie diesen mit Hilfe der Variable $SLURM_GPUS_ON_NODE flexibel angeben. Ihr Programm nutzt dann immer automatisch genau die Zahl an GPUs, die Sie angefordert haben.

Die Angabe „--gres=Klasse:Typ:Anzahl“ bezieht sich immer auf einen einzelnen Beschleuniger-Rechenknoten, und auf ganze GPU-Karten. Es gibt keinen Weg, explizit nur eine gewisse Anzahl an GPU-Kernen (z.B. 48 Tensor-Units) anzufordern – nur eine bis vier ganze GPU-Karten.

Wenn Sie keine Anzahl an „CPU-Kernen pro Task“ („-c #“ bzw. „--cpus-per-task=#“) explizit angeben, wird Ihrem Job automatisch pro angeforderter GPU ein Viertel der CPU-Kerne des Rechenknotens (96/4 = 24) zugewiesen.

Fordern Sie also ohne Angabe von „-c #“ nur „--gres=gpu:a100:2“ an, findet Ihr Job 48 nutzbare CPU-Kerne (und 2 GPUs) vor.

Interaktives Arbeiten auf Clusterknoten ist prinzipiell möglich, allerdings ist es insbesondere bei einer hohen Clusterauslastung sehr unpraktisch. Außer zum Debugging ist es immer besser, nicht-interaktive Jobs im Batch-System zu verwenden.

Falls interaktives Arbeiten unbedingt notwendig ist, kann dies mit dem srun Kommando und dem Parameter --pty /bin/bash angefordert werden. Die drei immer notwendigen Parameter -t (Zeit), -n (Task Zahl) und --mem-per-cpu= (Speicher pro CPU-Kern) müssen ebenfalls angegeben werden. Optionale Parameter wie z.B. features und mail Optionen können ebenfalls auf der Kommandozeile angegeben werden.

Beispiel:

srun -t15 -n4 --mem-per-cpu=500 --pty /bin/bash

Generell ist der direkte Login auf die Rechenknoten nicht möglich.

Die einzige Ausnahme sind die Knoten, auf denen gerade einer Ihrer Jobs läuft – vom Login-Node aus (nicht aus dem Internet) können Sie sich dann auf diese Knoten weiterverbinden.

Das dient dazu, das Verhalten Ihrer Jobs direkt auf den ausführenden Rechenknoten mittels „top“ oder „strace“ oder ähnlichen Tools zu beobachten.

Da die Rechenknoten nicht direkt mit dem Internet verbunden sind, funktioniert das nur von den Loginknoten aus.

Die (Liste der) ausführenden Rechenknoten erhalten Sie vom Kommando

squeue -t RUNNING

in der Spalte NODELIST.

Melden Sie sich dann (vom Loginknoten aus) auf einem von diesen an:

ssh <name of compute node as shown in NODELIST>

Haben Sie in Summe nur einen Node angefordert (squeue zeigt unter „NODELIST“ nur einen Knotennamen an), können Sie dasselbe auch per

srun --jobid=<IhreJobID> --pty bash

ohne vorherige Extraktion der NODELIST erreichen.

Im Fall von MPI-Jobs, die auf mehreren Knoten laufen, setzt Sie obiger Befehl allerdings nur auf irgendeinem dieser Knoten ab. Wenn Sie auf andere beteiligte Nodes wollen, müssen Sie die „NODELIST“ vom squeue in einzelne Hostnamen zerlegen. Beispielsweise ergibt „mpsc[301,307,412-413]“ folgende Knoten -

mpsc0301
mpsc0307
mpsc0412
mpsc0413

Auf jeden dieser Knoten können Sie sich (vom Loginknoten aus) mittels „ssh mpsc0…“ weiterverbinden, solange Ihr Job darauf läuft.

Um Ihrem Job nun detaillierter bei der Arbeit zuzusehen bzw. zu beurteilen, wie (und ob) er die zugewiesenen Ressourcen ausnutzt, können Sie Kommandos wie „top“ oder „htop“ oder andere bzw. Ihre eigenen Linux-Werkzeuge nutzen.

Sollten Sie noch eingeloggt sein, wenn Ihr Job endet, wird auch Ihre separate ssh-Sitzung zum Rechenknoten beendet und Sie sind wieder auf dem Loginknoten.