..
Suche
Hinweise zum Einsatz der Google Suche
Personensuchezur unisono Personensuche
Veranstaltungssuchezur unisono Veranstaltungssuche
Katalog plus

MPI (Message Passing Interface)

Einleitung:

Message Passing Interface Progrmmier Model: Verteilter Speicher. Prozesse kommunizieren über Nachrichten. SPMD: Sequenzielles Programm, und Daten Partitionierung

 

Benutzung:

Aufruf:

Ein MPI Programm kann mit dem Befehl mpiexec aufgerufen werden.

Beispiel:

$ mpiexec -n 3 myProgramm arg1 arg2   

SLURM:

Um ein MPI Programm mit SLURM zu starten benutzt man den Befehl srun.

Beispiel:

$ surn -N 3 myProgramm   

 

Option
Funktion

--partition, -p

Definiert die Partition auf welcher der Job laufen soll. Wenn dies nicht angegeben wird, wird defq verwendet.


--nodes, -N


Definiert die Anzahl der Knoten, auf denen der Job laufen soll.


--ntasks, -n


Definiert die Anzahl der Tasks für den Job.


--ntasks-per-node


Definiert die maximale Anzahl der Tasks pro Knoten. Wird in der Regel mit MPI Programmen benutzt.


--cpus-per-task


Definiert die Anzahl der Rechenkerne pro Task. In der Regel bei Verwendung von OpenMP wichtig.


--mem


Definiert das Arbeitsspeicher-Limit pro Knoten. Der Job wird abgebrochen, sollte das Limit überschritten werden. Der Zahlenwert ist in Megabyte.


--time, -t


Definiert das Zeitlimit des Jobs. Wird das Limit überschritten, wird der Job abgebrochen. Format: D-HH:MM:SS


--output=<Dateiname>


Beim sbatch-Befehl spezifiziert dies die Log-Datei in welcher der stdout-Stream geleitet wird. Standardmäßig wird im Ordner, in dem sbatch ausgeführt wurde, eine Datei namens slurm-<JobID>.out angelegt.


--error=<Dateiname>


Beim sbatch-Befehl spezifiziert dies die Log-Datei, in die der stdout-Stream geleitet wird. Standardmäßig wird im Ordner, in dem sbatch ausgeführt wurde, eine Datei namens slurm-<JobID>.out angelegt.


--mail-type


Spezifiziert die Ereignisse, bei denen eine E-Mail an die mit --mail-user spezifizierte Adresse versendet werden soll. Mögliche Angaben sind BEGIN, END, FAIL, REQUEUE, ALL.


--mail-user=<Adresse>


Spezifiziert den Empfänger der E-mail.


 

Man kann ein MPI Programm auch über ein Bash-Script starten. Dazu wird der Befehl sbatch verwendet.

Beispiel:

$ sbatch beispiel.sh   

Im Bash-Script lassen sich die SLURM Parameter über #SBATCH setzten.

Beispiel Scrpit:


#!/bin/bash
#SBATCH –time=0:20:00
#SBATCH –nodes=3
#SBATCH –tasks-per-node=1
#SBATCH --mem 48000
#SBATCH –partition=short
module load openmpi/gcc/64/2.1.2

echo "Number of tasks: " echo $SLURM_NTASKS

mpirun -np $SLURM_NTASKS ~/myProgramm

# Alternativ geht im Scrpit auch:
# srun -N 3 ~/myProgramm

Programmierung:

Benutzte Librarry:

#include <mpi.h>   

MPI-1.2 hat 129 Routinen (und MPI-2 hat sogar noch mehr ...)

  • Oft reichen schon 6 Routinen um ein MPI Programm zu schreiben:
  • MPI_Init – MPI initialisieren
  • MPI_Finalize – MPI aufräumen
  • MPI_Comm_size – Gibt die Anzahl der Prozesse zurück
  • MPI_Comm_rank – Gibt die eigene Prozessnummer zurück
  • MPI_Send – Sende einen Nachricht
  • MPI_Recv – Empfange eine Nachricht

MPI initialisieren und beenden:

Definition: MPI_Init

Jeder MPI Prozess muss MPI_Init aufrufen, bevor er andere MPI Routinen nutzen kann.

int MPI_Init(int *argc, char ***argv)
INOUT
 argc  Pointer to argc of main()
INOUT
 argv  Pointer to argv of main()
Result    
 MPI_SUCCESS or error code

