o
    e                     @   s   d dl Z d dlmZmZ d dlZd dlZd dlZd dlmZm	Z	m
Z
mZmZ G dd dZ	ddeded	ee d
ee deddfddZdS )    N)ListTuple)
ModelProto	NodeProtoTensorProtoValueInfoProtoFunctionProtoc                   @   s4  e Zd ZdeddfddZedd Zdd	 Zd
ee	 dee
 fddZd
ee	 dee
 fddZde	dee	 dee ddfddZdee	 dee	 dee fddZdd Zdee deee ee
 f fddZdee dee
 dee
 dee d ee
 d!ee defd"d#Zdee	 dee	 defd$d%ZdS )&	ExtractormodelreturnNc                 C   s<   t j|| _| jj| _| | jj| _| | jj| _	d S N)
onnxZshape_inferenceZinfer_shapesr
   graph_build_name2obj_dictinitializerwmap
value_infovimap)selfr
    r   :D:\Projects\ConvertPro\env\Lib\site-packages\onnx/utils.py__init__   s   
zExtractor.__init__c                 C   s   dd | D S )Nc                 S   s   i | ]}|j |qS r   )name).0objr   r   r   
<dictcomp>       z2Extractor._build_name2obj_dict.<locals>.<dictcomp>r   )Zobjsr   r   r   r      s   zExtractor._build_name2obj_dictc           
         s   |  |}t| }t|}||@ }|| }g }|D ]	}	|||	  q|D ]
}	|| j|	  q'|  |  fdd|D S )Nc                    s   g | ]} | qS r   r   )r   r   Znew_io_tensors_mapr   r   
<listcomp>(   r   z2Extractor._collect_new_io_core.<locals>.<listcomp>)r   setkeysappendr   )
r   Zoriginal_ioZio_names_to_extractZoriginal_io_mapZoriginal_io_namesZs_io_names_to_extractZio_names_to_keepZnew_io_names_to_addZnew_io_tensorsr   r   r   r   _collect_new_io_core   s   

zExtractor._collect_new_io_corenamesc                 C      |  | jj|S r   )r"   r   inputr   r#   r   r   r   _collect_new_inputs*      zExtractor._collect_new_inputsc                 C   r$   r   )r"   r   outputr&   r   r   r   _collect_new_outputs-   r(   zExtractor._collect_new_outputsnode_output_namegraph_input_namesreachable_nodesc                 C   sX   ||v rd S | j jD ]}||v rq
||jvrq
|| |jD ]	}| ||| qq
d S r   )r   noder)   r!   r%   _dfs_search_reachable_nodes)r   r+   r,   r-   r.   r   r   r   r   r/   0   s   


z%Extractor._dfs_search_reachable_nodesinput_namesoutput_namesc                    s8   t   |D ]	}| ||  q fdd| jjD }|S )Nc                    s   g | ]}| v r|qS r   r   )r   nr-   r   r   r   J   s    z6Extractor._collect_reachable_nodes.<locals>.<listcomp>)listr/   r   r.   )r   r0   r1   r   nodesr   r3   r   _collect_reachable_nodesA   s
   z"Extractor._collect_reachable_nodesc                    s0    fdd}g }|||}|r|||}|s|S )Nc                    sP   g }| D ]! t  fddjjD d }|r%||vr%|| ||j q|S )Nc                 3   s,    | ]}|j  jkr|j jkr|V  qd S r   )r   Zop_typedomain)r   fr.   r   r   	<genexpr>Y   s    z[Extractor._collect_referred_local_functions.<locals>.find_referred_funcs.<locals>.<genexpr>)nextr
   	functionsr!   extendr.   )r5   referred_local_functions	new_nodesZmatch_functionr   r9   r   find_referred_funcsU   s   
zHExtractor._collect_referred_local_functions.<locals>.find_referred_funcsr   )r   r5   rA   r>   r?   r   r@   r   !_collect_referred_local_functionsM   s   

z+Extractor._collect_referred_local_functionsr5   c                    s   t   |D ]}|jD ]} | q
|jD ]} | qq fddj D } fddj D }tjj	dksBJ tjj
dksLJ ||fS )Nc                       g | ]}| v rj | qS r   )r   r   tZall_tensors_namer   r   r   r   u       z8Extractor._collect_reachable_tensors.<locals>.<listcomp>c                    rC   r   )r   rD   rF   r   r   r   v   rG   r   )r   r%   addr)   r   r    r   lenr   Zsparse_initializerZquantization_annotation)r   r5   r.   r   r   r   r   rF   r   _collect_reachable_tensorsj   s   

z$Extractor._collect_reachable_tensorsinputsoutputsr   r   local_functionsc           
      C   sR   d| j j d }tjj||||||d}| jj| jjd|d}	tjj|fi |	S )NzExtracted from {})r   r   zonnx.utils.extract_model)
ir_versionZopset_importsZproducer_namer<   )	r   r   r   helperZ
make_graphr
   rO   Zopset_importZ
make_model)
r   r5   rK   rL   r   r   rM   r   r   metar   r   r   _make_model{   s   	zExtractor._make_modelc           
      C   sP   |  |}| |}| ||}| |\}}| |}| ||||||}	|	S r   )r'   r*   r6   rJ   rB   rR   )
r   r0   r1   rK   rL   r5   r   r   rM   r
   r   r   r   extract_model   s   


zExtractor.extract_model)__name__
__module____qualname__r   r   staticmethodr   r"   r   strr   r'   r*   r   r/   r6   rB   r   r   rJ   r   rR   rS   r   r   r   r   r	      sf    




r	   T
input_pathoutput_pathr0   r1   check_modelr   c                 C   s   t j| std|  |std|stdtj|  t| }t|}|	||}t
|| |r>tj| dS dS )a  Extracts sub-model from an ONNX model.

    The sub-model is defined by the names of the input and output tensors *exactly*.

    Note: For control-flow operators, e.g. If and Loop, the _boundary of sub-model_,
    which is defined by the input and output tensors, should not _cut through_ the
    subgraph that is connected to the _main graph_ as attributes of these operators.

    Arguments:
        input_path (string): The path to original ONNX model.
        output_path (string): The path to save the extracted ONNX model.
        input_names (list of string): The names of the input tensors that to be extracted.
        output_names (list of string): The names of the output tensors that to be extracted.
        check_model (bool): Whether to run model checker on the extracted model.
    zInvalid input model path: z%Output model path shall not be empty!z'Output tensor names shall not be empty!N)ospathexists
ValueErrorr   checkerr[   loadr	   rS   save)rY   rZ   r0   r1   r[   r
   eZ	extractedr   r   r   rS      s   
rS   )T)r\   typingr   r   Zonnx.checkerr   Zonnx.helperZonnx.shape_inferencer   r   r   r   r   r	   rX   boolrS   r   r   r   r   <module>   s,    