HPC
- Omni-Path Cluster bis 2021
- Single-chip Cloud Computer bis 2017
- Zuse Cluster bis 2017
- Leibniz Cluster bis 2011
- Highland Cluster bis 2009
- Einstein Cluster bis 2009
- Uranus Cluster bis 2006
- Ägäis Cluster bis 2003
Der Zugang zum Cluster erfolgt ausschließlich über den Login-Node:
$ ssh -l USER login.hpc.cs.uni-potsdam.de
Um auf den Login-Node von außen zuzugreifen, müssen sie SSH-Key's generieren und über die Accountverwaltung hochladen.
SSH-Key generieren:
$ ssh-keygen -t ecdsa -b 521
Über die Login-Node können sie sich folgendermaßen verbinden:
$ ssh -J USERNAME@login.cs.uni-potsdam.de USERNAME@HOST
Mit älteren SSH-Versionen können sie sich folgendermaßen verbinden:
$ ssh -o ProxyCommand="ssh -W %h:%p USERNAME@login.cs.uni-potsdam.de" USERNAME@HOST
Über die ~/.ssh/config können sie den Zugriff auf die Nodes vereinfachen. Bei den Zeilen musst USERNAME durch deinen eigentlichen Nutzernamen ersetzen und SSH-KEY mit dem erzeugten SSH-KEY.
Host cs-login
User USERNAME
Hostname login.cs.uni-potsdam.de
IdentityFile ~/.ssh/SSH-KEY
Host hpc
User USERNAME
HostName login.hpc.cs.uni-potsdam.de
IdentityFile ~/.ssh/SSH-KEY
ProxyJump cs-login
Host *
AddKeysToAgent yes
ForwardAgent yes
Nachdem sie die Konfiguration angepasst haben, können sie sich folgendermaßen verbinden:
$ ssh hpc
Die Home-Verzeichnisse werden über das parallele Dateisystem BeeGFS mit einer Kapazität von 34 TB auf allen Nodes im Cluster bereitgestellt. Die Anbindung erfolgt über Infiniband.
Mit folgenden Kommandos können Daten auf das Cluster kopiert werden:
$ scp file USER@login.hpc.cs.uni-potsdam.de:~/
$ rsync -av file USER@login.hpc.cs.uni-potsdam.de:~/
Die Nutzung der Disk-Quotas kann man sich mit folgendem Kommando anzeigen lassen:
$ /usr/sbin/beegfs-ctl --getquota --uid USER
Auf allen Cluster-Nodes ist Debian 10 als Betriebssystem installiert.
Environment Modules ist ein Hilfsmittel zur Verwaltung von Umgebungsvariablen der Shell. Typischerweise werden Variablen, die Suchpfade enthalten, erweitert oder verkürzt (PATH, MANPATH, etc.). Durch Erweiterungen der Suchpfade wird Software aufrufbar gemacht.
Verfügbare Module anzeigen:
$ module avail
Geladenen Module anzeigen:
$ module list
Modul laden:
$ module load program[/version]
Modul wechseln (z.B. Compiler-Version):
$ module switch program program/version
Modul entladen:
$ module unload program
Alle Module entladen:
$ module purge
Sollen Module automatisch beim Login geladen werden, müssen diese z.B. in die ~/.bashrc eingetragen werden:
# load modulefile into the shell environment
module load program[/version]
MPICH verwenden die PMI2-API. Jobs können folgendermaßen gestartet werden:
$ salloc -N 2 -n 2 --tasks-per-node 1 srun ./hello_world_mpi
$ srun -N 2 -n 2 --tasks-per-node=1 ./hello_world_mpi
$ sbatch <job_script>
Einfaches Batch-Skript:
#!/bin/bash
# Do not forget to select a proper partition if
# the default one is no fit for the job!
#SBATCH --output=results/out.%j
#SBATCH --error=results/err.%j
#SBATCH --nodes=2 # number of nodes
#SBATCH --ntasks=2 # number of processor cores (i.e. tasks)
#SBATCH --tasks-per-node=1 # number of tasks per node
#SBATCH --exclusive
#SBATCH --time=00:10:00 # walltime
# Good Idea to stop operation on first error.
set -e
# Load environment modules for your application here.
source /etc/profile.d/modules.sh
module load mpich
# Actual work starting here.
srun ./hello_world_mpi
OpenMPI verwenden die PMI2-API. Jobs können folgendermaßen gestartet werden:
$ salloc -N 2 -n 2 --tasks-per-node 1 srun ./hello_world_mpi
$ srun -N 2 -n 2 --tasks-per-node=1 ./hello_world_mpi
$ sbatch <job_script>
Einfaches Batch-Skript:
#!/bin/bash
# Do not forget to select a proper partition if
# the default one is no fit for the job!
#SBATCH --output=results/out.%j
#SBATCH --error=results/err.%j
#SBATCH --nodes=2 # number of nodes
#SBATCH --ntasks=2 # number of processor cores (i.e. tasks)
#SBATCH --tasks-per-node=1 # number of tasks per node
#SBATCH --exclusive
#SBATCH --time=00:10:00 # walltime
# Good Idea to stop operation on first error.
set -e
# Load environment modules for your application here.
source /etc/profile.d/modules.sh
module load openmpi
# Actual work starting here.
srun ./hello_world_mpi
Über die Umgeungsvariable FI_PROVIDER kann die Kommunikationsschnittstelle ausgewählt werden. Z.B. kann die in der ~/.bashrc gesetzt werden.
# IntelMPI
export FI_PROVIDER=verbs,tcp
IntelMPI verwenden die PMI2-API. Jobs können folgendermaßen gestartet werden:
$ salloc -N 2 -n 2 --tasks-per-node=1 srun ./hello_world_mpi
$ srun -N 2 -n 2 --tasks-per-node=1 ./hello_world_mpi
$ sbatch <job_script>
Einfaches Batch-Skript:
#!/bin/bash
# Do not forget to select a proper partition if
# the default one is no fit for the job!
#SBATCH --output=results/out.%j
#SBATCH --error=results/err.%j
#SBATCH --nodes=2 # number of nodes
#SBATCH --ntasks=2 # number of processor cores (i.e. tasks)
#SBATCH --tasks-per-node=1 # number of tasks per node
#SBATCH --exclusive
#SBATCH --time=00:10:00 # walltime
# Good Idea to stop operation on first error.
set -e
# Load environment modules for your application here.
source /etc/profile.d/modules.sh
module load mpi
# Actual work starting here.
srun ./hello_world_mpi
Für `Shared Memory` Programmierung, auf Multiprozessor-Systemen, hat sich OpenMP als de facto Standart etabiliert. OpenMP ist eine Spracherweiterung und Bibliothek für die Sprachen C, C++ und FORTRAN. Die Parallelisierung mittels OpenMP findet auf Thread-, bzw. Schleifenebene statt. Im OpenMP-Standard sind dafür spezielle Compiler-Direktiven definiert worden. Mit Hilfe dieser kann z. B. eine for-Schleife auf mehrere Threads und/oder Prozessoren aufgeteilt werden. Compiler die mit OpenMP nicht umgehen können interpretieren diese Anweisungen als Kommentare oder ignorieren sie einfach.
Die auf dem Cluster installierten Compiler unterstützen OpenMP. Um OpenMP zu nutzen muss beim GNU-Compiler (gcc)
die Compile-Option -fopenmp
gesetzt werden.
Einfaches Beispiel:
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int id,i;
#pragma omp parallel for private(id) /* OpenMP Pragma */
for (i = 0; i < 8; ++i)
{
id = omp_get_thread_num();
printf("Hello World from thread %d\n", id);
if (id == 0)
printf("There are %d threads\n", omp_get_num_threads());
}
return 0;
}
Mit folgendem Aufruf wird das Programm compiliert:
$ gcc -Wall -fopenmp -o hello_world_omp hello_world_omp.c
Mit folgendem Aufruf wird das Programm gestartet:
$ OMP_NUM_THREADS=4 ./hello_world_omp
Für `Distributed Memory` Programmierung gilt MPI (Message Passing Interface) als Standard. Ein Programm welches mit MPI parallelisiert wurde, besteht aus miteinander kommunizierenden Prozessen, die bei der Programmausführung parallel gestartet werden. Für den Datenaustausch werden Nachrichten verwendet. MPI selbst beschreibt lediglich den Nachrichtenaustausch auf verteilten Computersystemen, es wird eine Programmierschnittstelle bereitgestellt aber keine Implementierung. Diese werden durch Dritte als freie (quelloffene) oder kommerzielle Implementierung bereitgestellt.
Auf dem Cluster wurden MPICH, OpenMPI, MVAPICH und IntelMPI installiert.
Einfaches Beispiel:
#include <mpi.h>
#include <stdio.h>
int main(int argc, char** argv) {
// Initialize the MPI environment.
MPI_Init(NULL, NULL);
// Get the number of processes
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
// Get the rank of the process
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
// Get the name of the processor
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// Print off a hello world message
printf("Hello world from processor %s, rank %d out of %d processors\n",
processor_name, world_rank, world_size);
// Finalize the MPI environment. No more MPI calls can be made after this
MPI_Finalize();
}
Mit folgendem Aufruf wird das Programm compiliert:
$ mpicc -o hello_world_mpi hello_world_mpi.c
Mit folgendem Aufruf wird das Programm gestartet:
$ mpirun -np 4 -hostfile NODEFILE ./hello_world_mpi
Die Ressourcen eines Clusters werden von einer zentralen Instanz, dem RMS (Resource Management System), verwaltet. Auf dem Turing-Cluster wurde Slurm als Resource Manager ausgewählt.
Auf dem Cluster gibt es mehrere Partitionen, wobei die Partition short die Default-Partition ist. Dort ist die Laufzeit auf 30 Minuten und die Anzahl der Nodes auf 4 limitiert. Für alle Partitionen gilt ein Limit von 100 Jobs die im Status Pending oder Running sein können.
Im folgenden sind die wichtigsten Elemente von Slurm aufgeführt. Die vollständige Dokumentation ist unter http://slurm.schedmd.com/documentation.html zu finden.
Job abschicken:
$ sbatch <job_script>
Interaktiv arbeiten:
$ salloc [options]
Informationen zu den Partitionen und Nodes auflisten:
$ sinfo -l
Status aller Jobs anzeigen:
$ squeue
Alle eigenen Jobs anzeigen:
$ squeue -u USER
Status eines Jobs anzeigen:
$ squeue -j <job_id>
Zu erwartende Startzeit eines Jobs anzeigen:
$ squeue --start -j <job_id>
Job löschen oder abbrechen:
$ scancel <job_id>
Interaktives Arbeiten unter Kontrolle des Batch-Systems wird insbesondere bei der Entwicklung und Portierung paralleler Programme benötigt. Unter Slurm erfolgt die Zuweisung über das Kommando salloc. Der Kontrollprozess selbst bleibt auf dem Node, von dem aus salloc aufgerufen wurde.
Mit folgendem Aufruf bekommt man N Nodes zugewiesen:
$ salloc --nodes=N
Ein MPI-Programm kann man wie gewohnt aufrufen:
$ srun ./hello_world_mpi
Ein OpenMP-Programm wird durch das Kommando srun auf dem zugewiesenen Node zur Ausführung gebracht:
$ export OMP_NUM_THREADS=N
$ srun ./hello_world_mpi
Im Node, hpc-node27, ist eine Tesla A2 GPU verbaut und die Nodes hpc-node28-30 sind mit je zwei Tesla P4 GPUs ausgestattet. Über die Parameter --gres und --constraint können die GPUs vom Batch-Systems angefordert werden.
Ein Node mit einer GPU anfordern:
$ srun --nodes=1 --gres=gpu:1 hostname
Ein Node mit zwei GPUs anfordern:
$ srun --nodes=1 --gres=gpu:2 hostname
Einen Node mit einer GPU vom Typ P4 anfordern:
$ srun --nodes=1 --gres=gpu:1 --constraint="gpu,p4" hostname
Einen Node mit einer GPU vom Typ A2 anfordern:
$ srun --nodes=1 --gres=gpu:1 --constraint="gpu,a2" hostname
Job-Name:--job-name=name
Stdout-Datei:--output=name
Stderr-Datei:--error=name
Partition:--partition=name
Anzahl der Nodes:--nodes=n
Anzahl der Cores:--ntasks=n
Prozesse pro Node:--tasks-per-node=n
GPUs pro Node:--gres=gpu:n
Nodes nicht teilen:--exclusive
Zeitlimit:--time=minutes, --time=hh:mm:ss
Email-Adresse:--mail-user=address
Email-Benachrichtigung:--mail-type=BEGIN, --mail-type=END, --mail-type=FAIL, --mail-type=ALL
$SLURM_JOBID:Job-ID
$SLURM_SUBMIT_DIR:Verzeichnis aus dem der Job abgeschickt wurde
$SLURM_JOB_NODELIST:Liste der zugewiesenen Nodes
Alle Nodes sind mit 2 CPUs vom Typ Intel Xeon E5-2650v4, PCIe Gen3 x16, 64 GB Hauptspeicher und einem FDR Infiniband Adapter (Mellanox MCX353A-FCBT) ausgestattet.
Service-Nodes
Storage-Nodes
Compute-Nodes: node1 - node26
GPU-Nodes: node27 - node30
CPU: Intel Xeon E5-2650v4
GPU: Nvidia A2, Ampere
Infiniband Adapter: Mellanox MCX353A-FCBT
Interconnect: FDR Infiniband
Interconnect: Gigabit Ethernet
Netzwerk: Ethernet
$ iperf3 -s -A 2
$ iperf3 -c <IP> -f M -t 12 -O 2
[ ID] Interval Transfer Bandwidth
[ 5] 0.00-12.00 sec 1.38 GBytes 118 MBytes/sec receiver
Netzwerk: Infiniband IPoIB
$ iperf3 -s -A 2
$ iperf3 -c <IP> -f M -t 12 -O 2
[ ID] Interval Transfer Bandwidth
[ 5] 0.00-12.00 sec 31.9 GBytes 2720 MBytes/sec receiver
Netzwerk: Infiniband RDMA
$ ib_read_bw -F
$ ib_read_bw <IP> -F
#bytes #iterations BW peak[MB/sec] BW average[MB/sec] MsgRate[Mpps]
65536 1000 6163.42 6163.28 0.097012
$ ib_write_bw -F
$ ib_write_bw <IP> -F
#bytes #iterations BW peak[MB/sec] BW average[MB/sec] MsgRate[Mpps]
1048576 5000 6105.46 6105.38 0.006105
I/O: MD1400
$ dd if=/dev/zero of=/mnt/beegfs/storage/benchmark bs=1G count=10 oflag=direct
10737418240 bytes (11 GB, 10 GiB) copied, 10.9005 s, 985 MB/s
I/O: gemountetes BeeGFS Filesystem
$ dd if=/dev/zero of=/mnt/beegfs/client/benchmark bs=1G count=10 oflag=direct
10737418240 bytes (11 GB, 10 GiB) copied, 6.4314 s, 1.7 GB/s
Bei jedem Zugriff auf das Cluster werden zum Zwecke der Betriebs- und Datensicherheit sowie zu statistischen Zwecken die Login- und Jobdaten gespeichert.
Eine Auflistung aller gespeicherten Jobdaten kann in der Dokumentation des Batch-Systems eingesehen werden.
Die Daten werden maximal 4 Wochen gespeichert. Eine Zusammenführung mit anderen Datenbeständen erfolgt nicht.
Das RoCE-Cluster ist ein hybrider Parallelrechner, welcher aus sechs Nodes besteht.
Die Nodes sind sowohl über Gigabit Ethernet als auch über RoCE: RDMA over Converged Ethernet miteinander verbunden. Wobei Gigabit Ethernet als Management-Netzwerk und RoCE als Hochgeschwindigkeits-Netzwerk fungiert. Da die Nodes direkt über den RoCE-Switch miteinander verbunden sind, kann die Kommunikation zwischen den Nodes ohne zusätzliche Hops stattfinden.
Auf allen Cluster-Nodes ist Debian 12 als Betriebssystem installiert.
Compute-Nodes: fips1 - fips2
Compute-Nodes: fips3 - fips4
Compute-Nodes: naaice1 - naaice2
Der Intel Core i9-12900 ist eine High-End-CPU auf Basis der neuen Alder-Lake-Architektur, die im Januar 2022 vorgestellt wurde. Der Basistakt beträgt 2,4 GHz und kann bei optimalen Bedingungen bis zu 5,1 GHz erreichen. Die insgesamt 24 Threads unterteilen sich in P-Cores und E-Cores, die mit der neuen Alder-Lake-Architektur Einzug halten. Dabei bieten die 8 Performance-Kerne (P-Cores) zudem Hyperthreading. Die 8 energieeffizienten E-Cores können auf dieses Feature nicht zurückgreifen.
Das Omni-Path-Cluster ist ein hybrider Parallelrechner, welcher aus acht Nodes besteht.
Die Nodes sind sowohl über Gigabit Ethernet als auch über Omni-Path miteinander verbunden. Wobei Gigabit Ethernet als Management-Netzwerk und Omni-Path als Hochgeschwindigkeits-Netzwerk fungiert. Da die Nodes direkt über den Omni-Path-Switch miteinander verbunden sind, kann die Kommunikation zwischen den Nodes ohne zusätzliche Hops stattfinden.
Auf allen Cluster-Nodes ist Debian 9 als Betriebssystem installiert.
Alle Nodes sind mit einer CPU vom Typ Intel Core i7-8700, 32 GB Arbeitsspeicher und einem Omni-Path Adapter (Intel 100HFA016LS) ausgestattet.
Compute-Nodes: bsnode1 - bsnode8
CPU: Intel Core i7-8700
Omni-Path Adapter: Intel 100HFA016LS
Interconnect: Omni-Path
Interconnect: Gigabit Ethernet
Der Single-Chip Cloud Computer (SCC) ist ein experimenteller Prozessor mit 48 Kernen, den Intel als Plattform für die Many-Core-Software-Forschung entwickelte.
Der SCC besteht aus 48 Kernen, die fast identisch zu Pentium 5 Prozessoren sind. Verbunden sind die Prozessoren über ein Hochgeschwindigkeitsnetzwerk und vier DDR-3 Speicherkanäle.
Die Verbindung der Kerne wird durch ein 4 x 6 Gitter NoC (Network on Chip) realisiert.
Der SCC hat spezielle Hardware-Unterstützung für Message Passing und Energiemanagement.
Intel hat, zur Inter-Core-Kommunikation, eine angepasste Message Passing Interface Implementierung (MPI) genannt RCKMPI bereitgestellt.
Die 48 Kerne der SCC-Plattform laufen unter eine spezielle Linux Distribution, die die RCCE Bibliothek für die Inter-Core-Kommunikation nutzt. Auf jedem Core läuft eine separate Instanz der angepassten Linux Distribution. So kann der SCC als eine verteilte Plattform, mit separaten Kerneln auf jedem Prozessor betrachtet werden. Die Interaktion zwischen den Cores ist exklusiv durch Message Passing realisiert.
Um auf die Benchmark-Nodes coll.lab.cs.uni-potsdam.de und tiree.lab.cs.uni-potsdam.de von außen zuzugreifen, müssen sie SSH-Key's generieren und über die Accountverwaltung hochladen.
SSH-Key generieren:
$ ssh-keygen -t ecdsa -b 521
Über die Loginknoten können sie sich folgendermaßen verbinden:
$ ssh -J USERNAME@login.cs.uni-potsdam.de USERNAME@HOST
Mit älteren SSH-Versionen können sie sich folgendermaßen verbinden:
$ ssh -o ProxyCommand="ssh -W %h:%p USERNAME@login.cs.uni-potsdam.de" USERNAME@HOST
Über die ~/.ssh/config können sie den Zugriff auf die Nodes vereinfachen. Bei den Zeilen musst USERNAME durch deinen eigentlichen Nutzernamen ersetzen und SSH-KEY mit dem erzeugten SSH-KEY.
Host cs-login
User USERNAME
Hostname login.cs.uni-potsdam.de
IdentityFile ~/.ssh/SSH-KEY
Host coll
User USERNAME
HostName coll.lab.cs.uni-potsdam.de
IdentityFile ~/.ssh/SSH-KEY
ProxyJump cs-login
Host tiree
User USERNAME
HostName tiree.lab.cs.uni-potsdam.de
IdentityFile ~/.ssh/SSH-KEY
ProxyJump cs-login
Host *
AddKeysToAgent yes
ForwardAgent yes
Im aktuellen Windows 10 ist ein OpenSSH-Client fest in das System integriert. Über die Eingabeaufforderung oder die Windows PowerShell kann auf den Client zugegriffen werden.
Host coll
HostName coll.lab.cs.uni-potsdam.de
ProxyCommand C:\Windows\System32\OpenSSH\ssh.exe -q -W %h:%p USERNAME@login.cs.uni-potsdam.de
Host tiree
HostName tiree.lab.cs.uni-potsdam.de
ProxyCommand C:\Windows\System32\OpenSSH\ssh.exe -q -W %h:%p USERNAME@login.cs.uni-potsdam.de
Nachdem sie die Konfiguration angepasst haben, können sie sich folgendermaßen verbinden:
$ ssh coll
Nodes | Users |
---|---|
bsnode1 | |
bsnode2 | |
bsnode3 | Philipp S. |
bsnode4 | Stoll |
bsnode5 | Körner |
bsnode6 | |
bsnode7 | IoT-Monitoring |
bsnode8 | |
fips1 | Max S. |
fips2 | Max S. |
fips3 | Max S. |
fips4 | Max S. |
naaice1 | Lea, Hannes Signer, Perfacct |
naaice2 | Lea, Hannes Signer, Perfacct |
Bei technischen Problemen und Fragen zur Nutzung steht ein zentraler Helpdesk zur Verfügung:
helpdesk(at)cs.uni-potsdam.de