提交 cda98029 authored 作者: Pascal Lamblin's avatar Pascal Lamblin

In get_scalar_constant_value, do not return internal memory of constant

上级 ec0419a6
...@@ -612,14 +612,14 @@ def get_scalar_constant_value(orig_v, elemwise=True, ...@@ -612,14 +612,14 @@ def get_scalar_constant_value(orig_v, elemwise=True,
return numpy.asarray(v) return numpy.asarray(v)
if isinstance(v, numpy.ndarray): if isinstance(v, numpy.ndarray):
return numpy_scalar(v) return numpy_scalar(v).copy()
if isinstance(v, Constant): if isinstance(v, Constant):
if getattr(v.tag, 'unique_value', None) is not None: if getattr(v.tag, 'unique_value', None) is not None:
data = v.tag.unique_value data = v.tag.unique_value
else: else:
data = v.data data = v.data
return numpy_scalar(data) return numpy_scalar(data).copy()
if not only_process_constants and getattr(v, 'owner', None): if not only_process_constants and getattr(v, 'owner', None):
if isinstance(v.owner.op, (Alloc, DimShuffle, Rebroadcast, if isinstance(v.owner.op, (Alloc, DimShuffle, Rebroadcast,
...@@ -649,7 +649,7 @@ def get_scalar_constant_value(orig_v, elemwise=True, ...@@ -649,7 +649,7 @@ def get_scalar_constant_value(orig_v, elemwise=True,
for i in v.owner.inputs] for i in v.owner.inputs]
ret = [[None]] ret = [[None]]
v.owner.op.perform(v.owner, const, ret) v.owner.op.perform(v.owner, const, ret)
return ret[0][0] return ret[0][0].copy()
elif elemwise and isinstance(v.owner.op, Elemwise): elif elemwise and 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
...@@ -662,13 +662,13 @@ def get_scalar_constant_value(orig_v, elemwise=True, ...@@ -662,13 +662,13 @@ def get_scalar_constant_value(orig_v, elemwise=True,
for i in v.owner.inputs] for i in v.owner.inputs]
ret = [[None]] ret = [[None]]
v.owner.op.perform(v.owner, const, ret) v.owner.op.perform(v.owner, const, ret)
return ret[0][0] return ret[0][0].copy()
elif (isinstance(v.owner.op, theano.tensor.subtensor.Subtensor) and elif (isinstance(v.owner.op, theano.tensor.subtensor.Subtensor) and
v.ndim == 0): v.ndim == 0):
if isinstance(v.owner.inputs[0], TensorConstant): if isinstance(v.owner.inputs[0], TensorConstant):
cdata = tuple(v.owner.op.get_constant_idx(v.owner.inputs)) cdata = tuple(v.owner.op.get_constant_idx(v.owner.inputs))
try: try:
return v.owner.inputs[0].data.__getitem__(cdata) return v.owner.inputs[0].data.__getitem__(cdata).copy()
except IndexError: except IndexError:
raise IndexError( raise IndexError(
str(tuple(v.owner.op.idx_list)) + str(tuple(v.owner.op.idx_list)) +
......
...@@ -48,7 +48,7 @@ from theano.tensor import (_shared, wvector, bvector, autocast_float_as, ...@@ -48,7 +48,7 @@ from theano.tensor import (_shared, wvector, bvector, autocast_float_as,
nonzero, flatnonzero, nonzero_values, nonzero, flatnonzero, nonzero_values,
stacklists, DimShuffle, hessian, ptp, power, stacklists, DimShuffle, hessian, ptp, power,
swapaxes, choose, Choose, NoneConst, AllocEmpty, swapaxes, choose, Choose, NoneConst, AllocEmpty,
isclose, allclose, mgrid, ogrid, isclose, allclose, mgrid, ogrid, extract_constant,
) )
from theano.tests import unittest_tools as utt from theano.tests import unittest_tools as utt
...@@ -7026,12 +7026,21 @@ class T_get_scalar_constant_value(unittest.TestCase): ...@@ -7026,12 +7026,21 @@ class T_get_scalar_constant_value(unittest.TestCase):
s = theano.tensor.second(shp, c) s = theano.tensor.second(shp, c)
assert get_scalar_constant_value(s) == c.data assert get_scalar_constant_value(s) == c.data
def test_copy(self):
# Make sure we do not return the internal storage of a constant,
# so we cannot change the value of a constant by mistake.
c = theano.tensor.constant(3)
d = extract_constant(c)
d += 1
e = extract_constant(c)
self.assertTrue(e == 3, (c, d, e))
class T_as_tensor_variable(unittest.TestCase): class T_as_tensor_variable(unittest.TestCase):
""" """
We test that ticket #649 stay fixed. We test that ticket #649 stay fixed.
We should not allow as_tensor_variable to accept True or False We should not allow as_tensor_variable to accept True or False
But it should upcast an ndrarray of bool to uint8 But it should upcast an ndarray of bool to uint8
""" """
def test_bool(self): def test_bool(self):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论