Seite druckenPDF Version herunterladenSeitenstruktur anzeigenSeite durchsuchen
nach oben

Kurzübersicht mit Sprungmarken



Batch-System / Torque

Submittieren von Jobs

Einleitung

Der Cluster besteht aus Knoten (Nodes) identischer Bauart bei unterschiedlicher Speicherausstattung. Wir unterscheiden anhand des Merkmals Speicher zwei Typen c von d. Typ c (node1 - node70) sind mit 16GB RAM (2GB pro Core) und Typ d (node71 - node84) mit 32GB RAM ausgestattet (4GB pro Core).

Queues

Es stehen - folgt man dem obigen Klassifizierungsmerkmal - zwei Typen von Queues, Typ c und d, zur Verfügung. Neben diesen führen wir noch Test-Queues, bei denen die Speicherzusammensetzung zunächst keine Relevanz hat.

Unter einer Queue versteht man den Kanal, über den man Ressourcen des Clusters zu Berechnungszwecken anfordert. Der Scheduler arbeitet die durch das Batch-System an die Queue übermittelten Jobs unter Berücksichtigung des Queue-Policy-Schemas sowie spezifischer Priorisierungs-Schemata ab (Sehen sie bitte Informationen zur Konfiguration des Schedulers sowie des Scheduling-Verhaltens). Üblicherweise entspricht dies ungefähr dem Prinzip First in - First out (FIFO). Der Scheduler kann Jobs temporär zurückstellen (blocken), wenn sie nicht den adaptierten Policies zur Optimierung des Scheduling-Verhaltens entsprechen.

Die konkrete Bezeichnung einer Queue setzt sich zusammen aus Typ + Anzahl an Tasks. Tasks sind meist gleichbedeutend mit Cores. Ein Knoten besitzt insgesamt 8 Cores. Ein simples Beispiel: 1x 16GB Node entspricht der Queue c8. Die Queue d32 dagegen, belegt ganze 4 Knoten mit 32GB Speicher mit jeweils 8 Tasks / Cores pro Node. Es folgt eine Auflistung sämtlicher Queues mit dem Befehl qstat:

rz9a024@hpclogin:~> qstat -q

server: master

Queue            Memory CPU Time Walltime Node  Run Que Lm  State
---------------- ------ -------- -------- ----  --- --- --  -----
c1                 --      --    336:00:0     1   0   0 16   E R
c8                 --      --    72:00:00     1   0   0 16   E R
d8                 --      --    72:00:00     1   3   0  8   E R
c16                --      --    120:00:0     2   1   0 10   E R
c32                --      --    48:00:00     4   0   0 10   E R
d16                --      --    72:00:00     2   0   0  7   E R
d32                --      --    48:00:00     4   0   0  3   E R
test               --      --    02:00:00     4   0   0 16   E R
batch              --      --       --      --    0   0 --   D S
d8_long            --      --    192:00:0     1   4   0  4   E R
atk                --      --    72:00:00     2   1   0  1   E R
c64                --      --    72:00:00     8   0   0  1   E R
test8_short        --      --    00:12:00     1   0   0  4   E R
                                               ----- -----
						  9      0
rz9a024@hpclogin:~>

Ein weiteres wichtiges Merkmal der Queues ist, neben der Taskanzahl und der Speicherbelegung pro Knoten, die maximale mögliche Laufzeit (=Walltime) der Jobs. Diese ist aus der obigen Tabelle für die aufgeführten Queues ersichtlich.

Weitere detailierte Informationen einer Queue erfragt man mit dem Befehl: qsub -Q [Queue] -f.

Hier ein Beispiel:
 1 rz9a024@hpclogin:~> qstat -Q c8 -f
 2 Queue: c8
 3 queue_type = Execution
 4 max_queuable = 30
 5 total_jobs = 0
 6 state_count = Transit:0 Queued:0 Held:0 Waiting:0 Running:0 Exiting:0
 7 max_running = 16
 8 resources_max.ncpus = 8
 9 resources_max.nodect = 1
10 resources_max.walltime = 72:00:00
11 resources_min.ncpus = 4
12 resources_min.nodect = 1
13 mtime = 1243586154
14 resources_assigned.ncpus = 0
15 resources_assigned.nodect = 0
16 max_user_run = 8
17 enabled = True
18 started = True

Zeile 3 zeigt an, dass es sich um eine "ausführende" Queue zu Berechnungs- bzw. Test-Zwecken (execution) handelt. Zeile 4 gibt die Zahl max. einzustellender Jobs in die Warteliste an. Zeile 5 zeigt die Anzahl aktuell laufender Jobs. Zeile 7 zeigt die maximale Zahl simultan lauffähiger Jobs, Zeile 16 maximale Jobs pro Benutzer. Zeile 9 zeigt die max. Anzahl anforderbarer Nodes an, Zeile 8, die anforderbaren CPUs/Cores, Zeile 10 die Walltime im Format HH:MM:SS, Zeile 11-12 das Minimum der Ressourcen aus Zeile 8, 9. Zeile 14,15 zeigt die Zahl der von Jobs benutzten CPUs/Cores bzw. Nodes.

