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

Merged

......@@ -24,3 +24,5 @@ pull.sh
setuptools-*.egg
theano/version.py
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
global-include *.cuh
global-include *.sh
include ChangeLog
include distribute_setup.py
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:
......
差异被折叠。
......@@ -20,7 +20,7 @@ to be installed:
We develop mainly on 64-bit Linux machines. 32-bit architectures are
not well-tested.
Python >= 2.4
Python_ >= 2.4
Including the development package (``python-dev`` or ``python-devel``
on most Linux distributions).
......@@ -34,7 +34,7 @@ to be installed:
`SciPy <http://scipy.org>`_
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``
is buggy in 0.6 (the ``scipy.csc_matrix`` version of ``dot()`` has a
bug with singleton dimensions, there may be more bugs).
......@@ -46,6 +46,7 @@ to be installed:
.. _BLAS: http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms
.. _Accelerate framework: http://developer.apple.com/performance/accelerateframework.html
.. _Python: http://www.python.org/
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/>`_
For building the documentation. LaTeX_ and dvipng_ are also necessary
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.
`NVIDIA CUDA drivers and SDK
<http://developer.nvidia.com/object/gpucomputing.html>`_
`NVIDIA CUDA drivers and SDK`_
Required for GPU code generation/execution. Only NVIDIA GPUs using
32-bit floating point numbers are currently supported.
.. _LaTeX: http://www.latex-project.org/
.. _dvipng: http://savannah.nongnu.org/projects/dvipng/
.. _NVIDIA CUDA drivers and SDK: http://developer.nvidia.com/object/gpucomputing.html
Basic user install instructions
-------------------------------
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,
`setuptools`_). If you have one of these installed, installing Theano should
be simply a matter of::
pip_ (a replacement for easy_install_ provided by setuptools_/distribute_)
by typing
.. 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/
.. _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:
Bleeding-edge (developer) install instructions
----------------------------------------------
If you are a developer of Theano, then check out the :ref:`dev_start_guide`
guide.
If you are a developer of Theano, then check out the :ref:`dev_start_guide`.
The following are general instructions that will set you up with the
bleeding-edge version of Theano. First, get the code using `mercurial
<http://www.selenic.com/mercurial/wiki/>`__:
bleeding-edge version of Theano. First, get the code using `Mercurial
<http://mercurial.selenic.com/>`__:
.. code-block:: bash
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
your ``PYTHONPATH``. In order to do that, you can either create a symbolic
link to Theano/theano in a directory already mentioned in your ``PYTHONPATH``
environment variable, or modify the ``PYTHONPATH`` so that it mentions Theano.
This will install a ``.pth`` file in your ``site-packages`` directory that
tells Python where to look for your Theano installation (i.e. in the
directory your just checked out of Mercurial). Using ``develop`` mode is
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
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
export PYTHONPATH=<path to Theano's parent dir>/Theano:$PYTHONPATH
export PYTHONPATH=<new location to add>:$PYTHONPATH
In 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
---------------------------
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
THEANO_FLAGS=warn.ignore_bug_before=all nosetests #execute all the tests
>>> import theano
>>> 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
(:ref:`libdoc_config`). For Windows users, you can remove it or see the
......@@ -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
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.
Troubleshooting: Make sure you have a BLAS library
......@@ -169,7 +238,6 @@ entry like this:
.. code-block:: cfg
# other stuff can go here
[blas]
ldflags = -lf77blas -latlas -lgfortran #put your flags here
......
......@@ -100,8 +100,9 @@ Nightly test
============
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
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
detail :ref:`see <metadocumentation_nightly_build>`.
email to the `theano-buildbot`_ mailing list.
.. _theano-buildbot: https://groups.google.com/group/theano-buildbot
For more detail, see :ref:`see <metadocumentation_nightly_build>`.
......@@ -129,33 +129,19 @@ You can see a list of all `pylint messages
The nightly build/tests process
---------------------------------------
The user ``lisa`` runs a cronjob on the computer ``boltzmann``.
This happens nightly.
The cronjob executes the script ``~/www/nightly_build/do_nightly_build_theano``.
This script performs a an "hg pull -u" of theano (and pylearn too).
Then it executes something like
The user ``lisa`` runs a cronjob on the computer ``ceylon``, this
happens nightly. (To have the crontab executed, the ``lisa`` user must
be logged into ``ceylon``, Fred leaves a shell open for that.)
.. code-block:: bash
THEANO_FLAGS='unittests.rseed=<SEED>,mode=DEBUG_MODE' /usr/bin/nosetests --with-coverage --cover-package=theano --cover-package=pylearn
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.
The cronjob executes the scripts
``~/nightly_build/do_nightly_build_{theano,pylearn,deeplearning}``.
These scripts perform an "hg pull -u" of theano (and pylearn, and
DeepLearningTutorials too), and execute nosetests (in various settings).
We can't email directly to the mailing list as it is emailed as the root user.
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.
The output is emailed automatically to the `theano-buildbot`_ mailing list.
Also, to have the crontab executed, *the ``lisa`` user must be logged into
``boltzmann``*.
.. _theano-buildbot: https://groups.google.com/group/theano-buildbot
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
---------------------------------------
......
......@@ -4,11 +4,21 @@
# * Figure out how to compile and install documentation automatically
# * 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 subprocess
CLASSIFIERS = """\
Development Status :: 4 - Beta
Intended Audience :: Education
Intended Audience :: Science/Research
Intended Audience :: Developers
License :: OSI Approved :: BSD License
......@@ -26,7 +36,7 @@ MAINTAINER = "LISA laboratory, University of Montreal"
MAINTAINER_EMAIL = "theano-dev@googlegroups.com"
DESCRIPTION = ('Optimizing compiler for evaluating mathematical ' +
'expressions on CPUs and GPUs.')
LONG_DESCRIPTION = ""
LONG_DESCRIPTION = open("DESCRIPTION.txt").read()
URL = "http://deeplearning.net/software/theano/"
DOWNLOAD_URL = ""
LICENSE = 'BSD'
......@@ -37,7 +47,7 @@ PLATFORMS = ["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"]
MAJOR = 0
MINOR = 3
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
VERSION = '%d.%d.%d%s' % (MAJOR, MINOR, MICRO, SUFFIX)
......@@ -106,14 +116,16 @@ if not release:
def do_setup():
write_version_py()
from setuptools import setup, find_packages
setup(name=NAME,
version=VERSION,
description=DESCRIPTION,
long_description=LONG_DESCRIPTION,
classifiers=CLASSIFIERS,
author=AUTHOR,
author_email=AUTHOR_EMAIL,
url=URL,
license=LICENSE,
platforms=PLATFORMS,
packages=find_packages(),
install_requires=['numpy>=1.3.0', 'scipy>=0.7.0'],
package_data={
......
......@@ -110,7 +110,4 @@ try:
import theano.version
__version__ = theano.version.version
except ImportError:
import warnings
warnings.warn(
"version.py could not be imported. Run setup.py at least once to generate it"
)
__version__ = "unknown"
import atexit, gc, os, stat
import atexit, os, stat
from theano.compile import optdb
from theano import config
......@@ -96,9 +96,6 @@ if cuda_available:
cuda_initialization_error_message = ""
# actively closing our gpu session presents segfault-on-exit on some systems
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:
cuda_available = False
cuda_initialization_error_message = e.message
......
......@@ -12,11 +12,43 @@
//If true, we fill with NAN allocated device memory.
#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
/////////////////////////
/**
*
* In the test program I'm using, the _outstanding_mallocs decreases with every call.
......@@ -48,6 +80,9 @@ void * device_malloc(size_t size)
return 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
for(int i=0;i<TABLE_SIZE;i++){
if(NULL==_alloc_size_table[i].ptr){
......@@ -81,6 +116,9 @@ int device_free(void *ptr)
return -1;
}
_outstanding_mallocs[0] -= (ptr != NULL);
if(ptr != NULL) {
gpu_context_decref();
}
#if COMPUTE_GPU_MEM_USED
int i=0;
for(;i<TABLE_SIZE;i++)
......@@ -1888,7 +1926,7 @@ CudaNdarray_gpu_init(PyObject* _unused, PyObject* args)
PyObject *
CudaNdarray_gpu_shutdown(PyObject* _unused, PyObject* _unused_args) {
cudaThreadExit();
gpu_context_decref();
Py_INCREF(Py_None);
return Py_None;
}
......
......@@ -812,8 +812,8 @@ def test_shared_float32():
del theano.shared.constructors[-1]
import theano.tensor.tests.test_basic
test_shared_options = theano.tensor.tests.test_basic.makeSharedTester(
import theano.tensor.tests.test_sharedvar
test_shared_options = theano.tensor.tests.test_sharedvar.makeSharedTester(
tcn.shared_constructor, 'float32', False, False, False,
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
from theano.tests import unittest_tools as utt
from theano import tensor
from theano.tensor.basic import _allclose
def eval_outputs(outputs):
......@@ -298,7 +299,7 @@ class test_structureddot(unittest.TestCase):
scipy_result = spmat * mat
assert theano_result.shape == scipy_result.shape
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):
......@@ -440,8 +441,8 @@ class test_structureddot(unittest.TestCase):
self.failUnless(numpy.allclose(theano_result, scipy_result))
self.failIf(theano_time > overhead_rtol*scipy_time + overhead_tol)
import theano.tensor.tests.test_basic
test_shared_options=theano.tensor.tests.test_basic.makeSharedTester(
import theano.tensor.tests.test_sharedvar
test_shared_options=theano.tensor.tests.test_sharedvar.makeSharedTester(
theano.sparse.shared, 'float64',
True, True, True, scipy.sparse.csc_matrix, scipy.sparse.issparse,
lambda a: dense_from_sparse(a*2.),
......
......@@ -321,6 +321,11 @@ def _allclose(a, b):
else:
atol = float64_atol
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)
def get_constant_value(v):
......
......@@ -3440,202 +3440,6 @@ def test_dimshuffle_duplicate():
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 1:
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论