o
    Xi                     @  s\   d Z ddlmZ dgZddlZddlZeeZ	G dd dej
jZdd
dZdddZdS )a%  Output fix pass for adding Identity nodes.

- Graph inputs are directly used as outputs (without any intermediate nodes).
- A value is used multiple times as a graph output (ensuring each output is unique).

This ensures compliance with the ONNX specification for valid output configurations.
    )annotationsOutputFixPassNc                   @  s   e Zd ZdZd	ddZdS )
r   aC  Pass for adding Identity nodes to fix invalid output configurations.

    This pass adds Identity nodes according to the following rules:

    - If a graph input is directly used as a graph output (without any intermediate nodes),
      insert an Identity node between them. The ONNX specification does not allow a graph
      input to be directly used as a graph output without any processing nodes in between.
    - If a value is used multiple times as graph outputs, insert Identity nodes for each
      duplicate usage (keeping the first usage unchanged). This ensures each output value
      is unique, as required by the ONNX specification.

    This pass processes both the main graph and all subgraphs (e.g., in control flow operators).

    Example transformations:
        Direct input-to-output:
            Before: input -> (direct connection) -> output
            After:  input -> Identity -> output

        Duplicate outputs:
            Before: value -> [output1, output2]
            After:  value -> output1, value -> Identity -> output2

    .. versionadded:: 0.1.13
    modelir.Modelreturnir.passes.PassResultc                 C  sX   d}t |jr	d}t|jrd}|j D ]}t |rd}t|r#d}qtjj||dS )z)Main entry point for the output fix pass.FT)modified)_alias_multi_used_outputsgraph_alias_direct_outputs	functionsvaluesirpasses
PassResult)selfr   r   function r   T/home/ubuntu/.local/lib/python3.10/site-packages/onnx_ir/passes/common/output_fix.pycall2   s   

zOutputFixPass.callN)r   r   r   r   )__name__
__module____qualname____doc__r   r   r   r   r   r      s    
graph_likeir.Graph | ir.Functionr   boolc                 C  s   d}| g|   R D ]T}t }t|jD ]I\}}||vr"|| qtjd|gd}|jd }|j d| |_|j|_|j	|_	|j
|j
 |j|_|| ||j|< td| d}qq
|S )zUInsert Identity nodes for values that appear in the graph output list multiple times.FIdentityinputsr   _alias_z=Added Identity node for graph output '%s' used multiple timesT)	subgraphsset	enumerateoutputsaddr   nodenameshapetypemetadata_propsupdate
doc_stringappendloggerdebug)r   r   r
   seenioutputidentity_nodeidentity_outputr   r   r   r	   F   s,   



r	   c           	      C  s   d}| g|   R D ]]}g }t|jD ]\}}| r"|||f q|D ]A\}}tjd|gd}|jd }|j|_|j|_|j	|_	|j
|j
 |j|_|j d|_|| ||j|< td| d}q%q
|S )z@Insert Identity nodes for graph inputs used directly as outputs.Fr   r   r   _origz7Added Identity node for graph input '%s' used as outputT)r!   r#   r$   is_graph_inputr-   r   r&   r'   r(   r)   r*   r+   r,   r.   r/   )	r   r   r
   outputs_to_fixr1   r2   indexr3   r4   r   r   r   r   k   s,   


r   )r   r   r   r   )r   
__future__r   __all__loggingonnx_irr   	getLoggerr   r.   r   InPlacePassr   r	   r   r   r   r   r   <module>   s   

.%