Definition: MPI_Finalize

Jeder MPI Prozess muss am ende MPI_Finalize aufrufen. MPI_Finalize dient dem freigeben von Ressourcen. Danach dürfen keine weiteren MPI Routinen mehr benutzt werden.

Achtung MPI_Finalize Terminiert nicht den Prozess.

int MPI_Finalize

Result

MPI_SUCCESS or error code

 

Beispiel:


int main(int argc, char **argv){
        MPI_Init(&argc, &argv);         //Aufruf von MPI_Init mit Übergabe der Kommandozeilen Parameter.                                        

        …                                //In diesem Abschnitt können MPI Routinen aufgerufen werden.                                            
                                         
        MPI_Finalize;                   //Deallokieren der Ressourcen.
}

 

Definition MPI_Comm_Size:

Gibt die Anzahl der Prozesse zurück.

int MPI_Comm_size(MPI_Comm comm, int *size)

In

comm

Communicator

OUT

size

Number of processes in comm

 

Beispiel:


MPI_Comm_size(MPI_COMM_WORLD, &nprocs)  //gibt die Anzahl an MPI Prozessen in nprocs zurück

 

Definition MPI_Comm_rank:

Gitb die Prozessnummer zurück. Die Prozessnummernirrung startet bei 0 und zählt aufwerts.

int int MPI_Comm_rank(MPI_Comm comm, int *rank)

In

comm

Communicator

OUT

rank

Number of processes in comm

 

Zu Kommunikatoren:

Kommunikatoren sind Gruppen von Prozessen. In der vordefinierten Gruppe MIP_COMM_WORLD sind alle Prozesse der parallelen Anwendung enthalten. Neue Kommunikatoren könne bei bedarf erzeugt werden. (dazu später mehr).

 

Definition MPI_Get_processor_name:

Gibt den Namen des Knotens sowie die Länge des Namens als Integer an.

int int MPI_Get_processor(char *name, int *resultlen)

OUT

name

A unique specifiert for the physical node

OUT

resultlen

Length of name must be array of length [MPI_MAX_PROCESSOR_NAME]

 

Senden und empfangen mit MPI_Send und MPI_Recv:

MPI_Send und MPI_Recv sind beides blockierende Operationen d.h. der Prozess wartet bis die Nachricht komplett von dem Sendepuffer gelesen wurde bzw. komplett in den Empfangspuffer geschrieben wurde.

 

Definition MPI_Send:

int MPI_Send(void *buf, int count, MPI_Datatype dtype, int dest, int tag, MPI_Comm comm)

IN

buf

(Pointer to) the data to be sent (send buffer)

IN

count

Number of data elements (of type dtype )

IN

dtype

Data type of the individual data elements

IN

dest

Rank of destination process in communicator comm

IN

tag

Message tag

IN

comm

Communicator

 

Definition MPI_Recv:

int MPI_Recv(void *buf, int count, MPI_Datatype dtype, int source, int tag, MPI_Comm comm, MPI_Status *status)

OUT

buf

(Pointer to) receive buffer

IN

count

Buffer size (number of data elements of type dtype)

IN

dtype

Data type of the individual data elements

IN

source

Rank of source process in communicator comm

IN

tag

Message tag

IN

comm

Communicator

OUT

status

Status (among others: actual message length)

 

Damit ein Prozess einen Nachricht empfangen kann müssen sowohl der Parameter Tag als auch der Kommunikator bei Sender und Empfänger übereinstimmen. Des weiteren muss der Parameter Source beim Empfänger mit dem Parameter Dest des Sender übereinstimmen. Für Tag und Sender können auch folgende wild-cards verwendet werden:

MPI_ANY_SOURCE
MPI_ANY_TAG

Des weiteren darf die Nachricht nicht größer sein als die angegeben Puffergröße sein.

 

MPI Datentypen:

MPI Datentypen sind:

MPI

C

MPI_CHAR

char

MPI_SHORT

short

MPI_INT

int

MPI_LONG

long

MPI_FLOAT

float

MPI_DOUBLE

double

MPI_BYTE

Byte with 8 bits

MPI_UNSIGNED_CHAR

unsigned char

MPI_UNSIGNED_SHORT

unsigned short

MPI_UNSIGNED

unsigned int

MPI_UNSIGNED_LONG

unsigned long

MPI_LONG_DOUBLE

long double

MPI_PACKED

Packed Data