def _populate_var_to_app_to_idx(outputs, wrt, consider_constant):

    # Validate and format consider_constant
    if consider_constant is None:
        consider_constant = []
    else:
        # error checking on consider_constant: verify that it is a collection
        # of theano variables
        # this is important, if someone accidentally passes a nested data
        # structure with theano variables at the leaves, only the root will
        # be properly considered constant
        try:
            iter(consider_constant)
        except TypeError:
            raise TypeError('consider_constant must be an iterable collection,'
                            ' got ' + str(type(consider_constant)))
        for elem in consider_constant:
            if not isinstance(elem, gof.Variable):
                raise TypeError('Elements of consider_constant must be '
                                'variables, but got ' + str(type(elem)))

    # var_to_app_to_idx[var][node] = [i,j] means node has
    # var as input at positions i and j
    var_to_app_to_idx = OrderedDict()

    # Set of variables that have been added to their true parents
    # ('true' here means that the elements of the variable are a function
    #  of the elements of the parent, according to the op's
    #  connection_pattern)
    # Note: we need to revisit the apply nodes repeatedly, because
    #       different outputs of the apply node are connected to
    #       different subsets of the inputs.
    accounted_for = set([])

    def account_for(var):
        # Don't visit the same variable twice
        if var in accounted_for:
            return
        accounted_for.add(var)

        # Constants are not a function of anything
        if var in consider_constant:
            return

        # Recursively add the variables that this variable is
        # a function of.
        if var.owner is not None:
            app = var.owner

            connection_pattern = _node_to_pattern(app)

            var_idx = app.outputs.index(var)

            for i, ipt in enumerate(app.inputs):

                # don't process ipt if it is not a true
                # parent of var
                if not connection_pattern[i][var_idx]:
                    continue

                if ipt not in var_to_app_to_idx:
                    # This object here *must* be an OrderedDict, because
                    # we iterate over its keys when adding up the terms of the
                    # gradient on ipt. If it is a regular dict, the grad method
                    # will return something that is analytically correct, but
                    # whose order of doing additions depends on the memory
                    # location of the apply nodes.
                    var_to_app_to_idx[ipt] = OrderedDict()
                app_to_idx = var_to_app_to_idx[ipt]
                if app not in app_to_idx:
                    app_to_idx[app] = []
                idx = app_to_idx[app]
                if i not in idx:
                    idx.append(i)
                account_for(ipt)

    # add all variables that are true ancestors of the cost
    for output in outputs:
        account_for(output)

    # determine which variables have elements of wrt as a true
    # ancestor. Do this with an upward pass starting from wrt,
    # following only true connections
    visited = set([])

    def visit(var):
        if var in visited:
            return
        if var not in var_to_app_to_idx:
            return
        visited.add(var)
        nodes = var_to_app_to_idx[var]
        for node in nodes:
            connection_pattern = _node_to_pattern(node)
            for idx in nodes[node]:
                for ii, output in enumerate(node.outputs):
                    if connection_pattern[idx][ii]:
                        visit(output)

    for elem in wrt:
        visit(elem)

    # Remove variables that don't have wrt as a true ancestor
    orig_vars = list(var_to_app_to_idx.keys())
    for var in orig_vars:
        if var not in visited:
            del var_to_app_to_idx[var]

    return var_to_app_to_idx
Collect stats
dataset/ETHPy150Open rizar/attention-lvcsr/libs/Theano/theano/gradient.py/_populate_var_to_app_to_idx--crossover with--dataset/ETHPy150Open BrightcoveOS/Diamond/src/collectors/ceph/ceph.py/CephCollector.collect