o
    ¢Äi)  ã                   @   sX   d dl mZ d dl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 )é    )Ú	getLoggerN)ÚFusion)ÚTensorProtoÚhelper)Ú	OnnxModelc                       s6   e Zd Zd	def‡ fdd„Zdedefdd„Z‡  ZS )
ÚFusionGroupNormTÚmodelc                    s   t ƒ  |dd¡ || _d S )NÚ	GroupNormÚAdd)ÚsuperÚ__init__Úchannels_last)Úselfr   r   ©Ú	__class__© úd/home/kim/smarthome/.venv/lib/python3.10/site-packages/onnxruntime/transformers/fusion_group_norm.pyr      s   
zFusionGroupNorm.__init__Úinput_name_to_nodesÚoutput_name_to_nodec           #      C   s¢  | j  |g d¢g d¢|¡}|du rdS |\}}}}|jd }	| j  |dgdg|¡}
|
du r/dS |
d jd |	kr:dS |
d }| j  |d¡}d}|dur^| j  |dgdg|¡}|dur^|d }|jd| j  |jd |¡  }| j  |d	d
¡swdS |jd| j  |jd |¡  }| j  |d	d¡sdS | j  |¡}|du rœdS t|j	ƒd	kr±|j	d dkr±|j	d dks³dS | j  |¡}|du r¿dS t|j	ƒd	krÔ|j	d dkrÔ|j	d dksÖdS t
t |j	¡ƒ}t
t |j	¡ƒ}||krìdS | j  |jd ¡}|du st|j	ƒdkrdS t
|j	d ƒ}| j  |jd ¡}|du s |j	|j	kr"dS t t |¡|¡s.dS t t |¡|¡s:dS | j jddd}| j|d tj|g|d | j|d tj|g|d |}||||||g}|oj|}|rz|rz| ||g¡ |}| j  ||j||¡s| j |g¡ n| j |¡ d| _|	}|jd }| jr¥|d n|}| jr¯|d n|}| jrÖtjd|g|g| j jdddg d¢d} | j | ¡ | j| j| j< tjd||d |d g|g|d}!|!j  |j ¡ |!j  t !d|¡g¡ |!j  t !d|rdnd¡g¡ | js|!j  t !dd¡g¡ d|!_"| j |!¡ | j| j|!j< | jrOtjd|g|g| j jdddg d¢d}"| j |"¡ | j| j|"j< dS dS )a‚  
         Fuse Group Normalization subgraph into one node GroupNorm.
         The following is the pattern with swish activation:
               +----------------Shape-------------------------------+
               |                                                    |
               |    (0, 32, -1)                                     v     (512x1x1) (512x1x1) (optional)
           [Root] --> Reshape -------> InstanceNormalization --> Reshape ---> Mul --> Add --> Mul--> [output]
        Bx512xHxW                 (scale=ones(32), B=zeros(32))                        |       ^     Bx512xHxW
                                                                                       |       |
                                                                                       +--->Sigmoid (optional)
        The Mul and Sigmoid before output is for Swish activation. They are optional.
        )ÚMulÚReshapeZInstanceNormalizationr   )r   r   r   r   Nr   ZShapeé   r   ZSigmoidé   zgroup norm weightzlayernorm biasé   r	   )Zname_prefixZ_gamma)ÚnameZ	data_typeÚdimsÚvalsZ_betaTZ_NHWCZ	TransposeZTranspose_NCHW_to_NHWC)r   r   r   r   )r   Úperm)ZinputsZoutputsr   ÚgroupsZ
activationr   zcom.microsoftZTranspose_NHWC_to_NCHW)r   r   r   r   )#r   Zmatch_parent_pathÚinputZfind_first_child_by_typeZinput_indexÚoutputZ$is_constant_with_specified_dimensionZget_constant_valueÚlenÚshapeÚintÚnpÚprodZallcloseZ	ones_likeZ
zeros_likeZcreate_node_nameZadd_initializerr   ÚFLOATÚextendZis_safe_to_fuse_nodesZnodes_to_removeZprune_graphr   r   Z	make_nodeZnodes_to_addÚappendZthis_graph_nameZnode_name_to_graph_namer   Ú	attributeZmake_attributeÚdomain)#r   Úadd_noder   r   ÚnodesZ
weight_mulZ
reshape_4dZinstance_normZ
reshape_3dÚrootÚparentsZ
shape_nodeZ	swish_mulZswish_sigmoidZsigmoid_pathZweight_inputZ
bias_inputÚweightZbiasZweight_elementsZbias_elementsZinstance_norm_scaleZ
num_groupsZinstance_norm_biasZgroup_norm_nameZ	last_nodeZsubgraph_nodesZhas_swish_activationZ
input_nameZoutput_nameZgroup_norm_input_nameZgroup_norm_output_nameZtranspose_inputÚnew_nodeZtranspose_outputr   r   r   Úfuse   sê   ÿ
**üü
ü
ûü û÷zFusionGroupNorm.fuse)T)Ú__name__Ú
__module__Ú__qualname__r   r   Údictr1   Ú__classcell__r   r   r   r   r      s    r   )Úloggingr   Únumpyr$   Zfusion_baser   Zonnxr   r   Z
onnx_modelr   r2   Úloggerr   r   r   r   r   Ú<module>   s   