提交 a170708b authored 作者: James Bergstra's avatar James Bergstra

added some tests to DebugMode to deal with aliased apply outputs

上级 76aa3c78
...@@ -368,3 +368,102 @@ def test_badviewmap_c(): ...@@ -368,3 +368,102 @@ def test_badviewmap_c():
assert False #failed to raise error assert False #failed to raise error
except debugmode.BadDestroyMap: except debugmode.BadDestroyMap:
pass pass
def test_aliased_outputs_ok():
#here aliased outputs is ok because they are both aliased to an input as well
class CustomOp(gof.Op):
view_map = {0:[0], 1:[0]}
def make_node(self, a, b):
c = a.type()
d = a.type()
return gof.Apply(self, [a,b], [c,d])
def perform(self, node, (a,b), (c,)):
c[0] = a
d[0] = a[1:]
x = theano.tensor.dvector()
y = theano.tensor.dvector()
f = theano.function([x, y], CustomOp()(x,y), mode='DEBUG_MODE')
r0, r1 = f([1,2,3,4])
assert numpy.all(r0 == [1,2,3,4])
assert numpy.all(r1 == [2,3,4])
def test_aliased_outputs_ok_output():
# here aliased outputs is ok because they are both outputs of the function as a whole and
# thus not destroy-able
class CustomOp(gof.Op):
def make_node(self, a, b):
c = a.type()
d = a.type()
return gof.Apply(self, [a,b], [c,d])
def perform(self, node, (a,b), (c,)):
r = a * 2
c[0] = r
d[0] = r[1:]
x = theano.tensor.dvector()
y = theano.tensor.dvector()
f = theano.function([x, y], CustomOp()(x,y), mode='DEBUG_MODE')
r0, r1 = f([1,2,3,4])
assert numpy.all(r0 == [2,4,6,8])
assert numpy.all(r1 == [4,6,8])
def test_aliased_outputs_ok_shadow():
# here the alias between outputs is ok because one of them is not used for subsequent
# computation. This is like the case where we use one output as a memory buffer to serve
# another output.
class CustomOp(gof.Op):
def make_node(self, a, b):
c = a.type()
d = a.type()
return gof.Apply(self, [a,b], [c,d])
def perform(self, node, (a,b), (c,)):
r = a * 1
c[0] = r
d[0] = r[1:]
x = theano.tensor.dvector()
y = theano.tensor.dvector()
f = theano.function([x, y], CustomOp()(x,y)[0] * 2, mode='DEBUG_MODE')
r0 = f([1,2,3,4])
assert numpy.all(r0 == [2,4,6,8])
def test_aliased_outputs_bad():
# here the alias between outputs is not ok because destroying one destroys the other, but
# there's no way to warn theano about it through the view_map mechanism.
class CustomOp(gof.Op):
def make_node(self, a, b):
c = a.type()
d = a.type()
return gof.Apply(self, [a,b], [c,d])
def perform(self, node, (a,b), (c,)):
r = a * 1
c[0] = r[:-1]
d[0] = r[1:]
custom_op = CustomOp()
x = theano.tensor.dvector()
y = theano.tensor.dvector()
bad_xy0, bad_xy1 = custom_op(x, y)
out = bad_xy0 * 2 + bad_xy1 * 2
f = theano.function([x, y], out, mode='DEBUG_MODE')
try:
r0 = f([1,2,3,4])
assert False # DebugMode should have caught the error
except debugmode.BadViewMap, e:
pass
# the situation can be rescued by picking one of the inputs and pretending that it is
# aliased to both the outputs. This unfairly disables any destructive operations on the
# input, but guarantees correctness.
custom_op.view_map = {0:[0], 1:[1]}
f([1,2,3,4])
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论