Esempio n. 1
0
def group_horizontal_links(all_nodes):
    """group direct horizontal links (por)"""
    h_groups = UnorderedGroup()
    excluded_nodes = OrderedSet()
    for i in all_nodes:
        if not i.directions.get("w"): # find leftmost nodes
            excluded_nodes.add(i)
            if i.directions.get("e"):
                h_group = HorizontalGroup([i])
                _add_nodes_horizontally(i, h_group, excluded_nodes)
                if len(h_group) > 1:
                    h_groups.append(h_group)
                else:
                    h_groups.append(i)
            else:
                h_groups.append(i)
        # now handle circles (we find them by identifying left-over nodes that still have "e" links)
    for i in all_nodes:
        if not i in excluded_nodes:
            excluded_nodes.add(i)
            if i.directions.get("e"):
                h_group = HorizontalGroup([i])
                _add_nodes_horizontally(i, h_group, excluded_nodes)
                if len(h_group) > 1:
                    h_groups.append(h_group)
                else:
                    h_groups.append(i)
            else:
                h_groups.append(i)
    _fix_link_inheritance(h_groups, OrderedSet())
    return h_groups
Esempio n. 2
0
def _fix_link_inheritance(group, excluded_nodes):
    """recursive helper function to mark for a group and every sub-group into which directions it is linked.
    The function adds the links as .directions to the group and its sub-groups, and carries a set of
    excluded_nodes to remember which links should not be inherited upwards"""

    from copy import deepcopy
    if hasattr(group, "uid"):
        excluded_nodes.add(group)
    else:
        for i in group:
            locally_excluded_nodes = OrderedSet()
            _fix_link_inheritance(i, locally_excluded_nodes)
            for d in i.directions:
                if d not in group.directions:
                    group.directions[d] = OrderedSet()
                for node in i.directions[d]:
                    group.directions[d].add(node)
            for i in locally_excluded_nodes:
                excluded_nodes.add(i)
        # now delete all links to excluded nodes
        dirs_copy = group.directions.copy()
        for d in dirs_copy:
            for node in deepcopy(dirs_copy[d]):
                if node in excluded_nodes:
                    group.directions[d].remove(node)
            if not group.directions[d]:
                del group.directions[d]
Esempio n. 3
0
def group_other_links(all_groups):
    """group other horizontal links (native modules)"""
    excluded_nodes = OrderedSet()
    _group_other_links(all_groups, excluded_nodes, "O")
    _group_other_links(all_groups, excluded_nodes, "o")
    _fix_link_inheritance(all_groups, OrderedSet())
    return all_groups
Esempio n. 4
0
def unify_links(nodenet, node_id_list):
    """create a proxy representation of the node space to simplify bi-directional links.
    This structure is an ordered set of proxy nodes (DisplayNode) with directions.
    Each direction is marked by its key (such as "n"), and followed by a list of nodes
    that are linked in that direction. The nodes are sorted by their index (as marked in
    the node net).

    Arguments:
        nodenet: the nodenet that we are working on
        node_id_list: a list of node ids to be processed
    """

    node_index = OrderedDict([(i, DisplayNode(i)) for i in node_id_list])

    for node_id in node_id_list:
        node = nodenet.get_node(node_id)
        vertical_only = True
        for gate_type in node.get_gate_types():
            direction = {
                "sub": "s",
                "ret": "w",
                "cat": "ne",
                "sym": "nw",
                "sur": "n",
                "por": "e",
                "exp": "sw",
                "ref": "se",
                "gen": "n"
            }.get(gate_type, "o")
            if direction:
                # "o" is for unknown gate types
                for link in node.get_gate(gate_type).get_links():
                    target_node_id = link.target_node.uid
                    if target_node_id in node_index:
                        # otherwise, the link points outside the current nodespace and will be ignored here
                        if direction not in node_index[node_id].directions:
                            node_index[node_id].directions[
                                direction] = OrderedSet()
                        node_index[node_id].directions[direction].add(
                            node_index[target_node_id])
                        inverse = INVERSE_DIRECTIONS[direction]
                        if inverse not in node_index[
                                target_node_id].directions:
                            node_index[target_node_id].directions[
                                inverse] = OrderedSet()
                        node_index[target_node_id].directions[inverse].add(
                            node_index[node_id])
            if direction != 'n' and direction != 's':
                vertical_only = False
        node_index[node_id].stackable = vertical_only

    # finally, let us sort all node_id_list in the direction groups
    for node_id in node_index:
        for direction in node_index[node_id].directions:
            node_index[node_id].directions[direction] = list(
                node_index[node_id].directions[direction])
            node_index[node_id].directions[direction].sort(
                key=lambda i: nodenet.get_node(i.uid).index)

    return UnorderedGroup(node_index.values())
