提交 655ecd92 authored 作者: Razvan Pascanu's avatar Razvan Pascanu

aliasing bug reported by Ian fixed ..

上级 56f5d44a
......@@ -17,6 +17,7 @@ import theano.gof
import mode as mode_module
from io import *
import logging
_logger = logging.getLogger('theano.compile.function_module')
......@@ -163,6 +164,18 @@ class AliasedMemoryError(Exception):
### Function
###
class DeepCopyOp(theano.gof.Op):
def __init__(self):
pass
def make_node(self, x):
return theano.gof.Apply(self, [x], [x.type()])
def perform( self, node, args, outs):
outs[0][0] = copy.deepcopy(args[0])
deep_copy_op = DeepCopyOp()
DUPLICATE = ['DUPLICATE'] # unique id object used as a placeholder for duplicate entries
class Function(object):
"""
......@@ -752,6 +765,20 @@ class FunctionMaker(object):
t0 = time.time()
optimizer(env)
_logger.debug('Optimizing took %f seconds' % (time.time() - t0))
# This loop was inserted to remove aliasing between outputs when they all
# evaluete to the same value. Originally it was OK for outputs to be aliased,
# but some of the outputs can be shared variables, and is not good for shared
# variables to be aliased. It might be possible to optimize this by making sure
# there is no aliasing only between shared variables.
for i in xrange(len(env.outputs)):
views = set()
view_tree_set(alias_root(env.outputs[i]), views)
for j in xrange(i+1, len(env.outputs)):
if env.outputs[j] in views:
env.change_input('output', j, deep_copy_op(env.outputs[j]))
# initialize the linker
if not hasattr(linker, 'accept'):
......
......@@ -474,6 +474,53 @@ class Test_pfunc(unittest.TestCase):
assert f() == 21
assert f() == 34
def aliasing_test(self):
A = shared(numpy.zeros((2,2)))
B = shared(numpy.zeros((2,2)))
C = numpy.zeros((2,2))
D = tensor.dmatrix()
DD = D + 5
f = pfunc([D], [], updates=[ (A,D), (B,D) ])
f(C)
assert not numpy.may_share_memory(A.value,B.value)
f = pfunc([D], [], updates=[ (A,D[:]), (B,D) ])
f(C)
assert not numpy.may_share_memory(A.value,B.value)
f = pfunc([D], [], updates=[ (A,D+5), (B,D[:]) ])
f(C)
assert not numpy.may_share_memory(A.value,B.value)
f = pfunc([D], [], updates=[ (A,D+5), (B,D) ])
f(C)
assert not numpy.may_share_memory(A.value,B.value)
f = pfunc([D], DD, updates=[ (A,DD[:1]), (B,DD) ])
R=f(C)
assert not numpy.may_share_memory(A.value,B.value)
assert not numpy.may_share_memory(R,B.value)
assert not numpy.may_share_memory(R,A.value)
f = pfunc([D], DD, updates=[ (A,DD[:1]), (B,DD[:1]*2) ])
R=f(C)
assert not numpy.may_share_memory(A.value,B.value)
assert not numpy.may_share_memory(R,B.value)
assert not numpy.may_share_memory(R,A.value)
f = pfunc([D], DD*4, updates=[ (A,DD[:1]*3), (B,DD[:1]*2) ])
R=f(C)
assert not numpy.may_share_memory(A.value,B.value)
assert not numpy.may_share_memory(R,B.value)
assert not numpy.may_share_memory(R,A.value)
f = pfunc([D], DD*4, updates=[ (A,DD[:1]*3), (B,DD[:1]*3) ])
R=f(C)
assert not numpy.may_share_memory(A.value,B.value)
assert not numpy.may_share_memory(R,B.value)
assert not numpy.may_share_memory(R,A.value)
if __name__ == '__main__':
theano.config.mode = 'FAST_COMPILE'
Test_pfunc().test_default_scalar_container()
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论