o
    Xi                     @  sf   d Z ddlmZ ddlZddlmZmZ ddlmZ ddl	Z
ed ZdddZdddZdddZdS )z0Utilities for extracting subgraphs from a graph.    )annotationsN)
CollectionSequence)Union)ir.Graphzir.Functionzir.GraphViewparent_graphr   graphreturnset[ir.Value]c                 C  sF   t  }tj|D ]}|jD ]}|du rq|j| u r|| qq	|S )a,  Collects all values in the given graph-like object.

    Args:
        parent_graph: The parent graph to which collected values must belong.
        graph: The graph-like object to collect values from.

    Returns:
        A set of :class:`~onnx_ir.Value` objects belonging to ``parent_graph``.
    N)setir	traversalRecursiveGraphIteratorinputsr   add)r   r   valuesnodeval r   S/home/ubuntu/.local/lib/python3.10/site-packages/onnx_ir/_convenience/_extractor.py_collect_all_external_values   s   



r   	GraphLiker   Collection[ir.Value]outputs*tuple[list[ir.Node], Collection[ir.Value]]c                   s*  t | tjr
t }ndd |D }dd t| D  g }g |}t }t|}|r| }	|	|v r2q'|	 r;||	 ||	 |	  }
dur|
|vr||
 |	|
 |
j
D ]}||vrh|durh|	| qY|
j D ]@}|jtjjkrt|| }|D ]}||vr|	| qqn|jtjjkr| D ]}t||}|D ]}||vr|	| qqqn|s)t }|D ]}
|
j
D ]}|du rq| }|du s||vr|| qqg }t|}t|dd dD ]}||vr| s|	| q|rd	d
 |D }tdd| |j fddd ||fS )a  Finds the subgraph bounded by the given inputs and outputs.

    Args:
        graph: The graph to search.
        inputs: The inputs to the subgraph.
        outputs: The outputs of the subgraph.
        parent_graph: The parent graph of the subgraph.

    Returns:
        A list of nodes in the subgraph and the initializers used.

    Raises:
        ValueError: If the subgraph is not properly bounded by the given inputs and outputs.
    c                 S  s   h | ]}|  r|qS r   )is_initializer.0r   r   r   r   	<setcomp>;   s    z3_find_subgraph_bounded_by_values.<locals>.<setcomp>c                 S  s   i | ]\}}||qS r   r   )r   idxr   r   r   r   
<dictcomp><       z4_find_subgraph_bounded_by_values.<locals>.<dictcomp>Nc                 S  s
   | j pdS )N name)vr   r   r   <lambda>q   s   
 z2_find_subgraph_bounded_by_values.<locals>.<lambda>)keyc                 S  s   g | ]}|j pd qS )z<None>r#   r   r   r   r   
<listcomp>v   r!   z4_find_subgraph_bounded_by_values.<locals>.<listcomp>zThe subgraph is not properly bounded by the specified inputs and outputs. The following graph inputs are required but not provided: z, c                   s    |  S )Nr   )n
node_indexr   r   r&   }   s    )
isinstancer   Functionr   	enumeratepopr   r   producerappendr   
attributesr   typeAttributeTypeGRAPHr   as_graphGRAPHS	as_graphssorted
ValueErrorjoinsort)r   r   r   r   initialized_values	all_nodesvalue_stackvisited_nodesvisited_valuesvaluer   inputattrr   r   ginput_frontier	input_valr0   unspecified_graph_inputs
inputs_setvalue_namesr   r*   r    _find_subgraph_bounded_by_values$   s   








!



rK   Sequence[ir.Value | str]
graph_likec             
     s6  t | tjr
| j}n| }tjj|dd t | tj}t||D ]6}t |tj	rJ|sI|j|urI|j
dur7|j
nd}td| d| jj d| dq | vrVtd	| d
q  fdd|D } fdd|D }|sotd|d j}	|	duszJ t| |||	d\}
}tj|||
t|| j| j| j
| jd}| S )aR  Extracts a subgraph from the given graph-like object.

    .. versionadded:: 0.1.14

    Args:
        graph_like: The graph-like object to extract from.
        inputs: The inputs to the subgraph. Can be Value objects or their names.
        outputs: The outputs of the subgraph. Can be Value objects or their names.

    Returns:
        The extracted subgraph as a new :class:`~onnx_ir.Graph` object.

    Raises:
        ValueError: If any of the inputs or outputs are not found in the graph.
        ValueError: If the subgraph is not properly bounded by the given inputs and outputs.
    F)include_subgraphsNzunnamed graphzValue 'z' does not belong to the given z (z).zValue with name 'z' not found in the graph.c                   "   g | ]}t |tr | n|qS r   r,   strr   r   r   r   r(         " zextract.<locals>.<listcomp>c                   rO   r   rP   r   rR   r   r   r(      rS   z;At least one output must be provided to extract a subgraph.r   )r   )nodesinitializers
doc_stringopset_importsr$   metadata_props)r,   r   r-   r   conveniencecreate_value_mapping	GraphView	itertoolschainValuer$   r:   	__class____name__rK   tuplerV   rW   rX   clone)rM   r   r   r   is_graph_viewr   
graph_name
input_valsoutput_valsr   extracted_nodesr=   
graph_viewr   rR   r   extract   sP   

ri   )r   r   r   r   r	   r
   )
r   r   r   r   r   r   r   r   r	   r   )r   rL   r   rL   rM   r   r	   r   )__doc__
__future__r   r\   collections.abcr   r   typingr   onnx_irr   r   r   rK   ri   r   r   r   r   <module>   s   

]