o
    Xi                      @  s   d dl mZ g dZd dlZd dlZd dlZeeZ	dddZ
dddZdddZG dd dejjZG dd dejjZG dd dejjZdS )    )annotations)RemoveUnusedNodesPassRemoveUnusedFunctionsPassRemoveUnusedOpsetsPassNnodeir.Nodegraph_outputsfrozenset[ir.Value]onnx_opset_versionintreturnNonec           
        s  zj dvr	W d S tjjj|j d}W n ty'   tjddd Y d S w jdkrbd fdd}|ds=|dr?d S tj	dkrLdj	d _
tj	dkrYdj	d _
jdd  d S g }|j	D ]}|jtjjjjkru d S ||jtjjjjk qgtdd |D dkrd S tj	D ]\}}| vr| s|| du rd|_
qtj	}	tttj	D ]}j	| j
s|	d8 }	q |	 d S )N>   onnx.ai )domainz=Failed to get schema for %s, skipping optional output removalT)
stack_infoBatchNormalizationir   r   boolc                   s0   | t jk rj|  }| v pt| S dS )NF)lenoutputsr   uses)r   valr   r    X/home/ubuntu/.local/lib/python3.10/site-packages/onnx_ir/passes/common/unused_removal.pyis_used_output&   s   
z7_remove_unused_optional_outputs.<locals>.is_used_output      r   training_modec                 S  s   g | ]}|d kqS )r   r   ).0or   r   r   
<listcomp><   s    z3_remove_unused_optional_outputs.<locals>.<listcomp>r   )r   r   r   r   )r   onnxdefs
get_schemaop_type	Exceptionloggerinfor   r   name
attributespopoptionOpSchemaFormalParameterOptionVariadicappendOptional	enumerater   reversedrangeresize_outputs)
r   r   r
   	op_schemar   optional_infor!   r   outnew_output_countr   r   r   _remove_unused_optional_outputs   sN   




r;   c                 C  sH   t | j}ttt | jD ]}| j| d u r|d8 }q | | d S )Nr   )r   inputsr4   r5   resize_inputs)r   new_input_countr   r   r   r   _remove_trailing_empty_inputsM   s   

r?   function_or_graphir.Function | ir.Graphc           	      C  s   t | j}| jdd }d}t| D ]^}d}|jD ]}||v s#| r'd} nq|r6| j|dd |d7 }qt| |d urDt||| |j	
 D ]&}|jtjjkr[|t| 7 }qI|jtjjkro| D ]}|t|7 }qfqIq|S )Nr   r   TF)safer   )	frozensetr   opset_importsgetr4   r   remover?   r;   r+   valuestypeirAttributeTypeGRAPH"_remove_unused_nodes_in_graph_likeas_graphGRAPHS	as_graphs)	r@   r   r
   countr   	removableoutputattrgraphr   r   r   rL   X   s2   


rL   c                   @  s   e Zd ZdZd	ddZdS )
r   a  Pass for removing unused nodes and initializers (dead code elimination).

    This pass does not modify the model signature (inputs and outputs). It ensures
    that unused nodes and initializers are removed while preserving the original
    contract of the model.
    modelir.Modelr   ir.passes.PassResultc                 C  s   t |j}t|jj}t|jj}|jj}t| D ]}| s8||v s8||v s8|j	d us0J ||j	= |d7 }q|j
 D ]}|t |7 }q>|rOtd| tjj|t|dS )Nr   zRemoved %s unused nodesmodified)rL   rT   rC   r   r<   initializerslistrG   r   r*   	functionsr(   r)   rI   passes
PassResultr   )selfrU   rP   r   graph_inputsrZ   initfunctionr   r   r   callz   s   
zRemoveUnusedNodesPass.callNrU   rV   r   rW   )__name__
__module____qualname____doc__rc   r   r   r   r   r   r   s    r   c                      s:   e Zd Z fddZdddZdddZdddZ  ZS )r   c                   s   t    d | _d S N)super__init___used)r_   	__class__r   r   rk         

z"RemoveUnusedFunctionsPass.__init__rU   rV   r   rW   c                 C  s   t  | _tj|jD ]}| || qt |j| j }|s+t	d tj
j|ddS |D ]}|j|= q-t	dt| tdt|j td| d | _tj
j|t|dS )NzNo unused functions to removeFrX   zRemoved %s unused functionszFunctions left: %szFunctions removed: %s)setrl   rI   	traversalRecursiveGraphIteratorrT   
_call_noder\   r(   r)   r]   r^   r   debugr[   r   )r_   rU   r   unusedop_identifierr   r   r   rc      s   

zRemoveUnusedFunctionsPass.callrb   ir.Functionr   c                 C  sR   | j d usJ | | j v rd S | j |  tj|D ]}| || qd S ri   )rl   
identifieraddrI   rq   rr   rs   )r_   rU   rb   r   r   r   r   _call_function   s   z(RemoveUnusedFunctionsPass._call_functionr   r   c                 C  s,   |  }||jvrd S | ||j|  d S ri   )rv   r\   rz   )r_   rU   r   rv   r   r   r   rs      s   
z$RemoveUnusedFunctionsPass._call_noderd   )rU   rV   rb   rw   r   r   )rU   rV   r   r   r   r   )re   rf   rg   rk   rc   rz   rs   __classcell__r   r   rm   r   r      s
    

	r   c                      s8   e Zd ZdZdd fddZdddZdddZ  ZS )r   a)  Remove unused opset imports from the model and functions.

    Attributes:
        process_functions: Whether to process functions in the model. If True, the pass will
            remove unused opset imports from functions as well. If False, only the main graph
            will be processed.
    Tprocess_functionsr   c                   s   t    || _d S ri   )rj   rk   r|   )r_   r|   rm   r   r   rk      ro   zRemoveUnusedOpsetsPass.__init__
graph_likeir.Graph | ir.Functionused_domainsset[str]r   c                 C  sF   t j|D ]}||j qt|j| }|D ]}|j|= qt|S ri   )rI   rq   rr   ry   r   rp   rD   r   )r_   r}   r   r   ru   r   r   r   r   _process_graph_like   s   
z*RemoveUnusedOpsetsPass._process_graph_likerU   rV   rW   c                 C  sl   dh}|j  D ]}||j q| j|j|d}| jr.|j  D ]}|| j|dhdO }q!tjj	||dS )Nr   )r   rX   )
r\   rG   ry   r   r   rT   r|   rI   r]   r^   )r_   rU   r   rb   rY   r   r   r   rc      s   zRemoveUnusedOpsetsPass.call)T)r|   r   )r}   r~   r   r   r   r   rd   )re   rf   rg   rh   rk   r   rc   r{   r   r   rm   r   r      s
    

r   )r   r   r   r	   r
   r   r   r   )r   r   r   r   )r@   rA   r   r   )
__future__r   __all__loggingr#   onnx_irrI   	getLoggerre   r(   r;   r?   rL   r]   InPlacePassr   r   r   r   r   r   r   <module>   s   


9
*