提交 6e8c2b92 authored 作者: Brandon T. Willard's avatar Brandon T. Willard

Remove theano_nose.py and other nose references

上级 603c7167
......@@ -8,7 +8,6 @@ global-include *.sh
global-include *.pkl
recursive-include doc
include bin/theano-cache
include bin/theano-nose
prune .jenkins
prune .travis
include versioneer.py
......
#!/usr/bin/env python
"""
This script should behave the same as the `nosetests` command.
The reason for its existence is that on some systems, it may not be obvious to
find where nosetests is installed in order to run it in a different process.
It is also used to load the KnownFailure plugin, in order to hide
KnownFailureTests error messages. Use --without-knownfailure to
disable that plugin.
`run_tests_in_batch.py` will in turn call back this script in another process.
"""
from __future__ import print_function
__authors__ = "Olivier Delalleau, Pascal Lamblin, Eric Larsen"
__contact__ = "delallea@iro"
import logging
_logger = logging.getLogger('theano.bin.theano-nose')
import os
import nose
import textwrap
import sys
from nose.plugins import Plugin
def main_function():
# Handle the --theano arguments
if "--theano" in sys.argv:
i = sys.argv.index("--theano")
import theano
sys.argv[i] = theano.__path__[0]
# Many Theano tests suppose device=cpu, so we need to raise an
# error if device==gpu.
# I don't know how to do this check only if we use theano-nose on
# Theano tests. So I make an try..except in case the script get
# reused elsewhere.
# We should not import theano before call nose.main()
# As this cause import problem with nosetests.
# Should we find a way to don't modify sys.path?
if not os.path.exists('theano/__init__.py'):
try:
from theano import config
if config.device != "cpu":
raise ValueError("Theano tests must be run with device=cpu."
" This will also run GPU tests when possible.\n"
" If you want GPU-related tests to run on a"
" specific GPU device, and not the default one,"
" you should use the init_gpu_device theano flag.")
except ImportError:
pass
# Handle --batch[=n] arguments
batch_args = [arg for arg in sys.argv if arg.startswith('--batch')]
for arg in batch_args:
sys.argv.remove(arg)
batch_size = None
if len(batch_args):
if len(batch_args) > 1:
_logger.warn(
'Multiple --batch arguments detected, using the last one '
'and ignoring the first ones.')
batch_arg = batch_args[-1]
elems = batch_arg.split('=', 1)
if len(elems) == 2:
batch_size = int(elems[1])
# Handle the --debug-batch argument.
display_batch_output = False
if '--debug-batch' in sys.argv:
if not batch_args:
raise AssertionError(
'You can only use the --debug-batch argument with the '
'--batch[=n] option')
while '--debug-batch' in sys.argv:
sys.argv.remove('--debug-batch')
sys.argv += ['--verbose', '--nocapture', '--detailed-errors']
display_batch_output = True
# Handle --time_prof arguments
time_prof_args = [arg for arg in sys.argv if arg=='--time-profile']
for arg in time_prof_args:
sys.argv.remove(arg)
# Time-profiling and batch modes
if time_prof_args or batch_args:
from theano.tests import run_tests_in_batch
return run_tests_in_batch.main(
theano_nose=os.path.realpath(__file__),
batch_size=batch_size,
time_profile=bool(time_prof_args),
display_batch_output=display_batch_output)
# Non-batch mode.
addplugins = []
# We include KnownFailure plugin by default, unless
# it is disabled by the "--without-knownfailure" arg.
if '--without-knownfailure' not in sys.argv:
try:
from numpy.testing.noseclasses import KnownFailure
except ImportError:
try:
from numpy.testing._private.noseclasses import KnownFailure
addplugins.append(KnownFailure())
except ImportError:
_logger.warn(
'KnownFailure plugin from NumPy could not be imported. '
'Use --without-knownfailure to disable this warning.')
else:
addplugins.append(KnownFailure())
else:
sys.argv.remove('--without-knownfailure')
# When 'theano-nose' is called-back under the time-profile option, an
# instance of the custom Nosetests plugin class 'DisabDocString' (see
# below) is loaded. The latter ensures that the test name will not be
# replaced in display by the first line of the documentation string.
if '--disabdocstring' in sys.argv:
addplugins.append(DisabDocString())
try:
if addplugins:
ret = nose.main(addplugins=addplugins)
else:
ret = nose.main()
return ret
except TypeError as e:
if "got an unexpected keyword argument 'addplugins'" in e.message:
# This means nose is too old and does not support plugins
_logger.warn(
'KnownFailure plugin from NumPy can\'t'
' be used as nosetests is too old. '
'Use --without-knownfailure to disable this warning.')
nose.main()
else:
raise
def help():
help_msg = """
This script behaves mostly the same as the `nosetests` command.
The main difference is that it loads automatically the
KnownFailure plugin, in order to hide KnownFailureTests error
messages. It also supports executing tests by batches.
Local options:
--help, -h: Displays this help.
--batch[=n]:
If specified without option '--time-profile', do not run all
the tests in one run, but split the execution in batches of
`n` tests each. Default n is 100.
--time-profile:
Each test will be run and timed separately and the results will
be deposited in the files 'timeprof_sort', 'timeprof_nosort'
and 'timeprof_rawlog' in the current directory. If the
'--batch[=n]' option is also specified, notification of the
progresses will be made to standard output after every group of
n tests. Otherwise, notification will occur after every group
of 100 tests.
The files 'timeprof_sort' and 'timeprof_nosort' both contain one
record for each test and comprise the following fields:
- test running-time
- nosetests sequential test number
- test name
- name of class to which test belongs (if any), otherwise full
information is contained in test name
- test outcome ('OK', 'SKIPPED TEST', 'FAILED TEST' or
'FAILED PARSING')
In 'timeprof_sort', test records are sorted according to
running-time whereas in 'timeprof_nosort' records are reported
according to sequential number. The former classification is the
main information source for time-profiling. Since tests belonging
to same or close classes and files have close sequential, the
latter may be used to identify duration patterns among the tests
numbers. A full log is also saved as 'timeprof_rawlog'.
--without-knownfailure: Do not load the KnownFailure plugin.
--theano: This parameter is replaced with the path to the theano
library. As theano-nose is a wrapper to nosetests, it
expects a path to the tests to run.
If you do not know where theano is installed, use this
option to have it inserted automatically.
--debug-batch:
Use this parameter to run nosetests with options '--verbose',
'--nocapture' and '--detailed-errors' and show the output of
nosetests during batch execution. This can be useful to debug
situations where re-running only the failed tests after batch
execution is not working properly. This option can only be used
in conjunction with the '--batch=[n]' argument.
The other options will be passed to nosetests, see ``nosetests -h``.
"""
print(textwrap.dedent(help_msg))
def main():
if '--help' in sys.argv or '-h' in sys.argv:
help()
else:
result = main_function()
sys.exit(result)
class DisabDocString(Plugin):
"""
When activated, a custom Nosetests plugin created through this class
will preclude automatic replacement in display of the name of the test
by the first line in its documentation string.
Sources:
http://nose.readthedocs.org/en/latest/developing.html
http://nose.readthedocs.org/en/latest/further_reading.html
http://www.siafoo.net/article/54
https://github.com/nose-devs/nose/issues/294
http://python-nose.googlecode.com/svn/trunk/nose/plugins/base.py
Nat Williams:
https://github.com/Merino/nose-description-fixer-plugin/commit/
df94596f29c04fea8001713dd9b04bf3720aebf4
"""
enabled = False # plugin disabled by default
score = 2000 # high score ensures priority over other plugins
def __init__(self):
# 'super.__init__(self):' would have achieved exactly the same
if self.name is None:
self.name = self.__class__.__name__.lower()
if self.enableOpt is None:
self.enableOpt = ("enable_plugin_%s"
% self.name.replace('-', '_'))
def options(self, parser, env):
env_opt = 'NOSE_WITH_%s' % self.name.upper()
# latter expression to be used if plugin called from the command line
parser.add_option("--%s" % self.name,
# will be called with Nosetests 'main' or 'run'
# function's' argument '--disabdocstring'
action="store_true",
dest=self.enableOpt,
# the latter entails that the boolean self.enableOpt
# is set to 'True' when plugin is called through a
# function's argument
default=env.get(env_opt),
# entails that plugin will be enabled when command
# line trigger 'env_opt' will be activated
help="Enable plugin %s: %s [%s]" %
(self.__class__.__name__,
self.help(), env_opt))
def configure(self, options, conf):
self.conf = conf
# plugin will be enabled when called through argument
self.enabled = getattr(options, self.enableOpt)
def describeTest(self, test):
# 'describeTest' is also called when the test result in Nosetests calls
# 'test.shortDescription()' and can thus be used to alter the display.
return False
if __name__ == '__main__':
main()
......@@ -25,7 +25,7 @@ requirements:
test:
requires:
- nose >=1.3.0
- pytest
imports:
- theano
......
......@@ -38,14 +38,14 @@ To get up to speed, you'll need to
trickier files (like tensor.py).
- Go through the `NumPy documentation`_.
- Learn to write reStructuredText_ for Sphinx_.
- Learn about how unittest_ and nose_ work
- Learn about how unittest_ and pytest_ work
.. _Sphinx: http://sphinx.pocoo.org/
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
.. _Allowed docstring sections in Napoleon: https://sphinxcontrib-napoleon.readthedocs.org/en/latest/#docstring-sections
.. _NumPy documentation: http://docs.scipy.org/numpy/
.. _unittest: http://docs.python.org/library/unittest.html
.. _nose: http://nose.readthedocs.org/en/latest/
.. _pytest: http://docs.pytest.org/en/latest/
.. _quality_contributions:
......@@ -53,16 +53,16 @@ To get up to speed, you'll need to
Requirements for Quality Contributions
======================================
* All the code should be properly tested.
* All the code should be properly tested.
* The code should be compatible with Python 2.7 and above, as well as
Python 3.4 and above (using `six` if needed).
* All the code should respect the
* All the code should respect the
`PEP8 Code Style Guide <http://www.python.org/dev/peps/pep-0008>`_.
* The docstrings of all the classes and functions should respect the
`PEP257 <https://www.python.org/dev/peps/pep-0257/>`_ rules and follow the
`PEP257 <https://www.python.org/dev/peps/pep-0257/>`_ rules and follow the
`Numpy docstring standard
<https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt>`_.
......@@ -85,7 +85,7 @@ make sure there are no global impacts.
Also, if you are changing GPU code, Travis doesn't test that, because
there are no GPUs on the test nodes.
To run the test suite with the default options, see
To run the test suite with the default options, see
:ref:`test_theano`.
Each night we execute all the unit tests automatically, with several
......@@ -101,8 +101,8 @@ this script:
theano/misc/do_nightly_build
This script accepts arguments that it forwards to nosetests. You can
run only some tests or enable pdb by giving the equivalent nosetests
This script accepts arguments that it forwards to ``pytest``. You can
run only some tests or enable pdb by giving the equivalent ``pytest``
parameters.
Setting up your Editor for PEP8
......@@ -130,7 +130,7 @@ To setup VIM:
.. warning:: Starting version 3.0.0, flake8 changed its dependencies and
moved its Python API to a legacy module, breaking Theano's flake8 tests.
We recommend using a version prior to 3.
We recommend using a version prior to 3.
.. note:: You can use ``easy_install`` instead of ``pip``, and ``pep8``
instead of ``flake8`` if you prefer. The important thing is that the
......@@ -167,9 +167,9 @@ To setup VIM:
let g:syntastic_auto_jump = 0 "do not jump to errors when detected
#. Open a new vim and run ``:PluginInstall`` to automatically install the
plugins. When the installation is done, close the installation "window"
with ``:q``.
From now on Vim will check for PEP8 errors and highlight them whenever a
plugins. When the installation is done, close the installation "window"
with ``:q``.
From now on Vim will check for PEP8 errors and highlight them whenever a
file is saved.
A few useful commands
......@@ -237,7 +237,6 @@ Then in your ``~/.emacs`` file, add this:
(require 'epy-completion) ;; If you want the autocompletion settings [optional]
(require 'epy-editing) ;; For configurations related to editing [optional]
;; [newer version of emacs-for-python]
(require 'epy-nose) ;; For shortcut to call nosetests [optional]
;; Define f10 to previous error
;; Define f11 to next error
......@@ -270,20 +269,20 @@ Documentation and docstrings
* The documentation should be written in `reStructuredText`_ and the
docstrings of all the classes and functions should respect the
`PEP257 <https://www.python.org/dev/peps/pep-0257/>`_ rules and follow the
`PEP257 <https://www.python.org/dev/peps/pep-0257/>`_ rules and follow the
`Numpy docstring standard
<https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt>`_.
* Split the docstrings in sections, according to the `Allowed docstring
sections in Napoleon`_
* To cross-reference other objects (e.g. reference other classes or methods) in
* To cross-reference other objects (e.g. reference other classes or methods) in
the docstrings, use the
`cross-referencing objects <http://www.sphinx-doc.org/en/stable/domains.html#cross-referencing-python-objects>`_
syntax. ``:py`` can be omitted, see e.g. this
`cross-referencing objects <http://www.sphinx-doc.org/en/stable/domains.html#cross-referencing-python-objects>`_
syntax. ``:py`` can be omitted, see e.g. this
`stackoverflow answer <http://stackoverflow.com/a/7754189>`_.
* See :ref:`metadocumentation`, for some information on how to generate the
* See :ref:`metadocumentation`, for some information on how to generate the
documentation.
......@@ -449,7 +448,7 @@ Once your code is ready for others to review, you need to commit all the changes
branch to your github fork first:
.. code-block:: bash
git commit -a -m "your message here"
.. code-block:: bash
......
......@@ -546,7 +546,7 @@ How To Test it
Theano has some functionalities to simplify testing. These help test the
``infer_shape``, ``grad`` and ``R_op`` methods. Put the following code
in a file and execute it with the ``theano-nose`` program.
in a file and execute it with the ``pytest`` program.
Basic Tests
^^^^^^^^^^^
......@@ -676,50 +676,7 @@ For instance, to verify the Rop method of the DoubleOp, you can use this:
Running Your Tests
^^^^^^^^^^^^^^^^^^
To perform your tests, you may select either one of the three
following methods:
theano-nose
"""""""""""
The method of choice to conduct tests is to run the file
``theano-nose``. In a regular Theano installation, the latter will be
on the operating system's path and directly accessible from any
folder. Otherwise, it can be accessed in the ``Theano/bin``
folder. The following command lines may be used for the corresponding
purposes:
* ``theano-nose --theano``: Run every test found in Theano's path.
* ``theano-nose folder_name``: Run every test found in the folder *folder_name*.
* ``theano-nose test_file.py``: Run every test found in the file *test_file.py*.
The following are particularly useful for development purposes since
they call for particular classes or even for particular tests:
* ``theano-nose test_file.py:TestDoubleRop``: Run every test found inside the
class *TestDoubleRop*.
* ``theano-nose test_file.py:TestDoubleRop.test_double_op``: Run only the test
*test_double_op* in the class *TestDoubleRop*.
Help with the use and functionalities of ``theano-nose`` may be
obtained by running it with the command line parameter ``--help
(-h)``.
nosetests
"""""""""
The command ``nosetests`` can also be used. Although it lacks the
useful functionalities that ``theano-nose`` provides, ``nosetests``
can be called similarly to ``theano-nose`` from any folder in Python's
path like so:
``nosetests [suffix similar to the above]``.
More documentation on ``nosetests`` is available here:
`nosetests <http://readthedocs.org/docs/nose/en/latest/>`_.
To perform your tests, simply run ``pytest``.
In-file
"""""""
......
......@@ -557,8 +557,8 @@ storage with the right shape and number of dimensions.
The ``c_code`` method accepts variable names as arguments (``name``, ``inp``,
``out``, ``sub``) and returns a C code fragment that computes the expression
output. In case of error, the ``%(fail)s`` statement cleans up and returns
``out``, ``sub``) and returns a C code fragment that computes the expression
output. In case of error, the ``%(fail)s`` statement cleans up and returns
properly.
More complex C Op example
......@@ -1038,12 +1038,12 @@ For the GPU, you must add in this second flag `nvcc.flags=-g` (it slow
down computation on the GPU, but it is enabled by default on the CPU).
Then you must start Python inside GDB and in it start your Python
process (e.g. theano-nose):
process:
.. code-block:: sh
$gdb python
(gdb)r bin/theano-nose theano/
(gdb)r pytest theano/
`Quick guide to GDB <https://www.cs.cmu.edu/~gilpin/tutorial/>`_.
......
......@@ -47,6 +47,7 @@ Here is some code that allows the Op to be optional:
.. code-block:: python
try:
import scipy.linalg
imported_scipy = True
......@@ -61,12 +62,10 @@ Here is some code that allows the Op to be optional:
"SciPy not available. SciPy is needed for the SomeOp op.")
...
from nose.plugins.skip import SkipTest
class TestSomeOp(utt.InferShapeTester):
...
@pytest.mark.skipif(not imported_scipy, reason="SciPy needed for the SomeOp op.")
def test_infer_shape(self):
if not imported_scipy:
raise SkipTest("SciPy needed for the SomeOp op.")
...
.. _sparse_ops:
......
......@@ -225,9 +225,9 @@ type this:
.. code-block:: bash
THEANO_FLAGS='mode=FAST_COMPILE' theano-nose
THEANO_FLAGS='mode=FAST_RUN' theano-nose
THEANO_FLAGS='mode=DebugMode' theano-nose
THEANO_FLAGS='mode=FAST_COMPILE' pytest
THEANO_FLAGS='mode=FAST_RUN' pytest
THEANO_FLAGS='mode=DebugMode' pytest
.. _random_value_in_tests:
......@@ -267,7 +267,7 @@ The behaviour of ``seed_rng`` is as follows:
The main advantage of using ``unittest_tools.seed_rng`` is that it allows
us to change the seed used in the unitests, without having to manually
edit all the files. For example, this allows the nightly build to run
``theano-nose`` repeatedly, changing the seed on every run (hence achieving
``pytest`` repeatedly, changing the seed on every run (hence achieving
a higher confidence that the variables are correct), while still
making sure unittests are deterministic.
......@@ -285,7 +285,7 @@ Similarly, to provide a seed to ``numpy.random.RandomState``, simply use:
# OR providing an explicit seed
rng = numpy.random.RandomState(unittest_tools.fetch_seed(1231)) # again not recommended
Note that the ability to change the seed from one nosetest to another,
Note that the ability to change the seed from one test to another,
is incompatible with the method of hard-coding the baseline variables
(against which we compare the theano outputs). These must then be
determined "algorithmically". Although this represents more work, the
......
.. include:: css.inc
.. _install_centos6:
CentOS 6 Installation Instructions
##################################
......@@ -25,5 +25,5 @@ Requirements through System Packages (not recommended)
.. code-block:: bash
sudo yum install python-devel python-nose python-setuptools gcc gcc-gfortran gcc-c++ blas-devel lapack-devel atlas-devel
sudo yum install python-devel python-pytest python-setuptools gcc gcc-gfortran gcc-c++ blas-devel lapack-devel atlas-devel
sudo easy_install pip
......@@ -12,9 +12,9 @@ Mac OS Installation Instructions
page <http://deeplearning.net/software/theano_versions/dev/install_macos.html>`_.
There are various ways to install Theano dependencies on a Mac. Here
we describe the process in detail with Anaconda, Homebrew or MacPorts
but if you did it differently and it worked, please let us know the
details on the `theano-users`_ mailing-list, so that we can add
we describe the process in detail with Anaconda, Homebrew or MacPorts
but if you did it differently and it worked, please let us know the
details on the `theano-users`_ mailing-list, so that we can add
alternative instructions here.
.. _theano-users: http://groups.google.com/group/theano-users?pli=1
......@@ -147,10 +147,9 @@ Theano dependencies is easy, but be aware that it will take a long time
``/opt/local/sbin`` before any other paths (to ensure that the Python and
gcc binaries that you installed with MacPorts are visible first).
- MacPorts does not create automatically ``nosetests`` and ``pip`` symlinks
pointing to the MacPorts version, so you can add them yourself with
- MacPorts does not automatically create ``pip`` symlinks pointing to the
MacPorts version; you can add them yourself with
.. code-block:: bash
$ sudo ln -s /opt/local/bin/nosetests-2.7 /opt/local/bin/nosetests
$ sudo ln -s /opt/local/bin/pip-2.7 /opt/local/bin/pip
......@@ -13,7 +13,7 @@ NVIDIA Jetson TX1 embedded platform
.. code-block:: bash
sudo apt-get install python-numpy python-scipy python-dev python-pip python-nose g++ libblas-dev git
sudo apt-get install python-numpy python-scipy python-dev python-pip python-pytest g++ libblas-dev git
pip install --upgrade --no-deps git+git://github.com/Theano/Theano.git --user # Need Theano 0.8 or more recent
Gentoo
......
......@@ -32,7 +32,7 @@ For Ubuntu 16.04 with cuda 7.5
.. code-block:: bash
sudo apt-get install python-numpy python-scipy python-dev python-pip python-nose g++ libopenblas-dev git graphviz
sudo apt-get install python-numpy python-scipy python-dev python-pip python-pytest g++ libopenblas-dev git graphviz
sudo pip install Theano
# cuda 7.5 don't support the default g++ version. Install an supported version and make it the default.
......@@ -54,20 +54,20 @@ For Ubuntu 11.10 through 14.04:
.. code-block:: bash
sudo apt-get install python-numpy python-scipy python-dev python-pip python-nose g++ libopenblas-dev git
sudo apt-get install python-numpy python-scipy python-dev python-pip python-pytest g++ libopenblas-dev git
On 14.04, this will install Python 2 by default. If you want to use Python 3:
.. code-block:: bash
sudo apt-get install python3-numpy python3-scipy python3-dev python3-pip python3-nose g++ libopenblas-dev git
sudo apt-get install python3-numpy python3-scipy python3-dev python3-pip python3-pytest g++ libopenblas-dev git
sudo pip3 install Theano
For Ubuntu 11.04:
.. code-block:: bash
sudo apt-get install python-numpy python-scipy python-dev python-pip python-nose g++ git libatlas3gf-base libatlas-dev
sudo apt-get install python-numpy python-scipy python-dev python-pip python-pytest g++ git libatlas3gf-base libatlas-dev
Manual Openblas installation (deprecated)
-----------------------------------------
......
......@@ -24,7 +24,7 @@ Install requirements and optional packages
.. code-block:: bash
conda install numpy scipy mkl-service libpython <m2w64-toolchain> <nose> <sphinx> <pydot-ng> <git>
conda install numpy scipy mkl-service libpython <m2w64-toolchain> pytest <sphinx> <pydot-ng> <git>
.. note::
......
......@@ -12,7 +12,7 @@ Theano requirements
-------------------
- git_: A distributed revision control system (RCS).
- nosetests_: A system for unit tests.
- pytest_: A system for unit testing.
- numpy_: A library for efficient numerical computing.
- python_: The programming language Theano is for.
- scipy_: A library for scientific computing.
......@@ -38,7 +38,7 @@ This is a sort of memo for developers and would-be developers.
.. _git: http://git-scm.com/
.. _nosetests: http://nose.readthedocs.org/en/latest/
.. _pytest: http://docs.pytest.org/en/latest/
.. _numpy: http://numpy.scipy.org/
.. _python: http://www.python.org
.. _scipy: http://scipy.org/
......@@ -54,4 +54,3 @@ This is a sort of memo for developers and would-be developers.
.. _unpython: http://code.google.com/p/unpython/
.. _pycppad: http://www.seanet.com/~bradbell/pycppad/index.xml
.. _shedskin: http://shed-skin.blogspot.com/
......@@ -35,9 +35,6 @@ Requirements
|PlatformCompiler|
**Highly recommended.** Theano can fall back on a NumPy-based Python execution model, but a C compiler allows for vastly faster execution.
`nose <http://nose.readthedocs.io/en/latest/>`_ >= 1.3.0
Recommended, to run Theano's test-suite.
`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.
......@@ -83,7 +80,7 @@ Install requirements and optional packages
.. code-block:: bash
conda install numpy scipy mkl <nose> <sphinx> <pydot-ng>
conda install numpy scipy mkl pytest <sphinx> <pydot-ng>
* Arguments between <...> are optional.
......
......@@ -110,32 +110,6 @@ write an Op:**
UnaryScalarOp is the same as scalar.ScalarOp with member variable nin=1.
**give an example of this**
=======================================================
Documentation on how to write tests
=======================================================
Guillaume can you make sure to hit these points:
* What are canonical examples of tests?
* What are the different test patterns?
* nnet.py:
* What is going on with test1, test2, test3, test4?
* What is the right eq function to use?
* There are a lot of tests that define their own epsilon, but this should be standardized. e.g. in test_elemwise.py ``self.assertTrue((numpy.abs(f(xv) - zv) < 1e-10).all())``
* If the expected variable of a test is that an Exception is thrown, how do we correctly detect and handle that?
nosetests has ``assertRaises``
* Convention is that all test files must start with ``test_``, not
``_test_``, so rename all that use the old convention?
=======================================================
How to use the PrintOp
=======================================================
......
sphinx>=1.3.0
pygments
nose>=1.3.0
pytest
numpy
gnumpy
pydot
pydot2
Cython
scipy==0.13
[nosetest]
match=^test
nocapture=1
[flake8]
ignore=E501,E123,E133,FI12,FI14,FI15,FI50,FI51,FI53,W503,W504,E203,C901,E231,E741
per-file-ignores =
......
......@@ -127,12 +127,7 @@ def do_setup():
"theano.misc": ["*.sh"],
"theano.d3viz": ["html/*", "css/*", "js/*"],
},
entry_points={
"console_scripts": [
"theano-cache = bin.theano_cache:main",
"theano-nose = bin.theano_nose:main",
]
},
entry_points={"console_scripts": ["theano-cache = bin.theano_cache:main",]},
keywords=" ".join(
[
"theano",
......
......@@ -169,16 +169,6 @@ from theano.gradient import Rop, Lop, grad, subgraph_grad
# needed during that phase.
import theano.tests
if hasattr(theano.tests, "TheanoNoseTester"):
test = theano.tests.TheanoNoseTester().test
else:
def test():
raise ImportError(
"The nose module is not installed." " It is needed for Theano tests."
)
if (
config.device.startswith("cuda")
or config.device.startswith("opencl")
......
......@@ -78,7 +78,7 @@ def thunk_hook(type, value, trace):
Notes
-----
This hook replaced by nosetests, so it does not run in nose tests.
This hook replaced in testing, so it does not run.
"""
log_thunk_trace(value)
......
#!/usr/bin/env python
# Without args, this script executes all its tests like `nosetests -vs`
# Without args, this script executes all its tests like `pytest -vs`
# python check_dnn_conv.py
# If there is only one arg `infos`, this script prints some infos about
......@@ -10,8 +10,8 @@
# If there is only one arg `list`, this script prints all test cases without running them.
# python check_dnn_conv.py list
# Else, any arg will be directly passed to nosetests.
# python check_dnn_conv.py -xvs # nosetests: verbose mode, capture output, exit at first error.
# Else, any arg will be directly passed to pytest.
# python check_dnn_conv.py -xvs # verbose mode, capture output, exit at first error.
from __future__ import absolute_import, print_function, division
......@@ -885,10 +885,7 @@ class BaseTestDnnConv(object):
self.should_fail(self.run_conv_gradweight, *args)
def get_expected_tcount(self):
"""
Utility function to get expected test count
without actually run nosetests.
"""
"""Utility function to get expected test count without actually running pytest."""
return (
sum(1 for t in self.test_fwd())
+ sum(1 for t in self.test_gradweight())
......
......@@ -33,15 +33,13 @@ if [ "$1" == "--buildbot" ]; then
git rev-parse HEAD
#Run tests from inside the Theano directory to prevent import problem.
# PROFILING="--with-coverage --cover-package=theano"
NOSETESTS=${ROOT_CWD}/Theano/bin/theano-nose
export PYTHONPATH=${ROOT_CWD}:$PYTHONPATH
else
ROOT_CWD=.
COMPILEDIR=`python -c "from __future__ import print_function; import theano; print(theano.config.compiledir)"|tail -1`
NOSETESTS=`python -c "from __future__ import print_function; import theano; print(theano.__path__[0])"|tail -1`/../bin/theano-nose
fi
# nosetests xunit for test profiling
# tests xunit for test profiling
XUNIT="--with-xunit --xunit-file="
echo "Number of elements in the compiledir:"
......@@ -65,23 +63,23 @@ FLAGS=${FLAGS},device=cpu,floatX=float64
if [ "$RELEASE" ]; then
echo "Executing tests with default mode and compute_test_value"
date
THEANO_FLAGS=${FLAGS},compute_test_value=ignore ${NOSETESTS} ${ARGS}
THEANO_FLAGS=${FLAGS},compute_test_value=ignore pytest ${ARGS}
echo "Number of elements in the compiledir:"
ls ${COMPILEDIR}|wc -l
echo
echo "Executing tests with linker=vm,floatX=float32"
echo "THEANO_FLAGS=${FLAGS},linker=vm,floatX=float32 ${NOSETESTS} ${ARGS}"
echo "THEANO_FLAGS=${FLAGS},linker=vm,floatX=float32 pytest ${ARGS}"
date
THEANO_FLAGS=${FLAGS},linker=vm,floatX=float32 ${NOSETESTS} ${ARGS}
THEANO_FLAGS=${FLAGS},linker=vm,floatX=float32 pytest ${ARGS}
echo "Number of elements in the compiledir:"
ls ${COMPILEDIR}|wc -l
echo
echo "Executing tests with cxx="
echo "THEANO_FLAGS=${FLAGS},cxx= ${NOSETESTS} ${ARGS}"
echo "THEANO_FLAGS=${FLAGS},cxx= pytest ${ARGS}"
date
THEANO_FLAGS=${FLAGS},cxx= ${NOSETESTS} ${ARGS}
THEANO_FLAGS=${FLAGS},cxx= pytest ${ARGS}
echo "Number of elements in the compiledir:"
ls ${COMPILEDIR}|wc -l
echo
......@@ -90,27 +88,27 @@ fi
echo "Executing tests with mode=FAST_RUN"
FILE=${ROOT_CWD}/theano_fastrun_tests.xml
echo "THEANO_FLAGS=cmodule.warn_no_version=True,${FLAGS},mode=FAST_RUN ${NOSETESTS} ${PROFILING} ${ARGS} ${XUNIT}${FILE}"
echo "THEANO_FLAGS=cmodule.warn_no_version=True,${FLAGS},mode=FAST_RUN pytest ${PROFILING} ${ARGS} ${XUNIT}${FILE}"
date
THEANO_FLAGS=cmodule.warn_no_version=True,${FLAGS},mode=FAST_RUN ${NOSETESTS} ${PROFILING} ${ARGS} ${XUNIT}${FILE}
THEANO_FLAGS=cmodule.warn_no_version=True,${FLAGS},mode=FAST_RUN pytest ${PROFILING} ${ARGS} ${XUNIT}${FILE}
echo "Number of elements in the compiledir:"
ls ${COMPILEDIR}|wc -l
echo
echo "Executing tests with mode=FAST_RUN,floatX=float32"
FILE=${ROOT_CWD}/theano_fastrun_float32_tests.xml
echo "THEANO_FLAGS=${FLAGS},mode=FAST_RUN,floatX=float32 ${NOSETESTS} ${ARGS} ${XUNIT}${FILE}"
echo "THEANO_FLAGS=${FLAGS},mode=FAST_RUN,floatX=float32 pytest ${ARGS} ${XUNIT}${FILE}"
date
THEANO_FLAGS=${FLAGS},mode=FAST_RUN,floatX=float32 ${NOSETESTS} ${ARGS} ${XUNIT}${FILE}
THEANO_FLAGS=${FLAGS},mode=FAST_RUN,floatX=float32 pytest ${ARGS} ${XUNIT}${FILE}
echo "Number of elements in the compiledir:"
ls ${COMPILEDIR}|wc -l
echo
echo "Executing tests with linker=vm,vm.lazy=True,floatX=float32"
FILE=${ROOT_CWD}/theano_fastrun_float32_lazyvm_tests.xml
echo "THEANO_FLAGS=${FLAGS},linker=vm,vm.lazy=True,floatX=float32 ${NOSETESTS} ${ARGS} ${XUNIT}${FILE}"
echo "THEANO_FLAGS=${FLAGS},linker=vm,vm.lazy=True,floatX=float32 pytest ${ARGS} ${XUNIT}${FILE}"
date
THEANO_FLAGS=${FLAGS},linker=vm,vm.lazy=True,floatX=float32 ${NOSETESTS} ${ARGS} ${XUNIT}${FILE}
THEANO_FLAGS=${FLAGS},linker=vm,vm.lazy=True,floatX=float32 pytest ${ARGS} ${XUNIT}${FILE}
echo "Number of elements in the compiledir:"
ls ${COMPILEDIR}|wc -l
echo
......@@ -119,9 +117,9 @@ echo
seed=$RANDOM
echo "Executing tests with mode=DEBUG_MODE with seed of the day $seed"
FILE=${ROOT_CWD}/theano_debug_tests.xml
echo "THEANO_FLAGS=${FLAGS},unittests.rseed=$seed,mode=DEBUG_MODE,DebugMode.check_strides=0,DebugMode.patience=3,DebugMode.check_preallocated_output= ${NOSETESTS} ${ARGS} ${XUNIT}${FILE}"
echo "THEANO_FLAGS=${FLAGS},unittests.rseed=$seed,mode=DEBUG_MODE,DebugMode.check_strides=0,DebugMode.patience=3,DebugMode.check_preallocated_output= pytest ${ARGS} ${XUNIT}${FILE}"
date
THEANO_FLAGS=${FLAGS},unittests.rseed=$seed,mode=DEBUG_MODE,DebugMode.check_strides=0,DebugMode.patience=3,DebugMode.check_preallocated_output= ${NOSETESTS} ${ARGS} ${XUNIT}${FILE}
THEANO_FLAGS=${FLAGS},unittests.rseed=$seed,mode=DEBUG_MODE,DebugMode.check_strides=0,DebugMode.patience=3,DebugMode.check_preallocated_output= pytest ${ARGS} ${XUNIT}${FILE}
echo "Number of elements in the compiledir:"
ls ${COMPILEDIR}|wc -l
......@@ -132,9 +130,9 @@ echo
# with --batch=1000" # The buildbot freeze sometimes when collecting the tests to run
echo "Executing tests with mode=FAST_COMPILE"
FILE=${ROOT_CWD}/theano_fastcompile_tests.xml
echo "THEANO_FLAGS=${FLAGS},mode=FAST_COMPILE ${NOSETESTS} ${ARGS} ${XUNIT}${FILE}"
echo "THEANO_FLAGS=${FLAGS},mode=FAST_COMPILE pytest ${ARGS} ${XUNIT}${FILE}"
date
THEANO_FLAGS=${FLAGS},mode=FAST_COMPILE ${NOSETESTS} ${ARGS} ${XUNIT}${FILE}
THEANO_FLAGS=${FLAGS},mode=FAST_COMPILE pytest ${ARGS} ${XUNIT}${FILE}
echo "Number of elements in the compiledir:"
ls ${COMPILEDIR}|wc -l
......
......@@ -52,7 +52,7 @@ def makeSharedTester(
:param ref_fct_: A reference function that should return the same value as the theano_fct_
:param cast_value_: A callable that cast an ndarray into the internal shared variable representation
:param name: This string is used to set the returned class' __name__
attribute. This is needed for nosetests to properly tag the
attribute. This is needed for tests to properly tag the
test with its correct name, rather than use the generic
SharedTester name. This parameter is mandatory (keeping the
default None value will raise an error), and must be set to
......
from __future__ import absolute_import, print_function, division
try:
from theano.tests.main import main, TheanoNoseTester
except ImportError:
pass
from __future__ import absolute_import, print_function, division
import os
import unittest
import sys
try:
from numpy.testing.nosetester import NoseTester
except ImportError:
# The tester has been moved in recent versions of numpy
from numpy.testing._private.nosetester import NoseTester
# This class contains code adapted from NumPy,
# numpy/testing/nosetester.py,
# Copyright (c) 2005-2011, NumPy Developers
class TheanoNoseTester(NoseTester):
"""
Nose test runner.
This class enables running nose tests from inside Theano,
by calling theano.test().
This version is more adapted to what we want than Numpy's one.
"""
def _test_argv(self, verbose, extra_argv):
"""
Generate argv for nosetest command
:type verbose: int
:param verbose: Verbosity value for test outputs, in the range 1-10.
Default is 1.
:type extra_argv: list
:param extra_argv: List with any extra arguments to pass to nosetests.
"""
# self.package_path = os.path.abspath(self.package_path)
argv = [__file__, self.package_path]
argv += ["--verbosity", str(verbose)]
if extra_argv:
argv += extra_argv
return argv
def _show_system_info(self):
import theano
print("Theano version %s" % theano.__version__)
theano_dir = os.path.dirname(theano.__file__)
print("theano is installed in %s" % theano_dir)
super(TheanoNoseTester, self)._show_system_info()
def prepare_test_args(
self,
verbose=1,
extra_argv=None,
coverage=False,
capture=True,
knownfailure=True,
):
"""
Prepare arguments for the `test` method.
Takes the same arguments as `test`.
"""
import nose.plugins.builtin
# compile argv
argv = self._test_argv(verbose, extra_argv)
# numpy way of doing coverage
if coverage:
argv += [
"--cover-package=%s" % self.package_name,
"--with-coverage",
"--cover-tests",
"--cover-inclusive",
"--cover-erase",
]
# Capture output only if needed
if not capture:
argv += ["-s"]
# construct list of plugins
plugins = []
if knownfailure:
from numpy.testing.noseclasses import KnownFailure
plugins.append(KnownFailure())
plugins += [p() for p in nose.plugins.builtin.plugins]
return argv, plugins
def test(
self,
verbose=1,
extra_argv=None,
coverage=False,
capture=True,
knownfailure=True,
):
"""
Run tests for module using nose.
:type verbose: int
:param verbose: Verbosity value for test outputs, in the range 1-10.
Default is 1.
:type extra_argv: list
:param extra_argv: List with any extra arguments to pass to nosetests.
:type coverage: bool
:param coverage: If True, report coverage of Theano
code. Default is False.
:type capture: bool
:param capture: If True, capture the standard output of the tests, like
nosetests does in command-line. The output of failing
tests will be displayed at the end. Default is True.
:type knownfailure: bool
:param knownfailure: If True, tests raising KnownFailureTest will
not be considered Errors nor Failure, but reported as
"known failures" and treated quite like skipped tests.
Default is True.
:returns: Returns the result of running the tests as a
``nose.result.TextTestResult`` object.
"""
from nose.config import Config
from nose.plugins.manager import PluginManager
from numpy.testing.noseclasses import NumpyTestProgram
# Many Theano tests suppose device=cpu, so we need to raise an
# error if device==gpu.
if not os.path.exists("theano/__init__.py"):
try:
from theano import config
if config.device != "cpu":
raise ValueError(
"Theano tests must be run with device=cpu."
" This will also run GPU tests when possible.\n"
" If you want GPU-related tests to run on a"
" specific GPU device, and not the default one,"
" you should use the init_gpu_device theano flag."
)
except ImportError:
pass
# cap verbosity at 3 because nose becomes *very* verbose beyond that
verbose = min(verbose, 3)
self._show_system_info()
cwd = os.getcwd()
if self.package_path in os.listdir(cwd):
# The tests give weird errors if the package to test is
# in current directory.
raise RuntimeError(
(
"This function does not run correctly when, at the time "
"theano was imported, the working directory was theano's "
"parent directory. You should exit your Python prompt, change "
"directory, then launch Python again, import theano, then "
"launch theano.test()."
)
)
argv, plugins = self.prepare_test_args(
verbose, extra_argv, coverage, capture, knownfailure
)
# The "plugins" keyword of NumpyTestProgram gets ignored if config is
# specified. Moreover, using "addplugins" instead can lead to strange
# errors. So, we specify the plugins in the Config as well.
cfg = Config(includeExe=True, plugins=PluginManager(plugins=plugins))
t = NumpyTestProgram(argv=argv, exit=False, config=cfg)
return t.result
def main(modulename):
if 0:
unittest.main()
elif len(sys.argv) == 2 and sys.argv[1] == "--debug":
module = __import__(modulename)
tests = unittest.TestLoader().loadTestsFromModule(module)
tests.debug()
elif len(sys.argv) == 1:
module = __import__(modulename)
tests = unittest.TestLoader().loadTestsFromModule(module)
unittest.TextTestRunner(verbosity=2).run(tests)
else:
print("options: [--debug]")
#!/usr/bin/env python
from __future__ import absolute_import, print_function, division
import datetime
import os
import subprocess
import sys
import time
from six.moves import xrange
import six.moves.cPickle as pickle
import theano
from theano.misc.windows import output_subprocess_Popen
__authors__ = "Olivier Delalleau, Eric Larsen"
__contact__ = "delallea@iro"
"""
Run this script to run tests in small batches rather than all at the same time
or to conduct time-profiling.
If no argument is provided, then the whole Theano test-suite is run.
Otherwise, only tests found in the directory given as argument are run.
If 'time_profile=False', this script performs three tasks:
1. Run `nosetests --collect-only --with-id` to collect test IDs
2. Run `nosetests --with-id i1 ... iN` with batches of 'batch_size'
indices, until all tests have been run (currently batch_size=100 by
default).
3. Run `nosetests --failed` to re-run only tests that failed
=> The output of this 3rd step is the one you should care about
If 'time_profile=True', this script conducts time-profiling of the tests:
1. Run `nosetests --collect-only --with-id` to collect test IDs
2. Run `nosetests --with-id i`, one test with ID 'i' at a time, collecting
timing information and displaying progresses on standard output after
every group of 'batch_size' (100 by default), until all tests have
been run.
The results are deposited in the files 'timeprof_sort' and
'timeprof_nosort' in the current directory. Both contain one record for
each test and comprise the following fields:
- test running-time
- nosetests sequential test number
- test name
- name of class to which test belongs (if any), otherwise full
information is contained in test name
- test outcome ('OK', 'SKIPPED TEST', 'FAILED TEST' or 'FAILED PARSING')
In 'timeprof_sort', test records are sorted according to run-time
whereas in 'timeprof_nosort' records are reported according to
sequential number. The former classification is the main information
source for time-profiling. Since tests belonging to same or close
classes and files have close sequential numbers, the latter may be used
to identify duration patterns among the tests. A full log is also saved
as 'timeprof_rawlog'.
One reason to use this script is if you are a Windows user, and see errors like
"Not enough storage is available to process this command" when trying to simply
run `nosetests` in your Theano installation directory. This error is apparently
caused by memory fragmentation: at some point Windows runs out of contiguous
memory to load the C modules compiled by Theano in the test-suite.
By using this script, nosetests is run on a small subset (batch) of tests until
all tests are run. Note that this is slower, in particular because of the
initial cost of importing theano and loading the C module cache on each call of
nosetests.
"""
def main(
stdout=None,
stderr=None,
argv=None,
theano_nose=None,
batch_size=None,
time_profile=False,
display_batch_output=False,
):
"""
Run tests with optional output redirection.
Parameters stdout and stderr should be file-like objects used to redirect
the output. None uses default sys.stdout and sys.stderr.
If argv is None, then we use arguments from sys.argv, otherwise we use the
provided arguments instead.
If theano_nose is None, then we use the theano-nose script found in
Theano/bin to call nosetests. Otherwise we call the provided script.
If batch_size is None, we use a default value of 100.
If display_batch_output is False, then the output of nosetests during batch
execution is hidden.
"""
if stdout is None:
stdout = sys.stdout
if stderr is None:
stderr = sys.stderr
if argv is None:
argv = sys.argv
if theano_nose is None:
# If Theano is installed with pip/easy_install, it can be in the
# */lib/python2.7/site-packages/theano, but theano-nose in */bin
for i in range(1, 5):
path = theano.__path__[0]
for _ in range(i):
path = os.path.join(path, "..")
path = os.path.join(path, "bin", "theano-nose")
if os.path.exists(path):
theano_nose = path
break
if theano_nose is None:
raise Exception("Unable to find theano-nose")
if batch_size is None:
batch_size = 100
stdout_backup = sys.stdout
stderr_backup = sys.stderr
try:
sys.stdout = stdout
sys.stderr = stderr
run(
stdout,
stderr,
argv,
theano_nose,
batch_size,
time_profile,
display_batch_output,
)
finally:
sys.stdout = stdout_backup
sys.stderr = stderr_backup
def run(
stdout, stderr, argv, theano_nose, batch_size, time_profile, display_batch_output
):
# Setting aside current working directory for later saving
sav_dir = os.getcwd()
# The first argument is the called script.
argv = argv[1:]
# It seems safer to fully regenerate the list of tests on each call.
if os.path.isfile(".noseids"):
os.remove(".noseids")
# Collect test IDs.
print(
"""\
####################
# COLLECTING TESTS #
####################"""
)
stdout.flush()
stderr.flush()
dummy_in = open(os.devnull)
# We need to call 'python' on Windows, because theano-nose is not a
# native Windows app; and it does not hurt to call it on Unix.
# Using sys.executable, so that the same Python version is used.
python = sys.executable
rval = subprocess.call(
([python, theano_nose, "--collect-only", "--with-id"] + argv),
stdin=dummy_in.fileno(),
stdout=stdout.fileno(),
stderr=stderr.fileno(),
)
stdout.flush()
stderr.flush()
assert rval == 0
noseids_file = ".noseids"
with open(noseids_file, "rb") as f:
data = pickle.load(f)
ids = data["ids"]
n_tests = len(ids)
if n_tests == 0:
raise Exception("0 test selected")
assert n_tests == max(ids)
# Standard batch testing is called for
if not time_profile:
failed = set()
print(
"""\
###################################
# RUNNING TESTS IN BATCHES OF %s #
###################################"""
% batch_size
)
# When `display_batch_output` is False, we suppress all output because
# we want the user to focus only on the failed tests, which are re-run
# (with output) below.
dummy_out = open(os.devnull, "w")
for test_id in xrange(1, n_tests + 1, batch_size):
stdout.flush()
stderr.flush()
test_range = list(range(test_id, min(test_id + batch_size, n_tests + 1)))
cmd = [python, theano_nose, "--with-id"] + list(map(str, test_range)) + argv
subprocess_extra_args = dict(stdin=dummy_in.fileno())
if not display_batch_output:
# Use quiet mode in nosetests.
cmd.append("-q")
# Suppress all output.
subprocess_extra_args.update(
dict(stdout=dummy_out.fileno(), stderr=dummy_out.fileno())
)
t0 = time.time()
subprocess.call(cmd, **subprocess_extra_args)
t1 = time.time()
# Recover failed test indices from the 'failed' field of the
# '.noseids' file. We need to do it after each batch because
# otherwise this field may get erased. We use a set because it
# seems like it is not systematically erased though, and we want
# to avoid duplicates.
with open(noseids_file, "rb") as f:
failed = failed.union(pickle.load(f)["failed"])
print(
"%s%% done in %.3fs (failed: %s)"
% ((test_range[-1] * 100) // n_tests, t1 - t0, len(failed))
)
# Sort for cosmetic purpose only.
failed = sorted(failed)
if failed:
# Re-run only failed tests
print(
"""\
################################
# RE-RUNNING FAILED TESTS ONLY #
################################"""
)
stdout.flush()
stderr.flush()
subprocess.call(
([python, theano_nose, "-v", "--with-id"] + failed + argv),
stdin=dummy_in.fileno(),
stdout=stdout.fileno(),
stderr=stderr.fileno(),
)
stdout.flush()
stderr.flush()
return 0
else:
print(
"""\
####################
# ALL TESTS PASSED #
####################"""
)
# Time-profiling is called for
else:
print(
"""\
########################################
# RUNNING TESTS IN TIME-PROFILING MODE #
########################################"""
)
# finds first word of list l containing string s
def getIndexOfFirst(l, s):
for pos, word in enumerate(l):
if s in word:
return pos
# finds last word of list l containing string s
def getIndexOfLast(l, s):
for pos, word in enumerate(reversed(l)):
if s in word:
return len(l) - pos - 1
# iterating through tests
# initializing master profiling list and raw log
prof_master_nosort = []
dummy_out = open(os.devnull, "w")
path_rawlog = os.path.join(sav_dir, "timeprof_rawlog")
stamp = str(datetime.datetime.now()) + "\n\n"
f_rawlog = open(path_rawlog, "w")
f_rawlog.write("TIME-PROFILING OF THEANO'S NOSETESTS" " (raw log)\n\n" + stamp)
f_rawlog.flush()
stamp = str(datetime.datetime.now()) + "\n\n"
fields = (
"Fields: computation time; nosetests sequential id;"
" test name; parent class (if any); outcome\n\n"
)
path_nosort = os.path.join(sav_dir, "timeprof_nosort")
# probably this part can be extracted for function with many args
with open(path_nosort, "w") as f_nosort:
# begin of saving nosort
f_nosort.write(
"TIME-PROFILING OF THEANO'S NOSETESTS"
" (by sequential id)\n\n" + stamp + fields
)
f_nosort.flush()
for test_floor in xrange(1, n_tests + 1, batch_size):
for test_id in xrange(
test_floor, min(test_floor + batch_size, n_tests + 1)
):
# Print the test we will start in the raw log to help
# debug tests that are too long.
f_rawlog.write(
"\n%s Will run test #%d %s\n"
% (time.ctime(), test_id, data["ids"][test_id])
)
f_rawlog.flush()
p_out = output_subprocess_Popen(
(
[python, theano_nose, "-v", "--with-id"]
+ [str(test_id)]
+ argv
+ ["--disabdocstring"]
)
)
# the previous option calls a custom Nosetests plugin
# precluding automatic sustitution of doc. string for
# test name in display
# (see class 'DisabDocString' in file theano-nose)
# recovering and processing data from pipe
err = p_out[1]
# print the raw log
f_rawlog.write(err)
f_rawlog.flush()
# parsing the output
l_err = err.split()
try:
pos_id = getIndexOfFirst(l_err, "#")
prof_id = l_err[pos_id]
pos_dot = getIndexOfFirst(l_err, "...")
prof_test = ""
for s in l_err[pos_id + 1 : pos_dot]:
prof_test += s + " "
if "OK" in err:
pos_ok = getIndexOfLast(l_err, "OK")
if len(l_err) == pos_ok + 1:
prof_time = float(l_err[pos_ok - 1][0:-1])
prof_pass = "OK"
elif "SKIP" in l_err[pos_ok + 1]:
prof_time = 0.0
prof_pass = "SKIPPED TEST"
elif "KNOWNFAIL" in l_err[pos_ok + 1]:
prof_time = float(l_err[pos_ok - 1][0:-1])
prof_pass = "OK"
else:
prof_time = 0.0
prof_pass = "FAILED TEST"
else:
prof_time = 0.0
prof_pass = "FAILED TEST"
except Exception:
prof_time = 0
prof_id = "#" + str(test_id)
prof_test = "FAILED PARSING, see raw log for details" " on test"
prof_pass = ""
prof_tuple = (prof_time, prof_id, prof_test, prof_pass)
# appending tuple to master list
prof_master_nosort.append(prof_tuple)
# write the no sort file
s_nosort = (
(str(prof_tuple[0]) + "s").ljust(10)
+ " "
+ prof_tuple[1].ljust(7)
+ " "
+ prof_tuple[2]
+ prof_tuple[3]
+ "\n"
)
f_nosort.write(s_nosort)
f_nosort.flush()
print("%s%% time-profiled" % ((test_id * 100) // n_tests))
f_rawlog.close()
# sorting tests according to running-time
prof_master_sort = sorted(
prof_master_nosort, key=lambda test: test[0], reverse=True
)
# saving results to readable files
path_sort = os.path.join(sav_dir, "timeprof_sort")
with open(path_sort, "w") as f_sort:
f_sort.write(
"TIME-PROFILING OF THEANO'S NOSETESTS"
" (sorted by computation time)\n\n" + stamp + fields
)
for i in xrange(len(prof_master_nosort)):
s_sort = (
(str(prof_master_sort[i][0]) + "s").ljust(10)
+ " "
+ prof_master_sort[i][1].ljust(7)
+ " "
+ prof_master_sort[i][2]
+ prof_master_sort[i][3]
+ "\n"
)
f_sort.write(s_sort)
# end of saving nosort
if __name__ == "__main__":
sys.exit(main())
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论