Cluster: Jobs einstellen

Cluster Benutzung

In Kürze

Schwierigkeit

Mittel


Kosten

Kostenfrei


Erste SChritte

Auf dem Cluster werden Rechnungen in sogenannten Jobs ausgeführt. Ein Job ist eine in sich abgeschlossene, vom Nutzer definierte Aufgabe. Als Nutzer geben Sie auch an, wie viele Ressourcen (Knoten, Kerne, Arbeitsspeicher) für wie lange benötigt werden. Dieser Job wird dann in eine Warteschlange eingestellt, wo eine als Scheduler bezeichnete Software den Job startet, sobald die Ressourcen verfügbar sind.

Der auf dem OMNI-Cluster installierte Scheduler heißt SLURM (Simple Linux Utility for Resource Management), er ist in der Version 20.02.5 installiert. SLURM wird mit einer Reihe von Konsolenbefehlen bedient, mit denen Jobs eingestellt, überwacht und gegebenenfalls abgebrochen werden können. Die wichtigsten werden unten vorgestellt und sind hier separat aufgelistet.

Ein Job beinhaltet in der Regel die Ausführung eines Linux-Befehl oder eines (Shell-)Skripts mit einer Reihe von Linux-Befehlen.

Die Warteschlangen auf dem OMNI-Cluster sind vom ZIMT konfiguriert und unterscheiden sich im Wesentlichen in der erlaubten Maximallaufzeit von Jobs. Im Allgemeinen werden diese Warteschlangen als Queues bezeichnet, SLURM-intern ist jedoch der Begriff Partition üblich.

Warteschlangen

Auf dem Cluster sind die folgenden Warteschlangen konfiguriert (die Sie sich mit spartition anzeigen lassen können):

$ spartition

PartitionName   DefaultTime       MaxTime   MaxNodesPerJob

        debug      00:15:00      01:00:00                2
       expert    1-00:00:00    1-00:00:00              128
          gpu      12:00:00    1-00:00:00                2

      jupyter      12:00:00    1-00:00:00                1
         long    5-00:00:00   20-00:00:00                8
       medium      12:00:00    1-00:00:00               32
        short      01:00:00      02:00:00               32
          smp      12:00:00    5-00:00:00                1

Zu beachten ist hier:

  • short ist die Standard-Warteschlange (Default Queue). Jobs, bei denen die Queue nicht explizit angegeben ist, werden in short eingestellt.
  • gpu ist für Jobs, die GPUs benötigen. Die GPUs an sich müssen zusätzlich in den SLURM-Einstellungen angefordert werden, sonst verwendet der betreffende Job sie nicht.
  • smp ist die Queue für die SMP-Knoten (SMP = Shared Multiprocessing), zwei größere Knoten mit je 1536 GB Arbeitsspeicher, die für besonders RAM-intensive Berechnungen gedacht sind.
  • expert ist eine spezielle Queue, die sehr große Jobs zulässt. Wenn Sie sie nutzen möchten, kontaktieren Sie uns. Wir begutachten jeden Anwendungsfall für die expert-Queue einzeln.
  • jupyter ist für Jupyter-Jobs reserviert.

Job-Skripte

Die Vorgehensweise beim Erstellen von Jobs ist üblicherweise wie folgt:

Vorgehen

  1. Sie schreiben ein Job-Skript. Das Job-Skript hat die folgenden Aufgaben:
    • Aufruf Ihrer Software
    • Definition Ihrer Job-Einstellungen
    • Laden Ihrer Environments
    • Je nach Job gegebenenfalls andere nötige Aufgaben.
  2. Sie bereiten Ihre Software (z.B. Compilieren) und Ihre Daten (z.B. Parameterdateien) vor. Gegebenenfalls allokieren Sie einen Workspace.
  3. Sie stellen Ihr Skript mit sbatch in die Warteschlange ein.
  4. Sie warten, bis Ihr Job angelaufen ist.
  5. Nachdem Ihr Job angelaufen ist, überprüfen Sie am besten ob alles richtig eingestellt wurde und Ihre Software läuft.
  6. Sie warten, bis Ihr Job durchgelaufen ist.

Tipp: Während Ihr Job läuft, können Sie sich per ssh vom Login-Knoten zu dem entsprechenden Compute-Knoten verbinden und dort top ausführen, um Ihren Job zu kontrollieren. Der squeue-Befehl zeigt an, auf welchen Knoten Ihr Job läuft. Nutzer haben nur SSH-Zugriff zu Compute-Knoten, auf denen gerade ein Job des betreffenden Nutzers läuft.

