提交 40e03686 authored 作者: James Bergstra's avatar James Bergstra

Fixed an longstanding subtle bug in the cache mechanism.

CLinker returns keys that include the role of each variable, as well as the no_recycling parameter. This fixes an incorrect result I am seeing, and I believe it fixes the mysterious 'output-borrowing' behaviour that Olivier Delalleau reported.
上级 9317a03b
...@@ -793,7 +793,7 @@ class CLinker(link.Linker): ...@@ -793,7 +793,7 @@ class CLinker(link.Linker):
""" """
order = list(self.env.toposort()) order = list(self.env.toposort())
env_inputs_dict = dict((i, (-1, pos)) for pos, i in enumerate(self.env.inputs)) env_inputs_dict = dict((i, [-1, pos]) for pos, i in enumerate(self.env.inputs))
env_computed_set = set() env_computed_set = set()
constant_ids = dict() constant_ids = dict()
op_pos = {} # Apply -> topological position op_pos = {} # Apply -> topological position
...@@ -806,21 +806,33 @@ class CLinker(link.Linker): ...@@ -806,21 +806,33 @@ class CLinker(link.Linker):
# - an env input # - an env input
# - an output from a node in the Env # - an output from a node in the Env
# - a Constant # - a Constant
# It is important that a variable (i)
# yield a 'position' that reflects its role in code_gen()
def graphpos(i, topological_pos, i_idx): def graphpos(i, topological_pos, i_idx):
if isinstance(i, graph.Constant): rval = []
if isinstance(i, graph.Constant): #orphans
if id(i) not in constant_ids: if id(i) not in constant_ids:
constant_ids[id(i)] = (i.signature(), topological_pos, i_idx) constant_ids[id(i)] = [i.signature(), topological_pos, i_idx]
return constant_ids[id(i)] rval += constant_ids[id(i)]
#print 'SIGNATURE', i.signature() #print 'SIGNATURE', i.signature()
#return i.signature() #return i.signature()
elif i in env_inputs_dict: elif i in env_inputs_dict: #inputs
return env_inputs_dict[i] rval += env_inputs_dict[i]
else: else:
if i.owner is None: if i.owner is None:
assert all( all(out is not None for out in o.outputs) for o in order) assert all( all(out is not None for out in o.outputs) for o in order)
assert all( input.owner is None for input in self.env.inputs) assert all( input.owner is None for input in self.env.inputs)
raise Exception('what is this?', (i, type(i), i.clients, self.env)) raise Exception('what is this?', (i, type(i), i.clients, self.env))
return (op_pos[i.owner], i.owner.outputs.index(i)) if i in self.env.outputs:
rval += [op_pos[i.owner], # outputs
i.owner.outputs.index(i),
self.env.outputs.index(i)]
else:
rval += [op_pos[i.owner], i.owner.outputs.index(i)] # temps
assert rval
rval.append(i in self.no_recycling)
return tuple(rval)
for node_pos, node in enumerate(order): for node_pos, node in enumerate(order):
version.append(node.op.c_code_cache_version_apply(node)) version.append(node.op.c_code_cache_version_apply(node))
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论