o
    ;ήcD                     @   sh   d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	 ee
ZG dd deZG dd	 d	eZd
S )    )	getLogger)Fusion)NumpyHelper)helper)	OnnxModelc                       s.   e Zd ZdZdef fddZdd Z  ZS )FusionSkipLayerNormalizationz
    Fuse Add + LayerNormalization into one node: SkipLayerNormalization
    Note: This fusion does not check the input shape of Add and LayerNormalization.
    modelc                    sD   t  |dd | jjddddd| _| jd u r td d S d S )	NSkipLayerNormalizationLayerNormalization      )
batch_sizeseq_lenT)updatez,symbolic shape inference disabled or failed.)super__init__r   infer_runtime_shapeshape_infer_helperloggerwarningselfr   	__class__ T/tmp/pip-target-vg8gfxp4/lib/python/onnxruntime/transformers/fusion_skiplayernorm.pyr      s
   
z%FusionSkipLayerNormalization.__init__c           
      C   s  | j |d|}|d u rd S |jD ]}| j |d kr d S qt| j |dkr+d S | jd urM| j|jd |jd sLt	d|jd |jd  d S nt	d d S | j 
|dgd g}|d ur| j |d jd d u r| j 
|d dgdgd u rd S |d ur|jdkr| j ||g|j||r| j||g |jd |jd |jd |jd g}tjd	||jd g| j jd	d
dd}d|_|jD ]}	|	jdkr|j|	g qt|jdkr|jtddg | j| | j| j|j< d S d S d S d S )Nr         zNskip SkipLayerNormalization fusion since shape of inputs (%s, %s) are not samezHskip SkipLayerNormalization fusion since symbolic shape inference failedGatherConstantOfShapeAddr	   SkipLayerNorm)name_prefixinputsoutputsnamecom.microsoftepsilon-q=)r   
get_parentinputget_initializerlenget_parentsr   compare_shaper   debugmatch_parent_pathfind_graph_inputop_typeis_safe_to_fuse_nodesoutputnodes_to_removeextendr   	make_nodecreate_node_namedomain	attributer&   make_attributenodes_to_addappendthis_graph_namenode_name_to_graph_name)
r   nodeinput_name_to_nodesoutput_name_to_nodeadd	add_inputgather_pathr$   normalize_nodeattr   r   r   fuse   s`   


"$


z!FusionSkipLayerNormalization.fuse)__name__
__module____qualname____doc__r   r   rI   __classcell__r   r   r   r   r      s    	r   c                       s*   e Zd Zdef fddZdd Z  ZS ) FusionBiasSkipLayerNormalizationr   c                    s   t  |ddd d S )Nr	   zadd bias)r   r   r   r   r   r   r   ^   s   z)FusionBiasSkipLayerNormalization.__init__c                 C   s  t |jdkr	d S g }| j|ddgd d gd |}|d u rd S t |dks'J |d }|dkr1d S |\}}d}	t|jD ]\}
}| j|}|d u rKq<|
}	t|} |d u r^t	d d S t |j
dkrlt	d	 d S ||g}| j||jd g||st	d
 d S | j| |jd|  |jd |jd |jd |j|	 g}tjd||j| jddd}d|_|jD ]}|jdkr|j|g qt |jdkr|jtddg | j| | j| j|j< d S )Nr   r    MatMulr   r   zBias weight not foundr   zBias weight is not 1DzASkip fusing SkipLayerNormalization with Bias since it is not safe   r	   SkipLayerNorm_AddBias_r#   r'   r(   r)   )r-   r+   r   r1   	enumerater,   r   to_arrayr   r0   shaper4   r5   r6   r7   r   r8   r9   r:   r;   r&   r<   r=   r>   r?   r@   )r   rA   rB   rC   return_indicenodesadd_input_indexrD   matmul
bias_indexir+   initializerbias_weightsubgraph_nodesr$   new_noderH   r   r   r   rI   a   sj   





z%FusionBiasSkipLayerNormalization.fuse)rJ   rK   rL   r   r   rI   rN   r   r   r   r   rO   ]   s    rO   N)loggingr   fusion_baser   fusion_utilsr   onnxr   
onnx_modelr   rJ   r   r   rO   r   r   r   r   <module>   s   M