Weitere Informationen erhalten sie mit dem Befehl: man qstat

Job-Submission

Jobs werden mit dem Befehl qsub an das Batch-System übergeben. Die allgemeine Syntax für den Befehl lautet: qsub -qQUEUE BATCHFILE -lnodes=NNodes:ppn=NCPUs:feature (mem16 für c-Knoten oder mem32 für d-Knoten). Das Batch-File ist ein Textfile, das eine Beschreibung des auszuführenden Jobs liefert:

 1 #!/bin/bash
 2
 3 #PBS -l nodes=2:ppn=8:mem16
 4 #PBS -m abe
 5 #PBS -M user.nachname@domain.com
 6
 7 EXEC="/opt/intel/impi/3.2.1/test/test_openmpi1.3.1"
 8 MPIRUN="/opt/openmpi/1.3.1/intel/bin/mpirun"
 9
10 export LD_LIBRARY_PATH="/opt/openmpi/1.3.1/intel/lib/"
11 source /opt/intel/Compiler/11.0/081/bin/iccvars.sh intel64
12
13 $MPIRUN --mca mpi_paffinity_alone 1 $EXEC

Zeile 1 dient der Beschreibung des Text-Files. In Zeile 3 werden Ressourcen für den Job angefordert: nodes=AnzahlNodes:ppn=ProzessorenproNode. In Zeile 4-5 wird das Batch-System angewiesen, bei Beginn, Beendingung oder Abbruch der Berechnung eine Nachricht (Email) an den angegebenen Empfänger zu versenden. Zeile 7 definiert das Executable, welches als Argument in Zeile 13 dem auszuführenden Befehl (üblicherweise mpirun) übergeben wird. In Zeile 10-11 werden zusätzliche Umgebungsvariablen definiert, die bei Laufzeit benötigt werden.

Zusatz: An Stelle des in Zeile 13 ausgeführten Executable könnte prinzipiell jeder beliebige Befehl (auch non-MPI-Programme oder in Ausnahmefällen sogar ein Skript) stehen. Zum besseren Verständnis sei vermerkt, dass der Befehl mpirun dabei insgesamt soviele Prozesse wie mit der Ressourcen-Angabe definiert worden sind erzeugt und jeweils das Executable einmal pro Thread ausführt. Ein Nutzen von MPI liegt hier neben anderen in der Realisierung des Datenaustauschs auch über die Knotengrenze hinweg. Als technische Basis dient hier der dem Transfer zugrunde gelegte und sehr kurze Latenzzeiten ermöglichende Infiniband-Stack (OFED).

Sie submittieren diesen Job mit: qsub -qc16 BATCHFILE.

Um flexibler bei Berechnungen zu sein, ist es auch möglich ein rudimentäres Batch-File zu halten, wobei dann Ressourcen und zusätzliche Paramter an den Befehl qsub übergeben werden müssen. Mit der Option -l können dafür Ressourcen speziell für den Job angefordert werden, z.B.: qsub -qc16 -lnodes=2:ppn=8:mem16. Die nächste Abbildung zeigt so ein Batch-File:

 1 #!/bin/bash
 2
 3 #PBS -V
 4
 5 EXEC="/opt/intel/impi/3.2.1/test/test_openmpi1.3.1"
 6 MPIRUN="/opt/openmpi/1.3.1/intel/bin/mpirun"
 7
 8 export LD_LIBRARY_PATH="/opt/openmpi/1.3.1/intel/lib/"
 9 source /opt/intel/Compiler/11.0/081/bin/iccvars.sh intel64
10
11 $MPIRUN --mca mpi_paffinity_alone 1 $EXEC

Auch die Mailbenachrichtigung kann per Kommando eingeschaltet werden: qsub -qc16 -lnodes=2:ppn=8:mem16 -m abe -M empfänger@domain.com BATCHFILE

Bitte beachten sie, dass wenn die Ressourcen-Angabe nicht präzise erfolgt (im Batchfile oder über Argumente), der Job in der Queue hängen bleibt und verwaist.

Hier geht's zur Gesamtübersicht vorhandener MPI-Implementationen.

weitere Themen

(simples) Debugging von Batchfiles

Die Batchfiles sind eigentlich Shell-Skripte, die mit zusätzlichen Steuerkommandos an PBS übergeben werden. Sie testen darum ein Batchfile vor seiner Submittierung am besten indem Sie interaktiv einen Knoten reservieren und dort das Script direkt in der Linux-Konsole ausführen: ./BATCHFILE. Etwaige Fehler lassen sich so frühzeitig erkennen.

Job-Handling

Löschen eines Jobs geschieht mit dem Befehl "qdel". Siehe hierzu: "man qdel"

Job-Outputs / Logging

Sämtliche Outputs eines Jobs werden bei dessen Laufzeit in die Datei BATCHFILENAME.oJOBID bzw. Errors auch nach BATCHFILENAME.eJOBID geschrieben; das heißt in das Verzeichnis, von dem aus man den Job (mit dem Befehl "qsub") submitiert hat. Das ist meistens jedoch: /G/home/USER/. Hier ein simples Beispiel: Heißt das Batchfile z.B. "batch.test" und qsub bzw. qstat geben als JobID "8300" aus, dann finden sich die Ausgaben in batch.test.8300o bzw. die Errors in batch.test.8300e. Man kann sich komfortabel über "cat *JOBID* | less" (für JOBID die Jobnummer einsetzen!) den gesamten Log ausgeben lassen.

