提交 483cb9d3 authored 作者: lamblin's avatar lamblin

Merge pull request #1161 from goodfeli/rebase

Ready to merge: get rid of dangerous "TypeError = not constant" mechanism
...@@ -163,7 +163,7 @@ def dot(l, r): ...@@ -163,7 +163,7 @@ def dot(l, r):
return rval return rval
def get_constant_value(v): def get_scalar_constant_value(v):
"""return the constant scalar(0-D) value underlying variable `v` """return the constant scalar(0-D) value underlying variable `v`
If v is the output of dimshuffles, fills, allocs, rebroadcasts, cast If v is the output of dimshuffles, fills, allocs, rebroadcasts, cast
...@@ -171,12 +171,13 @@ def get_constant_value(v): ...@@ -171,12 +171,13 @@ def get_constant_value(v):
If theano.sparse is also there, we will look over CSM op. If theano.sparse is also there, we will look over CSM op.
If `v` is not some view of constant data, then raise a TypeError. If `v` is not some view of constant data, then raise a
tensor.basic.NotScalarConstantError.
""" """
if hasattr(theano, 'sparse') and isinstance(v.type, if hasattr(theano, 'sparse') and isinstance(v.type,
theano.sparse.SparseType): theano.sparse.SparseType):
if v.owner is not None and isinstance(v.owner.op, if v.owner is not None and isinstance(v.owner.op,
theano.sparse.CSM): theano.sparse.CSM):
data = v.owner.inputs[0] data = v.owner.inputs[0]
return tensor.get_constant_value(data) return tensor.get_scalar_constant_value(data)
return tensor.get_constant_value(v) return tensor.get_scalar_constant_value(v)
...@@ -975,7 +975,7 @@ def _populate_grad_dict(var_to_app_to_idx, ...@@ -975,7 +975,7 @@ def _populate_grad_dict(var_to_app_to_idx,
msg += "%s." msg += "%s."
msg % (str(node.op), str(term), str(type(term)), msg % (str(node.op), str(term), str(type(term)),
i, str(theano.get_constant_value(term))) i, str(theano.get_scalar_constant_value(term)))
raise ValueError(msg) raise ValueError(msg)
...@@ -1616,9 +1616,9 @@ def _is_zero(x): ...@@ -1616,9 +1616,9 @@ def _is_zero(x):
no_constant_value = True no_constant_value = True
try: try:
constant_value = theano.get_constant_value(x) constant_value = theano.get_scalar_constant_value(x)
no_constant_value = False no_constant_value = False
except TypeError: except theano.tensor.basic.NotScalarConstantError:
pass pass
if no_constant_value: if no_constant_value:
......
...@@ -2691,8 +2691,8 @@ class GpuAlloc(GpuOp): ...@@ -2691,8 +2691,8 @@ class GpuAlloc(GpuOp):
raise TypeError('Shape arguments must be integers', s) raise TypeError('Shape arguments must be integers', s)
# if s is constant 1, then we're broadcastable in that dim # if s is constant 1, then we're broadcastable in that dim
try: try:
const_shp = tensor.get_constant_value(s) const_shp = tensor.get_scalar_constant_value(s)
except TypeError: except tensor.NotScalarConstantError:
const_shp = None const_shp = None
bcast.append(numpy.all(1 == const_shp)) bcast.append(numpy.all(1 == const_shp))
otype = CudaNdarrayType(dtype='float32', broadcastable=bcast) otype = CudaNdarrayType(dtype='float32', broadcastable=bcast)
......
...@@ -214,8 +214,8 @@ def is_positive(v): ...@@ -214,8 +214,8 @@ def is_positive(v):
logger.debug('is_positive: %s' % str(v)) logger.debug('is_positive: %s' % str(v))
if v.owner and v.owner.op == tensor.pow: if v.owner and v.owner.op == tensor.pow:
try: try:
exponent = tensor.get_constant_value(v.owner.inputs[1]) exponent = tensor.get_scalar_constant_value(v.owner.inputs[1])
except TypeError: except tensor.basic.NotScalarConstantError:
return False return False
if 0 == exponent % 2: if 0 == exponent % 2:
return True return True
......
...@@ -135,8 +135,8 @@ def scan(fn, ...@@ -135,8 +135,8 @@ def scan(fn,
n_fixed_steps = int(n_steps) n_fixed_steps = int(n_steps)
else: else:
try: try:
n_fixed_steps = opt.get_constant_value(n_steps) n_fixed_steps = opt.get_scalar_constant_value(n_steps)
except (TypeError, AttributeError): except tensor.basic.NotScalarConstantError:
n_fixed_steps = None n_fixed_steps = None
# Check n_steps is an int # Check n_steps is an int
......
...@@ -335,7 +335,7 @@ def scan(fn, ...@@ -335,7 +335,7 @@ def scan(fn,
T_value = int(n_steps) T_value = int(n_steps)
else: else:
try: try:
T_value = opt.get_constant_value(n_steps) T_value = opt.get_scalar_constant_value(n_steps)
except (TypeError, AttributeError): except (TypeError, AttributeError):
T_value = None T_value = None
......
...@@ -24,7 +24,7 @@ from theano.compile.pfunc import rebuild_collect_shared ...@@ -24,7 +24,7 @@ from theano.compile.pfunc import rebuild_collect_shared
from theano import gof from theano import gof
from theano import tensor, scalar from theano import tensor, scalar
from theano.gof.python25 import all from theano.gof.python25 import all
from theano.tensor.basic import get_constant_value from theano.tensor.basic import get_scalar_constant_value
# Logging function for sending warning or info # Logging function for sending warning or info
......
...@@ -363,8 +363,8 @@ def scan(fn, ...@@ -363,8 +363,8 @@ def scan(fn,
n_fixed_steps = int(n_steps) n_fixed_steps = int(n_steps)
else: else:
try: try:
n_fixed_steps = opt.get_constant_value(n_steps) n_fixed_steps = opt.get_scalar_constant_value(n_steps)
except (TypeError, AttributeError): except tensor.basic.NotScalarConstantError:
n_fixed_steps = None n_fixed_steps = None
# Check n_steps is an int # Check n_steps is an int
......
...@@ -18,7 +18,7 @@ import numpy ...@@ -18,7 +18,7 @@ import numpy
import theano import theano
from theano import tensor from theano import tensor
from theano.tensor import opt, get_constant_value from theano.tensor import opt, get_scalar_constant_value
from theano import gof from theano import gof
from theano.gof.python25 import maxsize, any from theano.gof.python25 import maxsize, any
from theano.gof.opt import Optimizer from theano.gof.opt import Optimizer
...@@ -1164,14 +1164,14 @@ class ScanMerge(gof.Optimizer): ...@@ -1164,14 +1164,14 @@ class ScanMerge(gof.Optimizer):
nsteps = node.inputs[0] nsteps = node.inputs[0]
try: try:
nsteps = int(get_constant_value(nsteps)) nsteps = int(get_scalar_constant_value(nsteps))
except TypeError: except tensor.NotScalarConstantError:
pass pass
rep_nsteps = rep.inputs[0] rep_nsteps = rep.inputs[0]
try: try:
rep_nsteps = int(get_constant_value(rep_nsteps)) rep_nsteps = int(get_scalar_constant_value(rep_nsteps))
except TypeError: except tensor.NotScalarConstantError:
pass pass
# Check to see if it is an input of a different node # Check to see if it is an input of a different node
......
...@@ -25,7 +25,7 @@ from theano.compile.pfunc import rebuild_collect_shared ...@@ -25,7 +25,7 @@ from theano.compile.pfunc import rebuild_collect_shared
from theano import gof from theano import gof
from theano import tensor, scalar from theano import tensor, scalar
from theano.gof.python25 import all, OrderedDict from theano.gof.python25 import all, OrderedDict
from theano.tensor.basic import get_constant_value from theano.tensor.basic import get_scalar_constant_value
################ Utility Functions and Classes ####################### ################ Utility Functions and Classes #######################
...@@ -308,7 +308,7 @@ def isNaN_or_Inf_or_None(x): ...@@ -308,7 +308,7 @@ def isNaN_or_Inf_or_None(x):
isStr = False isStr = False
if not isNaN and not isInf: if not isNaN and not isInf:
try: try:
val = get_constant_value(x) val = get_scalar_constant_value(x)
isInf = numpy.isinf(val) isInf = numpy.isinf(val)
isNaN = numpy.isnan(val) isNaN = numpy.isnan(val)
except Exception: except Exception:
......
差异被折叠。
...@@ -1614,7 +1614,7 @@ def local_gemm_to_ger(node): ...@@ -1614,7 +1614,7 @@ def local_gemm_to_ger(node):
xv = x.dimshuffle(0) xv = x.dimshuffle(0)
yv = y.dimshuffle(1) yv = y.dimshuffle(1)
try: try:
bval = T.get_constant_value(b) bval = T.get_scalar_constant_value(b)
except TypeError: except TypeError:
# b isn't a constant, GEMM is doing useful pre-scaling # b isn't a constant, GEMM is doing useful pre-scaling
return return
......
...@@ -262,15 +262,15 @@ class RepeatOp(theano.Op): ...@@ -262,15 +262,15 @@ class RepeatOp(theano.Op):
broadcastable=[False] broadcastable=[False]
else: else:
try: try:
const_reps = basic.get_constant_value(repeats) const_reps = basic.get_scalar_constant_value(repeats)
except basic.NotConstantError: except basic.NotScalarConstantError:
const_reps = None const_reps = None
if const_reps == 1: if const_reps == 1:
broadcastable = x.broadcastable broadcastable = x.broadcastable
else: else:
broadcastable = list(x.broadcastable) broadcastable = list(x.broadcastable)
broadcastable[self.axis] = False broadcastable[self.axis] = False
out_type = theano.tensor.TensorType(x.dtype, broadcastable) out_type = theano.tensor.TensorType(x.dtype, broadcastable)
return theano.Apply(self, [x, repeats], [out_type()]) return theano.Apply(self, [x, repeats], [out_type()])
......
...@@ -15,7 +15,7 @@ import logging ...@@ -15,7 +15,7 @@ import logging
import numpy import numpy
import theano import theano
from theano.tensor import (as_tensor_variable, blas, get_constant_value, from theano.tensor import (as_tensor_variable, blas, get_scalar_constant_value,
patternbroadcast) patternbroadcast)
from theano import OpenMPOp, config from theano import OpenMPOp, config
from theano.gof import Apply from theano.gof import Apply
...@@ -90,7 +90,7 @@ def conv2d(input, filters, image_shape=None, filter_shape=None, ...@@ -90,7 +90,7 @@ def conv2d(input, filters, image_shape=None, filter_shape=None,
image_shape = list(image_shape) image_shape = list(image_shape)
for i in xrange(len(image_shape)): for i in xrange(len(image_shape)):
if image_shape[i] is not None: if image_shape[i] is not None:
image_shape[i] = get_constant_value( image_shape[i] = get_scalar_constant_value(
as_tensor_variable(image_shape[i])) as_tensor_variable(image_shape[i]))
assert str(image_shape[i].dtype).startswith('int') assert str(image_shape[i].dtype).startswith('int')
image_shape[i] = int(image_shape[i]) image_shape[i] = int(image_shape[i])
...@@ -98,7 +98,7 @@ def conv2d(input, filters, image_shape=None, filter_shape=None, ...@@ -98,7 +98,7 @@ def conv2d(input, filters, image_shape=None, filter_shape=None,
filter_shape = list(filter_shape) filter_shape = list(filter_shape)
for i in xrange(len(filter_shape)): for i in xrange(len(filter_shape)):
if filter_shape[i] is not None: if filter_shape[i] is not None:
filter_shape[i] = get_constant_value( filter_shape[i] = get_scalar_constant_value(
as_tensor_variable(filter_shape[i])) as_tensor_variable(filter_shape[i]))
assert str(filter_shape[i].dtype).startswith('int') assert str(filter_shape[i].dtype).startswith('int')
filter_shape[i] = int(filter_shape[i]) filter_shape[i] = int(filter_shape[i])
......
...@@ -1409,8 +1409,8 @@ def _check_rows_is_arange_len_labels(rows, labels): ...@@ -1409,8 +1409,8 @@ def _check_rows_is_arange_len_labels(rows, labels):
def _is_const(z, val, approx=False): def _is_const(z, val, approx=False):
try: try:
maybe = opt.get_constant_value(z) maybe = opt.get_scalar_constant_value(z)
except TypeError: except tensor.NotScalarConstantError:
return False return False
if approx: if approx:
return numpy.allclose(maybe, val) return numpy.allclose(maybe, val)
......
...@@ -14,7 +14,7 @@ from theano.compile import optdb ...@@ -14,7 +14,7 @@ from theano.compile import optdb
from theano.configparser import AddConfigVar, BoolParam from theano.configparser import AddConfigVar, BoolParam
from theano.printing import pprint, debugprint from theano.printing import pprint, debugprint
from theano.tensor import basic as tensor from theano.tensor import basic as tensor
from theano.tensor import elemwise, opt from theano.tensor import elemwise, opt, NotScalarConstantError
############ ############
...@@ -136,9 +136,9 @@ def _is_1(expr): ...@@ -136,9 +136,9 @@ def _is_1(expr):
"""rtype bool. True iff expr is a constant close to 1 """rtype bool. True iff expr is a constant close to 1
""" """
try: try:
v = opt.get_constant_value(expr) v = opt.get_scalar_constant_value(expr)
return numpy.allclose(v, 1) return numpy.allclose(v, 1)
except TypeError: except tensor.NotScalarConstantError:
return False return False
log1msigm_to_softplus = gof.PatternSub( log1msigm_to_softplus = gof.PatternSub(
...@@ -275,9 +275,9 @@ def is_neg(var): ...@@ -275,9 +275,9 @@ def is_neg(var):
if apply.op == tensor.mul and len(apply.inputs) >= 2: if apply.op == tensor.mul and len(apply.inputs) >= 2:
for idx, mul_input in enumerate(apply.inputs): for idx, mul_input in enumerate(apply.inputs):
try: try:
constant = opt.get_constant_value(mul_input) constant = opt.get_scalar_constant_value(mul_input)
is_minus_1 = numpy.allclose(constant, -1) is_minus_1 = numpy.allclose(constant, -1)
except TypeError: except NotScalarConstantError:
is_minus_1 = False is_minus_1 = False
if is_minus_1: if is_minus_1:
# Found a multiplication by -1. # Found a multiplication by -1.
...@@ -647,7 +647,7 @@ def local_1msigmoid(node): ...@@ -647,7 +647,7 @@ def local_1msigmoid(node):
return # graph is using both sigm and 1-sigm return # graph is using both sigm and 1-sigm
if sub_r.owner and sub_r.owner.op == sigmoid: if sub_r.owner and sub_r.owner.op == sigmoid:
try: try:
val_l = opt.get_constant_value(sub_l) val_l = opt.get_scalar_constant_value(sub_l)
except Exception, e: except Exception, e:
return return
if numpy.allclose(numpy.sum(val_l), 1): if numpy.allclose(numpy.sum(val_l), 1):
......
...@@ -30,10 +30,10 @@ class TestConv2D(utt.InferShapeTester): ...@@ -30,10 +30,10 @@ class TestConv2D(utt.InferShapeTester):
verify_grad=True, should_raise=False): verify_grad=True, should_raise=False):
if N_image_shape is None: if N_image_shape is None:
N_image_shape = [T.get_constant_value(T. N_image_shape = [T.get_scalar_constant_value(T.
as_tensor_variable(x)) for x in image_shape] as_tensor_variable(x)) for x in image_shape]
if N_filter_shape is None: if N_filter_shape is None:
N_filter_shape = [T.get_constant_value(T. N_filter_shape = [T.get_scalar_constant_value(T.
as_tensor_variable(x)) for x in filter_shape] as_tensor_variable(x)) for x in filter_shape]
if input is None: if input is None:
......
差异被折叠。
...@@ -41,7 +41,7 @@ from theano.gof.python25 import any, all ...@@ -41,7 +41,7 @@ from theano.gof.python25 import any, all
from theano.gof.opt import Optimizer from theano.gof.opt import Optimizer
from theano.gof import InconsistencyError, toolbox from theano.gof import InconsistencyError, toolbox
from basic import get_constant_value from basic import get_scalar_constant_value, NotScalarConstantError
from theano.tensor.opt import register_uncanonicalize from theano.tensor.opt import register_uncanonicalize
from theano import scalar as scal from theano import scalar as scal
...@@ -64,8 +64,8 @@ class MaxAndArgmaxOptimizer(Optimizer): ...@@ -64,8 +64,8 @@ class MaxAndArgmaxOptimizer(Optimizer):
if node.op == T._max_and_argmax: if node.op == T._max_and_argmax:
if len(node.outputs[1].clients)==0: if len(node.outputs[1].clients)==0:
try: try:
axis=get_constant_value(node.inputs[1]) axis=get_scalar_constant_value(node.inputs[1])
except (ValueError, TypeError), e: except NotScalarConstantError:
return False return False
new = CAReduce(scal.maximum,axis)(node.inputs[0]) new = CAReduce(scal.maximum,axis)(node.inputs[0])
......
...@@ -34,7 +34,7 @@ from theano.tensor import (_shared, wvector, bvector, autocast_float_as, ...@@ -34,7 +34,7 @@ from theano.tensor import (_shared, wvector, bvector, autocast_float_as,
Reshape, row, scalar, scalars, second, smallest, stack, sub, Tensor, Reshape, row, scalar, scalars, second, smallest, stack, sub, Tensor,
tensor_copy, tensordot, tensordot_grad, TensorType, unbroadcast, tensor_copy, tensordot, tensordot_grad, TensorType, unbroadcast,
var, Join, shape, MaxAndArgmax, lscalar, zvector, exp, var, Join, shape, MaxAndArgmax, lscalar, zvector, exp,
get_constant_value, ivector, reshape, scalar_from_tensor, scal, get_scalar_constant_value, ivector, reshape, scalar_from_tensor, scal,
iscalars, arange, dscalars, fvector, imatrix, numeric_grad, iscalars, arange, dscalars, fvector, imatrix, numeric_grad,
opt, ComplexError, TensorDot, lvector, true_div, max, min, Split, roll, opt, ComplexError, TensorDot, lvector, true_div, max, min, Split, roll,
tile, patternbroadcast, Eye, Shape, Default, Dot, PermuteRowElements, tile, patternbroadcast, Eye, Shape, Default, Dot, PermuteRowElements,
...@@ -2140,7 +2140,7 @@ class T_max_and_argmax(unittest.TestCase): ...@@ -2140,7 +2140,7 @@ class T_max_and_argmax(unittest.TestCase):
cost = argmax(x, axis=0).sum() cost = argmax(x, axis=0).sum()
value_error_raised = False value_error_raised = False
gx = grad(cost, x) gx = grad(cost, x)
val = tensor.get_constant_value(gx) val = tensor.get_scalar_constant_value(gx)
assert val == 0.0 assert val == 0.0
def test_grad(self): def test_grad(self):
...@@ -6167,40 +6167,40 @@ def test_dimshuffle_duplicate(): ...@@ -6167,40 +6167,40 @@ def test_dimshuffle_duplicate():
assert success assert success
class T_get_constant_value(unittest.TestCase): class T_get_scalar_constant_value(unittest.TestCase):
def test_get_constant_value(self): def test_get_scalar_constant_value(self):
a = tensor.stack(1, 2, 3) a = tensor.stack(1, 2, 3)
assert get_constant_value(a[0]) == 1 assert get_scalar_constant_value(a[0]) == 1
assert get_constant_value(a[1]) == 2 assert get_scalar_constant_value(a[1]) == 2
assert get_constant_value(a[2]) == 3 assert get_scalar_constant_value(a[2]) == 3
b = tensor.iscalar() b = tensor.iscalar()
a = tensor.stack(b, 2, 3) a = tensor.stack(b, 2, 3)
self.assertRaises(TypeError, get_constant_value, a[0]) self.assertRaises(tensor.basic.NotScalarConstantError, get_scalar_constant_value, a[0])
assert get_constant_value(a[1]) == 2 assert get_scalar_constant_value(a[1]) == 2
assert get_constant_value(a[2]) == 3 assert get_scalar_constant_value(a[2]) == 3
# For now get_constant_value goes through only MakeVector and Join of # For now get_scalar_constant_value goes through only MakeVector and Join of
# scalars. # scalars.
v = tensor.ivector() v = tensor.ivector()
a = tensor.stack(v, 2, 3) a = tensor.stack(v, 2, 3)
self.assertRaises(TypeError, get_constant_value, a[0]) self.assertRaises(tensor.NotScalarConstantError, get_scalar_constant_value, a[0])
self.assertRaises(TypeError, get_constant_value, a[1]) self.assertRaises(tensor.NotScalarConstantError, get_scalar_constant_value, a[1])
self.assertRaises(TypeError, get_constant_value, a[2]) self.assertRaises(tensor.NotScalarConstantError, get_scalar_constant_value, a[2])
# Test the case SubTensor(Shape(v)) when the dimensions # Test the case SubTensor(Shape(v)) when the dimensions
# is broadcastable. # is broadcastable.
v = tensor.row() v = tensor.row()
assert get_constant_value(v.shape[0]) == 1 assert get_scalar_constant_value(v.shape[0]) == 1
def test_subtensor_of_constant(self): def test_subtensor_of_constant(self):
c = constant(rand(5)) c = constant(rand(5))
for i in range(c.value.shape[0]): for i in range(c.value.shape[0]):
assert get_constant_value(c[i]) == c.value[i] assert get_scalar_constant_value(c[i]) == c.value[i]
c = constant(rand(5, 5)) c = constant(rand(5, 5))
for i in range(c.value.shape[0]): for i in range(c.value.shape[0]):
for j in range(c.value.shape[1]): for j in range(c.value.shape[1]):
assert get_constant_value(c[i, j]) == c.value[i, j] assert get_scalar_constant_value(c[i, j]) == c.value[i, j]
class T_as_tensor_variable(unittest.TestCase): class T_as_tensor_variable(unittest.TestCase):
......
...@@ -856,7 +856,7 @@ def test_gt_grad(): ...@@ -856,7 +856,7 @@ def test_gt_grad():
"""A user test that failed. """A user test that failed.
Something about it made Elemwise.grad return something that was Something about it made Elemwise.grad return something that was
too complicated for get_constant_value to recognize as being 0, so too complicated for get_scalar_constant_value to recognize as being 0, so
gradient.grad reported that it was not a valid gradient of an gradient.grad reported that it was not a valid gradient of an
integer. integer.
......
...@@ -936,7 +936,7 @@ class T_fibby(unittest.TestCase): ...@@ -936,7 +936,7 @@ class T_fibby(unittest.TestCase):
if node.op == fibby: if node.op == fibby:
x = node.inputs[0] x = node.inputs[0]
try: try:
if numpy.all(0 == get_constant_value(x)): if numpy.all(0 == get_scalar_constant_value(x)):
return [x] return [x]
except TypeError: except TypeError:
pass pass
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论