def re_numerate_output_ports(loop_node: Node): """ Update output ports ids to be consecutive from 0 to num_output_ports - 1 and update the port_map values of the Loop node. :param loop_node: the Loop node :return: None """ assert loop_node.soft_get('type') == 'Loop' def re_number_output_port(loop_node: Node, old_port_id: int, new_port_id: int): loop_node.add_output_port(new_port_id, skip_if_exist=True) loop_node.out_port(old_port_id).get_connection().set_source( loop_node.out_port(new_port_id)) Loop.update_port_map_value(loop_node.output_port_map, 'external_port_id', old_port_id, new_port_id) if len(loop_node.out_ports()) > 0: max_port_id = sorted(loop_node.out_ports().keys())[-1] new_port_id = 0 for port_id in range(max_port_id + 1): if port_id in loop_node.out_ports(): if port_id != new_port_id: re_number_output_port(loop_node, port_id, new_port_id) new_port_id += 1 for port_idx_to_remove in reversed( range(new_port_id, max_port_id + 1)): if port_idx_to_remove in loop_node.out_ports().keys(): loop_node.delete_output_port(port_idx_to_remove)
def remove_unused_ops_from_port_map(loop_node: Node, port_map: dict, port_map_attr: str, dir: [None, str] = None): """ Find unused operations in the Loop body referenced in the port_map and removes Loop ports connected to it. Loop input port with index 0 and 1 are mandatory so cannot be removed. Output ports of the Loop may not be connected so check for that case also and remove such an ops from the port_map. The only exception is the "execution_condition" output which is a mandatory. :param loop_node: the Loop node to update :param port_map: the port_map (input, output or back edges) :param port_map_attr: the port_map attribute containing the `internal_layer_id` :param dir: the direction of the port_map meaning 'in' or 'out' port of the Loop :return: """ record_ids_to_remove = [] for record_id, record in enumerate(port_map): if len(loop_node.body.get_op_nodes(internal_layer_id=record[port_map_attr])) == 0 or \ (dir == 'out' and record.get('purpose', "") != 'execution_condition' and record['external_port_id'] not in loop_node.out_ports()): record_ids_to_remove.append(record_id) for record_id_to_remove in reversed(record_ids_to_remove): if dir in ['in', 'out']: port_to_remove = port_map[record_id_to_remove][ 'external_port_id'] if port_to_remove != -1: if dir == 'in': # input port 0 and 1 are mandatory for the Loop node if port_to_remove not in [ 0, 1 ] and port_to_remove in loop_node.in_ports().keys(): loop_node.delete_input_port(port_to_remove) elif dir == 'out' and port_to_remove in loop_node.out_ports( ): loop_node.delete_output_port(port_to_remove) del port_map[record_id_to_remove]