afe.ir.net ========== .. py:module:: afe.ir.net Attributes ---------- .. autoapisummary:: afe.ir.net.NodeCallable Classes ------- .. autoapisummary:: afe.ir.net.AwesomeNet afe.ir.net.Renaming Functions --------- .. autoapisummary:: afe.ir.net.rename_node_name afe.ir.net.rename_mut_node afe.ir.net.rename_mut_awesomenet afe.ir.net.rename_awesomenet_nodes afe.ir.net.update_awesomenet_status afe.ir.net.is_one_mla_segment_net afe.ir.net.inline_awesomenet_subgraphs afe.ir.net.inline_ev_subgraphs afe.ir.net.dispatch_backend Module Contents --------------- .. py:data:: NodeCallable .. py:class:: AwesomeNet(name: str, nodes: dict[afe.ir.defines.NodeName, afe.ir.node.AwesomeNode], input_node_names: list[afe.ir.defines.NodeName], output_node_name: afe.ir.defines.NodeName, _status: afe.ir.defines.Status = Status.RELAY, _execution_order: list[afe.ir.defines.NodeName] | None = None, _prune_dict: dict[afe.ir.defines.NodeName, list[afe.ir.defines.NodeName]] | None = None, _float_node_list: list[afe.ir.defines.NodeName] | None = None, _is_subgraph: bool = False, _backend: afe.backends.Backend = Backend.NONE, _target: sima_utils.common.Platform = gen1_target, _output_labels: list[str] | None = None, _model_path: str | None = None, _fp_input_range: dict[afe.ir.defines.NodeName, list[float]] | None = None) This class is in charge of managing and executing a network contained which consists of a collection of AwesomeNodes .. py:attribute:: name .. py:attribute:: nodes .. py:attribute:: input_node_names .. py:attribute:: output_node_name .. py:property:: status :type: afe.ir.defines.Status .. py:property:: backend :type: afe.backends.Backend .. py:property:: sub_graph_names :type: list[afe.ir.defines.NodeName] Return list of sub-graph names :return: List[NodeName] .. py:method:: get_sub_graph(sub_graph_name: afe.ir.defines.NodeName | str) -> Union[AwesomeNet, afe.ir.sima_ir.SiMaIR, None] Given a sub-graph name, return the sub-graph object if the sub-graph name is in the AwesomeNet and the node is a sub-graph. Else return None :param sub_graph_name: str :returns: Optional[Union[AwesomeNet, SiMaIR]] .. py:method:: topological_sort() -> None self._execution_order: Sort the nodes topologically and store the order of NodeName in self._execution_order Set the self._prune_dict with new topologically sorted nodes at the end self._prune_dict: Fills out self._prune_dict which is a dictonary names of consumer nodes to lists of producer node names. The consumer node is the last node to access the producer nodes. We find these producers and consumers by mimicking network execution order, performing a depth first search on the network starting from the network's output node. .. py:method:: dequantize_outputs(outputs: list[numpy.ndarray]) -> list[numpy.ndarray] .. py:method:: run(inputs: dict[afe.ir.defines.NodeName, numpy.ndarray], node_callable: NodeCallable | None = None, node_outputs: dict[afe.ir.defines.NodeName, Any] | None = None, keep_intermediate_results: bool = False) -> list[Any] Runs the entire network after inserting the network inputs into placeholder nodes. Execution of the network happens in the order that is preserved in _execution_order attribute. Node is executed using node_callable function that user needs to provide. After a node executes, it's output is inserted into internal_node_outputs dictionary so if another node depends on it, it can just reference the data in the dictionary. If data is no longer needed for execution of succeeding nodes, or does not need to be saved, it is pruned from the internal_node_outputs dictionary. :param inputs: Dictionary of placeholder node names (str) to the input data. :param node_callable: Function used to execute each node of the AwesomeNet. :param node_outputs: An optional dictionary used for storing the outputs obtained by AwesomeNet's node execution. Needs to be provided if keep_intermediate_results parameter is True. :param keep_intermediate_results: Whether to store intermediate results obtained by AwesomeNet's node execution. If set to True, user needs to provide the node_outputs dictionary as an argument. Returns: The result of executing the output node. If requested, may return additional intermediate results inside node_outputs dictionary. .. py:method:: run_batch(inputs: dict[afe.ir.defines.NodeName, numpy.ndarray], node_callable: NodeCallable | None = None, node_outputs: dict[afe.ir.defines.NodeName, Any] | None = None, keep_intermediate_results: bool = False) -> list[Any] Runs the entire network taking into account the batch size of the inputs. Inputs' batch size is obtained from the inputs dictionary, asserting that all inputs have matching batch size. Since AwesomeNet obtained by translation from any framework uses batch size equal to 1, network is copied and its copy is modified in order to take into account the batch size of the inputs. Execution of the modified network is performed using standard run() method. :param inputs: Dictionary of placeholder node names (str) to the input data. :param node_callable: A function used to execute nodes of the network. :param node_outputs: An optional dictionary used for storing the outputs obtained by AwesomeNet's node execution. Needs to be provided if keep_intermediate_results parameter is set to True. :param keep_intermediate_results: Whether to store results obtained by AwesomeNet's node execution. If set to True, user needs to provide the node_outputs dictionary as an argument. :returns: The result of executing the output node. .. py:method:: set_batch_size(batch_size: int) Modifies AwesomeNet's internal parameters to accommodate for a given batch size. When creating an AwesomeNet, it's input's batch size should be equal to 1 in order to enable supporting different batch sizes while executing and compiling a model. The process of setting a batch size to a value different from 1 is irreversible, so user needs to preserve original AwesomeNet in order to execute APIs not supporting the variable batch size (i.e. calibration / quantization). :param batch_size: Integer value representing the batch size of the inputs to the AwesomeNet. .. py:method:: get_batch_size() -> int Returns batch size currently set .. py:property:: execution_order .. py:property:: float_node_list .. py:method:: extend_float_node_list(node_list: list[str]) .. py:property:: fp_input_range .. py:property:: output_labels .. py:property:: model_path .. py:method:: has_mla_nodes() Check if net has MLA nodes. .. py:property:: target .. py:method:: iter_nodes_recursive() -> Iterator[afe.ir.node.AwesomeNode] Get an iterator over all nodes in the net, including nodes in subgraphs. Callers should not rely on the order of the iterator's contents. .. py:class:: Renaming A renaming on graph nodes. Each entry self.replacements[a] == b means that this renaming replaces references to node name a by references to node name b. Nodes that are not in self.replacements.keys() are not renamed. .. py:attribute:: replacements :type: dict[afe.ir.defines.NodeName, afe.ir.defines.NodeName] .. py:function:: rename_node_name(r: Renaming, n: afe.ir.defines.NodeName) -> afe.ir.defines.NodeName Rename a single node reference. .. py:function:: rename_mut_node(r: Renaming, node: afe.ir.node.AwesomeNode) -> None Rename all node references inside an AwesomeNode. The AwesomeNode is mutated. Subgraphs are not examined. Subgraphs, if they are present, comprise a different scope where the renaming is not applicable. .. py:function:: rename_mut_awesomenet(r: Renaming, net: AwesomeNet) -> None Rename all node references in the body of the AwesomeNet. Node definitions are not renamed. The AwesomeNet is mutated. .. py:function:: rename_awesomenet_nodes(r: Renaming, net: AwesomeNet) Rename all nodes inside the AwesomeNet and their references. Used when composing multiple AwesomeNets in order to avoid duplicate names. .. py:function:: update_awesomenet_status(net: AwesomeNet, status: afe.ir.defines.Status, force_update_status: bool = False) -> None Update the AwesomeNet's and its sub-graphs' status to the given input status recursively. :param net: AwesomeNet :param status: afe.ir.defines.Status .. py:function:: is_one_mla_segment_net(net: AwesomeNet) -> bool Given an AwesomeNet, traverse the nodes and count the number of sub-graphs, also check if some node can be translated to MLA backend IR. :param net: AwesomeNet :returns: True if AwesomeNet is contained of one segment only and this segment is assigned to MLA. .. py:function:: inline_awesomenet_subgraphs(net: AwesomeNet, inline_criteria: Callable[[AwesomeNet], bool]) Inlines the nodes that are a part of subgraph AwesomeNet, given that the inline criteria is being met. For all the sub-graphs that pass the inline criteria, the consisting AwesomeNodes are placed in the top-level AwesomeNet. :param net: Top-level AwesomeNet that may contain several subgraph AwesomeNodes which may be inlined depending on the inline criteria. :param inline_criteria: The function determining if a subgraph AwesomeNode should get inlined into a top-level AwesomeNet. :returns: None. The input AwesomeNet is mutated if any of the subgraph AwesomeNodes pass the inline criteria. .. py:function:: inline_ev_subgraphs(net: AwesomeNet) Inlines the sub-graph AwesomeNode consisting of the EV operators into the top-level AwesomeNet. :param net: The AwesomeNet which is mutated if it contains any EV sub-graphs. .. py:function:: dispatch_backend(backend_callables: list[tuple[Callable[[afe.ir.node.AwesomeNode], bool], NodeCallable]]) -> NodeCallable Process a node by dispatching to one of several functions depending on the node's properties. This is intended to be used as the node_callable parameter of AwesomeNet.run. Calling dispatch_backend(xs)(node, i, o) searches for and executes a matching callable. It finds the first item (f, g) in xs such that f(node) returns True, then executes g(node, i, o). It raises an exception if nothing matches. :param backend_callables: A list of predicates and callables. :returns: Callable that dispatches to the given callables.