Esempio n. 5
0
    def update_flow_graphs(self, node_uids=None):
        if self.is_flowbuilder_active:
            return
        self.flowfunctions = []
        startpoints = []
        endpoints = []
        pythonnodes = set()

        toposort = nx.topological_sort(self.flowgraph)
        self.flow_toposort = toposort
        for uid in toposort:
            node = self.flow_module_instances.get(uid)
            if node is not None:
                if node.implementation == 'python':
                    pythonnodes.add(uid)
                if node.is_input_node():
                    startpoints.append(uid)
                if node.is_output_node():
                    endpoints.append(uid)

        graphs = []
        for enduid in endpoints:
            ancestors = nx.ancestors(self.flowgraph, enduid)
            node = self.flow_module_instances[enduid]
            if ancestors or node.inputs == []:
                path = [uid for uid in toposort if uid in ancestors] + [enduid]
                if path:
                    graphs.append(path)

        # worldadapter_names = []
        # if self.worldadapter_instance is not None:
        #     worldadapter_names += self.worldadapter_instance.get_available_flow_datasources() + self.worldadapter_instance.get_available_flow_datatargets()

        flowfunctions = {}
        floworder = OrderedSet()
        for idx, graph in enumerate(graphs):
            # split graph in parts:
            # node_uids = [uid for uid in graph if uid not in worldadapter_names]
            node_uids = [uid for uid in graph]
            nodes = [self.get_node(uid) for uid in node_uids]
            paths = self.split_flow_graph_into_implementation_paths(nodes)
            for p in paths:
                floworder.add(p['hash'])
                if p['hash'] not in flowfunctions:
                    func, dang_in, dang_out = self.compile_flow_subgraph([n.uid for n in p['members']], use_unique_input_names=True)
                    if func:
                        flowfunctions[p['hash']] = {'callable': func, 'members': p['members'], 'endnodes': set([nodes[-1]]), 'inputs': dang_in, 'outputs': dang_out}
                else:
                    flowfunctions[p['hash']]['endnodes'].add(nodes[-1])
        for funcid in floworder:
            self.flowfunctions.append(flowfunctions[funcid])

        self.logger.debug("Compiled %d flowfunctions" % len(self.flowfunctions))
Esempio n. 6
0
def group_horizontal_links(all_nodes):
    """group direct horizontal links (por)"""
    h_groups = UnorderedGroup()
    excluded_nodes = OrderedSet()
    for i in all_nodes:
        if not i.directions.get("w"):  # find leftmost nodes
            excluded_nodes.add(i)
            if i.directions.get("e"):
                h_group = HorizontalGroup([i])
                _add_nodes_horizontally(i, h_group, excluded_nodes)
                if len(h_group) > 1:
                    h_groups.append(h_group)
                else:
                    h_groups.append(i)
            else:
                h_groups.append(i)
        # now handle circles (we find them by identifying left-over nodes that still have "e" links)
    for i in all_nodes:
        if i not in excluded_nodes:
            excluded_nodes.add(i)
            if i.directions.get("e"):
                h_group = HorizontalGroup([i])
                _add_nodes_horizontally(i, h_group, excluded_nodes)
                if len(h_group) > 1:
                    h_groups.append(h_group)
                else:
                    h_groups.append(i)
            else:
                h_groups.append(i)
    _fix_link_inheritance(h_groups, OrderedSet())
    return h_groups