Package mpi4py
[hide private]
[frames] | no frames]

Source Code for Package mpi4py

  1  # Author:  Lisandro Dalcin 
  2  # Contact: dalcinl@gmail.com 
  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__ = '2.0.0' 
 28  __author__  = 'Lisandro Dalcin' 
 29  __credits__ = 'MPI Forum, MPICH Team, Open MPI Team' 
 30   
 31  # -------------------------------------------------------------------- 
 32   
 33  __all__ = ['MPI'] 
 34   
 35  # -------------------------------------------------------------------- 
 36   
 37   
38 -def get_include():
39 """ 40 Return the directory in the package that contains header files. 41 42 Extension modules that need to compile against mpi4py should use 43 this function to locate the appropriate include directory. Using 44 Python distutils (or perhaps NumPy distutils):: 45 46 import mpi4py 47 Extension('extension_name', ... 48 include_dirs=[..., mpi4py.get_include()]) 49 50 """ 51 from os.path import join, dirname 52 return join(dirname(__file__), 'include')
53 54 # -------------------------------------------------------------------- 55 56
57 -def get_config():
58 """ 59 Return a dictionary with information about MPI. 60 """ 61 from os.path import join, dirname 62 try: 63 # pylint: disable=import-error 64 from configparser import ConfigParser 65 except ImportError: 66 # pylint: disable=import-error 67 from ConfigParser import ConfigParser 68 parser = ConfigParser() 69 parser.read(join(dirname(__file__), 'mpi.cfg')) 70 return dict(parser.items('mpi'))
71 72 # -------------------------------------------------------------------- 73 74
75 -def rc(**kargs): # pylint: disable=invalid-name
76 """ 77 Runtime configuration options. 78 79 Parameters 80 ---------- 81 initialize : bool 82 Automatic MPI initialization at import (default: True). 83 threads : bool 84 Request for thread support (default: True). 85 thread_level : {'multiple', 'serialized', 'funneled', 'single'} 86 Level of thread support to request (default: 'multiple'). 87 finalize : None or bool 88 Automatic MPI finalization at exit (default: None). 89 fast_reduce : bool 90 Use tree-based reductions for objects (default: True). 91 recv_mprobe : bool 92 Use matched probes to receive objects (default: True). 93 errors : {'exception', 'default', 'fatal'} 94 Error handling policy (default: 'exception'). 95 96 """ 97 for key in kargs: 98 if not hasattr(rc, key): 99 raise TypeError("unexpected argument '%s'" % key) 100 for key, value in kargs.items(): 101 setattr(rc, key, value) 102 103 rc.initialize = True 104 rc.threads = True 105 rc.thread_level = 'multiple' 106 rc.finalize = None 107 rc.fast_reduce = True 108 rc.recv_mprobe = True 109 rc.errors = 'exception' 110 111 from sys import modules 112 modules[__name__ + '.rc'] = rc 113 del modules 114 115 # -------------------------------------------------------------------- 116 117
118 -def profile(name='mpe', **kargs):
119 """ 120 Support for the MPI profiling interface. 121 122 Parameters 123 ---------- 124 name : str, optional 125 Name of the profiler to load. 126 path : list of str, optional 127 Additional paths to search for the profiler. 128 logfile : str, optional 129 Filename prefix for dumping profiler output. 130 """ 131 # pylint: disable=too-many-locals 132 # pylint: disable=too-many-branches 133 import sys 134 import os 135 try: 136 from .dl import dlopen, dlerror, RTLD_NOW, RTLD_GLOBAL 137 except ImportError: # pragma: no cover 138 from ctypes import CDLL as dlopen, RTLD_GLOBAL 139 try: 140 # pylint: disable=import-error 141 from DLFCN import RTLD_NOW 142 except ImportError: 143 RTLD_NOW = 2 # pylint: disable=invalid-name 144 dlerror = None 145 146 def lookup_dylib(name, path): 147 # pylint: disable=missing-docstring 148 import imp 149 pattern = [] 150 for suffix, _, kind in imp.get_suffixes(): 151 if kind == imp.C_EXTENSION: 152 pattern.append(('', suffix)) 153 if sys.platform.startswith('win'): # pragma: no cover 154 pattern.append(('', '.dll')) 155 elif sys.platform == 'darwin': # pragma: no cover 156 pattern.append(('lib', '.dylib')) 157 elif os.name == 'posix': # pragma: no cover 158 pattern.append(('lib', '.so')) 159 pattern.append(('', '')) 160 for pth in path: 161 for (lib, dso) in pattern: 162 filename = os.path.join(pth, lib + name + dso) 163 if os.path.isfile(filename): 164 return filename 165 return None
166 # 167 logfile = kargs.pop('logfile', None) 168 if logfile: 169 if name in ('mpe',): 170 if 'MPE_LOGFILE_PREFIX' not in os.environ: 171 os.environ['MPE_LOGFILE_PREFIX'] = logfile 172 if name in ('vt', 'vt-mpi', 'vt-hyb'): 173 if 'VT_FILE_PREFIX' not in os.environ: 174 os.environ['VT_FILE_PREFIX'] = logfile 175 path = kargs.pop('path', None) 176 if path is None: 177 path = [] 178 elif isinstance(path, str): 179 path = [path] 180 else: 181 path = list(path) 182 183 prefix = os.path.dirname(__file__) 184 path.append(os.path.join(prefix, 'lib-pmpi')) 185 filename = lookup_dylib(name, path) 186 if filename is None: 187 raise ValueError("profiler '%s' not found" % name) 188 else: 189 filename = os.path.abspath(filename) 190 191 handle = dlopen(filename, RTLD_NOW | RTLD_GLOBAL) 192 if handle: # pragma: no branch 193 profile.registry.append((name, (handle, filename))) 194 else: # pragma: no cover 195 from warnings import warn 196 if dlerror: 197 message = dlerror() 198 else: 199 message = "error loading '%s'" % filename 200 warn(message) 201 202 profile.registry = [] 203 204 # -------------------------------------------------------------------- 205