o
    ;ήc                     @   sp   d dl mZ d dlmZmZmZ d dlmZ d dlm	Z	 d dl
mZmZ d dlmZ eeZG dd deZd	S )
    )	getLogger)DictListUnion)Fusion)FusionUtils)	NodeProtoTensorProto)	OnnxModelc                       s   e Zd Zdef fddZdedeedf fddZd	e	deedf fd
dZ
dedee	ee f dee	ef fddZ  ZS )FusionShapemodelc                    s*   t  |dd t|| _d | _d| _d S )NShapeConcatF)super__init__r   utilsshape_infershape_infer_done)selfr   	__class__ L/tmp/pip-target-vg8gfxp4/lib/python/onnxruntime/transformers/fusion_shape.pyr      s   

zFusionShape.__init__tensor_protoreturnNc                 C   s"   |j jdrt|j jjjS d S )Nshape)typetensor_typeHasFieldlenr   dim)r   r   r   r   r    get_dimensions_from_tensor_proto   s   z,FusionShape.get_dimensions_from_tensor_proto
input_namec                 C   sX   | j |}|r| |S | js| j ji dd| _d| _| jd ur*| | jj| S d S )NT)update)r   find_graph_inputr!   r   infer_runtime_shaper   	known_vi_)r   r"   graph_inputr   r   r   get_dimensions   s   

zFusionShape.get_dimensionsconcat_nodeinput_name_to_nodesoutput_name_to_nodec                 C   s  | j  }t|j}d}d}t|D ]}| j |g d|ddg|}	|	du r) dS |	\}
}}|dkr7|jd }|du rK|jd }| ||krJ dS n
|jd |krU dS tj	|
ddddsa dS |dk rqt	|
ddgsp dS n| j
|
ddgs} dS | j |jd }dd	lm}m} t||r|jdkr| |ks dS q| j |jd du r| j |jd | |  jd7  _d
| _dS dS )a  
        Smplify subgraph like

                   (2d_input)
                    /                       Shape       shape
                /                         Gather(indices=0)  Gather(indices=1)
                |                |
            Unsqueeze(axes=0)   Unsqueeze(axes=0)
                   \          /
                      Concat 
                        |

        into  (2d_input) --> Shape -->
        N)	UnsqueezeGatherr   r   axis)default_value   axes   )array_equalndarrayT)r   get_opset_versionr   inputrangematch_parent_pathoutputr(   r   check_node_attributer   check_node_input_valueget_constant_valuenumpyr3   r4   
isinstancesizeitemfind_graph_outputreplace_input_of_all_nodesfused_countprune_graph)r   r)   r*   r+   opset_versioninputsrootshape_outputipath	unsqueezegatherr   valuer3   r4   r   r   r   fuse,   sR   




 
zFusionShape.fuse)__name__
__module____qualname__r
   r   r	   r   intr!   strr(   r   r   r   rN   __classcell__r   r   r   r   r      s    
r   N)loggingr   typingr   r   r   fusion_baser   fusion_utilsr   onnxr   r	   
onnx_modelr
   rO   loggerr   r   r   r   r   <module>   s   