1
2
3 """
4 This is the **MPI for Python** package.
5
6 What is *MPI*?
7 ==============
8
9 The *Message Passing Interface*, is a standardized and portable
10 message-passing system designed to function on a wide variety of
11 parallel computers. The standard defines the syntax and semantics of
12 library routines and allows users to write portable programs in the
13 main scientific programming languages (Fortran, C, or C++). Since
14 its release, the MPI specification has become the leading standard
15 for message-passing libraries for parallel computers.
16
17 What is *MPI for Python*?
18 =========================
19
20 *MPI for Python* provides MPI bindings for the Python programming
21 language, allowing any Python program to exploit multiple processors.
22 This package is constructed on top of the MPI-1/2 specifications and
23 provides an object oriented interface which closely follows MPI-2 C++
24 bindings.
25 """
26
27 __version__ = '3.0.3'
28 __author__ = 'Lisandro Dalcin'
29 __credits__ = 'MPI Forum, MPICH Team, Open MPI Team'
30
31
32 __all__ = ['MPI']
33
34
36 """Return the directory in the package that contains header files.
37
38 Extension modules that need to compile against mpi4py should use
39 this function to locate the appropriate include directory. Using
40 Python distutils (or perhaps NumPy distutils)::
41
42 import mpi4py
43 Extension('extension_name', ...
44 include_dirs=[..., mpi4py.get_include()])
45
46 """
47 from os.path import join, dirname
48 return join(dirname(__file__), 'include')
49
50
52 """Return a dictionary with information about MPI."""
53 from os.path import join, dirname
54 try:
55 from configparser import ConfigParser
56 except ImportError:
57 from ConfigParser import ConfigParser
58 parser = ConfigParser()
59 parser.read(join(dirname(__file__), 'mpi.cfg'))
60 return dict(parser.items('mpi'))
61
62
64 """Runtime configuration options.
65
66 Parameters
67 ----------
68 initialize : bool
69 Automatic MPI initialization at import (default: True).
70 threads : bool
71 Request for thread support (default: True).
72 thread_level : {'multiple', 'serialized', 'funneled', 'single'}
73 Level of thread support to request (default: 'multiple').
74 finalize : None or bool
75 Automatic MPI finalization at exit (default: None).
76 fast_reduce : bool
77 Use tree-based reductions for objects (default: True).
78 recv_mprobe : bool
79 Use matched probes to receive objects (default: True).
80 errors : {'exception', 'default', 'fatal'}
81 Error handling policy (default: 'exception').
82
83 """
84 for key in kargs:
85 if not hasattr(rc, key):
86 raise TypeError("unexpected argument '{0}'".format(key))
87 for key, value in kargs.items():
88 setattr(rc, key, value)
89
90 rc.initialize = True
91 rc.threads = True
92 rc.thread_level = 'multiple'
93 rc.finalize = None
94 rc.fast_reduce = True
95 rc.recv_mprobe = True
96 rc.errors = 'exception'
97 __import__('sys').modules[__name__ + '.rc'] = rc
98
99
101 """Support for the MPI profiling interface.
102
103 Parameters
104 ----------
105 name : str
106 Name of the profiler library to load.
107 path : list of str, optional
108 Additional paths to search for the profiler.
109 logfile : str, optional
110 Filename prefix for dumping profiler output.
111
112 """
113 import sys
114 import os
115 from .dl import dlopen, dlerror, RTLD_NOW, RTLD_GLOBAL
116
117 def lookup_dylib(name, path):
118
119 pattern = []
120 if sys.platform.startswith('win'):
121 pattern.append(('', '.dll'))
122 elif sys.platform == 'darwin':
123 pattern.append(('lib', '.dylib'))
124 elif os.name == 'posix':
125 pattern.append(('lib', '.so'))
126 pattern.append(('', ''))
127 for pth in path:
128 for (lib, dso) in pattern:
129 filename = os.path.join(pth, lib + name + dso)
130 if os.path.isfile(filename):
131 return os.path.abspath(filename)
132 return None
133
134 logfile = kargs.pop('logfile', None)
135 if logfile:
136 if name in ('mpe',):
137 if 'MPE_LOGFILE_PREFIX' not in os.environ:
138 os.environ['MPE_LOGFILE_PREFIX'] = logfile
139 if name in ('vt', 'vt-mpi', 'vt-hyb'):
140 if 'VT_FILE_PREFIX' not in os.environ:
141 os.environ['VT_FILE_PREFIX'] = logfile
142
143 path = kargs.pop('path', [])
144 if isinstance(path, str):
145 path = [path]
146 else:
147 path = list(path)
148 prefix = os.path.dirname(__file__)
149 path.append(os.path.join(prefix, 'lib-pmpi'))
150 filename = lookup_dylib(name, path)
151 if filename is None:
152 raise ValueError("profiler '{0}' not found".format(name))
153
154 handle = dlopen(filename, RTLD_NOW | RTLD_GLOBAL)
155 if handle:
156 profile.registry.append((name, (handle, filename)))
157 else:
158 from warnings import warn
159 warn(dlerror())
160
161 profile.registry = []
162