mpi4py

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

# Source Code for Package mpi4py

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