[python-dtcwt] 390/497: add switchable backend support
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Tue Jul 21 18:06:31 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to branch debian/sid
in repository python-dtcwt.
commit f3278a494f4ffbc8fe2683528fc5c799d463bb9a
Author: Rich Wareham <rjw57 at cam.ac.uk>
Date: Mon Feb 10 16:16:32 2014 +0000
add switchable backend support
---
dtcwt/__init__.py | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 123 insertions(+), 1 deletion(-)
diff --git a/dtcwt/__init__.py b/dtcwt/__init__.py
index dff5ee4..97c70f4 100644
--- a/dtcwt/__init__.py
+++ b/dtcwt/__init__.py
@@ -1,8 +1,130 @@
-from .numpy import Transform1d, Transform2d, Transform3d, Pyramid
+import os
+import sys
+
+import dtcwt.numpy
+import dtcwt.opencl
__all__ = [
'Transform1d',
'Transform2d',
'Transform3d',
'Pyramid',
+
+ 'backend_name',
+ 'push_backend',
+ 'pop_backend',
+ 'preserve_backend_stack',
]
+
+# An array of dictionaries. Each dictionary stores the top-level module
+# variables for that backend.
+_BACKEND_STACK = []
+
+# Possible backends keyed by name
+_AVAILABLE_BACKENDS = {
+ 'numpy': {
+ 'Transform1d': dtcwt.numpy.Transform1d,
+ 'Transform2d': dtcwt.numpy.Transform2d,
+ 'Transform3d': dtcwt.numpy.Transform3d,
+ 'Pyramid': dtcwt.numpy.Pyramid,
+ },
+ 'opencl': {
+ 'Transform1d': dtcwt.numpy.Transform1d,
+ 'Transform2d': dtcwt.opencl.Transform2d,
+ 'Transform3d': dtcwt.numpy.Transform3d,
+ 'Pyramid': dtcwt.opencl.Pyramid,
+ },
+}
+
+def _update_from_current_backend():
+ # Update values from backend
+ for k,v in _BACKEND_STACK[-1][1].items():
+ setattr(dtcwt, k, v)
+ dtcwt.backend_name = _BACKEND_STACK[-1][0]
+
+class _BackendGuard(object):
+ def __init__(self, stack):
+ self._stack = list(stack)
+
+ def __enter__(self):
+ return _BACKEND_STACK
+
+ def __exit__(self, exc_type, exc_value, exc_tb):
+ dtcwt._BACKEND_STACK = self._stack
+ # only re-raise if it's *not* the exception that was
+ # passed to throw(), because __exit__() must not raise
+ # an exception unless __exit__() itself failed. But
+ # throw() has to raise the exception to signal
+ # propagation, so this fixes the impedance mismatch
+ # between the throw() protocol and the __exit__()
+ # protocol.
+ #
+ if sys.exc_info()[1] is not exc_value:
+ raise
+
+def preserve_backend_stack():
+ """Return a generator object which can be used to preserve the backend
+ stack even when an exception has been raise. For example:
+
+ .. code-block:: python
+
+ # current backend is NumPy
+ assert dtcwt.backend_name == 'numpy'
+
+ with dtcwt.preserve_backend_stack():
+ dtcwt.push_backend('opencl')
+ # ... things which may raise an exception
+
+ # current backend is NumPy even if an exception was thrown
+ assert dtcwt.backend_name == 'numpy'
+
+ """
+ return _BackendGuard(_BACKEND_STACK)
+
+def push_backend(name):
+ """Switch backend implementation to *name*. Push the previous backend onto
+ the backend stack. The previous backend may be restored via
+ :py:func:`dtcwt.pop_backend`.
+
+ :param name: string identifying which backend to switch to
+ :raises ValueError: if *name* does not correspond to a known backend
+
+ *name* may take one of the following values:
+
+ * ``numpy``: the default NumPy backend. See :py:mod:`dtcwt.numpy`.
+ * ``opencl``: a backend which uses OpenCL where available. See
+ :py:mod:`dtcwt.opencl`.
+
+ """
+ try:
+ _BACKEND_STACK.append((name, _AVAILABLE_BACKENDS[name]))
+ except KeyError:
+ raise ValueError('No such backend: {0}'.format(name))
+ _update_from_current_backend()
+
+def pop_backend():
+ """Restore the backend after a call to :py:func:`push_backend`. Calls to
+ :py:func:`pop_backend` and :py:func:`pop_backend` may be neted. This
+ function will undo the most recent call to :py:func:`push_backend`.
+
+ :raise IndexError: if one attempts to pop more backends than one has pushed.
+
+ """
+ # It is an error to pop off the default backend
+ if len(_BACKEND_STACK) <= 1:
+ raise IndexError('Cannot pop default backend')
+
+ _BACKEND_STACK.pop()
+ _update_from_current_backend()
+
+backend_name = None
+"""A string providing a short human-readable name for the DTCWT backend
+currently being used. This corresponds to the *name* parameter passed to
+:py:func:`dtcwt.push_backend`. The *default* backend is ``numpy`` but can be
+overridden by setting the DTCWT_BACKEND environment variable to a valid backend
+name.
+"""
+
+# Default to the numpy backend unless DTCWT_BACKEND environment variable is
+# set.
+push_backend(os.getenv('DTCWT_BACKEND', 'numpy'))
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/python-dtcwt.git
More information about the debian-science-commits
mailing list