提交 3704fc21 authored 作者: Olivier Delalleau's avatar Olivier Delalleau

Merged

...@@ -24,3 +24,5 @@ pull.sh ...@@ -24,3 +24,5 @@ pull.sh
setuptools-*.egg setuptools-*.egg
theano/version.py theano/version.py
theano/version.py.out theano/version.py.out
distribute-*.egg
distribute-*.tar.gz
Theano is a Python library that allows you to define, optimize, and efficiently evaluate mathematical expressions involving multi-dimensional arrays. It is built on top of NumPy_. Theano features:
* **tight integration with NumPy:** a similar interface to NumPy's. numpy.ndarrays are also used internally in Theano-compiled functions.
* **transparent use of a GPU:** perform data-intensive computations up to 140x faster than on a CPU (support for float32 only).
* **efficient symbolic differentiation:** Theano can compute derivatives for functions of one or many inputs.
* **speed and stability optimizations:** avoid nasty bugs when computing expressions such as log(1+ exp(x) ) for large values of x.
* **dynamic C code generation:** evaluate expressions faster.
* **extensive unit-testing and self-verification:** includes tools for detecting and diagnosing bugs and/or potential problems.
Theano has been powering large-scale computationally intensive scientific
research since 2007, but it is also approachable enough to be used in the
classroom (IFT6266 at the University of Montreal).
.. _NumPy: http://numpy.scipy.org/
...@@ -3,3 +3,4 @@ global-include *.cu ...@@ -3,3 +3,4 @@ global-include *.cu
global-include *.cuh global-include *.cuh
global-include *.sh global-include *.sh
include ChangeLog include ChangeLog
include distribute_setup.py
To install the package, see this page: To install the package, see this page:
http://deeplearning.net/software/theano/install.html#install http://deeplearning.net/software/theano/install.html
For the documentation, see the project website: For the documentation, see the project website:
......
差异被折叠。
...@@ -20,7 +20,7 @@ to be installed: ...@@ -20,7 +20,7 @@ to be installed:
We develop mainly on 64-bit Linux machines. 32-bit architectures are We develop mainly on 64-bit Linux machines. 32-bit architectures are
not well-tested. not well-tested.
Python >= 2.4 Python_ >= 2.4
Including the development package (``python-dev`` or ``python-devel`` Including the development package (``python-dev`` or ``python-devel``
on most Linux distributions). on most Linux distributions).
...@@ -34,7 +34,7 @@ to be installed: ...@@ -34,7 +34,7 @@ to be installed:
`SciPy <http://scipy.org>`_ `SciPy <http://scipy.org>`_
Only currently required for sparse matrix and special functions Only currently required for sparse matrix and special functions
support, but highly recommended. We recommend SciPy support, but *highly* recommended. We recommend SciPy
>=0.7 if you are using sparse matrices, because ``scipy.sparse`` >=0.7 if you are using sparse matrices, because ``scipy.sparse``
is buggy in 0.6 (the ``scipy.csc_matrix`` version of ``dot()`` has a is buggy in 0.6 (the ``scipy.csc_matrix`` version of ``dot()`` has a
bug with singleton dimensions, there may be more bugs). bug with singleton dimensions, there may be more bugs).
...@@ -46,6 +46,7 @@ to be installed: ...@@ -46,6 +46,7 @@ to be installed:
.. _BLAS: http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms .. _BLAS: http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms
.. _Accelerate framework: http://developer.apple.com/performance/accelerateframework.html .. _Accelerate framework: http://developer.apple.com/performance/accelerateframework.html
.. _Python: http://www.python.org/
The following libraries and software are optional: The following libraries and software are optional:
...@@ -54,83 +55,151 @@ The following libraries and software are optional: ...@@ -54,83 +55,151 @@ The following libraries and software are optional:
`Sphinx <http://sphinx.pocoo.org/>`_ >= 0.5.1, `pygments <http://pygments.org/>`_ `Sphinx <http://sphinx.pocoo.org/>`_ >= 0.5.1, `pygments <http://pygments.org/>`_
For building the documentation. LaTeX_ and dvipng_ are also necessary For building the documentation. LaTeX_ and dvipng_ are also necessary
for math to show up as images. for math to show up as images.
`Mercurial <http://www.selenic.com/mercurial/>`_ `Mercurial <http://mercurial.selenic.com/>`_
To download bleeding-edge versions of Theano. To download bleeding-edge versions of Theano.
`NVIDIA CUDA drivers and SDK `NVIDIA CUDA drivers and SDK`_
<http://developer.nvidia.com/object/gpucomputing.html>`_
Required for GPU code generation/execution. Only NVIDIA GPUs using Required for GPU code generation/execution. Only NVIDIA GPUs using
32-bit floating point numbers are currently supported. 32-bit floating point numbers are currently supported.
.. _LaTeX: http://www.latex-project.org/ .. _LaTeX: http://www.latex-project.org/
.. _dvipng: http://savannah.nongnu.org/projects/dvipng/ .. _dvipng: http://savannah.nongnu.org/projects/dvipng/
.. _NVIDIA CUDA drivers and SDK: http://developer.nvidia.com/object/gpucomputing.html
Basic user install instructions Basic user install instructions
------------------------------- -------------------------------
The easiest way to obtain the released version of Theano is from PyPI using The easiest way to obtain the released version of Theano is from PyPI using
the ``easy_install`` command provided by distribute_ (and it's predecessor, pip_ (a replacement for easy_install_ provided by setuptools_/distribute_)
`setuptools`_). If you have one of these installed, installing Theano should by typing
be simply a matter of::
.. code-block:: bash
pip install Theano
You may need to add ``sudo`` before this command to install into your
system's ``site-packages`` directory. If you do not have administrator access
to your machine, you can install to an alternate prefix using
.. code-block:: bash
pip install Theano --install-option='--prefix=YOURPREFIX'
easy_install Theano e.g. using ``--install-option='--prefix=~/.local'`` on Python 2.4 would
install Theano into ``.local/lib/python2.4/site-packages`` inside your home
directory on Mac OS X or Unix/Linux (this ``site-packages`` directory must be
listed in your ``$PYTHONPATH``; for Python 2.6 and later, ``~/.local`` is
automatically searched and does *not* need to be explicitly included in
``$PYTHONPATH``, see :ref:`config_pythonpath` for instructions).
Alternatively you can use virtualenv_ to create an isolated ``site-packages``
directory; see the `virtualenv documentation`_ for details.
.. note::
Theano *can* be installed with easy_install_, however we recommend pip_ as
a long-standing bug in ``easy_install`` prevents ``theano.test()`` from
running the Theano test suite; ``pip`` offers many other benefits over
``easy_install`` such as more intelligent dependency management, better
error messages and a ``pip uninstall`` command for easily removing
packages.
If you do not have ``pip`` installed but do have ``easy_install``, you can
get ``pip`` by simply typing ``easy_install pip``.
.. _distribute: http://packages.python.org/distribute/ .. _distribute: http://packages.python.org/distribute/
.. _setuptools: http://pypi.python.org/pypi/setuptools .. _setuptools: http://pypi.python.org/pypi/setuptools
.. _easy_install: http://packages.python.org/distribute/easy_install.html
.. _virtualenv: http://pypi.python.org/pypi/virtualenv
.. _virtualenv documentation: http://virtualenv.openplans.org/
.. _pip: http://pypi.python.org/pypi/pip
.. _install_bleeding_edge: .. _install_bleeding_edge:
Bleeding-edge (developer) install instructions Bleeding-edge (developer) install instructions
---------------------------------------------- ----------------------------------------------
If you are a developer of Theano, then check out the :ref:`dev_start_guide` If you are a developer of Theano, then check out the :ref:`dev_start_guide`.
guide.
The following are general instructions that will set you up with the The following are general instructions that will set you up with the
bleeding-edge version of Theano. First, get the code using `mercurial bleeding-edge version of Theano. First, get the code using `Mercurial
<http://www.selenic.com/mercurial/wiki/>`__: <http://mercurial.selenic.com/>`__:
.. code-block:: bash .. code-block:: bash
hg clone http://hg.assembla.com/theano Theano hg clone http://hg.assembla.com/theano Theano
Configuring ``PYTHONPATH`` From here, the easiest way to get started is
--------------------------
.. code-block:: bash
cd Theano
python setup.py develop
The subdirectory ``Theano/theano`` has to be located in a path mentioned in This will install a ``.pth`` file in your ``site-packages`` directory that
your ``PYTHONPATH``. In order to do that, you can either create a symbolic tells Python where to look for your Theano installation (i.e. in the
link to Theano/theano in a directory already mentioned in your ``PYTHONPATH`` directory your just checked out of Mercurial). Using ``develop`` mode is
environment variable, or modify the ``PYTHONPATH`` so that it mentions Theano. preferable to ``install`` as any modifications you make in the checkout
directory (or changes you pull with Mercurial) will be automatically reflected
in the "installed" version without re-running ``python setup.py install``.
To create a symbolic link: If you do not have permission to modify your ``site-packages`` directory you
can specify an alternative installation prefix using
.. code-block:: bash .. code-block:: bash
ln -s Theano/theano <someplace on your PYTHONPATH>/theano python setup.py develop --prefix=YOURPREFIX
A common choice is ``~/.local`` which is automatically searched for Python >=
2.6; for earlier Python versions and other installation prefixes, the prefix
specified must contain ``lib/pythonA.B/site-packages``, where ``A.B`` is e.g.
2.5, and this ``site-packages`` directory must be listed in ``$PYTHONPATH``.
An alternative, perhaps simpler way of creating and using an isolated
``site-packages`` is to use virtualenv_; see the `virtualenv documentation`_
for details. If you find yourself using virtualenv frequently you may find the
virtualenvwrapper_ package useful for switching between them.
.. _virtualenv: http://pypi.python.org/pypi/virtualenv
.. _virtualenv documentation: http://virtualenv.openplans.org/
.. _virtualenvwrapper: http://www.doughellmann.com/projects/virtualenvwrapper/
.. _config_pythonpath:
Configuring ``PYTHONPATH``
##########################
To modify the environment variable PYTHONPATH in bash, you may do this: To modify the environment variable ``PYTHONPATH`` in bash, you may do this:
.. code-block:: bash .. code-block:: bash
export PYTHONPATH=<path to Theano's parent dir>/Theano:$PYTHONPATH export PYTHONPATH=<new location to add>:$PYTHONPATH
In csh: In csh:
.. code-block:: csh .. code-block:: csh
setenv PYTHONPATH <path to Theano's parent dir>/Theano:$PYTHONPATH setenv PYTHONPATH <new location to add>:$PYTHONPATH
To make this change stick you'll usually need to add the command to one or
more of your shell's startup scripts, i.e. ``~/.bashrc`` or ``~/.cshrc``.
Consult your shell's documentation for details.
Testing your installation Testing your installation
--------------------------- ---------------------------
Once you have completed these steps, you should run the theano test suite like this: Once you have completed these steps, you should run the Theano test suite. At
a Python (or IPython) interpreter,
.. code-block:: bash .. code-block:: python
cd Theano >>> import theano
THEANO_FLAGS=warn.ignore_bug_before=all nosetests #execute all the tests >>> theano.test()
You can also run them in-place from the Mercurial checkout directory by typing
.. code-block:: bash
nosetests
``THEANO_FLAGS`` is an environment variable that define Theano flags ``THEANO_FLAGS`` is an environment variable that define Theano flags
(:ref:`libdoc_config`). For Windows users, you can remove it or see the (:ref:`libdoc_config`). For Windows users, you can remove it or see the
...@@ -144,7 +213,7 @@ the ``theano-users@googlegroups.com`` mailing list. ...@@ -144,7 +213,7 @@ the ``theano-users@googlegroups.com`` mailing list.
`warn.ignore_bug_before=all` removes warnings that you don't need to see `warn.ignore_bug_before=all` removes warnings that you don't need to see
here. It is also recommended for a new user to set this flag to a here. It is also recommended for a new user to set this flag to a
different value into their .theanorc file. See different value in their ``.theanorc`` file. See
:attr:`config.warn.ignore_bug_before` for more details. :attr:`config.warn.ignore_bug_before` for more details.
Troubleshooting: Make sure you have a BLAS library Troubleshooting: Make sure you have a BLAS library
...@@ -169,7 +238,6 @@ entry like this: ...@@ -169,7 +238,6 @@ entry like this:
.. code-block:: cfg .. code-block:: cfg
# other stuff can go here # other stuff can go here
[blas] [blas]
ldflags = -lf77blas -latlas -lgfortran #put your flags here ldflags = -lf77blas -latlas -lgfortran #put your flags here
......
...@@ -100,8 +100,9 @@ Nightly test ...@@ -100,8 +100,9 @@ Nightly test
============ ============
Each night we execute all the unit tests automatically. The result is sent by Each night we execute all the unit tests automatically. The result is sent by
email to one of the developers, who (at his discretion) forwards it to the email to the `theano-buildbot`_ mailing list.
mailing list. Said developer may not read his email obsessively (especially
on the weekend) so there might be some latency in the process. For more .. _theano-buildbot: https://groups.google.com/group/theano-buildbot
detail :ref:`see <metadocumentation_nightly_build>`.
For more detail, see :ref:`see <metadocumentation_nightly_build>`.
...@@ -129,33 +129,19 @@ You can see a list of all `pylint messages ...@@ -129,33 +129,19 @@ You can see a list of all `pylint messages
The nightly build/tests process The nightly build/tests process
--------------------------------------- ---------------------------------------
The user ``lisa`` runs a cronjob on the computer ``boltzmann``. The user ``lisa`` runs a cronjob on the computer ``ceylon``, this
This happens nightly. happens nightly. (To have the crontab executed, the ``lisa`` user must
The cronjob executes the script ``~/www/nightly_build/do_nightly_build_theano``. be logged into ``ceylon``, Fred leaves a shell open for that.)
This script performs a an "hg pull -u" of theano (and pylearn too).
Then it executes something like
.. code-block:: bash The cronjob executes the scripts
``~/nightly_build/do_nightly_build_{theano,pylearn,deeplearning}``.
THEANO_FLAGS='unittests.rseed=<SEED>,mode=DEBUG_MODE' /usr/bin/nosetests --with-coverage --cover-package=theano --cover-package=pylearn These scripts perform an "hg pull -u" of theano (and pylearn, and
DeepLearningTutorials too), and execute nosetests (in various settings).
in the updated ``theano`` directory.
The output is emailed automatically to one of the developers.
This line is executed with a several fixed ``SEED`` values in DEBUG_MODE. It
is executed in FAST_RUN and FAST_COMPILE with just one SEED value.
We can't email directly to the mailing list as it is emailed as the root user. The output is emailed automatically to the `theano-buildbot`_ mailing list.
We haven't yet found a way to have google groups accept email from a user without sending an email to it.
As we don't have root control from this domain, we won't receive the email.
We haven't pursued the option of configuring the ``lisa`` account to send
email from an official gmail account.
Also, to have the crontab executed, *the ``lisa`` user must be logged into .. _theano-buildbot: https://groups.google.com/group/theano-buildbot
``boltzmann``*.
In a nutshell: Fred keeps a shell open on boltzmann at all times, gets the
email, and forwards it to the mailing list when something interesting shows up
in the report.
TO WRITE TO WRITE
--------------------------------------- ---------------------------------------
......
...@@ -4,11 +4,21 @@ ...@@ -4,11 +4,21 @@
# * Figure out how to compile and install documentation automatically # * Figure out how to compile and install documentation automatically
# * Add download_url # * Add download_url
# Detect whether or not the user has setuptools and use the bundled
# distribute_setup.py bootstrap module if they don't.
try:
from setuptools import setup, find_packages
except ImportError:
import distribute_setup
distribute_setup.use_setuptools()
from setuptools import setup, find_packages
import os import os
import subprocess import subprocess
CLASSIFIERS = """\ CLASSIFIERS = """\
Development Status :: 4 - Beta Development Status :: 4 - Beta
Intended Audience :: Education
Intended Audience :: Science/Research Intended Audience :: Science/Research
Intended Audience :: Developers Intended Audience :: Developers
License :: OSI Approved :: BSD License License :: OSI Approved :: BSD License
...@@ -26,7 +36,7 @@ MAINTAINER = "LISA laboratory, University of Montreal" ...@@ -26,7 +36,7 @@ MAINTAINER = "LISA laboratory, University of Montreal"
MAINTAINER_EMAIL = "theano-dev@googlegroups.com" MAINTAINER_EMAIL = "theano-dev@googlegroups.com"
DESCRIPTION = ('Optimizing compiler for evaluating mathematical ' + DESCRIPTION = ('Optimizing compiler for evaluating mathematical ' +
'expressions on CPUs and GPUs.') 'expressions on CPUs and GPUs.')
LONG_DESCRIPTION = "" LONG_DESCRIPTION = open("DESCRIPTION.txt").read()
URL = "http://deeplearning.net/software/theano/" URL = "http://deeplearning.net/software/theano/"
DOWNLOAD_URL = "" DOWNLOAD_URL = ""
LICENSE = 'BSD' LICENSE = 'BSD'
...@@ -37,7 +47,7 @@ PLATFORMS = ["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"] ...@@ -37,7 +47,7 @@ PLATFORMS = ["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"]
MAJOR = 0 MAJOR = 0
MINOR = 3 MINOR = 3
MICRO = 0 MICRO = 0
SUFFIX = "rc3" # Should be blank except for rc's, betas, etc. SUFFIX = "rc4" # Should be blank except for rc's, betas, etc.
ISRELEASED = False ISRELEASED = False
VERSION = '%d.%d.%d%s' % (MAJOR, MINOR, MICRO, SUFFIX) VERSION = '%d.%d.%d%s' % (MAJOR, MINOR, MICRO, SUFFIX)
...@@ -106,14 +116,16 @@ if not release: ...@@ -106,14 +116,16 @@ if not release:
def do_setup(): def do_setup():
write_version_py() write_version_py()
from setuptools import setup, find_packages
setup(name=NAME, setup(name=NAME,
version=VERSION, version=VERSION,
description=DESCRIPTION, description=DESCRIPTION,
long_description=LONG_DESCRIPTION,
classifiers=CLASSIFIERS,
author=AUTHOR, author=AUTHOR,
author_email=AUTHOR_EMAIL, author_email=AUTHOR_EMAIL,
url=URL, url=URL,
license=LICENSE, license=LICENSE,
platforms=PLATFORMS,
packages=find_packages(), packages=find_packages(),
install_requires=['numpy>=1.3.0', 'scipy>=0.7.0'], install_requires=['numpy>=1.3.0', 'scipy>=0.7.0'],
package_data={ package_data={
......
...@@ -110,7 +110,4 @@ try: ...@@ -110,7 +110,4 @@ try:
import theano.version import theano.version
__version__ = theano.version.version __version__ = theano.version.version
except ImportError: except ImportError:
import warnings __version__ = "unknown"
warnings.warn(
"version.py could not be imported. Run setup.py at least once to generate it"
)
import atexit, gc, os, stat import atexit, os, stat
from theano.compile import optdb from theano.compile import optdb
from theano import config from theano import config
...@@ -96,9 +96,6 @@ if cuda_available: ...@@ -96,9 +96,6 @@ if cuda_available:
cuda_initialization_error_message = "" cuda_initialization_error_message = ""
# actively closing our gpu session presents segfault-on-exit on some systems # actively closing our gpu session presents segfault-on-exit on some systems
atexit.register(gpu_shutdown) atexit.register(gpu_shutdown)
# do garbage collection before releasing the gpu to avoid releasing invalid pointers later
# note that atexit-registered calls are called in LIFO order
atexit.register(gc.collect)
except EnvironmentError, e: except EnvironmentError, e:
cuda_available = False cuda_available = False
cuda_initialization_error_message = e.message cuda_initialization_error_message = e.message
......
...@@ -12,11 +12,43 @@ ...@@ -12,11 +12,43 @@
//If true, we fill with NAN allocated device memory. //If true, we fill with NAN allocated device memory.
#define ALLOC_MEMSET 0 #define ALLOC_MEMSET 0
#define DEBUG_GPU_CONTEXT_REFCOUNT 0
// g_gpu_context_refcount starts at one b/c the gpu context will be implicitly created
// on the first successful cuda call. the matching decref is in CudaNdarray_gpu_shutdown.
static int g_gpu_context_refcount = 1;
///////////////////////////
// cuda context management
///////////////////////////
void gpu_context_incref() {
g_gpu_context_refcount++;
#if DEBUG_GPU_CONTEXT_REFCOUNT
fprintf(stderr, "gpu_context_incref, to %d\n", g_gpu_context_refcount);
#endif
}
void gpu_context_decref() {
g_gpu_context_refcount--;
#if DEBUG_GPU_CONTEXT_REFCOUNT
fprintf(stderr, "gpu_context_decref, to %d\n", g_gpu_context_refcount);
#endif
if(g_gpu_context_refcount == 0) {
// we're now free to close the cuda context; if we don't explicitly
// exit our cuda context, some systems segfault on process exit
// for as-yet unknown reasons; see
// http://groups.google.com/group/theano-users/browse_thread/thread/c351846e5cebe35f
cudaThreadExit();
#if DEBUG_GPU_CONTEXT_REFCOUNT
fprintf(stderr, "gpu_context_decref at 0, calling cudaThreadExit\n");
#endif
}
}
///////////////////////// /////////////////////////
// Alloc and Free // Alloc and Free
///////////////////////// /////////////////////////
/** /**
* *
* In the test program I'm using, the _outstanding_mallocs decreases with every call. * In the test program I'm using, the _outstanding_mallocs decreases with every call.
...@@ -48,6 +80,9 @@ void * device_malloc(size_t size) ...@@ -48,6 +80,9 @@ void * device_malloc(size_t size)
return NULL; return NULL;
} }
_outstanding_mallocs[0] += (rval != NULL); _outstanding_mallocs[0] += (rval != NULL);
if(rval != NULL) {
gpu_context_incref(); // keep the gpu context around until we've free this memory
}
#if COMPUTE_GPU_MEM_USED #if COMPUTE_GPU_MEM_USED
for(int i=0;i<TABLE_SIZE;i++){ for(int i=0;i<TABLE_SIZE;i++){
if(NULL==_alloc_size_table[i].ptr){ if(NULL==_alloc_size_table[i].ptr){
...@@ -81,6 +116,9 @@ int device_free(void *ptr) ...@@ -81,6 +116,9 @@ int device_free(void *ptr)
return -1; return -1;
} }
_outstanding_mallocs[0] -= (ptr != NULL); _outstanding_mallocs[0] -= (ptr != NULL);
if(ptr != NULL) {
gpu_context_decref();
}
#if COMPUTE_GPU_MEM_USED #if COMPUTE_GPU_MEM_USED
int i=0; int i=0;
for(;i<TABLE_SIZE;i++) for(;i<TABLE_SIZE;i++)
...@@ -1888,7 +1926,7 @@ CudaNdarray_gpu_init(PyObject* _unused, PyObject* args) ...@@ -1888,7 +1926,7 @@ CudaNdarray_gpu_init(PyObject* _unused, PyObject* args)
PyObject * PyObject *
CudaNdarray_gpu_shutdown(PyObject* _unused, PyObject* _unused_args) { CudaNdarray_gpu_shutdown(PyObject* _unused, PyObject* _unused_args) {
cudaThreadExit(); gpu_context_decref();
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
......
...@@ -812,8 +812,8 @@ def test_shared_float32(): ...@@ -812,8 +812,8 @@ def test_shared_float32():
del theano.shared.constructors[-1] del theano.shared.constructors[-1]
import theano.tensor.tests.test_basic import theano.tensor.tests.test_sharedvar
test_shared_options = theano.tensor.tests.test_basic.makeSharedTester( test_shared_options = theano.tensor.tests.test_sharedvar.makeSharedTester(
tcn.shared_constructor, 'float32', False, False, False, tcn.shared_constructor, 'float32', False, False, False,
cuda_ndarray.CudaNdarray, cuda_ndarray.CudaNdarray,
lambda a: isinstance(a,cuda_ndarray.CudaNdarray), lambda a: isinstance(a,cuda_ndarray.CudaNdarray),
......
...@@ -23,6 +23,7 @@ from theano.sparse import csc_from_dense, csr_from_dense, dense_from_sparse ...@@ -23,6 +23,7 @@ from theano.sparse import csc_from_dense, csr_from_dense, dense_from_sparse
from theano.tests import unittest_tools as utt from theano.tests import unittest_tools as utt
from theano import tensor from theano import tensor
from theano.tensor.basic import _allclose
def eval_outputs(outputs): def eval_outputs(outputs):
...@@ -298,7 +299,7 @@ class test_structureddot(unittest.TestCase): ...@@ -298,7 +299,7 @@ class test_structureddot(unittest.TestCase):
scipy_result = spmat * mat scipy_result = spmat * mat
assert theano_result.shape == scipy_result.shape assert theano_result.shape == scipy_result.shape
assert theano_result.dtype == scipy_result.dtype assert theano_result.dtype == scipy_result.dtype
assert numpy.allclose(theano_result, scipy_result) assert _allclose(theano_result, scipy_result)
def test_opt_unpack(self): def test_opt_unpack(self):
...@@ -440,8 +441,8 @@ class test_structureddot(unittest.TestCase): ...@@ -440,8 +441,8 @@ class test_structureddot(unittest.TestCase):
self.failUnless(numpy.allclose(theano_result, scipy_result)) self.failUnless(numpy.allclose(theano_result, scipy_result))
self.failIf(theano_time > overhead_rtol*scipy_time + overhead_tol) self.failIf(theano_time > overhead_rtol*scipy_time + overhead_tol)
import theano.tensor.tests.test_basic import theano.tensor.tests.test_sharedvar
test_shared_options=theano.tensor.tests.test_basic.makeSharedTester( test_shared_options=theano.tensor.tests.test_sharedvar.makeSharedTester(
theano.sparse.shared, 'float64', theano.sparse.shared, 'float64',
True, True, True, scipy.sparse.csc_matrix, scipy.sparse.issparse, True, True, True, scipy.sparse.csc_matrix, scipy.sparse.issparse,
lambda a: dense_from_sparse(a*2.), lambda a: dense_from_sparse(a*2.),
......
...@@ -321,6 +321,11 @@ def _allclose(a, b): ...@@ -321,6 +321,11 @@ def _allclose(a, b):
else: else:
atol = float64_atol atol = float64_atol
rtol = float64_rtol rtol = float64_rtol
# Work around bug in Numpy, see http://projects.scipy.org/numpy/ticket/1684
if str(b.dtype).startswith('int') and (numpy.absolute(b) < 0).any():
b = theano._asarray(b, dtype='float64')
return numpy.allclose(a,b, atol=atol, rtol=rtol) return numpy.allclose(a,b, atol=atol, rtol=rtol)
def get_constant_value(v): def get_constant_value(v):
......
...@@ -3440,202 +3440,6 @@ def test_dimshuffle_duplicate(): ...@@ -3440,202 +3440,6 @@ def test_dimshuffle_duplicate():
assert success assert success
def makeSharedTester(shared_constructor_,
dtype_,
get_value_borrow_true_alias_,
shared_borrow_true_alias_,
set_value_borrow_true_alias_,
internal_type_,
test_internal_type_,
theano_fct_,
ref_fct_,
cast_value_ = numpy.asarray,
add_matrix_ = False):
"""
This is a generic fct to allow reusing the same test function
for many shared variable of many types.
We must use /= as sparse type don't support other inplace operation.
"""
class SharedTester(unittest.TestCase):
shared_constructor = staticmethod(shared_constructor_)
dtype = dtype_
get_value_borrow_true_alias = get_value_borrow_true_alias_
shared_borrow_true_alias = shared_borrow_true_alias_
internal_type = internal_type_
test_internal_type = staticmethod(test_internal_type_)
theano_fct = staticmethod(theano_fct_)
ref_fct = staticmethod(ref_fct_)
set_value_borrow_true_alias = set_value_borrow_true_alias_
cast_value = staticmethod(cast_value_)
add_matrix = add_matrix_
def test_shared_dont_alias(self):
dtype = self.dtype
if dtype is None:
dtype = theano.config.floatX
rng = numpy.random.RandomState([3,5,17])
x = numpy.asarray(rng.uniform(0,1,[2,4]),dtype=dtype)
x = self.cast_value(x)
x_ref = self.ref_fct(x)
x_shared = self.shared_constructor(x, borrow = False)
total = self.theano_fct(x_shared)
total_func = theano.function([],total)
total_val = total_func()
assert numpy.allclose(self.ref_fct(x), total_val)
x /= .5
total_val_2 = total_func()
#value used to construct should not alias with internal
assert numpy.allclose(total_val, total_val_2)
x = x_shared.get_value(borrow = False)
x /= .5
total_val_3 = total_func()
#value returned by access should not alias with internal
assert numpy.allclose(total_val, total_val_3)
#in this case we can alias
x = x_shared.get_value(borrow = True)
x /= .5
#this is not required by the contract but it is a feature we've
#implemented for some type of SharedVariable.
if self.get_value_borrow_true_alias:
assert numpy.allclose(self.ref_fct(x), total_func())
else:
assert numpy.allclose(x_ref, total_func())
def test_return_internal_type(self):
dtype = self.dtype
if dtype is None:
dtype = theano.config.floatX
rng = numpy.random.RandomState([3,5,17])
x = numpy.asarray(rng.uniform(0,1,[2,4]),dtype=dtype)
x = self.cast_value(x)
x_ref = self.ref_fct(x)
x_shared = self.shared_constructor(x, borrow = False)
total = self.theano_fct(x_shared)
total_func = theano.function([],total)
#in this case we can alias with the internal value
x = x_shared.get_value(borrow = True, return_internal_type = True)
assert self.test_internal_type(x)
values_to_add = .5
if self.add_matrix:
values_to_add = self.internal_type(numpy.ones(x.shape,dtype=dtype)/2)#supported for cudandarray, but not ndarray.
x /= values_to_add#supported by ndarray and CudaNdarray
#this is not required by the contract but it is a feature we can
#implement for some type of SharedVariable.
assert numpy.allclose(self.ref_fct(x), total_func())
x = x_shared.get_value(borrow = False, return_internal_type = True)
assert self.test_internal_type(x)
assert x is not x_shared.container.value
x /= values_to_add#supported by ndarray and CudaNdarray
#this is required by the contract
assert not numpy.allclose(self.ref_fct(x), total_func())
def test_set_value(self):
dtype = self.dtype
if dtype is None:
dtype = theano.config.floatX
rng = numpy.random.RandomState([3,5,17])
x = numpy.asarray(rng.uniform(0,1,[2,4]),dtype=dtype)
x = self.cast_value(x)
x_orig = x
x_orig_copy = x.copy()
x_ref = self.ref_fct(x)
x_shared = self.shared_constructor(x, borrow = False)
total = self.theano_fct(x_shared)
total_func = theano.function([],total)
#test if that theano shared variable optimize set_value(borrow=True)
get_x = x_shared.get_value(borrow=True)
assert get_x is not x_orig#borrow=False to shared_constructor
get_x /= .5
x_shared.set_value(get_x, borrow=True)
x = x_shared.get_value(borrow=True)
if self.set_value_borrow_true_alias:
assert x is get_x
else:
assert x is not get_x
assert numpy.allclose(self.ref_fct(x_orig/.5),self.ref_fct(x))
#test optimized get set value on the gpu(don't pass data to the cpu)
get_x = x_shared.get_value(borrow=True, return_internal_type=True)
assert get_x is not x_orig#borrow=False to shared_constructor
assert self.test_internal_type(get_x)
values_to_add = .5
if self.add_matrix:
values_to_add = self.internal_type(numpy.ones(x.shape,dtype=dtype)/2)#supported for cudandarray, but not ndarray.
assert self.test_internal_type(values_to_add)
get_x /= values_to_add#supported by ndarray and CudaNdarray
assert self.test_internal_type(get_x)
x_shared.set_value(get_x, borrow=True)
x = x_shared.get_value(borrow=True, return_internal_type=True)
assert self.test_internal_type(x)
assert x is get_x
################ TODO test Out.
def test_shared_do_alias(self):
dtype = self.dtype
if dtype is None:
dtype = theano.config.floatX
rng = numpy.random.RandomState([2,4,16])
x = numpy.asarray(rng.uniform(1,2,[4,2]),dtype=dtype)
x = self.cast_value(x)
x_ref = self.ref_fct(x)
x_shared = self.shared_constructor(x, borrow = True)
total = self.theano_fct(x_shared)
total_func = theano.function([],total)
total_val = total_func()
assert numpy.allclose(self.ref_fct(x), total_val)
x /= .5
#not required by the contract but it is a feature we've implemented
if self.shared_borrow_true_alias:
assert numpy.allclose(self.ref_fct(x), total_func())
else:
assert numpy.allclose(x_ref, total_func())
return SharedTester
test_shared_options=makeSharedTester(tensor.shared, 'float64',
True, True, True,
numpy.ndarray,
lambda a: isinstance(a,numpy.ndarray),
theano.tensor.sum,
numpy.sum)
if __name__ == '__main__': if __name__ == '__main__':
if 1: if 1:
unittest.main() unittest.main()
......
import numpy
import unittest
import theano
from theano import tensor
def makeSharedTester(shared_constructor_,
dtype_,
get_value_borrow_true_alias_,
shared_borrow_true_alias_,
set_value_borrow_true_alias_,
internal_type_,
test_internal_type_,
theano_fct_,
ref_fct_,
cast_value_ = numpy.asarray,
add_matrix_ = False):
"""
This is a generic fct to allow reusing the same test function
for many shared variable of many types.
We must use /= as sparse type don't support other inplace operation.
"""
class SharedTester(unittest.TestCase):
shared_constructor = staticmethod(shared_constructor_)
dtype = dtype_
get_value_borrow_true_alias = get_value_borrow_true_alias_
shared_borrow_true_alias = shared_borrow_true_alias_
internal_type = internal_type_
test_internal_type = staticmethod(test_internal_type_)
theano_fct = staticmethod(theano_fct_)
ref_fct = staticmethod(ref_fct_)
set_value_borrow_true_alias = set_value_borrow_true_alias_
cast_value = staticmethod(cast_value_)
add_matrix = add_matrix_
def test_shared_dont_alias(self):
dtype = self.dtype
if dtype is None:
dtype = theano.config.floatX
rng = numpy.random.RandomState([3,5,17])
x = numpy.asarray(rng.uniform(0,1,[2,4]),dtype=dtype)
x = self.cast_value(x)
x_ref = self.ref_fct(x)
x_shared = self.shared_constructor(x, borrow = False)
total = self.theano_fct(x_shared)
total_func = theano.function([],total)
total_val = total_func()
assert numpy.allclose(self.ref_fct(x), total_val)
x /= .5
total_val_2 = total_func()
#value used to construct should not alias with internal
assert numpy.allclose(total_val, total_val_2)
x = x_shared.get_value(borrow = False)
x /= .5
total_val_3 = total_func()
#value returned by access should not alias with internal
assert numpy.allclose(total_val, total_val_3)
#in this case we can alias
x = x_shared.get_value(borrow = True)
x /= .5
#this is not required by the contract but it is a feature we've
#implemented for some type of SharedVariable.
if self.get_value_borrow_true_alias:
assert numpy.allclose(self.ref_fct(x), total_func())
else:
assert numpy.allclose(x_ref, total_func())
def test_return_internal_type(self):
dtype = self.dtype
if dtype is None:
dtype = theano.config.floatX
rng = numpy.random.RandomState([3,5,17])
x = numpy.asarray(rng.uniform(0,1,[2,4]),dtype=dtype)
x = self.cast_value(x)
x_ref = self.ref_fct(x)
x_shared = self.shared_constructor(x, borrow = False)
total = self.theano_fct(x_shared)
total_func = theano.function([],total)
#in this case we can alias with the internal value
x = x_shared.get_value(borrow = True, return_internal_type = True)
assert self.test_internal_type(x)
values_to_add = .5
if self.add_matrix:
values_to_add = self.internal_type(numpy.ones(x.shape,dtype=dtype)/2)#supported for cudandarray, but not ndarray.
x /= values_to_add#supported by ndarray and CudaNdarray
#this is not required by the contract but it is a feature we can
#implement for some type of SharedVariable.
assert numpy.allclose(self.ref_fct(x), total_func())
x = x_shared.get_value(borrow = False, return_internal_type = True)
assert self.test_internal_type(x)
assert x is not x_shared.container.value
x /= values_to_add#supported by ndarray and CudaNdarray
#this is required by the contract
assert not numpy.allclose(self.ref_fct(x), total_func())
def test_set_value(self):
dtype = self.dtype
if dtype is None:
dtype = theano.config.floatX
rng = numpy.random.RandomState([3,5,17])
x = numpy.asarray(rng.uniform(0,1,[2,4]),dtype=dtype)
x = self.cast_value(x)
x_orig = x
x_orig_copy = x.copy()
x_ref = self.ref_fct(x)
x_shared = self.shared_constructor(x, borrow = False)
total = self.theano_fct(x_shared)
total_func = theano.function([],total)
#test if that theano shared variable optimize set_value(borrow=True)
get_x = x_shared.get_value(borrow=True)
assert get_x is not x_orig#borrow=False to shared_constructor
get_x /= .5
x_shared.set_value(get_x, borrow=True)
x = x_shared.get_value(borrow=True)
if self.set_value_borrow_true_alias:
assert x is get_x
else:
assert x is not get_x
assert numpy.allclose(self.ref_fct(x_orig/.5),self.ref_fct(x))
#test optimized get set value on the gpu(don't pass data to the cpu)
get_x = x_shared.get_value(borrow=True, return_internal_type=True)
assert get_x is not x_orig#borrow=False to shared_constructor
assert self.test_internal_type(get_x)
values_to_add = .5
if self.add_matrix:
values_to_add = self.internal_type(numpy.ones(x.shape,dtype=dtype)/2)#supported for cudandarray, but not ndarray.
assert self.test_internal_type(values_to_add)
get_x /= values_to_add#supported by ndarray and CudaNdarray
assert self.test_internal_type(get_x)
x_shared.set_value(get_x, borrow=True)
x = x_shared.get_value(borrow=True, return_internal_type=True)
assert self.test_internal_type(x)
assert x is get_x
################ TODO test Out.
def test_shared_do_alias(self):
dtype = self.dtype
if dtype is None:
dtype = theano.config.floatX
rng = numpy.random.RandomState([2,4,16])
x = numpy.asarray(rng.uniform(1,2,[4,2]),dtype=dtype)
x = self.cast_value(x)
x_ref = self.ref_fct(x)
x_shared = self.shared_constructor(x, borrow = True)
total = self.theano_fct(x_shared)
total_func = theano.function([],total)
total_val = total_func()
assert numpy.allclose(self.ref_fct(x), total_val)
x /= .5
#not required by the contract but it is a feature we've implemented
if self.shared_borrow_true_alias:
assert numpy.allclose(self.ref_fct(x), total_func())
else:
assert numpy.allclose(x_ref, total_func())
return SharedTester
test_shared_options=makeSharedTester(tensor.shared, 'float64',
True, True, True,
numpy.ndarray,
lambda a: isinstance(a,numpy.ndarray),
theano.tensor.sum,
numpy.sum)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论