提交 eba84948 authored 作者: Frederic Bastien's avatar Frederic Bastien

Changed how DebugMode handle Op with make_thunk following code review.

上级 7e01a063
...@@ -1184,48 +1184,58 @@ class _Linker(gof.link.LocalLinker): ...@@ -1184,48 +1184,58 @@ class _Linker(gof.link.LocalLinker):
thunks_py = [] #python thunks thunks_py = [] #python thunks
thunks_c = [] #c thunks thunks_c = [] #c thunks
compute_map = {}
for k in storage_map:
compute_map[k] = [k.owner is None]
for node in order: for node in order:
node_input_storage = [storage_map[r] for r in node.inputs] node_input_storage = [storage_map[r] for r in node.inputs]
node_output_storage = [storage_map[r] for r in node.outputs] node_output_storage = [storage_map[r] for r in node.outputs]
if hasattr(node.op, '_op_use_c_code'):
old_value = node.op._op_use_c_code
else:
old_value = False
try: try:
# ! Problem ! We do not know if make_thunk succedded into if not self.maker.mode.check_c_code:
# generating a cthunk, or if it reverted back to a python raise utils.MethodNotDefined()
# thunk, or if it is none of the above ... e = Env(*graph.clone(node.inputs, node.outputs))
node.op._op_use_c_code = True e.toposort = lambda: e.nodes #WARNING: STOCHASTIC ORDER
tmp_thunk = node.op.make_thunk(node, # Specifically... e.nodes is a set, but of only 1 element
storage_map,
compute_map, cl = CLinker().accept(e, [r for r, r2 in zip(e.outputs, node.outputs) if r2 in no_recycling])
no_recycling)
if hasattr(tmp_thunk, 'cthunk'): thunk, node_input_filters, node_output_filters = cl.make_thunk(
# Arbritrary check to see if it has a C implementation input_storage = node_input_storage,
thunks_c.append(tmp_thunk) output_storage = node_output_storage)
else: thunk.inputs = node_input_storage
thunks_c.append(None) thunk.outputs = node_output_storage
finally: thunks_c.append(thunk)
node.op._op_use_c_code = old_value except (NotImplementedError, utils.MethodNotDefined):
thunks_c.append(None)
if self.maker.mode.check_py_code or thunks_c[-1] is None: if self.maker.mode.check_py_code or thunks_c[-1] is None:
try: p = node.op.perform
node.op._op_use_c_code = False thunk = (lambda p = p, i = node_input_storage, o = node_output_storage, n =
thunks_py += [node.op.make_thunk(node, node: p(n, [x[0] for x in i], o))
storage_map, thunk.inputs = node_input_storage
compute_map, thunk.outputs = node_output_storage
no_recycling)] thunk.perform = p
finally: thunks_py.append(thunk)
node.op._op_use_c_code = old_value
else: else:
thunks_py.append(None) thunks_py.append(None)
# If the op define its own make_thunk, check it
if node.op.make_thunk.im_func != theano.gof.Op.make_thunk.im_func:
compute_map = {}
for k in node.inputs:
compute_map[k] = [True]
for k in node.outputs:
compute_map[k] = [False]
thunk = node.op.make_thunk(node,
storage_map,
compute_map,
no_recycling)
if thunks_py[-1] is None:
thunks_py[-1] = thunk
elif thunks_c[-1] is None:
thunks_c[-1] = thunk
else:
_logger.warn("We won't check the perform function of node '%s' but we will check its make_thunk function"%node)
thunks_py[-1] = thunk
if no_recycling is True: if no_recycling is True:
no_recycling = storage_map.values() no_recycling = storage_map.values()
no_recycling = utils.difference(no_recycling, input_storage) no_recycling = utils.difference(no_recycling, input_storage)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论