File: overview.html

package info (click to toggle)
mpi4py 3.0.3-8
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 12,428 kB
  • sloc: python: 18,672; javascript: 9,118; ansic: 7,092; makefile: 567; sh: 183; f90: 158; cpp: 103
file content (541 lines) | stat: -rw-r--r-- 44,239 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Overview &#8212; MPI for Python 3.0.3 documentation</title>
    <link rel="stylesheet" href="_static/classic.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    
    <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <script type="text/javascript" src="_static/language_data.js"></script>
    
    <link rel="index" title="Index" href="genindex.html" />
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="Tutorial" href="tutorial.html" />
    <link rel="prev" title="Introduction" href="intro.html" /> 
  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="tutorial.html" title="Tutorial"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="intro.html" title="Introduction"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">MPI for Python 3.0.3 documentation</a> &#187;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="overview">
<h1>Overview<a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h1>
<p>MPI for Python provides an object oriented approach to message passing
which grounds on the standard MPI-2 C++ bindings. The interface was
designed with focus in translating MPI syntax and semantics of
standard MPI-2 bindings for C++ to Python. Any user of the standard
C/C++ MPI bindings should be able to use this module without need of
learning a new interface.</p>
<div class="section" id="communicating-python-objects-and-array-data">
<h2>Communicating Python Objects and Array Data<a class="headerlink" href="#communicating-python-objects-and-array-data" title="Permalink to this headline">¶</a></h2>
<p>The Python standard library supports different mechanisms for data
persistence. Many of them rely on disk storage, but <em>pickling</em> and
<em>marshaling</em> can also work with memory buffers.</p>
<p>The <a class="reference external" href="https://docs.python.org/3/library/pickle.html#module-pickle" title="(in Python v3.8)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">pickle</span></code></a> modules provide user-extensible facilities to
serialize general Python objects using ASCII or binary formats. The
<a class="reference external" href="https://docs.python.org/3/library/marshal.html#module-marshal" title="(in Python v3.8)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">marshal</span></code></a> module provides facilities to serialize built-in Python
objects using a binary format specific to Python, but independent of
machine architecture issues.</p>
<p><em>MPI for Python</em> can communicate any built-in or user-defined Python
object taking advantage of the features provided by the <a class="reference external" href="https://docs.python.org/3/library/pickle.html#module-pickle" title="(in Python v3.8)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">pickle</span></code></a>
module. These facilities will be routinely used to build binary
representations of objects to communicate (at sending processes), and
restoring them back (at receiving processes).</p>
<p>Although simple and general, the serialization approach (i.e.,
<em>pickling</em> and <em>unpickling</em>) previously discussed imposes important
overheads in memory as well as processor usage, especially in the
scenario of objects with large memory footprints being
communicated. Pickling general Python objects, ranging from primitive
or container built-in types to user-defined classes, necessarily
requires computer resources.  Processing is also needed for
dispatching the appropriate serialization method (that depends on the
type of the object) and doing the actual packing. Additional memory is
always needed, and if its total amount is not known <em>a priori</em>, many
reallocations can occur.  Indeed, in the case of large numeric arrays,
this is certainly unacceptable and precludes communication of objects
occupying half or more of the available memory resources.</p>
<p><em>MPI for Python</em> supports direct communication of any object exporting
the single-segment buffer interface. This interface is a standard
Python mechanism provided by some types (e.g., strings and numeric
arrays), allowing access in the C side to a contiguous memory buffer
(i.e., address and length) containing the relevant data. This feature,
in conjunction with the capability of constructing user-defined MPI
datatypes describing complicated memory layouts, enables the
implementation of many algorithms involving multidimensional numeric
arrays (e.g., image processing, fast Fourier transforms, finite
difference schemes on structured Cartesian grids) directly in Python,
with negligible overhead, and almost as fast as compiled Fortran, C,
or C++ codes.</p>
</div>
<div class="section" id="communicators">
<h2>Communicators<a class="headerlink" href="#communicators" title="Permalink to this headline">¶</a></h2>
<p>In <em>MPI for Python</em>, <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Comm</span></code> is the base class of
communicators. The <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Intracomm</span></code> and <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Intercomm</span></code>
classes are sublcasses of the <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Comm</span></code> class.  The
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Is_inter()</span></code> method (and <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Is_intra()</span></code>,
provided for convenience but not part of the MPI specification) is
defined for communicator objects and can be used to determine the
particular communicator class.</p>
<p>The two predefined intracommunicator instances are available:
<code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.COMM_SELF</span></code> and <code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.COMM_WORLD</span></code>. From them, new
communicators can be created as needed.</p>
<p>The number of processes in a communicator and the calling process rank
can be respectively obtained with methods <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Get_size()</span></code>
and <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Get_rank()</span></code>. The associated process group can be
retrieved from a communicator by calling the
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Get_group()</span></code> method, which returns an instance of the
<code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Group</span></code> class. Set operations with <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Group</span></code>
objects like like <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Group.Union()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Group.Intersect()</span></code>
and <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Group.Difference()</span></code> are fully supported, as well as the
creation of new communicators from these groups using
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Create()</span></code> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Create_group()</span></code>.</p>
<p>New communicator instances can be obtained with the
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Clone()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Dup()</span></code> and
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Split()</span></code> methods, as well methods
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intracomm.Create_intercomm()</span></code> and
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intercomm.Merge()</span></code>.</p>
<p>Virtual topologies (<code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Cartcomm</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Graphcomm</span></code> and
<code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Distgraphcomm</span></code> classes, which are specializations of the
<code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Intracomm</span></code> class) are fully supported. New instances can
be obtained from intracommunicator instances with factory methods
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intracomm.Create_cart()</span></code> and
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intracomm.Create_graph()</span></code>.</p>
</div>
<div class="section" id="point-to-point-communications">
<h2>Point-to-Point Communications<a class="headerlink" href="#point-to-point-communications" title="Permalink to this headline">¶</a></h2>
<p>Point to point communication is a fundamental capability of message
passing systems. This mechanism enables the transmission of data
between a pair of processes, one side sending, the other receiving.</p>
<p>MPI provides a set of <em>send</em> and <em>receive</em> functions allowing the
communication of <em>typed</em> data with an associated <em>tag</em>.  The type
information enables the conversion of data representation from one
architecture to another in the case of heterogeneous computing
environments; additionally, it allows the representation of
non-contiguous data layouts and user-defined datatypes, thus avoiding
the overhead of (otherwise unavoidable) packing/unpacking
operations. The tag information allows selectivity of messages at the
receiving end.</p>
<div class="section" id="blocking-communications">
<h3>Blocking Communications<a class="headerlink" href="#blocking-communications" title="Permalink to this headline">¶</a></h3>
<p>MPI provides basic send and receive functions that are <em>blocking</em>.
These functions block the caller until the data buffers involved in
the communication can be safely reused by the application program.</p>
<p>In <em>MPI for Python</em>, the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Send()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Recv()</span></code>
and <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Sendrecv()</span></code> methods of communicator objects provide
support for blocking point-to-point communications within
<code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Intracomm</span></code> and <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Intercomm</span></code> instances. These
methods can communicate memory buffers. The variants
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.send()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.recv()</span></code> and
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.sendrecv()</span></code> can communicate general Python objects.</p>
</div>
<div class="section" id="nonblocking-communications">
<h3>Nonblocking Communications<a class="headerlink" href="#nonblocking-communications" title="Permalink to this headline">¶</a></h3>
<p>On many systems, performance can be significantly increased by
overlapping communication and computation. This is particularly true
on systems where communication can be executed autonomously by an
intelligent, dedicated communication controller.</p>
<p>MPI provides <em>nonblocking</em> send and receive functions. They allow the
possible overlap of communication and computation.  Non-blocking
communication always come in two parts: posting functions, which begin
the requested operation; and test-for-completion functions, which
allow to discover whether the requested operation has completed.</p>
<p>In <em>MPI for Python</em>, the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Isend()</span></code> and
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Irecv()</span></code> methods initiate send and receive operations,
respectively. These methods return a <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Request</span></code> instance,
uniquely identifying the started operation.  Its completion can be
managed using the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Request.Test()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Request.Wait()</span></code>
and <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Request.Cancel()</span></code> methods. The management of
<code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Request</span></code> objects and associated memory buffers involved in
communication requires a careful, rather low-level coordination. Users
must ensure that objects exposing their memory buffers are not
accessed at the Python level while they are involved in nonblocking
message-passing operations.</p>
</div>
<div class="section" id="persistent-communications">
<h3>Persistent Communications<a class="headerlink" href="#persistent-communications" title="Permalink to this headline">¶</a></h3>
<p>Often a communication with the same argument list is repeatedly
executed within an inner loop. In such cases, communication can be
further optimized by using persistent communication, a particular case
of nonblocking communication allowing the reduction of the overhead
between processes and communication controllers. Furthermore , this
kind of optimization can also alleviate the extra call overheads
associated to interpreted, dynamic languages like Python.</p>
<p>In <em>MPI for Python</em>, the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Send_init()</span></code> and
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Recv_init()</span></code> methods create persistent requests for a
send and receive operation, respectively.  These methods return an
instance of the <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Prequest</span></code> class, a subclass of the
<code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Request</span></code> class. The actual communication can be
effectively started using the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Prequest.Start()</span></code> method, and
its completion can be managed as previously described.</p>
</div>
</div>
<div class="section" id="collective-communications">
<h2>Collective Communications<a class="headerlink" href="#collective-communications" title="Permalink to this headline">¶</a></h2>
<p>Collective communications allow the transmittal of data between
multiple processes of a group simultaneously. The syntax and semantics
of collective functions is consistent with point-to-point
communication. Collective functions communicate <em>typed</em> data, but
messages are not paired with an associated <em>tag</em>; selectivity of
messages is implied in the calling order. Additionally, collective
functions come in blocking versions only.</p>
<p>The more commonly used collective communication operations are the
following.</p>
<ul class="simple">
<li>Barrier synchronization across all group members.</li>
<li>Global communication functions<ul>
<li>Broadcast data from one member to all members of a group.</li>
<li>Gather data from all members to one member of a group.</li>
<li>Scatter data from one member to all members of a group.</li>
</ul>
</li>
<li>Global reduction operations such as sum, maximum, minimum, etc.</li>
</ul>
<p>In <em>MPI for Python</em>, the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Bcast()</span></code>,
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Scatter()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Gather()</span></code>,
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Allgather()</span></code>, and <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Alltoall()</span></code>
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Alltoallw()</span></code> methods provide support for collective
communications of memory buffers. The lower-case variants
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.bcast()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.scatter()</span></code>,
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.gather()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.allgather()</span></code> and
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.alltoall()</span></code> can communicate general Python objects.  The
vector variants (which can communicate different amounts of data to
each process) <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Scatterv()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Gatherv()</span></code>,
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Allgatherv()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Alltoallv()</span></code> and
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Alltoallw()</span></code> are also supported, they can only
communicate objects exposing memory buffers.</p>
<p>Global reduction operations on memory buffers are accessible through
the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Reduce()</span></code>, <cite>MPI.Comm.Reduce_scatter</cite>,
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Allreduce()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intracomm.Scan()</span></code> and
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intracomm.Exscan()</span></code> methods. The lower-case variants
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.reduce()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.allreduce()</span></code>,
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intracomm.scan()</span></code> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intracomm.exscan()</span></code> can
communicate general Python objects; however, the actual required
reduction computations are performed sequentially at some process. All
the predefined (i.e., <code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.SUM</span></code>, <code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.PROD</span></code>,
<code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.MAX</span></code>, etc.)  reduction operations can be applied.</p>
</div>
<div class="section" id="dynamic-process-management">
<h2>Dynamic Process Management<a class="headerlink" href="#dynamic-process-management" title="Permalink to this headline">¶</a></h2>
<p>In the context of the MPI-1 specification, a parallel application is
static; that is, no processes can be added to or deleted from a
running application after it has been started. Fortunately, this
limitation was addressed in MPI-2. The new specification added a
process management model providing a basic interface between an
application and external resources and process managers.</p>
<p>This MPI-2 extension can be really useful, especially for sequential
applications built on top of parallel modules, or parallel
applications with a client/server model. The MPI-2 process model
provides a mechanism to create new processes and establish
communication between them and the existing MPI application. It also
provides mechanisms to establish communication between two existing
MPI applications, even when one did not <em>start</em> the other.</p>
<p>In <em>MPI for Python</em>, new independent process groups can be created by
calling the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intracomm.Spawn()</span></code> method within an
intracommunicator.  This call returns a new intercommunicator (i.e.,
an <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Intercomm</span></code> instance) at the parent process group. The
child process group can retrieve the matching intercommunicator by
calling the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Get_parent()</span></code> class method. At each side,
the new intercommunicator can be used to perform point to point and
collective communications between the parent and child groups of
processes.</p>
<p>Alternatively, disjoint groups of processes can establish
communication using a client/server approach. Any server application
must first call the <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Open_port()</span></code> function to open a <em>port</em>
and the <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Publish_name()</span></code> function to publish a provided
<em>service</em>, and next call the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intracomm.Accept()</span></code> method.  Any
client applications can first find a published <em>service</em> by calling
the <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Lookup_name()</span></code> function, which returns the <em>port</em> where a
server can be contacted; and next call the
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intracomm.Connect()</span></code> method. Both
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intracomm.Accept()</span></code> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Intracomm.Connect()</span></code> methods
return an <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Intercomm</span></code> instance. When connection between
client/server processes is no longer needed, all of them must
cooperatively call the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Disconnect()</span></code>
method. Additionally, server applications should release resources by
calling the <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Unpublish_name()</span></code> and <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Close_port()</span></code>
functions.</p>
</div>
<div class="section" id="one-sided-communications">
<h2>One-Sided Communications<a class="headerlink" href="#one-sided-communications" title="Permalink to this headline">¶</a></h2>
<p>One-sided communications (also called <em>Remote Memory Access</em>, <em>RMA</em>)
supplements the traditional two-sided, send/receive based MPI
communication model with a one-sided, put/get based
interface. One-sided communication that can take advantage of the
capabilities of highly specialized network hardware. Additionally,
this extension lowers latency and software overhead in applications
written using a shared-memory-like paradigm.</p>
<p>The MPI specification revolves around the use of objects called
<em>windows</em>; they intuitively specify regions of a process’s memory that
have been made available for remote read and write operations.  The
published memory blocks can be accessed through three functions for
put (remote send), get (remote write), and accumulate (remote update
or reduction) data items. A much larger number of functions support
different synchronization styles; the semantics of these
synchronization operations are fairly complex.</p>
<p>In <em>MPI for Python</em>, one-sided operations are available by using
instances of the <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Win</span></code> class. New window objects are
created by calling the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Win.Create()</span></code> method at all processes
within a communicator and specifying a memory buffer . When a window
instance is no longer needed, the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Win.Free()</span></code> method should
be called.</p>
<p>The three one-sided MPI operations for remote write, read and
reduction are available through calling the methods
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Win.Put()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Win.Get()</span></code>, and
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Win.Accumulate()</span></code> respectively within a <code class="xref py py-class docutils literal notranslate"><span class="pre">Win</span></code>
instance.  These methods need an integer rank identifying the target
process and an integer offset relative the base address of the remote
memory block being accessed.</p>
<p>The one-sided operations read, write, and reduction are implicitly
nonblocking, and must be synchronized by using two primary modes.
Active target synchronization requires the origin process to call the
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Win.Start()</span></code> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Win.Complete()</span></code> methods at the
origin process, and target process cooperates by calling the
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Win.Post()</span></code> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Win.Wait()</span></code> methods. There is also a
collective variant provided by the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Win.Fence()</span></code>
method. Passive target synchronization is more lenient, only the
origin process calls the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Win.Lock()</span></code> and
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Win.Unlock()</span></code> methods. Locks are used to protect remote
accesses to the locked remote window and to protect local load/store
accesses to a locked local window.</p>
</div>
<div class="section" id="parallel-input-output">
<h2>Parallel Input/Output<a class="headerlink" href="#parallel-input-output" title="Permalink to this headline">¶</a></h2>
<p>The POSIX standard provides a model of a widely portable file
system. However, the optimization needed for parallel input/output
cannot be achieved with this generic interface. In order to ensure
efficiency and scalability, the underlying parallel input/output
system must provide a high-level interface supporting partitioning of
file data among processes and a collective interface supporting
complete transfers of global data structures between process memories
and files. Additionally, further efficiencies can be gained via
support for asynchronous input/output, strided accesses to data, and
control over physical file layout on storage devices. This scenario
motivated the inclusion in the MPI-2 standard of a custom interface in
order to support more elaborated parallel input/output operations.</p>
<p>The MPI specification for parallel input/output revolves around the
use objects called <em>files</em>. As defined by MPI, files are not just
contiguous byte streams. Instead, they are regarded as ordered
collections of <em>typed</em> data items. MPI supports sequential or random
access to any integral set of these items. Furthermore, files are
opened collectively by a group of processes.</p>
<p>The common patterns for accessing a shared file (broadcast, scatter,
gather, reduction) is expressed by using user-defined datatypes.
Compared to the communication patterns of point-to-point and
collective communications, this approach has the advantage of added
flexibility and expressiveness. Data access operations (read and
write) are defined for different kinds of positioning (using explicit
offsets, individual file pointers, and shared file pointers),
coordination (non-collective and collective), and synchronism
(blocking, nonblocking, and split collective with begin/end phases).</p>
<p>In <em>MPI for Python</em>, all MPI input/output operations are performed
through instances of the <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.File</span></code> class. File handles are
obtained by calling the <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.File.Open()</span></code> method at all processes
within a communicator and providing a file name and the intended
access mode.  After use, they must be closed by calling the
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.File.Close()</span></code> method.  Files even can be deleted by calling
method <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.File.Delete()</span></code>.</p>
<p>After creation, files are typically associated with a per-process
<em>view</em>. The view defines the current set of data visible and
accessible from an open file as an ordered set of elementary
datatypes. This data layout can be set and queried with the
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.File.Set_view()</span></code> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.File.Get_view()</span></code> methods
respectively.</p>
<p>Actual input/output operations are achieved by many methods combining
read and write calls with different behavior regarding positioning,
coordination, and synchronism. Summing up, <em>MPI for Python</em> provides
the thirty (30) methods defined in MPI-2 for reading from or writing
to files using explicit offsets or file pointers (individual or
shared), in blocking or nonblocking and collective or noncollective
versions.</p>
</div>
<div class="section" id="environmental-management">
<h2>Environmental Management<a class="headerlink" href="#environmental-management" title="Permalink to this headline">¶</a></h2>
<div class="section" id="initialization-and-exit">
<h3>Initialization and Exit<a class="headerlink" href="#initialization-and-exit" title="Permalink to this headline">¶</a></h3>
<p>Module functions <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Init()</span></code> or <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Init_thread()</span></code> and
<code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Finalize()</span></code> provide MPI initialization and finalization
respectively. Module functions <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Is_initialized()</span></code> and
<code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Is_finalized()</span></code> provide the respective tests for
initialization and finalization.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last"><code class="xref c c-func docutils literal notranslate"><span class="pre">MPI_Init()</span></code> or <code class="xref c c-func docutils literal notranslate"><span class="pre">MPI_Init_thread()</span></code> is actually
called when you import the <code class="xref py py-mod docutils literal notranslate"><span class="pre">MPI</span></code> module from the <code class="xref py py-mod docutils literal notranslate"><span class="pre">mpi4py</span></code>
package, but only if MPI is not already initialized. In such case,
calling <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Init()</span></code> or <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Init_thread()</span></code> from Python is
expected to generate an MPI error, and in turn an exception will be
raised.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last"><code class="xref c c-func docutils literal notranslate"><span class="pre">MPI_Finalize()</span></code> is registered (by using Python C/API
function <a class="reference external" href="https://docs.python.org/3/c-api/sys.html#c.Py_AtExit" title="(in Python v3.8)"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_AtExit()</span></code></a>) for being automatically called when
Python processes exit, but only if <code class="xref py py-mod docutils literal notranslate"><span class="pre">mpi4py</span></code> actually
initialized MPI. Therefore, there is no need to call
<code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Finalize()</span></code> from Python to ensure MPI finalization.</p>
</div>
</div>
<div class="section" id="implementation-information">
<h3>Implementation Information<a class="headerlink" href="#implementation-information" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li>The MPI version number can be retrieved from module function
<code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Get_version()</span></code>. It returns a two-integer tuple
<code class="docutils literal notranslate"><span class="pre">(version,subversion)</span></code>.</li>
<li>The <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Get_processor_name()</span></code> function can be used to access
the processor name.</li>
<li>The values of predefined attributes attached to the world
communicator can be obtained by calling the
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.Comm.Get_attr()</span></code> method within the <code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.COMM_WORLD</span></code>
instance.</li>
</ul>
</div>
<div class="section" id="timers">
<h3>Timers<a class="headerlink" href="#timers" title="Permalink to this headline">¶</a></h3>
<p>MPI timer functionalities are available through the <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Wtime()</span></code>
and <code class="xref py py-func docutils literal notranslate"><span class="pre">MPI.Wtick()</span></code> functions.</p>
</div>
<div class="section" id="error-handling">
<h3>Error Handling<a class="headerlink" href="#error-handling" title="Permalink to this headline">¶</a></h3>
<p>In order facilitate handle sharing with other Python modules
interfacing MPI-based parallel libraries, the predefined MPI error
handlers <code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.ERRORS_RETURN</span></code> and <code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.ERRORS_ARE_FATAL</span></code>
can be assigned to and retrieved from communicators, windows and files
using methods <code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.{Comm|Win|File}.Set_errhandler()</span></code> and
<code class="xref py py-meth docutils literal notranslate"><span class="pre">MPI.{Comm|Win|File}.Get_errhandler()</span></code>.</p>
<p>When the predefined error handler <code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.ERRORS_RETURN</span></code> is set,
errors returned from MPI calls within Python code will raise an
instance of the exception class <code class="xref py py-exc docutils literal notranslate"><span class="pre">MPI.Exception</span></code>, which is a
subclass of the standard Python exception <a class="reference external" href="https://docs.python.org/3/library/exceptions.html#RuntimeError" title="(in Python v3.8)"><code class="xref py py-exc docutils literal notranslate"><span class="pre">RuntimeError</span></code></a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">After import, mpi4py overrides the default MPI rules governing
inheritance of error handlers. The <code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.ERRORS_RETURN</span></code> error
handler is set in the predefined <code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.COMM_SELF</span></code> and
<code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.COMM_WORLD</span></code> communicators, as well as any new
<code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Comm</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.Win</span></code>, or <code class="xref py py-class docutils literal notranslate"><span class="pre">MPI.File</span></code> instance
created through mpi4py. If you ever pass such handles to
C/C++/Fortran library code, it is recommended to set the
<code class="xref py py-const docutils literal notranslate"><span class="pre">MPI.ERRORS_ARE_FATAL</span></code> error handler on them to ensure MPI
errors do not pass silently.</p>
</div>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Importing with <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">mpi4py.MPI</span> <span class="pre">import</span> <span class="pre">*</span></code> will cause a name
clashing with the standard Python <a class="reference external" href="https://docs.python.org/3/library/exceptions.html#Exception" title="(in Python v3.8)"><code class="xref py py-exc docutils literal notranslate"><span class="pre">Exception</span></code></a> base class.</p>
</div>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="index.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Overview</a><ul>
<li><a class="reference internal" href="#communicating-python-objects-and-array-data">Communicating Python Objects and Array Data</a></li>
<li><a class="reference internal" href="#communicators">Communicators</a></li>
<li><a class="reference internal" href="#point-to-point-communications">Point-to-Point Communications</a><ul>
<li><a class="reference internal" href="#blocking-communications">Blocking Communications</a></li>
<li><a class="reference internal" href="#nonblocking-communications">Nonblocking Communications</a></li>
<li><a class="reference internal" href="#persistent-communications">Persistent Communications</a></li>
</ul>
</li>
<li><a class="reference internal" href="#collective-communications">Collective Communications</a></li>
<li><a class="reference internal" href="#dynamic-process-management">Dynamic Process Management</a></li>
<li><a class="reference internal" href="#one-sided-communications">One-Sided Communications</a></li>
<li><a class="reference internal" href="#parallel-input-output">Parallel Input/Output</a></li>
<li><a class="reference internal" href="#environmental-management">Environmental Management</a><ul>
<li><a class="reference internal" href="#initialization-and-exit">Initialization and Exit</a></li>
<li><a class="reference internal" href="#implementation-information">Implementation Information</a></li>
<li><a class="reference internal" href="#timers">Timers</a></li>
<li><a class="reference internal" href="#error-handling">Error Handling</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="intro.html"
                        title="previous chapter">Introduction</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="tutorial.html"
                        title="next chapter">Tutorial</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="_sources/overview.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="tutorial.html" title="Tutorial"
             >next</a> |</li>
        <li class="right" >
          <a href="intro.html" title="Introduction"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">MPI for Python 3.0.3 documentation</a> &#187;</li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
        &#169; Copyright 2019, Lisandro Dalcin.
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
    </div>
  </body>
</html>