提交 21581731 authored 作者: Arnaud Bergeron's avatar Arnaud Bergeron

Revise makeTester to make it easier to test Gpu ops.

上级 890b9af0
...@@ -504,7 +504,7 @@ class GpuAlloc(HideC, Alloc): ...@@ -504,7 +504,7 @@ class GpuAlloc(HideC, Alloc):
} }
if (GpuArray_setarray(&%(zz)s->ga, &%(vv)s->ga) != GA_NO_ERROR) { if (GpuArray_setarray(&%(zz)s->ga, &%(vv)s->ga) != GA_NO_ERROR) {
PyErr_SetString(PyExc_RuntimeError, "setarray failed"); PyErr_SetString(PyExc_ValueError, "setarray failed");
%(fail)s %(fail)s
} }
""" % dict(name=name, ndim=ndim, zz=zz, vv=vv, fail=sub['fail']) """ % dict(name=name, ndim=ndim, zz=zz, vv=vv, fail=sub['fail'])
...@@ -515,6 +515,6 @@ class GpuAlloc(HideC, Alloc): ...@@ -515,6 +515,6 @@ class GpuAlloc(HideC, Alloc):
return code return code
def c_code_cache_version(self): def c_code_cache_version(self):
return (0,) return (1,)
gpu_alloc = GpuAlloc() gpu_alloc = GpuAlloc()
...@@ -5,7 +5,9 @@ from copy import copy, deepcopy ...@@ -5,7 +5,9 @@ from copy import copy, deepcopy
import numpy import numpy
import theano import theano
import theano.tensor as T import theano.tensor as T
from theano.tensor.tests.test_basic import safe_make_node from theano.tensor import TensorType
from theano.tensor.basic import alloc
from theano.tensor.tests.test_basic import rand, safe_make_node
from theano.tests.unittest_tools import SkipTest from theano.tests.unittest_tools import SkipTest
from numpy.testing.noseclasses import KnownFailureTest from numpy.testing.noseclasses import KnownFailureTest
...@@ -94,79 +96,81 @@ def rand_gpuarray(*shape, **kwargs): ...@@ -94,79 +96,81 @@ def rand_gpuarray(*shape, **kwargs):
return gpuarray.array(r, dtype=dtype, cls=cls) return gpuarray.array(r, dtype=dtype, cls=cls)
def makeTester(name, op, expected, good=None, bad_build=None, checks=None, def makeTester(name, op, gpu_op, cases, checks=None, mode_gpu=mode_with_gpu,
bad_runtime=None, mode=None, skip=False, eps=1e-10): mode_nogpu=mode_without_gpu, skip=False, eps=1e-10):
if good is None:
good = {}
if bad_build is None:
bad_build = {}
if bad_runtime is None:
bad_runtime = {}
if checks is None: if checks is None:
checks = {} checks = {}
_op = op _op = op
_expected = expected _gpu_op = gpu_op
_good = good _cases = cases
_bad_build = bad_build
_bad_runtime = bad_runtime
_skip = skip _skip = skip
_checks = checks _checks = checks
class Checker(unittest.TestCase): class Checker(unittest.TestCase):
op = staticmethod(_op) op = staticmethod(_op)
expected = staticmethod(_expected) gpu_op = staticmethod(_gpu_op)
good = _good cases = _cases
bad_build = _bad_build
bad_runtime = _bad_runtime
skip = _skip skip = _skip
checks = _checks checks = _checks
def setUp(self): def setUp(self):
eval(self.__class__.__module__ + '.' + self.__class__.__name__) eval(self.__class__.__module__ + '.' + self.__class__.__name__)
def test_good(self): def test_all(self):
if skip: if skip:
raise SkipTest(skip) raise SkipTest(skip)
for testname, inputs in good.items(): for testname, inputs in cases.items():
inputs = [copy(input) for input in inputs] self.run_case(testname,
inputrs = [fake_shared(input) for input in inputs] [theano.shared(input) for input in inputs])
def run_case(self, testname, inputs):
try: try:
node = safe_make_node(self.op, *inputrs) node = safe_make_node(self.op, *inputs)
except Exception, exc: except Exception, exc:
err_msg = ("Test %s::%s: Error occured while making " err_msg = ("Test %s::%s: Error occured while making "
"a node with inputs %s") % (self.op, testname, "a node with inputs %s") % (self.gpu_op, testname,
inputs) inputs)
exc.args += (err_msg,) exc.args += (err_msg,)
raise raise
try: try:
f = inplace_func([], node.outputs, mode=mode, f_ref = inplace_func([], node.outputs, mode=mode_nogpu)
name='test_good') f_tst = inplace_func([], node.outputs, mode=mode_gpu)
except Exception, exc: except Exception, exc:
err_msg = ("Test %s::%s: Error occured while trying to " err_msg = ("Test %s::%s: Error occured while trying to "
"make a Function") % (self.op, testname) "make a Function") % (self.gpu_op, testname)
exc.args += (err_msg,) exc.args += (err_msg,)
raise raise
if isinstance(self.expected, dict) and \ assert any(node.op is self.gpu_op
testname in self.expected: for node in f_tst.maker.fgraph.toposort()), testname
expecteds = self.expected[testname]
else:
expecteds = self.expected(*inputs)
if not isinstance(expecteds, (list, tuple)): ref_e = None
expecteds = (expecteds,) try:
expecteds = f_ref()
except Exception, exc:
ref_e = exc
try: try:
variables = f() variables = f_tst()
except Exception, exc: except Exception, exc:
err_msg = ("Test %s::%s: Error occured while calling " if ref_e is None:
"the Function on the inputs %s") % (self.op, err_msg = ("Test %s::%s: exception when calling the "
testname, "Function") % (self.gpu_op, testname)
inputs) exc.args += (err_msg,)
raise
else:
# if we raised an exception of the same type we're good.
if isinstance(exc, type(ref_e)):
return
else:
err_msg = ("Test %s::%s: exception raised during test "
"call was not the same as the reference "
"call (got: %s, expected %s)") % \
(self.gpu_op, testname, type(exc),
type(ref_e))
exc.args += (err_msg,) exc.args += (err_msg,)
raise raise
...@@ -174,7 +178,7 @@ def makeTester(name, op, expected, good=None, bad_build=None, checks=None, ...@@ -174,7 +178,7 @@ def makeTester(name, op, expected, good=None, bad_build=None, checks=None,
enumerate(izip(variables, expecteds)): enumerate(izip(variables, expecteds)):
if variable.dtype != expected.dtype or \ if variable.dtype != expected.dtype or \
variable.shape != expected.shape or \ variable.shape != expected.shape or \
not GpuArrayType.values_eq_approx(variable, not TensorType.values_eq_approx(variable,
expected): expected):
self.fail(("Test %s::%s: Output %s gave the wrong " self.fail(("Test %s::%s: Output %s gave the wrong "
"value. With inputs %s, expected %s " "value. With inputs %s, expected %s "
...@@ -189,40 +193,6 @@ def makeTester(name, op, expected, good=None, bad_build=None, checks=None, ...@@ -189,40 +193,6 @@ def makeTester(name, op, expected, good=None, bad_build=None, checks=None,
(self.op, testname, description, (self.op, testname, description,
inputs, variables)) inputs, variables))
def test_bad_build(self):
if skip:
raise SkipTest(skip)
for testname, inputs in self.bad_build.items():
inputs = [copy(input) for input in inputs]
inputrs = [fake_shared(input) for input in inputs]
self.assertRaises(Exception, safe_make_node, self.op, *inputrs)
def test_bad_runtime(self):
if skip:
raise SkipTest(skip)
for testname, inputs in self.bad_runtime.items():
inputrs = [fake_shared(input) for input in inputs]
try:
node = safe_make_node(self.op, *inputrs)
except Exception, exc:
err_msg = ("Test %s::%s: Error occured while trying to "
"make a node with inputs %s") % (self.op,
testname,
inputs)
exc.args += (err_msg,)
raise
try:
f = inplace_func([], node.outputs, mode=mode,
name="test_bad_runtime")
except Exception, exc:
err_msg = ("Test %s::%s: Error occured while trying to "
"make a Function") % (self.op, testname)
exc.args += (err_msg,)
raise
self.assertRaises(Exception, f, [])
Checker.__name__ = name Checker.__name__ = name
return Checker return Checker
...@@ -301,19 +271,18 @@ def gpu_alloc_expected(x, *shp): ...@@ -301,19 +271,18 @@ def gpu_alloc_expected(x, *shp):
GpuAllocTester = makeTester( GpuAllocTester = makeTester(
name="GpuAllocTester", name="GpuAllocTester",
op=gpu_alloc, op=alloc,
expected=gpu_alloc_expected, gpu_op=gpu_alloc,
good=dict( cases=dict(
correct01=(rand_gpuarray(), numpy.int32(7)), correct01=(rand(), numpy.int32(7)),
correct01_bcast=(rand_gpuarray(1), numpy.int32(7)), # just gives a DeepCopyOp with possibly wrong results on the CPU
correct02=(rand_gpuarray(), numpy.int32(4), numpy.int32(7)), # correct01_bcast=(rand(1), numpy.int32(7)),
correct12=(rand_gpuarray(7), numpy.int32(4), numpy.int32(7)), correct02=(rand(), numpy.int32(4), numpy.int32(7)),
correct13=(rand_gpuarray(7), numpy.int32(2), numpy.int32(4), correct12=(rand(7), numpy.int32(4), numpy.int32(7)),
correct13=(rand(7), numpy.int32(2), numpy.int32(4),
numpy.int32(7)),
correct23=(rand(4, 7), numpy.int32(2), numpy.int32(4),
numpy.int32(7)), numpy.int32(7)),
correct23=(rand_gpuarray(4, 7), numpy.int32(2), numpy.int32(4), bad_shape12=(rand(7), numpy.int32(7), numpy.int32(5)),
numpy.int32(7))
),
bad_runtime=dict(
bad_shape12=(rand_gpuarray(7), numpy.int32(7), numpy.int32(5)),
) )
) )
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论