1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
5 <title>Python Bindings</title>
6 <link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
7 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
8 <link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
9 <link rel="up" href="../mpi.html" title="Chapter 26. Boost.MPI">
10 <link rel="prev" href="../boost/mpi/timer.html" title="Class timer">
11 <link rel="next" href="../multi_array.html" title="Chapter 27. Boost.MultiArray Reference Manual">
13 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
14 <table cellpadding="2" width="100%"><tr>
15 <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
16 <td align="center"><a href="../../../index.html">Home</a></td>
17 <td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
18 <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
19 <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
20 <td align="center"><a href="../../../more/index.htm">More</a></td>
23 <div class="spirit-nav">
24 <a accesskey="p" href="../boost/mpi/timer.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../mpi.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../multi_array.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
27 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
28 <a name="mpi.python"></a>Python Bindings</h2></div></div></div>
29 <div class="toc"><dl class="toc">
30 <dt><span class="section"><a href="python.html#mpi.python_quickstart">Quickstart</a></span></dt>
31 <dt><span class="section"><a href="python.html#mpi.python_user_data">Transmitting User-Defined Data</a></span></dt>
32 <dt><span class="section"><a href="python.html#mpi.python_collectives">Collectives</a></span></dt>
33 <dt><span class="section"><a href="python.html#mpi.python_skeleton_content">Skeleton/Content Mechanism</a></span></dt>
34 <dt><span class="section"><a href="python.html#mpi.design">Design Philosophy</a></span></dt>
35 <dt><span class="section"><a href="python.html#mpi.threading">Threads</a></span></dt>
36 <dt><span class="section"><a href="python.html#mpi.performance">Performance Evaluation</a></span></dt>
37 <dt><span class="section"><a href="python.html#mpi.history">Revision History</a></span></dt>
38 <dt><span class="section"><a href="python.html#mpi.acknowledge">Acknowledgments</a></span></dt>
41 Boost.MPI provides an alternative MPI interface from the <a href="http://www.python.org" target="_top">Python</a>
42 programming language via the <code class="computeroutput"><span class="identifier">boost</span><span class="special">.</span><span class="identifier">mpi</span></code> module.
43 The Boost.MPI Python bindings, built on top of the C++ Boost.MPI using the
44 <a href="http://www.boost.org/libs/python/doc" target="_top">Boost.Python</a> library,
45 provide nearly all of the functionality of Boost.MPI within a dynamic, object-oriented
49 The Boost.MPI Python module can be built and installed from the <code class="computeroutput"><span class="identifier">libs</span><span class="special">/</span><span class="identifier">mpi</span><span class="special">/</span><span class="identifier">build</span></code> directory.
50 Just follow the <a class="link" href="getting_started.html#mpi.config" title="Configure and Build">configuration</a> and <a class="link" href="getting_started.html#mpi.installation" title="Build and Install">installation</a>
51 instructions for the C++ Boost.MPI. Once you have installed the Python module,
52 be sure that the installation location is in your <code class="computeroutput"><span class="identifier">PYTHONPATH</span></code>.
55 <div class="titlepage"><div><div><h3 class="title">
56 <a name="mpi.python_quickstart"></a>Quickstart</h3></div></div></div>
58 Getting started with the Boost.MPI Python module is as easy as importing
59 <code class="computeroutput"><span class="identifier">boost</span><span class="special">.</span><span class="identifier">mpi</span></code>. Our first "Hello, World!"
60 program is just two lines long:
62 <pre class="programlisting"><span class="keyword">import</span> <span class="identifier">boost</span><span class="special">.</span><span class="identifier">mpi</span> <span class="keyword">as</span> <span class="identifier">mpi</span>
63 <span class="keyword">print</span> <span class="string">"I am process %d of %d."</span> <span class="special">%</span> <span class="special">(</span><span class="identifier">mpi</span><span class="special">.</span><span class="identifier">rank</span><span class="special">,</span> <span class="identifier">mpi</span><span class="special">.</span><span class="identifier">size</span><span class="special">)</span>
66 Go ahead and run this program with several processes. Be sure to invoke the
67 <code class="computeroutput"><span class="identifier">python</span></code> interpreter from
68 <code class="computeroutput"><span class="identifier">mpirun</span></code>, e.g.,
70 <pre class="programlisting">mpirun -np 5 python hello_world.py
73 This will return output such as:
75 <pre class="programlisting">I am process 1 of 5.
82 Point-to-point operations in Boost.MPI have nearly the same syntax in Python
83 as in C++. We can write a simple two-process Python program that prints "Hello,
84 world!" by transmitting Python strings:
86 <pre class="programlisting"><span class="keyword">import</span> <span class="identifier">boost</span><span class="special">.</span><span class="identifier">mpi</span> <span class="keyword">as</span> <span class="identifier">mpi</span>
88 <span class="keyword">if</span> <span class="identifier">mpi</span><span class="special">.</span><span class="identifier">world</span><span class="special">.</span><span class="identifier">rank</span> <span class="special">==</span> <span class="number">0</span><span class="special">:</span>
89 <span class="identifier">mpi</span><span class="special">.</span><span class="identifier">world</span><span class="special">.</span><span class="identifier">send</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="string">'Hello'</span><span class="special">)</span>
90 <span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">mpi</span><span class="special">.</span><span class="identifier">world</span><span class="special">.</span><span class="identifier">recv</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span>
91 <span class="keyword">print</span> <span class="identifier">msg</span><span class="special">,</span><span class="string">'!'</span>
92 <span class="keyword">else</span><span class="special">:</span>
93 <span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">mpi</span><span class="special">.</span><span class="identifier">world</span><span class="special">.</span><span class="identifier">recv</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span>
94 <span class="keyword">print</span> <span class="special">(</span><span class="identifier">msg</span> <span class="special">+</span> <span class="string">', '</span><span class="special">),</span>
95 <span class="identifier">mpi</span><span class="special">.</span><span class="identifier">world</span><span class="special">.</span><span class="identifier">send</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="string">'world'</span><span class="special">)</span>
98 There are only a few notable differences between this Python code and the
99 example <a class="link" href="tutorial.html#mpi.point_to_point" title="Point-to-Point communication">in the C++ tutorial</a>. First
100 of all, we don't need to write any initialization code in Python: just loading
101 the <code class="computeroutput"><span class="identifier">boost</span><span class="special">.</span><span class="identifier">mpi</span></code> module makes the appropriate <code class="computeroutput"><span class="identifier">MPI_Init</span></code> and <code class="computeroutput"><span class="identifier">MPI_Finalize</span></code>
102 calls. Second, we're passing Python objects from one process to another through
103 MPI. Any Python object that can be pickled can be transmitted; the next section
104 will describe in more detail how the Boost.MPI Python layer transmits objects.
105 Finally, when we receive objects with <code class="computeroutput"><span class="identifier">recv</span></code>,
106 we don't need to specify the type because transmission of Python objects
110 When experimenting with Boost.MPI in Python, don't forget that help is always
111 available via <code class="computeroutput"><span class="identifier">pydoc</span></code>: just
112 pass the name of the module or module entity on the command line (e.g.,
113 <code class="computeroutput"><span class="identifier">pydoc</span> <span class="identifier">boost</span><span class="special">.</span><span class="identifier">mpi</span><span class="special">.</span><span class="identifier">communicator</span></code>) to receive complete reference
114 documentation. When in doubt, try it!
117 <div class="section">
118 <div class="titlepage"><div><div><h3 class="title">
119 <a name="mpi.python_user_data"></a>Transmitting User-Defined Data</h3></div></div></div>
121 Boost.MPI can transmit user-defined data in several different ways. Most
122 importantly, it can transmit arbitrary <a href="http://www.python.org" target="_top">Python</a>
123 objects by pickling them at the sender and unpickling them at the receiver,
124 allowing arbitrarily complex Python data structures to interoperate with
128 Boost.MPI also supports efficient serialization and transmission of C++ objects
129 (that have been exposed to Python) through its C++ interface. Any C++ type
130 that provides (de-)serialization routines that meet the requirements of the
131 Boost.Serialization library is eligible for this optimization, but the type
132 must be registered in advance. To register a C++ type, invoke the C++ function
133 <code class="computeroutput"><a class="link" href="../boost/mpi/python/register_serialized.html" title="Function template register_serialized">register_serialized</a></code>.
134 If your C++ types come from other Python modules (they probably will!), those
135 modules will need to link against the <code class="computeroutput"><span class="identifier">boost_mpi</span></code>
136 and <code class="computeroutput"><span class="identifier">boost_mpi_python</span></code> libraries
137 as described in the <a class="link" href="getting_started.html#mpi.installation" title="Build and Install">installation section</a>.
138 Note that you do <span class="bold"><strong>not</strong></span> need to link against
139 the Boost.MPI Python extension module.
142 Finally, Boost.MPI supports separation of the structure of an object from
143 the data it stores, allowing the two pieces to be transmitted separately.
144 This "skeleton/content" mechanism, described in more detail in
145 a later section, is a communication optimization suitable for problems with
146 fixed data structures whose internal data changes frequently.
149 <div class="section">
150 <div class="titlepage"><div><div><h3 class="title">
151 <a name="mpi.python_collectives"></a>Collectives</h3></div></div></div>
153 Boost.MPI supports all of the MPI collectives (<code class="computeroutput"><span class="identifier">scatter</span></code>,
154 <code class="computeroutput"><span class="identifier">reduce</span></code>, <code class="computeroutput"><span class="identifier">scan</span></code>,
155 <code class="computeroutput"><span class="identifier">broadcast</span></code>, etc.) for any
156 type of data that can be transmitted with the point-to-point communication
157 operations. For the MPI collectives that require a user-specified operation
158 (e.g., <code class="computeroutput"><span class="identifier">reduce</span></code> and <code class="computeroutput"><span class="identifier">scan</span></code>), the operation can be an arbitrary
159 Python function. For instance, one could concatenate strings with <code class="computeroutput"><span class="identifier">all_reduce</span></code>:
161 <pre class="programlisting"><span class="identifier">mpi</span><span class="special">.</span><span class="identifier">all_reduce</span><span class="special">(</span><span class="identifier">my_string</span><span class="special">,</span> <span class="keyword">lambda</span> <span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">:</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span>
164 The following module-level functions implement MPI collectives: all_gather
165 Gather the values from all processes. all_reduce Combine the results from
166 all processes. all_to_all Every process sends data to every other process.
167 broadcast Broadcast data from one process to all other processes. gather
168 Gather the values from all processes to the root. reduce Combine the results
169 from all processes to the root. scan Prefix reduction of the values from
170 all processes. scatter Scatter the values stored at the root to all processes.
173 <div class="section">
174 <div class="titlepage"><div><div><h3 class="title">
175 <a name="mpi.python_skeleton_content"></a>Skeleton/Content Mechanism</h3></div></div></div>
176 <div class="toc"><dl class="toc">
177 <dt><span class="section"><a href="python.html#mpi.python_compatibility">C++/Python MPI Compatibility</a></span></dt>
178 <dt><span class="section"><a href="python.html#mpi.pythonref">Reference</a></span></dt>
181 Boost.MPI provides a skeleton/content mechanism that allows the transfer
182 of large data structures to be split into two separate stages, with the skeleton
183 (or, "shape") of the data structure sent first and the content
184 (or, "data") of the data structure sent later, potentially several
185 times, so long as the structure has not changed since the skeleton was transferred.
186 The skeleton/content mechanism can improve performance when the data structure
187 is large and its shape is fixed, because while the skeleton requires serialization
188 (it has an unknown size), the content transfer is fixed-size and can be done
189 without extra copies.
192 To use the skeleton/content mechanism from Python, you must first register
193 the type of your data structure with the skeleton/content mechanism <span class="bold"><strong>from C++</strong></span>. The registration function is <code class="computeroutput"><a class="link" href="../boost/mpi/python/register_skel_idp669096704.html" title="Function template register_skeleton_and_content">register_skeleton_and_content</a></code>
194 and resides in the <code class="computeroutput"><a class="link" href="reference.html#header.boost.mpi.python_hpp" title="Header <boost/mpi/python.hpp>"><boost/mpi/python.hpp></a></code>
198 Once you have registered your C++ data structures, you can extract the skeleton
199 for an instance of that data structure with <code class="computeroutput"><span class="identifier">skeleton</span><span class="special">()</span></code>. The resulting <code class="computeroutput"><span class="identifier">skeleton_proxy</span></code>
200 can be transmitted via the normal send routine, e.g.,
202 <pre class="programlisting"><span class="identifier">mpi</span><span class="special">.</span><span class="identifier">world</span><span class="special">.</span><span class="identifier">send</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">skeleton</span><span class="special">(</span><span class="identifier">my_data_structure</span><span class="special">))</span>
205 <code class="computeroutput"><span class="identifier">skeleton_proxy</span></code> objects can
206 be received on the other end via <code class="computeroutput"><span class="identifier">recv</span><span class="special">()</span></code>, which stores a newly-created instance
207 of your data structure with the same "shape" as the sender in its
208 <code class="computeroutput"><span class="string">"object"</span></code> attribute:
210 <pre class="programlisting"><span class="identifier">shape</span> <span class="special">=</span> <span class="identifier">mpi</span><span class="special">.</span><span class="identifier">world</span><span class="special">.</span><span class="identifier">recv</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span>
211 <span class="identifier">my_data_structure</span> <span class="special">=</span> <span class="identifier">shape</span><span class="special">.</span><span class="identifier">object</span>
214 Once the skeleton has been transmitted, the content (accessed via <code class="computeroutput"><span class="identifier">get_content</span></code>) can be transmitted in much
215 the same way. Note, however, that the receiver also specifies <code class="computeroutput"><span class="identifier">get_content</span><span class="special">(</span><span class="identifier">my_data_structure</span><span class="special">)</span></code>
216 in its call to receive:
218 <pre class="programlisting"><span class="keyword">if</span> <span class="identifier">mpi</span><span class="special">.</span><span class="identifier">rank</span> <span class="special">==</span> <span class="number">0</span><span class="special">:</span>
219 <span class="identifier">mpi</span><span class="special">.</span><span class="identifier">world</span><span class="special">.</span><span class="identifier">send</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">get_content</span><span class="special">(</span><span class="identifier">my_data_structure</span><span class="special">))</span>
220 <span class="keyword">else</span><span class="special">:</span>
221 <span class="identifier">mpi</span><span class="special">.</span><span class="identifier">world</span><span class="special">.</span><span class="identifier">recv</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">get_content</span><span class="special">(</span><span class="identifier">my_data_structure</span><span class="special">))</span>
224 Of course, this transmission of content can occur repeatedly, if the values
225 in the data structure--but not its shape--changes.
228 The skeleton/content mechanism is a structured way to exploit the interaction
229 between custom-built MPI datatypes and <code class="computeroutput"><span class="identifier">MPI_BOTTOM</span></code>,
230 to eliminate extra buffer copies.
232 <div class="section">
233 <div class="titlepage"><div><div><h4 class="title">
234 <a name="mpi.python_compatibility"></a>C++/Python MPI Compatibility</h4></div></div></div>
236 Boost.MPI is a C++ library whose facilities have been exposed to Python
237 via the Boost.Python library. Since the Boost.MPI Python bindings are build
238 directly on top of the C++ library, and nearly every feature of C++ library
239 is available in Python, hybrid C++/Python programs using Boost.MPI can
240 interact, e.g., sending a value from Python but receiving that value in
241 C++ (or vice versa). However, doing so requires some care. Because Python
242 objects are dynamically typed, Boost.MPI transfers type information along
243 with the serialized form of the object, so that the object can be received
244 even when its type is not known. This mechanism differs from its C++ counterpart,
245 where the static types of transmitted values are always known.
248 The only way to communicate between the C++ and Python views on Boost.MPI
249 is to traffic entirely in Python objects. For Python, this is the normal
250 state of affairs, so nothing will change. For C++, this means sending and
251 receiving values of type <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code>,
252 from the <a href="http://www.boost.org/libs/python/doc" target="_top">Boost.Python</a>
253 library. For instance, say we want to transmit an integer value from Python:
255 <pre class="programlisting"><span class="identifier">comm</span><span class="special">.</span><span class="identifier">send</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">17</span><span class="special">)</span>
258 In C++, we would receive that value into a Python object and then <code class="computeroutput"><span class="identifier">extract</span></code> an integer value:
260 <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span> <span class="identifier">value</span><span class="special">;</span>
261 <span class="identifier">comm</span><span class="special">.</span><span class="identifier">recv</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">value</span><span class="special">);</span>
262 <span class="keyword">int</span> <span class="identifier">int_value</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">extract</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">value</span><span class="special">);</span>
265 In the future, Boost.MPI will be extended to allow improved interoperability
266 with the C++ Boost.MPI and the C MPI bindings.
269 <div class="section">
270 <div class="titlepage"><div><div><h4 class="title">
271 <a name="mpi.pythonref"></a>Reference</h4></div></div></div>
273 The Boost.MPI Python module, <code class="computeroutput"><span class="identifier">boost</span><span class="special">.</span><span class="identifier">mpi</span></code>,
274 has its own <a href="../boost.mpi.html" target="_top">reference documentation</a>,
275 which is also available using <code class="computeroutput"><span class="identifier">pydoc</span></code>
276 (from the command line) or <code class="computeroutput"><span class="identifier">help</span><span class="special">(</span><span class="identifier">boost</span><span class="special">.</span><span class="identifier">mpi</span><span class="special">)</span></code> (from the Python interpreter).
280 <div class="section">
281 <div class="titlepage"><div><div><h3 class="title">
282 <a name="mpi.design"></a>Design Philosophy</h3></div></div></div>
284 The design philosophy of the Parallel MPI library is very simple: be both
285 convenient and efficient. MPI is a library built for high-performance applications,
286 but it's FORTRAN-centric, performance-minded design makes it rather inflexible
287 from the C++ point of view: passing a string from one process to another
288 is inconvenient, requiring several messages and explicit buffering; passing
289 a container of strings from one process to another requires an extra level
290 of manual bookkeeping; and passing a map from strings to containers of strings
291 is positively infuriating. The Parallel MPI library allows all of these data
292 types to be passed using the same simple <code class="computeroutput"><span class="identifier">send</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">recv</span><span class="special">()</span></code> primitives. Likewise, collective operations
293 such as <code class="computeroutput"><a class="link" href="../boost/mpi/reduce.html" title="Function reduce">reduce()</a></code> allow arbitrary data types
294 and function objects, much like the C++ Standard Library would.
297 The higher-level abstractions provided for convenience must not have an impact
298 on the performance of the application. For instance, sending an integer via
299 <code class="computeroutput"><span class="identifier">send</span></code> must be as efficient
300 as a call to <code class="computeroutput"><span class="identifier">MPI_Send</span></code>, which
301 means that it must be implemented by a simple call to <code class="computeroutput"><span class="identifier">MPI_Send</span></code>;
302 likewise, an integer <code class="computeroutput"><a class="link" href="../boost/mpi/reduce.html" title="Function reduce">reduce()</a></code>
303 using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code> must
304 be implemented with a call to <code class="computeroutput"><span class="identifier">MPI_Reduce</span></code>
305 on integers using the <code class="computeroutput"><span class="identifier">MPI_SUM</span></code>
306 operation: anything less will impact performance. In essence, this is the
307 "don't pay for what you don't use" principle: if the user is not
308 transmitting strings, s/he should not pay the overhead associated with strings.
311 Sometimes, achieving maximal performance means foregoing convenient abstractions
312 and implementing certain functionality using lower-level primitives. For
313 this reason, it is always possible to extract enough information from the
314 abstractions in Boost.MPI to minimize the amount of effort required to interface
315 between Boost.MPI and the C MPI library.
318 <div class="section">
319 <div class="titlepage"><div><div><h3 class="title">
320 <a name="mpi.threading"></a>Threads</h3></div></div></div>
322 There are an increasing number of hybrid parallel applications that mix distributed
323 and shared memory parallelism. To know how to support that model, one need
324 to know what level of threading support is guaranteed by the MPI implementation.
325 There are 4 ordered level of possible threading support described by <code class="computeroutput"><a class="link" href="../boost/mpi/threading/level.html" title="Type level">mpi::threading::level</a></code>. At the
326 lowest level, you should not use threads at all, at the highest level, any
327 thread can perform MPI call.
330 If you want to use multi-threading in your MPI application, you should indicate
331 in the environment constructor your preferred threading support. Then probe
332 the one the library did provide, and decide what you can do with it (it could
333 be nothing, then aborting is a valid option):
335 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mpi</span><span class="special">/</span><span class="identifier">environment</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
336 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mpi</span><span class="special">/</span><span class="identifier">communicator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
337 <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
338 <span class="keyword">namespace</span> <span class="identifier">mpi</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpi</span><span class="special">;</span>
339 <span class="keyword">namespace</span> <span class="identifier">mt</span> <span class="special">=</span> <span class="identifier">mpi</span><span class="special">::</span><span class="identifier">threading</span><span class="special">;</span>
341 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
342 <span class="special">{</span>
343 <span class="identifier">mpi</span><span class="special">::</span><span class="identifier">environment</span> <span class="identifier">env</span><span class="special">(</span><span class="identifier">mt</span><span class="special">::</span><span class="identifier">funneled</span><span class="special">);</span>
344 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">env</span><span class="special">.</span><span class="identifier">thread_level</span><span class="special">()</span> <span class="special"><</span> <span class="identifier">mt</span><span class="special">::</span><span class="identifier">funneled</span><span class="special">)</span> <span class="special">{</span>
345 <span class="identifier">env</span><span class="special">.</span><span class="identifier">abort</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span>
346 <span class="special">}</span>
347 <span class="identifier">mpi</span><span class="special">::</span><span class="identifier">communicator</span> <span class="identifier">world</span><span class="special">;</span>
348 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"I am process "</span> <span class="special"><<</span> <span class="identifier">world</span><span class="special">.</span><span class="identifier">rank</span><span class="special">()</span> <span class="special"><<</span> <span class="string">" of "</span> <span class="special"><<</span> <span class="identifier">world</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span>
349 <span class="special"><<</span> <span class="string">"."</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
350 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
351 <span class="special">}</span>
354 <div class="section">
355 <div class="titlepage"><div><div><h3 class="title">
356 <a name="mpi.performance"></a>Performance Evaluation</h3></div></div></div>
358 Message-passing performance is crucial in high-performance distributed computing.
359 To evaluate the performance of Boost.MPI, we modified the standard <a href="http://www.scl.ameslab.gov/netpipe/" target="_top">NetPIPE</a> benchmark (version
360 3.6.2) to use Boost.MPI and compared its performance against raw MPI. We
361 ran five different variants of the NetPIPE benchmark:
363 <div class="orderedlist"><ol class="orderedlist" type="1">
364 <li class="listitem">
365 MPI: The unmodified NetPIPE benchmark.
367 <li class="listitem">
368 Boost.MPI: NetPIPE modified to use Boost.MPI calls for communication.
370 <li class="listitem">
371 MPI (Datatypes): NetPIPE modified to use a derived datatype (which itself
372 contains a single <code class="computeroutput"><span class="identifier">MPI_BYTE</span></code>)
373 rather than a fundamental datatype.
375 <li class="listitem">
376 Boost.MPI (Datatypes): NetPIPE modified to use a user-defined type <code class="computeroutput"><span class="identifier">Char</span></code> in place of the fundamental <code class="computeroutput"><span class="keyword">char</span></code> type. The <code class="computeroutput"><span class="identifier">Char</span></code>
377 type contains a single <code class="computeroutput"><span class="keyword">char</span></code>,
378 a <code class="computeroutput"><span class="identifier">serialize</span><span class="special">()</span></code>
379 method to make it serializable, and specializes <code class="computeroutput"><a class="link" href="../boost/mpi/is_mpi_datatype.html" title="Struct template is_mpi_datatype">is_mpi_datatype</a></code>
380 to force Boost.MPI to build a derived MPI data type for it.
382 <li class="listitem">
383 Boost.MPI (Serialized): NetPIPE modified to use a user-defined type
384 <code class="computeroutput"><span class="identifier">Char</span></code> in place of the
385 fundamental <code class="computeroutput"><span class="keyword">char</span></code> type. This
386 <code class="computeroutput"><span class="identifier">Char</span></code> type contains a
387 single <code class="computeroutput"><span class="keyword">char</span></code> and is serializable.
388 Unlike the Datatypes case, <code class="computeroutput"><a class="link" href="../boost/mpi/is_mpi_datatype.html" title="Struct template is_mpi_datatype">is_mpi_datatype</a></code>
389 is <span class="bold"><strong>not</strong></span> specialized, forcing Boost.MPI
390 to perform many, many serialization calls.
394 The actual tests were performed on the Odin cluster in the <a href="http://www.cs.indiana.edu/" target="_top">Department
395 of Computer Science</a> at <a href="http://www.iub.edu" target="_top">Indiana University</a>,
396 which contains 128 nodes connected via Infiniband. Each node contains 4GB
397 memory and two AMD Opteron processors. The NetPIPE benchmarks were compiled
398 with Intel's C++ Compiler, version 9.0, Boost 1.35.0 (prerelease), and <a href="http://www.open-mpi.org/" target="_top">Open MPI</a> version 1.1. The NetPIPE
402 <span class="inlinemediaobject"><img src="../../../libs/mpi/doc/netpipe.png" alt="netpipe"></span>
405 There are a some observations we can make about these NetPIPE results. First
406 of all, the top two plots show that Boost.MPI performs on par with MPI for
407 fundamental types. The next two plots show that Boost.MPI performs on par
408 with MPI for derived data types, even though Boost.MPI provides a much more
409 abstract, completely transparent approach to building derived data types
410 than raw MPI. Overall performance for derived data types is significantly
411 worse than for fundamental data types, but the bottleneck is in the underlying
412 MPI implementation itself. Finally, when forcing Boost.MPI to serialize characters
413 individually, performance suffers greatly. This particular instance is the
414 worst possible case for Boost.MPI, because we are serializing millions of
415 individual characters. Overall, the additional abstraction provided by Boost.MPI
416 does not impair its performance.
419 <div class="section">
420 <div class="titlepage"><div><div><h3 class="title">
421 <a name="mpi.history"></a>Revision History</h3></div></div></div>
422 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
423 <li class="listitem">
424 <span class="bold"><strong>Boost 1.36.0</strong></span>:
425 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem">
426 Support for non-blocking operations in Python, from Andreas Klöckner
429 <li class="listitem">
430 <span class="bold"><strong>Boost 1.35.0</strong></span>: Initial release, containing
431 the following post-review changes
432 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
433 <li class="listitem">
434 Support for arrays in all collective operations
436 <li class="listitem">
437 Support default-construction of <code class="computeroutput"><a class="link" href="../boost/mpi/environment.html" title="Class environment">environment</a></code>
441 <li class="listitem">
442 <span class="bold"><strong>2006-09-21</strong></span>: Boost.MPI accepted into
447 <div class="section">
448 <div class="titlepage"><div><div><h3 class="title">
449 <a name="mpi.acknowledge"></a>Acknowledgments</h3></div></div></div>
451 Boost.MPI was developed with support from Zurcher Kantonalbank. Daniel Egloff
452 and Michael Gauckler contributed many ideas to Boost.MPI's design, particularly
453 in the design of its abstractions for MPI data types and the novel skeleton/context
454 mechanism for large data structures. Prabhanjan (Anju) Kambadur developed
455 the predecessor to Boost.MPI that proved the usefulness of the Serialization
456 library in an MPI setting and the performance benefits of specialization
457 in a C++ abstraction layer for MPI. Jeremy Siek managed the formal review
462 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
463 <td align="left"></td>
464 <td align="right"><div class="copyright-footer">Copyright © 2005-2007 Douglas Gregor,
465 Matthias Troyer, Trustees of Indiana University<p>
466 Distributed under the Boost Software License, Version 1.0. (See accompanying
467 file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
468 http://www.boost.org/LICENSE_1_0.txt </a>)
473 <div class="spirit-nav">
474 <a accesskey="p" href="../boost/mpi/timer.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../mpi.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../multi_array.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>