📚 The CoCalc Library - books, templates and other resources
License: OTHER
%!TEX root = Programmierparadigmen.tex1\chapter{MPI}2\index{MPI|(}34Message Passing Interface (kurz: MPI) ist ein Standard,5der den Nachrichtenaustausch bei parallelen Berechnungen auf6verteilten Computersystemen beschreibt.78Prozesse kommunizieren in MPI über sog. \textit{Kommunikatoren}. Ein Kommunikator9(\texttt{MPI\_Comm}\xindex{MPI\_Comm@\texttt{MPI\_Comm}})10definiert eine Menge an Prozessen, die miteinander kommunizieren können. In dieser11Prozessgruppe hat jeder Prozess einen eindeutigen \textit{rank}\xindex{rank} über den die Prozesse12sich identifizieren können.1314\section{Erste Schritte}15\inputminted[numbersep=5pt, tabsize=4, frame=lines, label=hello-world.c]{c}{scripts/mpi/hello-world.c}1617Das wird \texttt{mpicc hello-world.c} kompiliert.\\18Mit \texttt{mpirun -np 14 scripts/mpi/a.out} werden 14 Kopien des Programms19gestartet.2021Hierbei ist \texttt{MPI\_COMM\_WORLD}\xindex{MPI\_COMM\_WORLD@\texttt{MPI\_COMM\_WORLD}} der Standard-Kommunikator,22der von \texttt{MPI\_Init} erstellt wird.2324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%25\section{MPI Datatypes}\label{sec:MPI-Datatypes}\xindex{MPI datatypes}%2627\begin{table}[h]28\begin{tabular}{|l|l||p{3.2cm}|l|}29\hline30\textbf{MPI datatype} & \textbf{C datatype} & \textbf{MPI datatype} & \textbf{C datatype} \\ \hline31MPI\_INT & signed int & MPI\_FLOAT & float \\32MPI\_UNSIGNED & unsigned int & MPI\_DOUBLE & double \\33MPI\_CHAR & signed char & MPI\_UNSIGNED\newline{}\_CHAR & unsigned char \\ \hline34\end{tabular}35\end{table}3637\section{Funktionen}38\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-size.c}\xindex{MPI\_Comm\_size@\texttt{MPI\_Comm\_size}}%39Liefert die Größe des angegebenen Kommunikators; dh. die Anzahl der Prozesse in der Gruppe.4041\textbf{Parameter}42\begin{itemize}43\item \textbf{comm}: Kommunikator (handle)44\item \textbf{size}: Anzahl der Prozesse in der Gruppe von \texttt{comm}45\end{itemize}4647\textbf{Beispiel}48\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-size-example.c}49%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%50\goodbreak51\rule{\textwidth}{0.4pt}\xindex{MPI\_Comm\_rank@\texttt{MPI\_Comm\_rank}}%52\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-rank.c}53Bestimmt den Rang des rufenden Prozesses innerhalb des Kommunikators.5455Der Rang wird von MPI zum Identifizieren eines Prozesses verwendet. Die Rangnummer ist innerhalb eines Kommunikators eindeutig. Dabei wird stets von Null beginnend durchnumeriert. Sender und Empfänger bei Sendeoperationen oder die Wurzel bei kollektiven Operationen werden immer mittels Rang angegeben.5657\textbf{Parameter}58\begin{itemize}59\item \textbf{comm}: Kommunikator (handle)60\item \textbf{rank}: Rang des rufenden Prozesses innerhalb von \texttt{comm}61\end{itemize}6263\textbf{Beispiel}64\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-rank-example.c}65%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%66\goodbreak67\rule{\textwidth}{0.4pt}\xindex{MPI\_Send@\texttt{MPI\_Send}}%68\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-send.c}69Senden einer Nachricht an einen anderen Prozeß innerhalb eines Kommunikators. (Standard-Send)7071\textbf{Parameter}72\begin{itemize}73\item \textbf{buf}: Anfangsadresse des Sendepuffers74\item \textbf{count}: Anzahl der Elemente des Sendepuffers (nichtnegativ)75\item \textbf{datatype}: Typ der Elemente des Sendepuffers (handle) (vgl. \cpageref{sec:MPI-Datatypes})76\item \textbf{dest}: Rang des Empfängerprozesses in comm (integer)77\item \textbf{tag}: message tag zur Unterscheidung verschiedener Nachrichten;78Ein Kommunikationsvorgang wird durch ein Tripel (Sender, Empfänger, tag) eindeutig beschrieben.79\item \textbf{comm}: Kommunikator (handle)80\end{itemize}8182\textbf{Beispiel}83\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-send-example.c}84%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%85\goodbreak86\rule{\textwidth}{0.4pt}\xindex{MPI\_Recv@\texttt{MPI\_Recv}}%87\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-receive.c}88Empfangen einer Nachricht (blockierend)8990\textbf{Parameter}91\begin{itemize}92\item \textbf{buf}: Anfangsadresse des Empfangspuffers93\item \textbf{count}: Anzahl (d.~h. $\geq 0$) der Elemente im Empfangspuffer94\item \textbf{datatype}: Typ der zu empfangenden Elemente (handle) (vgl. \cpageref{sec:MPI-Datatypes})95\item \textbf{source}: Rang des Senderprozesses in comm oder \texttt{MPI\_ANY\_SOURCE}96\item \textbf{tag}: message tag zur Unterscheidung verschiedener Nachrichten97Ein Kommunikationsvorgang wird durch ein Tripel (Sender, Empfänger, tag) eindeutig beschrieben. Um Nachrichten mit beliebigen tags zu empfangen, benutzt man die Konstante \texttt{MPI\_ANY\_TAG}.98\item \textbf{comm}: Kommunikator (handle)99\item \textbf{status}: Status, welcher source und tag angibt (\texttt{MPI\_Status}).100Soll dieser Status ignoriert werden, kann \texttt{MPI\_STATUS\_IGNORE}\xindex{MPI\_STATUS\_IGNORE@\texttt{MPI\_STATUS\_IGNORE}} angegeben werden.101\end{itemize}102103\textbf{Beispiel}104\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-receive-example.c}105%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%106\goodbreak107\rule{\textwidth}{0.4pt}\xindex{MPI\_Reduce@\texttt{MPI\_Reduce}}%108\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-reduce.c}109Führt eine globale Operation \textbf{op} aus; der Prozeß \enquote{root} erhält das Resultat.110111\textbf{Input-Parameter}112\begin{itemize}113\item \textbf{sendbuf}: Startadresse des Sendepuffers114\item \textbf{count}: Anzahl der Elemente im Sendepuffer115\item \textbf{datatype}: Typ der Elemente von \texttt{sendbuf} (vgl. \cpageref{sec:MPI-Datatypes})116\item \textbf{op}: auszuführende Operation (handle)117\item \textbf{root}: Rang des Root-Prozesses in comm, der das Ergebnis haben soll118\item \textbf{comm}: Kommunikator (handle)119\end{itemize}120121\textbf{Output-Parameter}122\begin{itemize}123\item \textbf{recvbuf}: Adresse des Puffers, in den das Ergebnis abgelegt wird (nur für \texttt{root} signifikant)124\end{itemize}125%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%126\goodbreak127\rule{\textwidth}{0.4pt}\xindex{MPI\_Alltoall@\texttt{MPI\_Alltoall}}%128\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-alltoall.c}129Teilt Daten von jedem Prozeß einer Gruppe an alle anderen auf.130131\textbf{Input-Parameter}132\begin{itemize}133\item \textbf{sendbuf}: Startadresse des Sendepuffers134\item \textbf{sendcount}: Anzahl der Elemente im Sendepuffer135\item \textbf{sendtype}: Typ der Elemente des Sendepuffers (handle) (vgl. \cpageref{sec:MPI-Datatypes})136\item \textbf{recvcount}: Anzahl der Elemente, die von jedem einzelnen Prozeß empfangen werden137\item \textbf{recvtype}: Typ der Elemente im Empfangspuffer (handle) (vgl. \cpageref{sec:MPI-Datatypes})138\item \textbf{comm}: Kommunikator (handle)139\end{itemize}140141\textbf{Output-Parameter}142\begin{itemize}143\item \textbf{recvbuf}: Anfangsadresse des Empfangspuffers144\end{itemize}145146\textbf{Beispiel}147\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-alltoall-example.c}148%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%149\goodbreak150\rule{\textwidth}{0.4pt}\xindex{MPI\_Bcast@\texttt{MPI\_Bcast}}%151\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-bcast.c}152Sendet eine Nachricht vom Prozess \texttt{root} an alle anderen Prozesse des153angegebenen Kommunikators.154155\textbf{Parameter}156\begin{itemize}157\item \textbf{buffer}: Startadresse des Datenpuffers158\item \textbf{count}: Anzahl der Elemente im Puffer159\item \textbf{datatype}: Typ der Pufferelemente (handle) (vgl. \cpageref{sec:MPI-Datatypes})160\item \textbf{root}: Wurzelprozeß; der, welcher sendet161\item \textbf{comm}: Kommunikator (handle)162\end{itemize}163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%164\goodbreak165\rule{\textwidth}{0.4pt}\xindex{MPI\_Scatter@\texttt{MPI\_Scatter}}%166\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-scatter.c}167Verteilt Daten vom Prozess \texttt{root} unter alle anderen Prozesse in der Gruppe, so daß, soweit möglich, alle Prozesse gleich große Anteile erhalten.168169\textbf{Input-Parameter}170\begin{itemize}171\item \textbf{sendbuf}: Anfangsadresse des Sendepuffers (Wert ist lediglich für \texttt{root} signifikant)172\item \textbf{sendcount}: Anzahl der Elemente, die jeder Prozeß geschickt bekommen soll (integer)173\item \textbf{sendtype}: Typ der Elemente in sendbuf (handle) (vgl. \cpageref{sec:MPI-Datatypes})174\item \textbf{recvcount}: Anzahl der Elemente im Empfangspuffer. Meist ist es günstig, recvcount = sendcount zu wählen.175\item \textbf{recvtype}: Typ der Elemente des Empfangspuffers (handle) (vgl. \cpageref{sec:MPI-Datatypes})176\item \textbf{root}: Rang des Prozesses in comm, der die Daten versendet177\item \textbf{comm}: Kommunikator (handle)178\end{itemize}179180\textbf{Output-Parameter}181\begin{itemize}182\item \textbf{recvbuf}: Adresse des Empfangsbuffers; auch \texttt{root} findet seinen Anteil an Daten nach der Operation dort183\end{itemize}184%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%185\goodbreak186\rule{\textwidth}{0.4pt}\xindex{MPI\_Allgather@\texttt{MPI\_Allgather}}%187\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-allgather.c}188Sammelt Daten, die in einer Prozeßgruppe verteilt sind, ein und verteilt das Resultat an alle Prozesse in der Gruppe.189190\textbf{Input-Parameter}191\begin{itemize}192\item \textbf{sendbuf}: Startadresse des Sendepuffers193\item \textbf{sendcount}: Anzahl der Elemente im Sendepuffer194\item \textbf{sendtype}: Datentyp der Elemente des Sendepuffers (handle) (vgl. \cpageref{sec:MPI-Datatypes})195\item \textbf{recvcount}: Anzahl der Elemente, die jeder einzelne Prozeß sendet (integer)196\item \textbf{recvtype}: Datentyp der Elemente im Empfangspuffer (handle) (vgl. \cpageref{sec:MPI-Datatypes})197\item \textbf{comm}: Kommunikator (handle)198\end{itemize}199200\textbf{Output-Parameter}201\begin{itemize}202\item \textbf{recvbuf}: Anfangsadresse des Empfangspuffers203\end{itemize}204205\textbf{Beispiel}206\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-allgather-example.c}207%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%208\goodbreak209\rule{\textwidth}{0.4pt}\xindex{MPI\_Gather@\texttt{MPI\_Gather}}%210\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-gather.c}211Sammelt Daten, die in einer Prozeßgruppe verteilt sind, ein.212213\textbf{Input-Parameter}214\begin{itemize}215\item \textbf{sendbuf}: Startadresse des Sendepuffers216\item \textbf{sendcount}: Anzahl der Elemente im Sendepuffer217\item \textbf{sendtype}: Datentyp der Elemente des Sendepuffers (handle)218\item \textbf{recvcount}: Anzahl der Elemente, die jeder einzelne Prozeß sendet (nur für \texttt{root} signifikant)219\item \textbf{recvtype}: Typ der Elemente im Empfangspuffer (handle) (nur für \texttt{root} signifikant) (vgl. \cpageref{sec:MPI-Datatypes})220\item \textbf{root}: Rang des empfangenden Prozesses in \texttt{comm}221\item \textbf{comm}: Kommunikator (handle)222\end{itemize}223224\textbf{Output-Parameter}225\begin{itemize}226\item \textbf{recvbuf}: Adresse des Empfangspuffers (nur für \texttt{root} signifikant)227\end{itemize}228229\textbf{Beispiel}230\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-reduce-example.c}231232\section{Beispiele}233\subsection{sum-reduce Implementierung}\xindex{MPI\_Reduce@\texttt{MPI\_Reduce}}%234\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-sum-reduce.c}235236\subsection[broadcast Implementierung]{broadcast Implementierung\footnote{Klausur WS 2012 / 2013}}\xindex{MPI\_Bcast@\texttt{MPI\_Bcast}}%237\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-mybroadcast.c}238239\section{Weitere Informationen}240\begin{itemize}241\item \url{http://mpitutorial.com/}242\item \url{http://www.open-mpi.org/}243\item \url{http://www.tu-chemnitz.de/informatik/RA/projects/mpihelp/}244\end{itemize}245246\index{MPI|)}247248