@register_canonicalize
@register_uncanonicalize  # Needed for MaxAndArgmax -> CAReduce
@gof.local_optimizer(ALL_REDUCE)
def local_reduce_join(node):
    """
    Reduce{scalar.op}(Join(axis=0, a, b), axis=0) -> Elemwise{scalar.op}(a, b)

    Notes
    -----
    Supported scalar.op are Maximum, Mimimum in some cases and Add and Mul in
    all cases.

    Currently we must reduce on axis 0. It is probably extensible to the case
    where we join and reduce on the same set of axis.

    """
    if (isinstance(node.op, T.CAReduce) and
            node.inputs[0].owner and
            isinstance(node.inputs[0].owner.op, T.Join)):
        join = node.inputs[0].owner
        if T.extract_constant(join.inputs[0]) != 0:
            return

        if isinstance(node.op.scalar_op, (scalar.Maximum, scalar.Minimum)):
            # Support only 2 inputs for now
            if len(join.inputs) != 3:
                return
        elif not isinstance(node.op.scalar_op, (scalar.Add, scalar.Mul)):
            return
        elif len(join.inputs) <= 2:
            # This is a useless join, that will get removed by another opt.
            return

        new_inp = []
        for inp in join.inputs[1:]:
            inp = inp.owner
            if not inp:
                return
            if (not isinstance(inp.op, DimShuffle) or
                    inp.op.new_order != ('x',) +
                    tuple(range(inp.inputs[0].ndim))):
                return
            new_inp.append(inp.inputs[0])
        ret = Elemwise(node.op.scalar_op)(*new_inp)

        if ret.dtype != node.outputs[0].dtype:
            # The reduction do something about the dtype.
            return

        reduce_axis = node.op.axis
        if reduce_axis is None:
            reduce_axis = tuple(xrange(node.inputs[0].ndim))

        # I put this warning late to don't add extra warning.
        if len(reduce_axis) != 1 or reduce_axis not in 0:
            if theano.config.warn.reduce_join:
                warnings.warn((
                    'Your current code is fine, but Theano versions '
                    'prior to 0.7 (or this development version Sept 2014) '
                    'might have given an incorrect result for this code. '
                    'To disable this warning, set the Theano flag '
                    'warn.reduce_join to False. The problem was an '
                    'optimization, that modified the pattern '
                    '"Reduce{scalar.op}(Join(axis=0, a, b), axis=0)", '
                    'did not check the reduction axis. So if the '
                    'reduction axis was not 0, you got a wrong answer.'))
            return

        # We add the new check late to don't add extra warning.
        try:
            join_axis = get_scalar_constant_value(join.inputs[0])
            if join_axis != reduce_axis[0]:
                return
        except NotScalarConstantError:
            return

        return [ret]
dataset/ETHPy150Open rizar/attention-lvcsr/libs/Theano/theano/tensor/opt.py/local_reduce_join/swapped operands of `not in`