def _node_to_pattern(node):

    if hasattr(node.op, 'connection_pattern'):
        connection_pattern = node.op.connection_pattern(node)

        if not isinstance(connection_pattern, list):
            raise TypeError(
                "Op.connection_pattern should return " +
                ("list of list of bool, but for Op=%s" % node.op) +
                "got %s with type %s." % (connection_pattern,
                                          type(connection_pattern)))
        if len(connection_pattern) != len(node.inputs):
            raise ValueError(
                '%s.connection_pattern should have %d' %
                (node.op, len(node.inputs)) + ' rows but has %d.' %
                len(connection_pattern))
        for ii, output_pattern in enumerate(connection_pattern):
            if not isinstance(output_pattern, list):
                raise TypeError(
                    '%s.connection_pattern should return' %
                    node.op + ' a list of lists, but element %d' % ii +
                    'is %s of type %s.' % (output_pattern,
                                           type(output_pattern)))
    else:
        connection_pattern = [[True for output in node.outputs]
                              for ipt in node.inputs]
    assert isinstance(connection_pattern, list)
    assert len(connection_pattern) == len(node.inputs)
    for ii in xrange(len(node.inputs)):
        assert isinstance(connection_pattern[ii], list)
        assert len(connection_pattern[ii]) == len(node.outputs)
    return connection_pattern
given an apply node, obtain its connection pattern
dataset/ETHPy150Open rizar/attention-lvcsr/libs/Theano/theano/gradient.py/_node_to_pattern