提交 2bfe3c82 authored 作者: abergeron's avatar abergeron

Merge pull request #2854 from nouiz/fix_warning

Fix warning reported on the mailing list
...@@ -293,6 +293,10 @@ class BadOptimization(DebugModeError): ...@@ -293,6 +293,10 @@ class BadOptimization(DebugModeError):
nv - ov)) nv - ov))
print >> ssio, " Std Abs Diff: ", numpy.std(numpy.absolute( print >> ssio, " Std Abs Diff: ", numpy.std(numpy.absolute(
nv - ov)) nv - ov))
arg_max_val = numpy.argmax(numpy.absolute(nv - ov))
values_at_max = (nv.flatten()[arg_max_val],
ov.flatten()[arg_max_val])
print >> ssio, " Value at Max Diff: ", values_at_max
# N.B. the maximum(..., 1e-8) protects against div by 0 when # N.B. the maximum(..., 1e-8) protects against div by 0 when
# nv == ov == 0 # nv == ov == 0
...@@ -304,6 +308,10 @@ class BadOptimization(DebugModeError): ...@@ -304,6 +308,10 @@ class BadOptimization(DebugModeError):
print >> ssio, " Mean Rel Diff: ", numpy.mean(reldiff) print >> ssio, " Mean Rel Diff: ", numpy.mean(reldiff)
print >> ssio, " Median Rel Diff: ", numpy.median(reldiff) print >> ssio, " Median Rel Diff: ", numpy.median(reldiff)
print >> ssio, " Std Rel Diff: ", numpy.std(reldiff) print >> ssio, " Std Rel Diff: ", numpy.std(reldiff)
arg_max_val = numpy.argmax(reldiff)
values_at_max = (nv.flatten()[arg_max_val],
ov.flatten()[arg_max_val])
print >> ssio, " Value at Max Diff: ", values_at_max
# only if all succeeds to we add anything to sio # only if all succeeds to we add anything to sio
print >> sio, ssio.getvalue() print >> sio, ssio.getvalue()
except Exception: except Exception:
...@@ -1559,10 +1567,13 @@ class _VariableEquivalenceTracker(object): ...@@ -1559,10 +1567,13 @@ class _VariableEquivalenceTracker(object):
if append_reason: if append_reason:
# N.B. compute the debugprint now, because future # N.B. compute the debugprint now, because future
# optimizations will change the graph # optimizations will change the graph
done = dict()
self.reasons[new_r].append((reason, self.reasons[new_r].append((reason,
r, r,
debugprint(r, prefix=' ', depth=6, file=StringIO()).getvalue(), debugprint(r, prefix=' ', depth=6,
debugprint(new_r, prefix=' ', depth=6, file=StringIO()).getvalue())) file=StringIO(), done=done).getvalue(),
debugprint(new_r, prefix=' ', depth=6,
file=StringIO(), done=done).getvalue()))
self.replaced_by[r].append((reason, new_r)) self.replaced_by[r].append((reason, new_r))
if r in self.equiv: if r in self.equiv:
......
...@@ -34,7 +34,8 @@ VALID_ASSOC = set(['left', 'right', 'either']) ...@@ -34,7 +34,8 @@ VALID_ASSOC = set(['left', 'right', 'either'])
def debugprint(obj, depth=-1, print_type=False, def debugprint(obj, depth=-1, print_type=False,
file=None, ids='CHAR', stop_on_name=False): file=None, ids='CHAR', stop_on_name=False,
done=None):
"""Print a computation graph as text to stdout or a file. """Print a computation graph as text to stdout or a file.
:type obj: Variable, Apply, or Function instance :type obj: Variable, Apply, or Function instance
...@@ -53,6 +54,9 @@ def debugprint(obj, depth=-1, print_type=False, ...@@ -53,6 +54,9 @@ def debugprint(obj, depth=-1, print_type=False,
"" - don't print an identifier "" - don't print an identifier
:param stop_on_name: When True, if a node in the graph has a name, :param stop_on_name: When True, if a node in the graph has a name,
we don't print anything below it. we don't print anything below it.
:type done: None or dict
:param done: A dict where we store the ids of printed node.
Useful to have multiple call to debugprint share the same ids.
:returns: string if `file` == 'str', else file arg :returns: string if `file` == 'str', else file arg
...@@ -80,6 +84,7 @@ def debugprint(obj, depth=-1, print_type=False, ...@@ -80,6 +84,7 @@ def debugprint(obj, depth=-1, print_type=False,
_file = sys.stdout _file = sys.stdout
else: else:
_file = file _file = file
if done is None:
done = dict() done = dict()
results_to_print = [] results_to_print = []
profile_list = [] profile_list = []
......
...@@ -1718,17 +1718,19 @@ if True: ...@@ -1718,17 +1718,19 @@ if True:
@register_opt('cudnn') @register_opt('cudnn')
@local_optimizer([SoftmaxGrad]) @local_optimizer([SoftmaxGrad])
def local_softmax_dnn_grad(node): def local_softmax_dnn_grad(node):
if ( if (isinstance(node.op, SoftmaxGrad) and
isinstance(node.op, SoftmaxGrad) ((node.inputs[0].owner and
and (isinstance(node.inputs[0].owner.op, HostFromGpu) isinstance(node.inputs[0].owner.op, HostFromGpu))
or isinstance(node.inputs[1].owner.op, HostFromGpu)) or (node.inputs[1].owner and
): isinstance(node.inputs[1].owner.op, HostFromGpu)))):
if not dnn_available(): if not dnn_available():
return return
ins = [] ins = []
for n in node.inputs: for n in node.inputs:
if isinstance(n.owner.op, HostFromGpu): if isinstance(n.owner.op, HostFromGpu):
n = n.owner.inputs[0] n = n.owner.inputs[0]
if n.ndim != 2:
return
ins.append(n.dimshuffle(0, 1, 'x', 'x')) ins.append(n.dimshuffle(0, 1, 'x', 'x'))
out = GpuDnnSoftmaxGrad( out = GpuDnnSoftmaxGrad(
......
...@@ -416,7 +416,7 @@ class test_SoftMax(unittest.TestCase): ...@@ -416,7 +416,7 @@ class test_SoftMax(unittest.TestCase):
# Verify that the SoftmaxGrad -> GpuDnnSoftmaxGrad optimization is not # Verify that the SoftmaxGrad -> GpuDnnSoftmaxGrad optimization is not
# applied when cudnn is excluded or not available # applied when cudnn is excluded or not available
mode_wo_cudnn = mode_with_gpu.excluding("cudnn") mode_wo_cudnn = mode_with_gpu.excluding("cudnn")
y = T.vector('y') y = T.fvector('y')
f = theano.function( f = theano.function(
[y], [y],
T.grad(T.nnet.softmax(y).mean(), y), T.grad(T.nnet.softmax(y).mean(), y),
...@@ -435,3 +435,22 @@ class test_SoftMax(unittest.TestCase): ...@@ -435,3 +435,22 @@ class test_SoftMax(unittest.TestCase):
i.op, i.op,
theano.tensor.nnet.SoftmaxGrad theano.tensor.nnet.SoftmaxGrad
)]) == 1) )]) == 1)
# Verify that the SoftmaxGrad -> GpuDnnSoftmaxGrad do not
# crash with manual graph
y = T.fvector('y')
o = theano.tensor.nnet.SoftmaxGrad()(y, y*2)
f = theano.function([y], o, mode=mode_with_gpu)
sorted_f = f.maker.fgraph.toposort()
assert(len([i
for i in sorted_f
if isinstance(
i.op,
theano.sandbox.cuda.dnn.GpuDnnSoftmaxGrad
)]) == 1)
assert(len([i
for i in sorted_f
if isinstance(
i.op,
theano.tensor.nnet.SoftmaxGrad
)]) == 0)
...@@ -279,21 +279,19 @@ class SoftmaxGrad(gof.Op): ...@@ -279,21 +279,19 @@ class SoftmaxGrad(gof.Op):
nin = 2 nin = 2
nout = 1 nout = 1
def __init__(self, **kwargs): __props__ = ()
gof.Op.__init__(self, **kwargs)
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return tensor.hashtype(self)
def __str__(self):
return self.__class__.__name__
def make_node(self, dy, sm, **kwargs): def make_node(self, dy, sm):
dy = tensor.as_tensor_variable(dy) dy = tensor.as_tensor_variable(dy)
sm = tensor.as_tensor_variable(sm) sm = tensor.as_tensor_variable(sm)
if dy.type.ndim not in (1, 2) \
or dy.type.dtype not in tensor.float_dtypes:
raise ValueError('dy must be 1-d or 2-d tensor of floats. Got ',
dy.type)
if dy.ndim == 1:
dy = tensor.shape_padleft(dy, n_ones=1)
if sm.ndim == 1:
sm = tensor.shape_padleft(sm, n_ones=1)
return Apply(self, [dy, sm], [sm.type.make_variable()]) return Apply(self, [dy, sm], [sm.type.make_variable()])
def perform(self, node, input_storage, output_storage): def perform(self, node, input_storage, output_storage):
...@@ -394,24 +392,14 @@ class Softmax(gof.Op): ...@@ -394,24 +392,14 @@ class Softmax(gof.Op):
nin = 1 nin = 1
nout = 1 nout = 1
__props__ = ()
def __init__(self, **kwargs):
gof.Op.__init__(self, **kwargs)
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, x): def make_node(self, x):
x = tensor.as_tensor_variable(x) x = tensor.as_tensor_variable(x)
if x.type.ndim not in (1, 2) \ if x.type.ndim not in (1, 2) \
or x.type.dtype not in tensor.float_dtypes: or x.type.dtype not in tensor.float_dtypes:
raise ValueError('x must be 1-d or 2-d tensor of floats. Got ', x.type) raise ValueError('x must be 1-d or 2-d tensor of floats. Got ',
x.type)
if x.ndim == 1: if x.ndim == 1:
x = tensor.shape_padleft(x, n_ones=1) x = tensor.shape_padleft(x, n_ones=1)
return Apply(self, [x], [x.type()]) return Apply(self, [x], [x.type()])
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论