@register_specialize
@register_canonicalize
@gof.local_optimizer([T.Join])
def local_join_empty(node):
    """Join(i, x, y, empty) => Join(i, x, y)

    Remove empty inputs to joins. The empty inputs can be anywhere.

    """
    if not isinstance(node.op, T.Join):
        return
    new_inputs = []
    try:
        join_idx = get_scalar_constant_value(node.inputs[0])
    except NotScalarConstantError:
        return
    for idx in xrange(1, len(node.inputs)):
        inp = node.inputs[idx]
        # We can not use size == 0,, as this can change shape from 3,0
        # to 2,0.  This trigger DebugMode error. This happen with
        # stack(...,[]) as this add a dimshuffle on [], that add a
        # dimensions with shape 1.
        if isinstance(inp, theano.Constant) and inp.data.shape[join_idx] == 0:
            continue
        new_inputs.append(inp)
    if len(node.inputs) - 1 < len(new_inputs):
        if len(new_inputs) == 0:
            # T.join do not work in that case.
            # constant folding will take care of this case.
            return
        ret = T.join(node.inputs[0], *new_inputs)
        o = node.outputs[0]
        if ret.dtype != o.dtype:
            # Join can upcast some inputs
            return

        # Copy over stacktrace from previous output (after join op)
        # to new output, because an error in the new op must be caused
        # by an error in the old join op.
        copy_stack_trace(node.outputs, ret)

        if ret.type != o.type:
            assert ret.dtype == o.dtype
            assert ret.ndim == o.ndim
            ret = T.patternbroadcast(ret, node.outputs[0].broadcastable)

        # Copy over stacktrace from previous output
        # (after patternbroadcast op) for same reasons as before.
        copy_stack_trace(node.outputs, ret)

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