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 |