mpi4py

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__ = '3.0.3'
     28  __author__ = 'Lisandro Dalcin'
     29  __credits__ = 'MPI Forum, MPICH Team, Open MPI Team'
     30
     31
     32  __all__ = ['MPI']
     33
     34
     35 -def get_include():
     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
     51 -def get_config():
     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:  # pragma: no cover
     57          from ConfigParser import ConfigParser
     58      parser = ConfigParser()
     59      parser.read(join(dirname(__file__), 'mpi.cfg'))
     60      return dict(parser.items('mpi'))
     61
     62
     63 -def rc(**kargs):  # pylint: disable=invalid-name
     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
    100 -def profile(name, **kargs):
    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          # pylint: disable=missing-docstring
    119          pattern = []
    120          if sys.platform.startswith('win'):  # pragma: no cover
    121              pattern.append(('', '.dll'))
    122          elif sys.platform == 'darwin':  # pragma: no cover
    123              pattern.append(('lib', '.dylib'))
    124          elif os.name == 'posix':  # pragma: no cover
    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