o
    Xi                     @  sR   d Z ddlmZ dgZddlZddlZeeZ	dd	d
Z
G dd dejjZdS )z@Identity elimination pass for removing redundant Identity nodes.    )annotationsIdentityEliminationPassNshape1ir.Shape | Noneshape2returnc                   sl   dd  | d u r
|S |d u r| S t | t |kr'tdt |  dt | dt fddt| |D S )Nc                 S  s>   | |kr| S t | tjs| S t |tjs|S | jd u r|S | S )N)
isinstanceirSymbolicDimvalue)dim1dim2 r   ^/home/ubuntu/.local/lib/python3.10/site-packages/onnx_ir/passes/common/identity_elimination.py
merge_dims   s   
z!_merge_shapes.<locals>.merge_dimsz$Shapes must have the same rank, got z and .c                   s   g | ]	\}} ||qS r   r   ).0r   r   r   r   r   
<listcomp>&   s    z!_merge_shapes.<locals>.<listcomp>)len
ValueErrorr	   Shapezip)r   r   r   r   r   _merge_shapes   s   r   c                   @  s$   e Zd ZdZdddZdddZdS )r   a9  Pass for eliminating redundant Identity nodes.

    This pass removes Identity nodes according to the following rules:

    1. For any node of the form `y = Identity(x)`, where `y` is not an output
       of any graph, replace all uses of `y` with a use of `x`, and remove the node.
    2. If `y` is an output of a graph, and `x` is not an input of any graph,
       we can still do the elimination, but the value `x` should be renamed to be `y`.
    3. If `y` is a graph-output and `x` is a graph-input, we cannot eliminate
       the node. It should be retained.
    modelir.Modelr   ir.passes.PassResultc                 C  st   d}t j|jD ]	}| |rd}q	|j D ]}t j|D ]	}| |r)d}q q|r2td t j	j
||dS )z3Main entry point for the identity elimination pass.FTz,Identity elimination pass modified the model)modified)r	   	traversalRecursiveGraphIteratorgraph_try_eliminate_identity_node	functionsvaluesloggerinfopasses
PassResult)selfr   r   nodefunctionr   r   r   call6   s   


zIdentityEliminationPass.callr)   ir.Nodeboolc                 C  s   |j dks
|jdkrdS t|jdkst|jdkrdS |jd }|jd }|du r,dS |j}|dus7J d| }| }|rE|rEdS t|j	|j	|_	|j
du rV|j
|_
tjj||dd	 |re|j|_|j|dd
 td| dS )zBTry to eliminate a single identity node. Returns True if modified.Identity F   r   NzNode must be in a graphT)replace_graph_outputs)safezEliminated identity node: %s)op_typedomainr   inputsoutputsr    is_graph_outputis_graph_inputr   shapetyper	   conveniencereplace_all_uses_withnameremover$   debug)r(   r)   input_valueoutput_value
graph_likeoutput_is_graph_outputinput_is_graph_inputr   r   r   r!   J   s2   


z4IdentityEliminationPass._try_eliminate_identity_nodeN)r   r   r   r   )r)   r,   r   r-   )__name__
__module____qualname____doc__r+   r!   r   r   r   r   r   )   s    
)r   r   r   r   r   r   )rH   
__future__r   __all__loggingonnx_irr	   	getLoggerrE   r$   r   r&   InPlacePassr   r   r   r   r   <module>   s   

