Skip to content

Commit

Permalink
Merge pull request #441 from odlgroup/issue-336__move_odlpp
Browse files Browse the repository at this point in the history
Issue 336  move odlpp
  • Loading branch information
adler-j committed Jun 30, 2016
2 parents b8b4eb4 + 40f9004 commit cdef98d
Show file tree
Hide file tree
Showing 55 changed files with 1,354 additions and 4,232 deletions.
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "odlpp"]
path = odlpp
url = https://github.com/odlgroup/odlpp.git
[submodule "doc/sphinxext"]
path = doc/sphinxext
url = https://github.com/odlgroup/numpydoc
26 changes: 12 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ where FOO, BAR, etc are the dependencies. Others require more complicated instal

| Package | Purpose | Dependency |
|---------|---------|------------|
| [odlcuda](https://github.com/odlgroup/odlcuda/) | CUDA backend | |
| [ASTRA](https://github.com/astra-toolbox/astra-toolbox) | Tomographic forward/backward projectors in [RayTransform](http://odl.readthedocs.io/generated/odl.tomo.operators.ray_trafo.RayTransform.html) | |
| [scikit-image](http://scikit-image.org/) | 2D parallel beam forward/backward projectors in [RayTransform](http://odl.readthedocs.io/generated/odl.tomo.operators.ray_trafo.RayTransform.html) | scikit |
| [FFTW](https://github.com/pyFFTW/pyFFTW) | Accelerated [FourierTransform](http://odl.readthedocs.io/generated/odl.trafos.fourier.FourierTransform.html) | fftw |
Expand All @@ -62,20 +63,17 @@ Compatibility
-------------
ODL is compatible to Python 2 and 3 through the `future` library. It is intended to work on all major platforms (GNU/Linux / Mac / Windows).

Currently (2016-06-10) working combinations are:

| Platform | Python | CUDA |
|--------------|-----------------|-------|
| Windows 7 | 2.7 ||
| Windows 10 | 2.7 ||
| Ubuntu 14.04 | 2.7 ||
| Ubuntu 15.10 | 2.7 / 3.4 / 3.5 ||
| Ubuntu 16.04 | 2.7 / 3.4 / 3.5 ||
| Fedora 22 | 2.7 / 3.4 | x (1) |
| Mac OSX | 3.5 | ?? |

(1) The default GCC 5.x compiler is not compatible with current CUDA (7.5)

Currently (2016-06-10) known working combinations are:

| Platform | Python |
|--------------|-----------------|
| Windows 7 | 2.7 |
| Windows 10 | 2.7 |
| Ubuntu 14.04 | 2.7 |
| Ubuntu 15.10 | 2.7 / 3.4 / 3.5 |
| Ubuntu 16.04 | 2.7 / 3.4 / 3.5 |
| Fedora 22 | 2.7 / 3.4 |
| Mac OSX | 3.5 |

License
-------
Expand Down
19 changes: 16 additions & 3 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,10 @@

import pytest
import odl
from odl.space.cu_ntuples import CUDA_AVAILABLE
from odl.trafos.wavelet import PYWAVELETS_AVAILABLE

collect_ignore = ['setup.py', 'run_tests.py']

if not CUDA_AVAILABLE:
collect_ignore.append('odl/space/cu_ntuples.py')
if not PYWAVELETS_AVAILABLE:
collect_ignore.append('odl/trafos/wavelet.py')

Expand All @@ -43,6 +40,22 @@ def pytest_addoption(parser):


# reusable fixtures
fn_impl_params = odl.FN_IMPLS.keys()
fn_impl_ids = [" impl='{}' ".format(p) for p in fn_impl_params]


@pytest.fixture(scope="module", ids=fn_impl_ids, params=fn_impl_params)
def fn_impl(request):
return request.param

ntuples_impl_params = odl.NTUPLES_IMPLS.keys()
ntuples_impl_ids = [" impl='{}' ".format(p) for p in ntuples_impl_params]


@pytest.fixture(scope="module", ids=ntuples_impl_ids, params=ntuples_impl_params)
def ntuples_impl(request):
return request.param

ufunc_params = [ufunc for ufunc in odl.util.ufuncs.UFUNCS]
ufunc_ids = [' ufunc={} '.format(p[0]) for p in ufunc_params]

Expand Down
3 changes: 2 additions & 1 deletion doc/source/dev/dev.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ Contents
.. toctree::
:maxdepth: 3

gitwash/index
extend
document
gitwash/index
23 changes: 23 additions & 0 deletions doc/source/dev/extend.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#############
Extending ODL
#############

ODL is written to be easy to extend with new functionality and classes, and new content is welcome. With that said, not everything fits inside the main library and some ideas are better done as *extension packages*. This may give your package more freedom and allows a faster development cycle and help keep ODL from overflowing with content.

There are several ways to extend ODL, some will be listed below.

Adding Fn spaces
----------------
The abstract spaces `FnBase` and `NtuplesBase` are the workhorses of the ODL space machinery. They are used in both the discrete :math:`R^n` case, as well as data representation for discretized function spaces such as :math:`L^2([0, 1])` in the `DiscretizedSpace` class. These are in general created through the `rn` and `uniform_discr` functions who take an ``impl`` parameter, allowing users to select the backend to use.

In the core ODL package, there is only a single backend available: `NumpyFn`/`NumpyNtuples`, given by ``impl='numpy'``, which is the default choice. Users can add CUDA support by installing the add-on library odlcuda_, which contains the additional spaces ``CudaFn``/``CudaNtuples``. By using the `rn`/`uniform_discr` functions, users can then seamlessly change the backend of their spaces.

As an advanced user, you may need to add additional spaces of this type that can be used inside ODL, perhaps to add MPI_ support. There are a few steps to do this:

* Create a new library with a ``setuptools`` installer.
* Add the spaces that you want to add to the library. The space needs to inherit from `NtuplesBase` or `FnBase`, respectively, and implement all of the abstract methods in those spaces. See the spaces for further information on the specific methods that need to be implemented.
* Add the methods ``ntuples_impls()`` and ``fn_impls()`` to a file ``odl_plugin.py`` in your library. These should return a ``dict`` mapping names to implementations.
* Add the following to your library's ``setup.py`` setup call: ``entry_points={'odl.space': ['odl_cuda = odlcuda.odl_plugin']``, where you replace ``odlcuda`` with the name of your plugin.

.. _odlcuda: https://github.com/odlgroup/odlcuda
.. _MPI: https://en.wikipedia.org/wiki/Message_Passing_Interface
19 changes: 18 additions & 1 deletion doc/source/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@
Release Notes
#############

ODL 0.3.0 Release Notes (2016-06-29)
====================================

This release marks the removal of odlpp from the core library. It has instead been moved to a separate library, odlcuda.

New features
------------
- To enable cuda backends for the odl spaces, an entry point ``'odl.space'`` has been added where external libraries can hook in to add `FnBase` and `NtuplesBase` type spaces.
- Add pytest fixtures ``'fn_impl'`` and ``'ntuple_impl'`` to the test config ``conf.py``. These can now be accessed from any test.
- Allow creation of general spaces using the ``fn``, ``cn`` and ``rn`` methods. This functions now take an ``impl`` parameter which defaults to ``'numpy'`` but with odlcuda installed it may also be set to ``'cuda'``. The old numpy specific ``Fn``, ``Cn`` and ``Rn`` functions have been removed.

Changes
-------
- Moved all CUDA specfic code out of the library into odlcuda. This means that ``cu_ntuples.py`` and related files have been removed.
- rename ``ntuples.py`` to ``npy_ntuples.py``.
- Added ``Numpy`` to the numy based spaces. They are now named ``NumpyFn`` and ``NumpyNtuples``.
- Prepended ``npy_`` to all methods specific to ``ntuples`` such as weightings.

ODL 0.2.4 Release Notes (2016-06-28)
====================================

Expand All @@ -25,7 +43,6 @@ Changes
- Rename ``RectPartition.is_uniform`` to ``RectPartition.is_uniform``
(`PR 468`).


ODL 0.2.3 Release Notes (2016-06-12)
====================================

Expand Down
11 changes: 5 additions & 6 deletions examples/diagnostics/diagonstics_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
from future import standard_library
standard_library.install_aliases()

# Internal
import odl

print('\n\n TESTING FOR Lp SPACE \n\n')
Expand All @@ -32,18 +31,18 @@

print('\n\n TESTING FOR Rn SPACE \n\n')

spc = odl.Rn(10)
spc = odl.rn(10)
odl.diagnostics.SpaceTest(spc).run_tests()


print('\n\n TESTING FOR Cn SPACE \n\n')

spc = odl.Cn(10)
spc = odl.cn(10)
odl.diagnostics.SpaceTest(spc).run_tests()


if odl.CUDA_AVAILABLE:
print('\n\n TESTING FOR CudaRn SPACE \n\n')
if 'cuda' in odl.FN_IMPLS:
print('\n\n TESTING FOR CUDA Rn SPACE \n\n')

spc = odl.CudaRn(10)
spc = odl.rn(10, impl='cuda')
odl.diagnostics.SpaceTest(spc, eps=0.0001).run_tests()
82 changes: 0 additions & 82 deletions examples/space/cudaspace_speedtest.py

This file was deleted.

26 changes: 13 additions & 13 deletions examples/space/simple_rn.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,23 +88,23 @@ def asarray(self, *args):
return self.data(*args)

r5 = SimpleRn(5)
odl.diagnostics.SpaceTest(r5).run_tests()
#odl.diagnostics.SpaceTest(r5).run_tests()

# Do some tests to compare
n = 10**7
iterations = 10

# Perform some benchmarks with Rn adn CudaRn
opt_spc = odl.Rn(n)
opt_spc = odl.rn(n)
simple_spc = SimpleRn(n)

x, y, z = np.random.rand(n), np.random.rand(n), np.random.rand(n)
ox, oy, oz = (opt_spc.element(x.copy()), opt_spc.element(y.copy()),
opt_spc.element(z.copy()))
sx, sy, sz = (simple_spc.element(x.copy()), simple_spc.element(y.copy()),
simple_spc.element(z.copy()))
if odl.CUDA_AVAILABLE:
cu_spc = odl.CudaRn(n)
if 'cuda' in odl.FN_IMPLS:
cu_spc = odl.rn(n, impl='cuda')
cx, cy, cz = (cu_spc.element(x.copy()), cu_spc.element(y.copy()),
cu_spc.element(z.copy()))

Expand All @@ -114,13 +114,13 @@ def asarray(self, *args):
simple_spc.lincomb(2.13, sx, 3.14, sy, out=sz)
print("result: {}".format(sz[1:5]))

with Timer("Rn"):
with Timer("odl numpy"):
for _ in range(iterations):
opt_spc.lincomb(2.13, ox, 3.14, oy, out=oz)
print("result: {}".format(oz[1:5]))

if odl.CUDA_AVAILABLE:
with Timer("CudaRn"):
if 'cuda' in odl.FN_IMPLS:
with Timer("odl cuda"):
for _ in range(iterations):
cu_spc.lincomb(2.13, cx, 3.14, cy, out=cz)
print("result: {}".format(cz[1:5]))
Expand All @@ -132,13 +132,13 @@ def asarray(self, *args):
result = sz.norm()
print("result: {}".format(result))

with Timer("Rn"):
with Timer("odl numpy"):
for _ in range(iterations):
result = oz.norm()
print("result: {}".format(result))

if odl.CUDA_AVAILABLE:
with Timer("CudaRn"):
if 'cuda' in odl.FN_IMPLS:
with Timer("odl cuda"):
for _ in range(iterations):
result = cz.norm()
print("result: {}".format(result))
Expand All @@ -150,13 +150,13 @@ def asarray(self, *args):
result = sz.inner(sx)
print("result: {}".format(result))

with Timer("Rn"):
with Timer("odl numpy"):
for _ in range(iterations):
result = oz.inner(ox)
print("result: {}".format(result))

if odl.CUDA_AVAILABLE:
with Timer("CudaRn"):
if 'cuda' in odl.FN_IMPLS:
with Timer("odl cuda"):
for _ in range(iterations):
result = cz.inner(cx)
print("result: {}".format(result))
2 changes: 1 addition & 1 deletion odl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

from __future__ import absolute_import

__version__ = '0.2.4'
__version__ = '0.3.0'
__all__ = ('diagnostics', 'discr', 'operator', 'set', 'space', 'solvers',
'tomo', 'trafos', 'util', 'phantom')

Expand Down
4 changes: 2 additions & 2 deletions odl/diagnostics/space.py
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,6 @@ def __repr__(self):


if __name__ == '__main__':
from odl import Rn, uniform_discr
SpaceTest(Rn(10)).run_tests()
from odl import rn, uniform_discr
SpaceTest(rn(10)).run_tests()
SpaceTest(uniform_discr([0, 0], [1, 1], [5, 5])).run_tests()
4 changes: 2 additions & 2 deletions odl/discr/diff_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ def derivative(self, point=None):

@property
def adjoint(self):
"""The adjoint operator.
"""Adjoint operator.
The adjoint is given by the negative `Divergence` with corrections for
the method and padding.
Expand Down Expand Up @@ -519,7 +519,7 @@ def derivative(self, point=None):

@property
def adjoint(self):
"""The adjoint operator.
"""Adjoint operator.
The adjoint is given by the negative `Gradient` with corrections for
the method and padding.
Expand Down
Loading

0 comments on commit cdef98d

Please sign in to comment.