diff --git a/.gitignore b/.gitignore index 0d20b64..108cb0f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ *.pyc +build/ +dist/ diff --git a/COMPILING b/COMPILING new file mode 120000 index 0000000..691d95d --- /dev/null +++ b/COMPILING @@ -0,0 +1 @@ +doc/installing.rst \ No newline at end of file diff --git a/doc/.gitignore b/doc/.gitignore index e35d885..207b927 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -1 +1 @@ -_build +html/ \ No newline at end of file diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 72b5d3f..0000000 --- a/doc/Makefile +++ /dev/null @@ -1,89 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/python-rdma.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/python-rdma.qhc" - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/doc/conf.py b/doc/conf.py index 2ab3950..98cc1b8 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -122,7 +122,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +#html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. diff --git a/doc/index.rst b/doc/index.rst index 76430d1..4fbcc74 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -13,6 +13,7 @@ Contents: :numbered: intro.rst + installing.rst rdma.rst IBA.rst mads.rst diff --git a/doc/installing.rst b/doc/installing.rst new file mode 100644 index 0000000..33edbcf --- /dev/null +++ b/doc/installing.rst @@ -0,0 +1,88 @@ +Installing +========== + +`python-rdma` relies on the standard python :mod:`distutils` functionality for +building and includes a `setup.py` script. The following will be required to +build the module: + +- `Python` 2.6 or later in the 2.x series. `Python` 3 is currently not + supported. +- A working C compiler that distutils can find +- `infiniband/verbs.h` must be in the compiler search path +- The C compiler must be able to link against `libibverbs` +- `Python` C development support must be installed (eg `python-dev` on Debian) + +The build process is simply:: + + $ ./setup.py build + [..] + +Once built the library can be tested without installation by setting +`PYTHONPATH`:: + + $ export PYTHONPATH=`pwd`/lib.*/ + $ ./ibtool help + +To install into `/usr/local/` use `./setup.py install`. + +If your system has IB libraries installed outside the system path, perform the +build similar to the following:: + + $ ./setup.py build_ext -I /opt/ofa64-1.5.1/include -L /opt/ofa64-1.5.1/lib/ --rpath=/opt/ofa64-1.5.1/lib + $ ./setup.py build + +.. note:: + `Python` 2.6 packages are available for RHEL and related via the Fedora + EPEL_. These packages perform a parallel install of `Python` and do not replace + the system version. Eg + http://download.fedora.redhat.com/pub/epel/5/x86_64/repoview/python26.html + +.. _EPEL: http://fedoraproject.org/wiki/EPEL + +For Development +--------------- + +The module ships with a few pre-built things, to do development work the +following will also be required: + +- Pyrex >= 0.9.9 +- Sphinx >= 0.6.6 + +To test the installation of the above tools do the following:: + + $ rm rdma/ibverbs.c + $ ./setup.py build docs + +To ease development I recommend installing the following symlink:: + + $ (cd rdma ; ln -s ../build/lib.*/rdma/ibverbs.so .) + +After which running Python programs from the top of the source tree will +automatically have the correct PYTHONPATH and changes to the source itself +will immediately be picked up without having to run `./setup.py build` + +However, be aware that changes to the `Pyrex` extension module will still +require running `./setup.py build_ext` to recompile. + +The two required modules are easily configured in a private user directory as +follows:: + + $ wget http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/Pyrex-0.9.9.tar.gz + $ wget http://pypi.python.org/packages/2.6/S/Sphinx/Sphinx-1.0.7-py2.6.egg#md5=a547658740040dd87ef71fbf723e7962 + $ tar -xzf Pyrex-0.9.9.tar.gz + $ ln -s Pyrex-0.9.9/Pyrex . + $ unzip Sphinx-1.0.7-py2.6.egg + $ export PYTHONPATH=`pwd` + +Other approaches are possible as well. + +Test Suite +~~~~~~~~~~ + +The library includes a test suite built with :mod:`unittest`. To run the test +suite the end port returned by :func:`rdma.get_end_port` must be connected to +a small fabric. Some ways of running the suite:: + + $ ./run-tests.py # Run everything + $ ./run-tests.py tests.verbs # Only run the verbs test. + diff --git a/doc/intro.rst b/doc/intro.rst index 51be25a..87a8720 100644 --- a/doc/intro.rst +++ b/doc/intro.rst @@ -36,7 +36,7 @@ has significant pre-existing knowledge of the InfiniBand Architecture (IBA) and OFA RDMA Verbs programming and principles. Comparison to the OFA C API -=========================== +--------------------------- For reference the `python-rdma` module covers the same areas as the following OFA code: diff --git a/rdma/.gitignore b/rdma/.gitignore new file mode 100644 index 0000000..2f75db4 --- /dev/null +++ b/rdma/.gitignore @@ -0,0 +1,3 @@ +ibverbs.so +libibverbs_enums.pxd +libibverbs_enums.pxi diff --git a/rdma/__init__.py b/rdma/__init__.py index 6caacde..a9c1740 100644 --- a/rdma/__init__.py +++ b/rdma/__init__.py @@ -74,7 +74,7 @@ def dump_detailed(self,F=None,prefix="",level=1): line is displayed. If *level* is 1 then all summary information is shown. If *level* is 2 then request and reply packets are dumped. - If the :esc:`MADError` includes a captured exception then + If the :exc:`MADError` includes a captured exception then dump_detailed will re-throw it after printing our information.""" if F is None: F = sys.stderr; diff --git a/setup.py b/setup.py index 87411f8..9dc6e46 100755 --- a/setup.py +++ b/setup.py @@ -5,11 +5,13 @@ import os.path from distutils import log from distutils.core import setup +from distutils.core import Command from distutils.extension import Extension try: import Pyrex.Distutils except ImportError: + log.info("Pyrex is not installed -- using shippped Pyrex output"); # If we don't have Pyrex then just use the shipped .c file that is already built. ibverbs_module = Extension('rdma.ibverbs', ['rdma/ibverbs.c'], libraries=['ibverbs']); @@ -48,6 +50,8 @@ def write_enums_pxi(self,F,enums): for e,v in sorted(enums.iteritems())); def codegen(self): + if not os.path.exists(self.build_temp): + os.makedirs(self.build_temp) verbs_h = os.path.join(self.build_temp,"verbs_h.c") verbs_h_o = verbs_h + ".out" with open(verbs_h,"wt") as F: @@ -67,13 +71,103 @@ def codegen(self): depends=['rdma/libibverbs.pxd', 'rdma/libibverbs.pxi']) +# From PyCA +class sphinx_build(Command): + description = 'build documentation using Sphinx' + user_options = [ + ('builder=', 'b', 'builder to use; default is html'), + ('all', 'a', 'write all files; default is to only write new and changed files'), + ('reload-env', 'E', "don't use a saved environment, always read all files"), + ('out-dir=', 'o', 'path where output is stored (default: doc/)'), + ('cache-dir=', 'd', 'path for the cached environment and doctree files (default: outdir/.doctrees)'), + ('conf-dir=', 'c', 'path where configuration file (conf.py) is located (default: same as source-dir)'), + ('set=', 'D', ' override a setting in configuration'), + ('no-color', 'N', 'do not do colored output'), + ('pdb', 'P', 'run Pdb on exception'), + ] + boolean_options = ['all', 'reload-env', 'no-color', 'pdb'] + + def initialize_options(self): + self.sphinx_args = [] + self.builder = None + self.all = False + self.reload_env = False + self.out_dir = None + self.cache_dir = None + self.conf_dir = None + self.set = None + self.no_color = False + self.pdb = False + self.build = None + self.build_lib = None + + def finalize_options(self): + self.set_undefined_options('build', + ('build_lib', 'build_lib')); + self.sphinx_args.append('sphinx-build') + + if self.builder is None: + self.builder = 'html' + self.sphinx_args.extend(['-b', self.builder]) + + if self.all: + self.sphinx_args.append('-a') + if self.reload_env: + self.sphinx_args.append('-E') + if self.no_color or ('PS1' not in os.environ and 'PROMPT_COMMAND' not in os.environ): + self.sphinx_args.append('-N') + if not self.distribution.verbose: + self.sphinx_args.append('-q') + if self.pdb: + self.sphinx_args.append('-P') + + if self.cache_dir is not None: + self.sphinx_args.extend(['-d', self.cache_dir]) + if self.conf_dir is not None: + self.sphinx_args.extend(['-c', self.conf_dir]) + if self.set is not None: + self.sphinx_args.extend(['-D', self.set]) + + self.source_dir = "doc"; + if self.out_dir is None: + self.out_dir = os.path.join('doc', self.builder) + + self.sphinx_args.extend([self.source_dir, self.out_dir]) + + def run(self): + try: + import sphinx + except ImportError: + log.info('Sphinx not installed -- skipping documentation. (%s)', sys.exc_info()[1]) + return + + if not os.path.exists(self.out_dir): + if self.dry_run: + self.announce('skipping creation of directory %s (dry run)' % self.out_dir) + else: + self.announce('creating directory %s' % self.out_dir) + os.makedirs(self.out_dir) + if self.dry_run: + self.announce('skipping %s (dry run)' % ' '.join(self.sphinx_args)) + else: + self.announce('running %s' % ' '.join(self.sphinx_args)) + opath = sys.path + try: + # We need to point Sphinx at the built library, including + # the extension module so that autodoc works properly. + sys.path.insert(0,self.build_lib) + sphinx.main(self.sphinx_args) + finally: + sys.path = opath; + setup(name='rdma', version='0.1', description='RDMA functionality for python', ext_modules=[ibverbs_module], packages=['rdma','libibtool'], scripts=['ibtool'], - cmdclass={'build_ext': build_ext}, + cmdclass={'build_ext': build_ext, + 'docs': sphinx_build}, platforms = "ALL", classifiers = [ 'Development Status :: 4 - Beta',