(node, aliases, duplicates)
return stack
Takes a node from the tree and searchs for any previously processed
    duplicates.
    If not a duplicate, returns a stage based from that node.
    If a duplicate, the node is replaced with an alias to the dup stage.
    In both cases the tree is removed below this node (and the alias remains).
Takes a node from the tree and searchs for any previously processed
    duplicates.
    If not a duplicate, returns a stage based from that node.
    If a duplicate, the node is replaced with an alias to the dup stage.
    In both cases the tree is removed below this node (and the alias remains).
Takes a node from the tree and searchs for any previously processed duplicates . If not a duplicate returns a stage based from that node . If a duplicate the node is replaced with an alias to the dup stage . In both cases the tree is removed below this node ( and the alias remains ) .
def _process_node(node, aliases, duplicates):
    """
    Takes a node from the tree and searchs for any previously processed
    duplicates.
    If not a duplicate, returns a stage based from that node.
    If a duplicate, the node is replaced with an alias to the dup stage.
    In both cases the tree is removed below this node (and the alias remains).
    """

    # generate a unique key from the stack of everything below this reduction
    stack = _post_order(node)
    key = list()
    for item in stack:
        # for operations, just append the name
        # aliases require the id as well since they encapsulate specific
        # tensors and constants
        if type(item[0]) is str and item not in aliases:
            key.append(item[0])
        # For tensor or constant or alias, append type and id.
        else:
            key.append(item[0:2])
    key = tuple(key)

    # use the generated key to look for duplicates
    dup_node = duplicates.get(key, False)
    if dup_node:
        # if this is a duplicate, replace the stack with the op node of the
        # original reduction
        node[0] = dup_node
        # no new stage is returned in this case, the node is just converted
        # into an alias
        stack = None
    else:
        # first time seeing this reduction, record it in the dict
        # the last item in the stack will be the reduction op
        duplicates[key] = stack[-1]
        # record which nodes can be aliased
        aliases.add(stack[-1])

    # drop any children (children start at position 3)
    while len(node) > 3:
        node.pop()

    return stack
def _process_node ( node , aliases , duplicates ) : # generate a unique key from the stack of everything below this reduction stack = _post_order ( node ) key = list ( ) for item in stack : # for operations, just append the name # aliases require the id as well since they encapsulate specific # tensors and constants if type ( item [ 0 ] ) is str and item not in aliases : key . append ( item [ 0 ] ) # For tensor or constant or alias, append type and id. else : key . append ( item [ 0 : 2 ] ) key = tuple ( key ) # use the generated key to look for duplicates dup_node = duplicates . get ( key , False ) if dup_node : # if this is a duplicate, replace the stack with the op node of the # original reduction node [ 0 ] = dup_node # no new stage is returned in this case, the node is just converted # into an alias stack = None else : # first time seeing this reduction, record it in the dict # the last item in the stack will be the reduction op duplicates [ key ] = stack [ - 1 ] # record which nodes can be aliased aliases . add ( stack [ - 1 ] ) # drop any children (children start at position 3) while len ( node ) > 3 : node . pop ( ) return stack