Turing

Login

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
    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 USERNAME@hpc
  

Datenhaltung

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
  

Software

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

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

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
  
IntelMPI

Ü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
  

Methoden der Parallelisierung

Shared Memory

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
  

Distributed Memory

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
  

Applications
  • MOM (Modular Ocean Model): In cooperation with PIK (Potsdam Institute for Climate Impact Research)
  • Simulation of seismic waves: In cooperation with the Institute for Geosciences, University Potsdam
  • Gadget: In cooperation with AIP (Astrophysical Institute Potsdam)
  • Cellular automaton: A Game-of-Life like application for experiments

Resource Manager Slurm

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.


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 RMS

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
  

GPU

Die Nodes node27-node30 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
  

Zwei Nodes mit je einer GPU vom Typ P4 anfordern:

  
  $ srun --nodes=2 --gres=gpu:1 --constraint="gpu,p4" hostname
  

Zwei GPU Nodes vom Typ P4 anfordern:

  
  $ srun --nodes=2 --constraint="gpu,p4" hostname
  

Parameter

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


Umgebungsvariablen

$SLURM_JOBID:Job-ID
$SLURM_SUBMIT_DIR:Verzeichnis aus dem der Job abgeschickt wurde
$SLURM_JOB_NODELIST:Liste der zugewiesenen Nodes

Hardware

Alle Nodes sind mit 2 CPUs vom Typ Intel Xeon E5-2650v4, 64 GB Hauptspeicher und einem FDR Infiniband Adapter (Mellanox MCX353A-FCBT) ausgestattet.


Service-Nodes

  • Dell PowerEdge R430

Storage-Nodes

  • Dell PowerEdge R430
  • Dell MD1400 mit 16 TB

Compute-Nodes: node1 - node26

  • Dell PowerEdge R430

GPU-Nodes: node27 - node30

  • Dell PowerEdge R730
  • NVIDIA P4

CPU: Intel Xeon E5-2650v4

  • Basistakt: 2.20GHz, Turbotakt: 2.90GHz, 12C/24T, L2-Cache: 3MB (12x 256kB), L3-Cache: 30MB, 9,6GT/s QPI
  • Vektoreinheit: AVX2

GPU: Nvidia P4, Pascal

  • SMs: 20
  • Cores/SM: 128
  • Cores/GPU: 2560
  • Memory Size: 8 GB
  • Compute Capability: 6.1

Infiniband Adapter: Mellanox MCX353A-FCBT

  • Link Speed: Fourteen Data Rate (FDR)
  • Signaling rate: 14 Gbit/s
  • Theoretical effective throughput: 13.5 Gbit/s
  • Speeds for 4x links: 54 Gbit/s

Interconnect: FDR Infiniband

  • Mellanox SX6025, FDR Infiniband, 1 HE, 36 QSFP+ Ports

Interconnect: Gigabit Ethernet

  • Dell PowerConnect 6248

Messungen

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
  

Datenschutzerklärung

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.

Benchmark-Nodes coll und tiree

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
    HostName coll.lab.cs.uni-potsdam.de
    IdentityFile ~/.ssh/SSH-KEY
    ProxyJump cs-login

  Host tiree
    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 USERNAME@coll
  

IT-Helpdesk

Bei technischen Problemen und Fragen zur Nutzung steht ein zentraler Helpdesk zur Verfügung:
helpdesk(at)cs.uni-potsdam.de