提交 f35c2fef authored 作者: nouiz's avatar nouiz

Merge pull request #902 from delallea/fixing_tests

Fixes for tests with --batch option
......@@ -13,22 +13,6 @@ It is also used to load the KnownFailure plugin, in order to hide
KnownFailureTests error messages. Use --without-knownfailure to
disable that plugin.
There are two additional local options: '--batch[=n]' and '--time-profile'.
If '--batch[=n]' is used without '--time-profile', this script will call
run_tests_in_batch.py` in order to run the tests by batches, not all at the
same time. The batches will comprise 100 elements each by default and
'n' elements if the option '=n' is specified.
If the '--time-profile' option is used, it will call `run_tests_in_batch.py`
with the option time_profile=True to conduct time-profiling of the tests.
(See 'help' function below for details.) If also specified, '--batch[=n]'
option will be interpreted as an indication of the number of tests to be run
between notifications of progress to standard output.
If the '--theano' option is used, it is replaced with the path to theano.
Useful if you don't know where it was installed.
`run_tests_in_batch.py` will in turn call back this script in another process.
"""
......@@ -64,16 +48,30 @@ def main():
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 len(time_prof_args) or len(batch_args):
if time_prof_args or batch_args:
from theano.tests import run_tests_in_batch
return run_tests_in_batch.main(batch_size=batch_size,
time_profile=len(time_prof_args) > 0)
return run_tests_in_batch.main(
batch_size=batch_size,
time_profile=bool(time_prof_args),
display_batch_output=display_batch_output)
# Non-batch mode.
addplugins = []
......@@ -110,6 +108,8 @@ def help():
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
......@@ -142,14 +142,21 @@ def help():
latter may be used to identify duration patterns among the tests
numbers. A full log is also saved as 'timeprof_rawlog'.
--help, -h: Displays this help.
--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 expect a path to the tests to run.
If you don't know where theano is installed, use this option
to have it inserted automatically.
--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``.
"""
......
......@@ -714,7 +714,7 @@ class CSM(gof.Op):
def __str__(self):
if self.kmap is not None:
return "%s{%s}" %(self.__class__.__name__, str(self.kmap))
return "%s{%s}" % (self.__class__.__name__, str(self.kmap))
return self.__class__.__name__
def make_node(self, data, indices, indptr, shape):
......@@ -2688,6 +2688,10 @@ def rint(x):
"""
# see decorator for function body
# Give it a simple name instead of the complex one that would automatically
# be derived from `tensor.round_half_to_even`.
rint.__name__ = 'rint'
@structured_monoid(tensor.sgn)
def sgn(x):
......
......@@ -721,8 +721,9 @@ class test_csm(unittest.TestCase):
a = as_sparse_variable(sp_types[format](random_lil((4, 3),
dtype, 1)))
f = theano.function([x, y, z, s], tensor.grad(dense_from_sparse(
a * CSM(format)(x, y, z, s)).sum(), x))
f = theano.function([x, y, z, s],
tensor.grad(dense_from_sparse(
a * CSM(format)(x, y, z, s)).sum(), x))
spmat = sp_types[format](random_lil((4, 3), dtype, 3))
......@@ -1012,9 +1013,10 @@ class test_structureddot(unittest.TestCase):
overhead_tol = 0.002 # seconds
overhead_rtol = 1.1 # times as long
self.assertTrue(numpy.allclose(theano_result, scipy_result))
if not theano.config.mode in ["DebugMode", "DEBUG_MODE"] and theano.config.cxx:
self.assertFalse(theano_time > overhead_rtol * scipy_time +
overhead_tol)
if (not theano.config.mode in ["DebugMode", "DEBUG_MODE"] and
theano.config.cxx):
self.assertFalse(theano_time > overhead_rtol * scipy_time +
overhead_tol)
class DotTests(unittest.TestCase):
......@@ -1954,7 +1956,8 @@ class CastTester(utt.InferShapeTester):
func = theano.function([variable], cast(variable, o_dtype))
cls = theano.function([variable], Cast(o_dtype)(variable))
prop = theano.function([variable], variable.astype(o_dtype))
prop = theano.function([variable],
variable.astype(o_dtype))
t_func, t_cls, t_prop = func(data), cls(data), prop(data)
......@@ -2241,7 +2244,7 @@ class MultinomialTester(utt.InferShapeTester):
def elemwise_checker(op, expected_f, gap=None, test_dtypes=None,
grad_test=True):
grad_test=True, name=None):
"""Return the appropriate test class for the elemwise on sparse.
:param op: Op to test.
......@@ -2268,13 +2271,14 @@ def elemwise_checker(op, expected_f, gap=None, test_dtypes=None,
test_dtypes = sparse.all_dtypes
class Tester(unittest.TestCase):
__name__ = op.__name__.capitalize() + 'Tester'
def setUp(self):
super(Tester, self).setUp()
self.op = op
self.expected_f = expected_f
self.gap = gap
# Ensure the test's name is correct.
assert eval(self.__class__.__name__) is self.__class__
def test_op(self):
for format in sparse.sparse_formats:
......@@ -2387,7 +2391,15 @@ def elemwise_checker(op, expected_f, gap=None, test_dtypes=None,
verify_grad_sparse(self.op,
data,
structured=True)
Tester.__name__ = op.__name__ + "Tester"
# Set proper class name to uniquely identify tests.
# Note that it is important to run this code *outside* of the `Tester`
# class itself, otherwise it will not work properly for some reason.
if name is None:
name = op.__name__.capitalize() + 'Tester'
Tester.__name__ = name
assert 'Roundhalftoeven' not in Tester.__name__
return Tester
......@@ -2420,32 +2432,39 @@ StructuredSigmoidTester = elemwise_checker(
test_dtypes=[m for m in sparse.all_dtypes
if (not m in sparse.complex_dtypes and
not m.startswith('uint'))],
gap=(-5, 5))
gap=(-5, 5),
name='StructuredSigmoidTester')
StructuredExpTester = elemwise_checker(
sparse.structured_exp,
structure_function(numpy.exp))
structure_function(numpy.exp),
name='StructuredExpTester')
StructuredLogTester = elemwise_checker(
sparse.structured_log,
structure_function(numpy.log),
gap=(0.5, 10))
gap=(0.5, 10),
name='StructuredLogTester')
StructuredPowTester = elemwise_checker(
lambda x: sparse.structured_pow(x, 2),
structure_function(lambda x: numpy.power(x, 2)))
structure_function(lambda x: numpy.power(x, 2)),
name='StructuredPowTester')
StructuredMinimumTester = elemwise_checker(
lambda x: structured_minimum(x, 2),
structure_function(lambda x: numpy.minimum(x, 2)))
structure_function(lambda x: numpy.minimum(x, 2)),
name='StructuredMinimumTester')
StructuredMaximumTester = elemwise_checker(
lambda x: structured_maximum(x, 2),
structure_function(lambda x: numpy.maximum(x, 2)))
structure_function(lambda x: numpy.maximum(x, 2)),
name='StructuredMaximumTester')
StructuredAddTester = elemwise_checker(
lambda x: structured_add(x, 2),
structure_function(lambda x: numpy.add(x, 2)))
structure_function(lambda x: numpy.add(x, 2)),
name='StructuredAddTester')
SinTester = elemwise_checker(
sparse.sin,
......@@ -2456,12 +2475,12 @@ TanTester = elemwise_checker(
numpy.tan,
gap=(-1, 1))
ArcSinTester = elemwise_checker(
ArcsinTester = elemwise_checker(
sparse.arcsin,
numpy.arcsin,
gap=(-1, 1))
ArcTanTester = elemwise_checker(
ArctanTester = elemwise_checker(
sparse.arctan,
numpy.arctan)
......@@ -2469,7 +2488,7 @@ SinhTester = elemwise_checker(
sparse.sinh,
numpy.sinh)
ArcSinhTester = elemwise_checker(
ArcsinhTester = elemwise_checker(
sparse.arcsinh,
numpy.arcsinh,
gap=(-1, 1))
......@@ -2479,7 +2498,7 @@ TanhTester = elemwise_checker(
numpy.tanh,
gap=(-1, 1))
ArcTanhTester = elemwise_checker(
ArctanhTester = elemwise_checker(
sparse.arctanh,
numpy.arctanh,
gap=(-0.9, 1))
......@@ -2521,13 +2540,13 @@ Expm1Tester = elemwise_checker(
sparse.expm1,
numpy.expm1)
Deg2RadTester = elemwise_checker(
Deg2radTester = elemwise_checker(
sparse.deg2rad,
numpy.deg2rad,
test_dtypes=[m for m in sparse.all_dtypes
if not m in sparse.complex_dtypes])
Rad2DegTester = elemwise_checker(
Rad2degTester = elemwise_checker(
sparse.rad2deg,
numpy.rad2deg,
test_dtypes=[m for m in sparse.all_dtypes
......
......@@ -5414,7 +5414,7 @@ class Reshape(Op):
requ_part = [ele for ele in requ if ele != -1]
crit = len(requ) - len(requ_part)
if crit == 1 and len(requ_part) > 0:
missing = mul(*ishapes[0]) / mul(*requ_part)
missing = mul(*ishapes[0]) // mul(*requ_part)
for i, ele in enumerate(requ):
if ele == -1:
requ[i] = missing
......
......@@ -214,6 +214,8 @@ def makeTester(name, op, expected, checks=None, good=None, bad_build=None,
test_memmap = _test_memmap
def setUp(self):
# Verify that the test's name is correctly set.
assert eval(self.__class__.__name__) is self.__class__
# If test_memmap is True, we create a temporary file
# containing a copy of the data passed in the "good" dict,
# then open it as a memmapped array, and use the result as a
......@@ -957,22 +959,23 @@ FloorTester = makeBroadcastTester(op=tensor.floor,
# yet it does not...
grad=_grad_broadcast_unary_normal)
TruncInplaceTester = makeBroadcastTester(
op=inplace.floor_inplace,
expected=lambda a: numpy.asarray(numpy.floor(a), a.dtype),
good=_good_broadcast_unary_normal_no_complex,
inplace=True)
TruncTester = makeBroadcastTester(
op=tensor.floor,
expected=lambda a: numpy.asarray(numpy.floor(a), a.dtype),
good=_good_broadcast_unary_normal_no_complex)
FloorInplaceTester = makeBroadcastTester(op=inplace.floor_inplace,
expected=lambda a: numpy.asarray(numpy.floor(a), a.dtype),
good=_good_broadcast_unary_normal_no_complex,
grad=_grad_broadcast_unary_normal,
inplace=True)
TruncInplaceTester = makeBroadcastTester(
op=inplace.trunc_inplace,
expected=lambda a: numpy.asarray(numpy.trunc(a), a.dtype),
good=_good_broadcast_unary_normal_no_complex,
inplace=True)
TruncTester = makeBroadcastTester(
op=tensor.trunc,
expected=lambda a: numpy.asarray(numpy.trunc(a), a.dtype),
good=_good_broadcast_unary_normal_no_complex)
RoundHalfToEvenTester = makeBroadcastTester(
op=tensor.round_half_to_even,
expected=numpy.round,
......@@ -1110,13 +1113,13 @@ if theano.config.floatX == 'float32':
else:
angle_eps = 1e-10
Deg2RadTester = makeBroadcastTester(
Deg2radTester = makeBroadcastTester(
op=tensor.deg2rad,
expected=numpy.deg2rad,
good=_good_broadcast_unary_normal_no_complex,
grad=_grad_broadcast_unary_normal_no_complex,
eps=angle_eps)
Deg2RadInplaceTester = makeBroadcastTester(
Deg2radInplaceTester = makeBroadcastTester(
op=inplace.deg2rad_inplace,
expected=numpy.deg2rad,
good=_good_broadcast_unary_normal_no_complex,
......@@ -1124,13 +1127,13 @@ Deg2RadInplaceTester = makeBroadcastTester(
inplace=True,
eps=angle_eps)
Rad2DegTester = makeBroadcastTester(
Rad2degTester = makeBroadcastTester(
op=tensor.rad2deg,
expected=numpy.rad2deg,
good=_good_broadcast_unary_normal_no_complex,
grad=_grad_broadcast_unary_normal_no_complex,
eps=angle_eps)
Rad2DegInplaceTester = makeBroadcastTester(
Rad2degInplaceTester = makeBroadcastTester(
op=inplace.rad2deg_inplace,
expected=numpy.rad2deg,
good=_good_broadcast_unary_normal_no_complex,
......@@ -1154,11 +1157,11 @@ _good_broadcast_unary_arcsin = dict(normal=(rand_ranged(-1, 1, (2, 3)),),
empty=(numpy.asarray([]),),)
_grad_broadcast_unary_arcsin = dict(normal=(rand_ranged(-1, 1, (2, 3)),),)
ArcSinTester = makeBroadcastTester(op=tensor.arcsin,
ArcsinTester = makeBroadcastTester(op=tensor.arcsin,
expected=numpy.arcsin,
good=_good_broadcast_unary_arcsin,
grad=_grad_broadcast_unary_arcsin)
ArcSinInplaceTester = makeBroadcastTester(op=inplace.arcsin_inplace,
ArcsinInplaceTester = makeBroadcastTester(op=inplace.arcsin_inplace,
expected=numpy.arcsin,
good=_good_broadcast_unary_arcsin,
grad=_grad_broadcast_unary_arcsin,
......@@ -1174,11 +1177,11 @@ CosInplaceTester = makeBroadcastTester(op=inplace.cos_inplace,
grad=_grad_broadcast_unary_wide,
inplace=True)
ArcCosTester = makeBroadcastTester(op=tensor.arccos,
ArccosTester = makeBroadcastTester(op=tensor.arccos,
expected=numpy.arccos,
good=_good_broadcast_unary_arcsin,
grad=_grad_broadcast_unary_arcsin)
ArcCosInplaceTester = makeBroadcastTester(op=inplace.arccos_inplace,
ArccosInplaceTester = makeBroadcastTester(op=inplace.arccos_inplace,
expected=numpy.arccos,
good=_good_broadcast_unary_arcsin,
grad=_grad_broadcast_unary_arcsin,
......@@ -1211,12 +1214,12 @@ TanInplaceTester = makeBroadcastTester(op=inplace.tan_inplace,
grad_rtol=tan_grad_rtol,
inplace=True)
ArcTanTester = makeBroadcastTester(op=tensor.arctan,
ArctanTester = makeBroadcastTester(op=tensor.arctan,
expected=numpy.arctan,
good=_good_broadcast_unary_wide,
grad=_grad_broadcast_unary_wide,
grad_rtol=tan_grad_rtol)
ArcTanInplaceTester = makeBroadcastTester(op=inplace.arctan_inplace,
ArctanInplaceTester = makeBroadcastTester(op=inplace.arctan_inplace,
expected=numpy.arctan,
good=_good_broadcast_unary_wide,
grad=_grad_broadcast_unary_wide,
......@@ -1242,12 +1245,12 @@ _grad_broadcast_binary_arctan2 = dict(
column=(rand(2, 3), rand(2, 1)),
)
ArcTan2Tester = makeBroadcastTester(op=tensor.arctan2,
Arctan2Tester = makeBroadcastTester(op=tensor.arctan2,
expected=numpy.arctan2,
good=_good_broadcast_binary_arctan2,
grad=_grad_broadcast_binary_arctan2,
grad_rtol=tan_grad_rtol)
ArcTan2InplaceTester = makeBroadcastTester(op=inplace.arctan2_inplace,
Arctan2InplaceTester = makeBroadcastTester(op=inplace.arctan2_inplace,
expected=numpy.arctan2,
good=_good_broadcast_binary_arctan2,
grad=_grad_broadcast_binary_arctan2,
......@@ -1271,11 +1274,11 @@ _good_broadcast_unary_arccosh = dict(
empty=(numpy.asarray([]),),)
_grad_broadcast_unary_arccosh = dict(normal=(rand_ranged(1, 1000, (2, 3)),),)
ArcCoshTester = makeBroadcastTester(op=tensor.arccosh,
ArccoshTester = makeBroadcastTester(op=tensor.arccosh,
expected=numpy.arccosh,
good=_good_broadcast_unary_arccosh,
grad=_grad_broadcast_unary_arccosh)
ArcCoshInplaceTester = makeBroadcastTester(op=inplace.arccosh_inplace,
ArccoshInplaceTester = makeBroadcastTester(op=inplace.arccosh_inplace,
expected=numpy.arccosh,
good=_good_broadcast_unary_arccosh,
grad=_grad_broadcast_unary_arccosh,
......@@ -1291,11 +1294,11 @@ SinhInplaceTester = makeBroadcastTester(op=inplace.sinh_inplace,
grad=_grad_broadcast_unary_normal,
inplace=True)
ArcSinhTester = makeBroadcastTester(op=tensor.arcsinh,
ArcsinhTester = makeBroadcastTester(op=tensor.arcsinh,
expected=numpy.arcsinh,
good=_good_broadcast_unary_normal,
grad=_grad_broadcast_unary_normal)
ArcSinhInplaceTester = makeBroadcastTester(op=inplace.arcsinh_inplace,
ArcsinhInplaceTester = makeBroadcastTester(op=inplace.arcsinh_inplace,
expected=numpy.arcsinh,
good=_good_broadcast_unary_normal,
grad=_grad_broadcast_unary_normal,
......@@ -1320,11 +1323,11 @@ _good_broadcast_unary_arctanh = dict(
_grad_broadcast_unary_arctanh = dict(
normal=(rand_ranged(-1 + _eps, 1 - _eps, (2, 3)),),)
ArcTanhTester = makeBroadcastTester(op=tensor.arctanh,
ArctanhTester = makeBroadcastTester(op=tensor.arctanh,
expected=numpy.arctanh,
good=_good_broadcast_unary_arctanh,
grad=_grad_broadcast_unary_arctanh)
ArcTanhInplaceTester = makeBroadcastTester(op=inplace.arctanh_inplace,
ArctanhInplaceTester = makeBroadcastTester(op=inplace.arctanh_inplace,
expected=numpy.arctanh,
good=_good_broadcast_unary_arctanh,
grad=_grad_broadcast_unary_arctanh,
......@@ -1416,7 +1419,7 @@ GammaInplaceTester = makeBroadcastTester(
inplace=True,
skip=skip_scipy)
GammaLnTester = makeBroadcastTester(
GammalnTester = makeBroadcastTester(
op=tensor.gammaln,
expected=expected_gammaln,
good=_good_broadcast_unary_gammaln,
......@@ -1424,7 +1427,7 @@ GammaLnTester = makeBroadcastTester(
eps=2e-10,
mode=mode_no_scipy,
skip=skip_scipy)
GammaLnInplaceTester = makeBroadcastTester(
GammalnInplaceTester = makeBroadcastTester(
op=inplace.gammaln_inplace,
expected=expected_gammaln,
good=_good_broadcast_unary_gammaln,
......@@ -1493,7 +1496,7 @@ ConjTester = makeBroadcastTester(
expected=numpy.conj,
good=_good_broadcast_unary_normal)
ConjInplaceTester = makeBroadcastTester(
op=tensor.conj,
op=inplace.conj_inplace,
expected=numpy.conj,
good=_good_broadcast_unary_normal,
inplace=True)
......
......@@ -32,7 +32,7 @@ If 'time_profile=True', this script conducts time-profiling of the tests:
- test name
- name of class to which test belongs (if any), otherwise full
information is contained in test name
- test outcome ('OK', 'SKIPPED TESTS', 'FAILED TEST' or 'FAILED PARSING')
- 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
......@@ -63,7 +63,7 @@ import theano
def main(stdout=None, stderr=None, argv=None, theano_nose=None,
batch_size=None, time_profile=False):
batch_size=None, time_profile=False, display_batch_output=False):
"""
Run tests with optional output redirection.
......@@ -77,6 +77,9 @@ def main(stdout=None, stderr=None, argv=None, theano_nose=None,
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:
......@@ -105,13 +108,15 @@ def main(stdout=None, stderr=None, argv=None, theano_nose=None,
try:
sys.stdout = stdout
sys.stderr = stderr
run(stdout, stderr, argv, theano_nose, batch_size, time_profile)
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):
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()
......@@ -156,20 +161,26 @@ def run(stdout, stderr, argv, theano_nose, batch_size, time_profile):
###################################
# RUNNING TESTS IN BATCHES OF %s #
###################################""" % batch_size
# We suppress all output because we want the user to focus only on
# the failed tests, which are re-run (with output) below.
# 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 = range(test_id, min(test_id + batch_size, n_tests + 1))
rval = subprocess.call(
([python, theano_nose, '-q', '--with-id']
+ map(str, test_range)
+ argv),
stdout=dummy_out.fileno(),
stderr=dummy_out.fileno(),
stdin=dummy_in.fileno())
cmd = ([python, theano_nose, '--with-id'] +
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()))
subprocess.call(cmd, **subprocess_extra_args)
# 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
......@@ -324,5 +335,3 @@ def run(stdout, stderr, argv, theano_nose, batch_size, time_profile):
if __name__ == '__main__':
sys.exit(main())
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论