Allgemeine Überlegungen

  • Je weniger Ressourcen (Tasks/Nodes) und je kürzer die Laufzeit, die Sie benötigen, desto kürzer ist die Wartezeit bis Ihr Job anläuft. Sie sollten allerdings zeitlich eine Reserve lassen, da Jobs bei Erreichen der Laufzeit sofort gestoppt werden.
  • Aus dem gleichen Grund empfiehlt es sich, den Job in die kürzestmögliche Schlange einzustellen (z.B. short wenn die Laufzeit unter 2 Stunden ist).
  • Es kann durch unvorhersehbare Umstände immer passieren, dass ein Job abbricht. Soweit möglich, sollten Sie während der Rechnung regelmäßig Dateien mit Zwischenergebnissen abspeichern (sog. Checkpointing). Damit müssen Sie bei einem Abbruch der Rechnung nicht von vorne anfangen.
  • Jeder SLURM-Job erhält eine laufende Nummer (Job-ID). Diese wird beim Einstellen angezeigt und dient zur eindeutigen Zuordnung des Jobs.
  • SLURM bietet auch eine Funktionalität, um Sie per E-Mail über den Jobstatus zu informieren.

Erstellen eines Job-Skripts

Hier ist ein Beispiel für ein Job-Skript, das die Finite-Elemente-Anwendung Abaqus ausführt:

#!/bin/bash
#SBATCH --time=0:20:00
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=16
#SBATCH --mem 128000
#SBATCH --partition=short

module load abaqus

echo "Number of tasks: "
echo $SLURM_NTASKS

abaqus job=Test.inp mp_mode=mpi interactive cpus=$SLURM_NTASKS

Die Befehle bedeuten im Einzelnen:

  • #!/bin/bash bedeutet, dass das Skript mit der Bash-Shell ausgeführt werden soll. Hier muss nicht unbedingt eine Linux-Konsole stehen, beispielsweise könnte ein Python-Skript auch mit #!/usr/bin/python ausgeführt werden.
  • Die Optionen mit #SBATCH sind Anweisungen an SLURM, mit welchen Optionen der Job auszuführen ist. In diesem Fall wird ein Knoten zugewiesen und auf diesem 16 Tasks (parallele Prozesse) gestartet. Die meisten dieser Optionen haben Standardwerte und müssen nicht zwangsläufig angegeben werden. Mögliche Optionen finden sich auf unserer Webseite unter SLURM sowie in der externen SLURM-Dokumentation.
  • Anschließend werden zusätzliche Operationen ausgeführt. In diesem Befehl wird ein notwendiges Modul geladen, dies können aber im Prinzip beliebige Linux-Befehle sein (z.B. Kopieren von Dateien, Anlegen von Ordnern).
  • Beispielhalber wird die Umgebungsvariable SLURM_NTASKS ausgegeben. SLURM setzt einige Umgebungsvariablen für den entsprechenden Job, die innerhalb des Jobs Informationen über den Job liefern. In diesem Fall ist SLURM_NTASKS=16 entsprechend den Job-Einstellungen.
  • Schließlich wird die entsprechende Anwendung aufgerufen, in diesem Fall Abaqus. Beachten Sie, dass die Umgebungsvariable genutzt wird, sodass Abaqus automatisch mit der korrekten Anzahl paralleler Prozesse aufgerufen wird.

Einstellen des Jobs

Ein Job-Skript dieser Art wird mit dem Befehl sbatch eingestellt, zum Beispiel:

$ sbatch --time 0:30:00 beispiel.sh

Dabei muss das Skript beispiel.sh nicht unbedingt ausführbar sein. Der sbatch-Befehl akzeptiert eine Reihe von Optionen, diese überschreiben die im Skript gegebenen. In diesem Beispiel würde das Skript nicht mit einer Laufzeit von 20 Minuten, wie oben im Skript selbst angegeben, sondern mit einer Laufzeit von 30 Minuten gestartet. Eine vollständige Liste von Optionen kann mit sbatch -h angezeigt werden und ist auch in der SLURM-Dokumentation beschrieben.

Interaktive Jobs

Manchmal benötigt eine Anwendung während des Laufens Nutzerinput, aber auch so viel Rechenleistung, dass sie auf dem Cluster in einem Job laufen muss. Für diesen Fall gibt es die Möglichkeit, interaktive Jobs einzustellen. Bei einem interaktiven Job bleibt eine Konsole offen und Sie können innerhalb des Jobs beliebige Anwendungen ausführen.

Achtung: Es ist verboten, rechenintensive Anwendungen auf den Login-Knoten laufen zu lassen, da sie alle anderen Nutzer beeinträchtigen. Das HPC-Team behält sich vor, solche Anwendungen ohne Vorwarnungen abzubrechen.

Ein interaktiver Job wird mit dem folgenden Befehl gestartet:

$ srun --pty /bin/bash

Der Befehl srun startet einen SLURM-Job, der einen bestimmten Befehl ausführt (im Gegensatz zu sbatch, das ein bestimmtes Skript ausführt). In diesem Fall wird eine Bash-Shell gestartet. Die Option --pty (“Pseudo-Terminal”) bewirkt, dass der Job interaktiv ist. Der Befehl srun akzeptiert dieselben Optionen zu Anzahl Knoten, Partition und Laufzeit wie sbatch. Alle Optionen können mit srun --help angezeigt werden.

