MPI.tex 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. %!TEX root = Programmierparadigmen.tex
  2. \chapter{MPI}
  3. \index{MPI|(}
  4. Message Passing Interface (kurz: MPI) ist ein Standard,
  5. der den Nachrichtenaustausch bei parallelen Berechnungen auf
  6. verteilten Computersystemen beschreibt.
  7. Prozesse kommunizieren in MPI über sog. \textit{Kommunikatoren}. Ein Kommunikator
  8. (\texttt{MPI\_Comm}\xindex{MPI\_Comm@\texttt{MPI\_Comm}})
  9. definiert eine Menge an Prozessen, die miteinander kommunizieren können. In dieser
  10. Prozessgruppe hat jeder Prozess einen eindeutigen \textit{rank}\xindex{rank} über den die Prozesse
  11. sich identifizieren können.
  12. \section{Erste Schritte}
  13. \inputminted[numbersep=5pt, tabsize=4, frame=lines, label=hello-world.c]{c}{scripts/mpi/hello-world.c}
  14. Das wird \texttt{mpicc hello-world.c} kompiliert.\\
  15. Mit \texttt{mpirun -np 14 scripts/mpi/a.out} werden 14 Kopien des Programms
  16. gestartet.
  17. Hierbei ist \texttt{MPI\_COMM\_WORLD}\xindex{MPI\_COMM\_WORLD@\texttt{MPI\_COMM\_WORLD}} der Standard-Kommunikator,
  18. der von \texttt{MPI\_Init} erstellt wird.
  19. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  20. \section{MPI Datatypes}\label{sec:MPI-Datatypes}\xindex{MPI datatypes}%
  21. \begin{table}[h]
  22. \begin{tabular}{|l|l||p{3.2cm}|l|}
  23. \hline
  24. \textbf{MPI datatype} & \textbf{C datatype} & \textbf{MPI datatype} & \textbf{C datatype} \\ \hline
  25. MPI\_INT & signed int & MPI\_FLOAT & float \\
  26. MPI\_UNSIGNED & unsigned int & MPI\_DOUBLE & double \\
  27. MPI\_CHAR & signed char & MPI\_UNSIGNED\newline{}\_CHAR & unsigned char \\ \hline
  28. \end{tabular}
  29. \end{table}
  30. \section{Funktionen}
  31. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-size.c}\xindex{MPI\_Comm\_size@\texttt{MPI\_Comm\_size}}%
  32. Liefert die Größe des angegebenen Kommunikators; dh. die Anzahl der Prozesse in der Gruppe.
  33. \textbf{Parameter}
  34. \begin{itemize}
  35. \item \textbf{comm}: Kommunikator (handle)
  36. \item \textbf{size}: Anzahl der Prozesse in der Gruppe von \texttt{comm}
  37. \end{itemize}
  38. \textbf{Beispiel}
  39. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-size-example.c}
  40. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  41. \goodbreak
  42. \rule{\textwidth}{0.4pt}\xindex{MPI\_Comm\_rank@\texttt{MPI\_Comm\_rank}}%
  43. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-rank.c}
  44. Bestimmt den Rang des rufenden Prozesses innerhalb des Kommunikators.
  45. Der 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.
  46. \textbf{Parameter}
  47. \begin{itemize}
  48. \item \textbf{comm}: Kommunikator (handle)
  49. \item \textbf{rank}: Rang des rufenden Prozesses innerhalb von \texttt{comm}
  50. \end{itemize}
  51. \textbf{Beispiel}
  52. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-rank-example.c}
  53. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  54. \goodbreak
  55. \rule{\textwidth}{0.4pt}\xindex{MPI\_Send@\texttt{MPI\_Send}}%
  56. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-send.c}
  57. Senden einer Nachricht an einen anderen Prozeß innerhalb eines Kommunikators. (Standard-Send)
  58. \textbf{Parameter}
  59. \begin{itemize}
  60. \item \textbf{buf}: Anfangsadresse des Sendepuffers
  61. \item \textbf{count}: Anzahl der Elemente des Sendepuffers (nichtnegativ)
  62. \item \textbf{datatype}: Typ der Elemente des Sendepuffers (handle) (vgl. \cpageref{sec:MPI-Datatypes})
  63. \item \textbf{dest}: Rang des Empfängerprozesses in comm (integer)
  64. \item \textbf{tag}: message tag zur Unterscheidung verschiedener Nachrichten;
  65. Ein Kommunikationsvorgang wird durch ein Tripel (Sender, Empfänger, tag) eindeutig beschrieben.
  66. \item \textbf{comm}: Kommunikator (handle)
  67. \end{itemize}
  68. \textbf{Beispiel}
  69. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-send-example.c}
  70. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  71. \goodbreak
  72. \rule{\textwidth}{0.4pt}\xindex{MPI\_Recv@\texttt{MPI\_Recv}}%
  73. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-receive.c}
  74. Empfangen einer Nachricht (blockierend)
  75. \textbf{Parameter}
  76. \begin{itemize}
  77. \item \textbf{buf}: Anfangsadresse des Empfangspuffers
  78. \item \textbf{count}: Anzahl (d.~h. $\geq 0$) der Elemente im Empfangspuffer
  79. \item \textbf{datatype}: Typ der zu empfangenden Elemente (handle) (vgl. \cpageref{sec:MPI-Datatypes})
  80. \item \textbf{source}: Rang des Senderprozesses in comm oder \texttt{MPI\_ANY\_SOURCE}
  81. \item \textbf{tag}: message tag zur Unterscheidung verschiedener Nachrichten
  82. Ein 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}.
  83. \item \textbf{comm}: Kommunikator (handle)
  84. \item \textbf{status}: Status, welcher source und tag angibt (\texttt{MPI\_Status}).
  85. Soll dieser Status ignoriert werden, kann \texttt{MPI\_STATUS\_IGNORE}\xindex{MPI\_STATUS\_IGNORE@\texttt{MPI\_STATUS\_IGNORE}} angegeben werden.
  86. \end{itemize}
  87. \textbf{Beispiel}
  88. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-receive-example.c}
  89. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  90. \goodbreak
  91. \rule{\textwidth}{0.4pt}\xindex{MPI\_Reduce@\texttt{MPI\_Reduce}}%
  92. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-reduce.c}
  93. Führt eine globale Operation \textbf{op} aus; der Prozeß \enquote{root} erhält das Resultat.
  94. \textbf{Input-Parameter}
  95. \begin{itemize}
  96. \item \textbf{sendbuf}: Startadresse des Sendepuffers
  97. \item \textbf{count}: Anzahl der Elemente im Sendepuffer
  98. \item \textbf{datatype}: Typ der Elemente von \texttt{sendbuf} (vgl. \cpageref{sec:MPI-Datatypes})
  99. \item \textbf{op}: auszuführende Operation (handle)
  100. \item \textbf{root}: Rang des Root-Prozesses in comm, der das Ergebnis haben soll
  101. \item \textbf{comm}: Kommunikator (handle)
  102. \end{itemize}
  103. \textbf{Output-Parameter}
  104. \begin{itemize}
  105. \item \textbf{recvbuf}: Adresse des Puffers, in den das Ergebnis abgelegt wird (nur für \texttt{root} signifikant)
  106. \end{itemize}
  107. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  108. \goodbreak
  109. \rule{\textwidth}{0.4pt}\xindex{MPI\_Alltoall@\texttt{MPI\_Alltoall}}%
  110. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-alltoall.c}
  111. Teilt Daten von jedem Prozeß einer Gruppe an alle anderen auf.
  112. \textbf{Input-Parameter}
  113. \begin{itemize}
  114. \item \textbf{sendbuf}: Startadresse des Sendepuffers
  115. \item \textbf{sendcount}: Anzahl der Elemente im Sendepuffer
  116. \item \textbf{sendtype}: Typ der Elemente des Sendepuffers (handle) (vgl. \cpageref{sec:MPI-Datatypes})
  117. \item \textbf{recvcount}: Anzahl der Elemente, die von jedem einzelnen Prozeß empfangen werden
  118. \item \textbf{recvtype}: Typ der Elemente im Empfangspuffer (handle) (vgl. \cpageref{sec:MPI-Datatypes})
  119. \item \textbf{comm}: Kommunikator (handle)
  120. \end{itemize}
  121. \textbf{Output-Parameter}
  122. \begin{itemize}
  123. \item \textbf{recvbuf}: Anfangsadresse des Empfangspuffers
  124. \end{itemize}
  125. \textbf{Beispiel}
  126. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-alltoall-example.c}
  127. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  128. \goodbreak
  129. \rule{\textwidth}{0.4pt}\xindex{MPI\_Bcast@\texttt{MPI\_Bcast}}%
  130. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-bcast.c}
  131. Sendet eine Nachricht vom Prozess \texttt{root} an alle anderen Prozesse des
  132. angegebenen Kommunikators.
  133. \textbf{Parameter}
  134. \begin{itemize}
  135. \item \textbf{buffer}: Startadresse des Datenpuffers
  136. \item \textbf{count}: Anzahl der Elemente im Puffer
  137. \item \textbf{datatype}: Typ der Pufferelemente (handle) (vgl. \cpageref{sec:MPI-Datatypes})
  138. \item \textbf{root}: Wurzelprozeß; der, welcher sendet
  139. \item \textbf{comm}: Kommunikator (handle)
  140. \end{itemize}
  141. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  142. \goodbreak
  143. \rule{\textwidth}{0.4pt}\xindex{MPI\_Scatter@\texttt{MPI\_Scatter}}%
  144. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-scatter.c}
  145. Verteilt Daten vom Prozess \texttt{root} unter alle anderen Prozesse in der Gruppe, so daß, soweit möglich, alle Prozesse gleich große Anteile erhalten.
  146. \textbf{Input-Parameter}
  147. \begin{itemize}
  148. \item \textbf{sendbuf}: Anfangsadresse des Sendepuffers (Wert ist lediglich für \texttt{root} signifikant)
  149. \item \textbf{sendcount}: Anzahl der Elemente, die jeder Prozeß geschickt bekommen soll (integer)
  150. \item \textbf{sendtype}: Typ der Elemente in sendbuf (handle) (vgl. \cpageref{sec:MPI-Datatypes})
  151. \item \textbf{recvcount}: Anzahl der Elemente im Empfangspuffer. Meist ist es günstig, recvcount = sendcount zu wählen.
  152. \item \textbf{recvtype}: Typ der Elemente des Empfangspuffers (handle) (vgl. \cpageref{sec:MPI-Datatypes})
  153. \item \textbf{root}: Rang des Prozesses in comm, der die Daten versendet
  154. \item \textbf{comm}: Kommunikator (handle)
  155. \end{itemize}
  156. \textbf{Output-Parameter}
  157. \begin{itemize}
  158. \item \textbf{recvbuf}: Adresse des Empfangsbuffers; auch \texttt{root} findet seinen Anteil an Daten nach der Operation dort
  159. \end{itemize}
  160. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  161. \goodbreak
  162. \rule{\textwidth}{0.4pt}\xindex{MPI\_Allgather@\texttt{MPI\_Allgather}}%
  163. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-allgather.c}
  164. Sammelt Daten, die in einer Prozeßgruppe verteilt sind, ein und verteilt das Resultat an alle Prozesse in der Gruppe.
  165. \textbf{Input-Parameter}
  166. \begin{itemize}
  167. \item \textbf{sendbuf}: Startadresse des Sendepuffers
  168. \item \textbf{sendcount}: Anzahl der Elemente im Sendepuffer
  169. \item \textbf{sendtype}: Datentyp der Elemente des Sendepuffers (handle) (vgl. \cpageref{sec:MPI-Datatypes})
  170. \item \textbf{recvcount}: Anzahl der Elemente, die jeder einzelne Prozeß sendet (integer)
  171. \item \textbf{recvtype}: Datentyp der Elemente im Empfangspuffer (handle) (vgl. \cpageref{sec:MPI-Datatypes})
  172. \item \textbf{comm}: Kommunikator (handle)
  173. \end{itemize}
  174. \textbf{Output-Parameter}
  175. \begin{itemize}
  176. \item \textbf{recvbuf}: Anfangsadresse des Empfangspuffers
  177. \end{itemize}
  178. \textbf{Beispiel}
  179. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-allgather-example.c}
  180. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  181. \goodbreak
  182. \rule{\textwidth}{0.4pt}\xindex{MPI\_Gather@\texttt{MPI\_Gather}}%
  183. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-gather.c}
  184. Sammelt Daten, die in einer Prozeßgruppe verteilt sind, ein.
  185. \textbf{Input-Parameter}
  186. \begin{itemize}
  187. \item \textbf{sendbuf}: Startadresse des Sendepuffers
  188. \item \textbf{sendcount}: Anzahl der Elemente im Sendepuffer
  189. \item \textbf{sendtype}: Datentyp der Elemente des Sendepuffers (handle)
  190. \item \textbf{recvcount}: Anzahl der Elemente, die jeder einzelne Prozeß sendet (nur für \texttt{root} signifikant)
  191. \item \textbf{recvtype}: Typ der Elemente im Empfangspuffer (handle) (nur für \texttt{root} signifikant) (vgl. \cpageref{sec:MPI-Datatypes})
  192. \item \textbf{root}: Rang des empfangenden Prozesses in \texttt{comm}
  193. \item \textbf{comm}: Kommunikator (handle)
  194. \end{itemize}
  195. \textbf{Output-Parameter}
  196. \begin{itemize}
  197. \item \textbf{recvbuf}: Adresse des Empfangspuffers (nur für \texttt{root} signifikant)
  198. \end{itemize}
  199. \textbf{Beispiel}
  200. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-reduce-example.c}
  201. \section{Beispiele}
  202. \subsection{sum-reduce Implementierung}\xindex{MPI\_Reduce@\texttt{MPI\_Reduce}}%
  203. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-sum-reduce.c}
  204. \subsection[broadcast Implementierung]{broadcast Implementierung\footnote{Klausur WS 2012 / 2013}}\xindex{MPI\_Bcast@\texttt{MPI\_Bcast}}%
  205. \inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-mybroadcast.c}
  206. \section{Weitere Informationen}
  207. \begin{itemize}
  208. \item \url{http://mpitutorial.com/}
  209. \item \url{http://www.open-mpi.org/}
  210. \item \url{http://www.tu-chemnitz.de/informatik/RA/projects/mpihelp/}
  211. \end{itemize}
  212. \index{MPI|)}