Job-Arrays

Job-Arrays ermöglichen es dem Benutzer, multibel Jobs abzuschicken, bei denen sich das Job-File selbst gar nicht oder nur geringfügig ändert. Man denke bei geringfügigen Änderungen beispielsweise an die Setzung neuer Parameter. Die allgemeine Syntax hierzu lautet: qsub -t[a..n(a)]{ ,[b..n(b)] ... } -q[Queue] [Jobfile]. Mit dem Schalter -t werden die Intervalle an den Befehl qsub übergeben. Beispielsweise:
qsub -t 0-4 -q test8_short testfile

Auch folgendes Kommando ist zulässig:

qsub -t 1-20,30-40,45-50 -q test8_short testfile
Job-Arrays benutzen daher auch eine besondere Art der Namenszuweisung (s. 1.Spalte, u.):
rz9a024@hpclogin:~> qstat
Job id                    Name             User            Time Use S Queue
------------------------- ---------------- --------------- -------- - -----
2491-0.master             test.sh-0        rz9a024                0 Q test8_short    
2491-1.master             test.sh-1        rz9a024                0 Q test8_short    
2491-2.master             test.sh-2        rz9a024                0 Q test8_short    
2491-3.master             test.sh-3        rz9a024                0 Q test8_short    
2491-4.master             test.sh-4        rz9a024                0 Q test8_short    
rz9a024@hpclogin:~> 

Die so erzeugten Jobs 2491-* des qsub-Befehls (hier der ersten Zeile; s.o.) werden in Form eines Arrays behandelt. An die identische Array-Jobnummer (Prefix vor '-') wird jeweils ein Suffix zur Bezeichnung der (Sub-)Jobs innherhalb des Arrays angehängt. Zusätzlich steht nun innerhalb eines ausgeführten Batch-Skripts die Variable $PBS_ARRAYID zur Verfügung. Variieren kann man daher den Job mit folgender simplen Abfrage-Technik:

#!/bin/bash

#PBS -V .......

(...)

while :
  do
    [ $PBS_ARRAYID -eq 0 ] && {
      echo "won't execute!"; break;
        }
    [ $PBS_ARRAYID -eq 1 ] && {
      echo "this won't execute, too!"; break;
        }
    [ $PBS_ARRAYID -eq 3 ] && {
      echo "execute with different parameters!";
    $MPIRUN -n 8 --mca mpi_paffinity_alone 1 $EXEC $EXTRA_ARGs
    break;
        }
    # all others
    $MPIRUN -n 8 --mca mpi_paffinity_alone 1 $EXEC
    break
done

(...)

Serielle und non-MPI - Jobs (z.B. R)

Für serielle und non-MPI Berechnungen steht ihnen die Queue c1 zur Verfügung. Beispiel:

cat BATCHFILE | qsub -qc1 -l ncpus=1
oder auch:
cat BATCHFILE | qsub -qc1 -l ncpus=1 -t0,1,2,3
... um z.B. gleichzeitig 4 Instanzen des Programms auf jeweils einem Core laufen zu lassen (Stichwort: Job-Arrays, s.o.).


"Local Scratch" auf den Knoten

Wir möchten Sie darauf hinweisen, dass Sie ab sofort für Single-Node-Jobs oder auch Jobs, die mehrere Nodes allozieren und kein Shared-Filesystem benötigen, lokalen Scratch pro Knoten individuell anfordern können:

Dafür übergeben sie beim Start eines Jobs mit qsub die Variable: PBS_LOCAL_SCRATCH=1

Ein Beispiel:

qsub -qc8 -vPBS_LOCAL_SCRATCH=1 -lnodes=1:ppn=8 impi/run-mpiexec.sh

Das Ressource-System erkennt, dass die Variable gesetzt ist und triggert das passende Prestaging vor der eigentlichen Ausführung des Jobs (Einrichten des lokalen Scratch) sowie das passende Poststaging nach Beendigung (Aufräumen des lokalen Scratch und Sichern der Daten in ihr Homeverzeichnis).

Die Daten werden dann pro Node in ihr Homeverzeichnis zurück gesichert. Und zwar in das Verzeichnis mit der Job-ID und gefolgt von den Unterverzeichnissen der für den Job eingesetzten Nodes.

In Ihrem Batch geben sie als Arbeitsverzeichnis dann an /work/[Ihre Kennung], z.B. /work/ab0cc0. Springen Sie vor der Ausführung ihres eigentlichen Executable dorthin.

#/bin/bash

#PBS -V

(...)

WORKDIR=/work/$USER
cd WORKDIR

(...)

#run my exec here:
$EXEC

Autor: Alexander Fitterling, Stand: 03.09.2012 08:46 Uhr

 Impressum  Datenschutzerklärung