提交 559bd4f9 authored 作者: Frédéric Bastien's avatar Frédéric Bastien 提交者: GitHub

Merge pull request #4617 from nouiz/fix_cycle_opt

[FIX TRAVIS] Make the new node on a graph not depend on the old node.
...@@ -590,6 +590,8 @@ def get_scalar_constant_value(orig_v, elemwise=True, ...@@ -590,6 +590,8 @@ def get_scalar_constant_value(orig_v, elemwise=True,
---------- ----------
elemwise : bool elemwise : bool
If False, we won't try to go into elemwise. So this call is faster. If False, we won't try to go into elemwise. So this call is faster.
But we still investigate in Second Elemwise (as this is a substitute
for Alloc)
only_process_constants : bool only_process_constants : bool
If True, we only attempt to obtain the value of `orig_v` if it's If True, we only attempt to obtain the value of `orig_v` if it's
directly constant and don't try to dig through dimshuffles, fills, directly constant and don't try to dig through dimshuffles, fills,
...@@ -650,14 +652,18 @@ def get_scalar_constant_value(orig_v, elemwise=True, ...@@ -650,14 +652,18 @@ def get_scalar_constant_value(orig_v, elemwise=True,
ret = [[None]] ret = [[None]]
v.owner.op.perform(v.owner, const, ret) v.owner.op.perform(v.owner, const, ret)
return ret[0][0].copy() return ret[0][0].copy()
elif elemwise and isinstance(v.owner.op, Elemwise): # In fast_compile, we don't enable local_fill_to_alloc, so
# we need to investigate Second as Alloc. So elemwise
# don't disable the check for Second.
elif isinstance(v.owner.op, Elemwise):
if isinstance(v.owner.op.scalar_op, scal.Second): if isinstance(v.owner.op.scalar_op, scal.Second):
# We don't need both input to be constant for second # We don't need both input to be constant for second
shp, val = v.owner.inputs shp, val = v.owner.inputs
v = val v = val
continue continue
elif isinstance(v.owner.op.scalar_op, elif elemwise and isinstance(
get_scalar_constant_value_elemwises): v.owner.op.scalar_op,
get_scalar_constant_value_elemwises):
const = [get_scalar_constant_value(i) const = [get_scalar_constant_value(i)
for i in v.owner.inputs] for i in v.owner.inputs]
ret = [[None]] ret = [[None]]
......
...@@ -3753,8 +3753,20 @@ def local_useless_switch(node): ...@@ -3753,8 +3753,20 @@ def local_useless_switch(node):
if out.type.broadcastable != node.outputs[0].type.broadcastable: if out.type.broadcastable != node.outputs[0].type.broadcastable:
# We need to copy data to the new dimensions during execution # We need to copy data to the new dimensions during execution
out = T.alloc(out, *[node.outputs[0].shape[i] for i
in xrange(out.ndim)]) # We should not depend on node.outputs as this would
# make the new node depend on the old one that will
# get optimized again. So this create a cycle.
shps = []
for idx, (b1, b2), in enumerate(zip(out.type.broadcastable,
node.outputs[0].type.broadcastable)):
if b1 == b2:
shps.append(out.shape[idx])
elif not node.inputs[1].type.broadcastable[idx]:
shps.append(node.inputs[1].shape[idx])
else:
shps.append(node.inputs[2].shape[idx])
out = T.alloc(out, *shps)
else: else:
out = out out = out
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论