Tipps:

  • Es ist keinesfalls nötig, dass hier eine Shell ausgeführt wird, srun kann beliebige Linux-Befehle ausführen.
  • Wird ein interaktiver Job eingestellt, bleibt die Konsole stehen, bis er anläuft. Wenn Sie bis zum Anlaufen des Jobs auf dem Login-Knoten weiterarbeiten möchten, sollten Sie eine zweite Konsole mit einer SSH-Verbindung zum Cluster öffnen.

Job-Überwachung und Abbruch

SLURM besitzt eine Reihe von Befehlen, mit denen Jobs überwacht werden können. Hier sind nur die wichtigsten gelistet, eine umfassendere Liste befindet sich hier. In der Regel lassen sich mit --help Optionen auflisten.

Insbesondere kann aufgelistet werden, welche Jobs in den Warteschlangen stehen, indem der Befehl squeue eingegeben wird. Dies kann noch weiter verfeinert werden, beispielsweise indem mit squeue -p <Warteschlangenname> nur eine bestimmte Warteschlange oder mit squeue -u <Username> nur ein bestimmter Nutzer angezeigt wird.

Der Status der Knoten des Clusters (frei, belegt, etc.) kann mit sinfo angezeigt werden, Information über die Konfiguration der Warteschlangen mit spartition. Detaillierte Informationen zu einem einzelnen Job können mit scontrol show job <Job-ID> erfragt werden.

Ein eingestellter Job kann mit scancel <Job-ID> abgebrochen werden, unabhängig davon ob er schon angelaufen ist oder nicht. Alle eigenen Jobs können mit scancel -u <EigenerUsername> abgebrochen werden.

Tipps

Sie haben einige Kontrolle darüber, welche Ressourcen Sie anfordern können und es empfiehlt sich darüber nachzudenken:

  • Wenn Ihr Anwendungsfall beispielsweise ein Programm ist, das nicht parallel läuft, aber den kompletten Arbeitsspeicher eines Knotens braucht, können Sie einen Knoten reservieren:$ sbatch --nodes 1 <Scriptname>wobei statt --nodes auch die Kurzform -N verwendet werden kann.
  • Wenn mehrere Prozesse gestartet werden sollen, müssen auch mehrere Tasks spezifiziert werden. So ist zum Beispiel bei MPI-Programmen ein Task gleich ein Prozess und ein Programm mit 24 MPI-Prozessen kann man aufrufen mit:$ sbatch --ntasks 24 <Scriptname>und im Jobskript selbst dann mpirun -np 24 angeben. Die Option --ntasks hat die Kurzform -n. Alternativ kann auch die Anzahl an Knoten und Tasks angegeben werden:$ sbatch -N 2 --tasks-per-node 12 <Scriptname>In diesem Fall würden auch 24 Tasks gestartet, es wäre aber garantiert, dass sich diese auf genau zwei Knoten verteilen. Es können nicht mehr Tasks auf einem Knoten gestartet werden, als CPUs vorhanden sind und SLURM wird beim Einstellen des Jobs eine Fehlermeldung erzeugen.
  • Wenn ein Programm mit mehreren Threads gestartet werden soll, wie zum Beispiel bei der Verwendung von OpenMP, wird nur ein Task für das Programm verwendet. Allerdings können einem Task auch mehrere CPUs zugewiesen werden:$ sbatch --nodes 1 --cpus-per-task 16 <Scriptname>In diesem Beispiel würde ein kompletter Knoten für ein einzelnes OpenMP-Programm verwendet werden.
  • Wenn Sie in einem Job ein Programm mehrmals parallel ausführen möchten, können Sie das mit srun tun. Wenn srun in einem Job-Skript steht, funktioniert er etwas anders, als wenn Sie ihn selbst eingeben: Es wird kein neuer Job eingestellt, sondern der Befehl im bestehenden Job mehrmals ausgeführt. Wenn es ein MPI-Programm ist, reicht allerdings ein mpirun ohne zusätzliches srun davor.
    SLURM setzt am Anfang des Jobs einige Umgebungsvariablen, in denen Informationen über den Job abrufbar sind. Beispielsweise steht in $SLURM_NTASKS, wie viele Tasks zur Verfügung stehen und man kann beim MPI-Aufruf angeben:$ mpirun -np $SLURM_NTASKS <Programmname>So wird automatisch die richtige Anzahl an MPI-Prozessen gestartet.

    Achtung: die Variable SLURM_NTASKS wird nur gesetzt, wenn die Anzahl an Tasks im Jobskript oder beim Einstellen des Jobs gesetzt wird (z.B. --ntasks-per-node oder --ntasks).