提交 944e36dd authored 作者: Pascal Lamblin's avatar Pascal Lamblin

Merge pull request #2992 from nouiz/subtensor_list

[CRASH] Subtensor list
......@@ -640,7 +640,7 @@ returned directly?"""
if c.required:
c.storage[0] = None
# if we are allowing garbage collection, remove the input and
# if we are allowing garbage collection, remove the
# output reference from the internal storage cells
if getattr(self.fn, 'allow_gc', False):
assert len(self.output_storage) == len(self.maker.fgraph.outputs)
......
......@@ -291,8 +291,6 @@ if 0:
####### Do the checking ###########
already_there = False
if self.fgraph is fgraph:
already_there = True
if self.fgraph not in [None, fgraph]:
raise Exception("A DestroyHandler instance can only serve"
" one FunctionGraph. (Matthew 6:24)")
......@@ -796,12 +794,11 @@ class DestroyHandler(toolbox.Bookkeeper):
# print 'DH IMPORT', app, id(app), id(self), len(self.debug_all_apps)
# If it's a destructive op, add it to our watch list
if getattr(app.op, 'destroy_map', OrderedDict()):
if getattr(app.op, 'destroy_map', {}):
self.destroyers.add(app)
# add this symbol to the forward and backward maps
for o_idx, i_idx_list in getattr(app.op, 'view_map',
OrderedDict()).items():
for o_idx, i_idx_list in getattr(app.op, 'view_map', {}).items():
if len(i_idx_list) > 1:
raise NotImplementedError(
'destroying this output invalidates multiple inputs',
......
......@@ -624,6 +624,12 @@ def gc_helper(node_list):
dictionary that maps each Variable instance to a the last node to use Variable as an input.
This is used to allow garbage collection within graphs.
It ignore view_map and destroy_map. This isn't needed as python
have referecence count. In Theano gc, we should not take into
account view_map and destroy_map as if the thunk decided to create
a new output, we would delay uselessly its gc by Python.
"""
# for freeing memory
last_user = {}
......
......@@ -378,8 +378,8 @@ class Stack(VM):
# destroy_dependencies
# --------------------
# The destroy_dependencies is a list of variables that are implicit
# dependencies induced by a destroy_map (compare node.inputs which
# are *explicit* dependencies). The variables in
# dependencies induced by destroy_map and view_map (compared to
# node.inputs which are *explicit* dependencies). The variables in
# destroy_dependencies would be impossible to compute after the
# current `node` runs, because node.thunk() is going to destroy a
# common input variable needed by whatever node owns each variable
......@@ -787,6 +787,12 @@ class VM_Linker(link.LocalLinker):
N.B. gc means garbage collection
Note
----
It don't take care of the view_map/destroy_map. So
it mean it rely on Python gc to don't free the object real
storage.
"""
dependencies = {}
for k in variables:
......@@ -796,6 +802,9 @@ class VM_Linker(link.LocalLinker):
# way of getting it back.
#
# XXX if k has no clients... what is it doing in the computation?
# Fred guess: it could happen for node with multiple outputs when
# we don't use all outputs.
if k.owner and k.clients:
ls = []
for cl in k.clients:
......
......@@ -730,7 +730,9 @@ def check_force_gemv_init():
f = theano.function(
[aa, yy, xx],
gemv_no_inplace(aa, 1., xx, yy, 0.),
theano.compile.Mode(optimizer='fast_compile')
theano.compile.Mode(optimizer='fast_compile').excluding('gpu',
'gpuarray'),
profile=False
)
finally:
theano.config.compute_test_value = tv
......
......@@ -315,6 +315,12 @@ class T_subtensor(unittest.TestCase, utt.TestOptimizationMixin):
n = self.shared(numpy.arange(12, dtype=self.dtype).reshape((4, 3)))
self.assertRaises(Exception, lambda: n[:(2L ** 63)])
def test_list_slice(self):
x = theano.tensor.arange(100).reshape((5, 5, 4))
res = x[[slice(1, -1)] * x.ndim].eval()
x = numpy.arange(100).reshape((5, 5, 4))
numpy.allclose(res, x[[slice(1, -1)] * x.ndim])
def test_newaxis(self):
"""
newaxis support comes from logic in the __getitem__ of TensorType
......
......@@ -355,7 +355,10 @@ class _tensor_py_operators:
# SLICING/INDEXING
def __getitem__(self, args):
if not isinstance(args, tuple):
if (isinstance(args, list) and
any([isinstance(a, slice) for a in args])):
pass
elif not isinstance(args, tuple):
args = args,
# Convert python literals to theano constants
args = theano.tensor.subtensor.make_constant(args)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论