o
    ¢Äi'$  ã                   @   sº   d dl Z 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
 d dlmZ d dlmZ d d	lmZ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dS )é    N)ÚFusionAttentionUnet)ÚFusionBiasAdd)ÚFusionBiasSplitGelu)ÚFusionGroupNorm)ÚFusionNhwcConv)ÚFusionOptions)ÚFusionSkipGroupNorm)ÚFusionInsertTransposeÚFusionTranspose)Úis_installed)Ú
ModelProto)Ú	OnnxModel)ÚBertOnnxModelc                       s    e Zd Zddededef‡ fdd„Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
ddedB fdd„Zdd„ ZddedB fdd„ZddedB fdd„Zdd„ Z‡  ZS ) ÚUnetOnnxModelr   ÚmodelÚ	num_headsÚhidden_sizec                    s>   |dkr|dks|dkr|| dksJ ‚t ƒ j|||d dS )aG  Initialize UNet ONNX Model.

        Args:
            model (ModelProto): the ONNX model
            num_heads (int, optional): number of attention heads. Defaults to 0 (detect the parameter automatically).
            hidden_size (int, optional): hidden dimension. Defaults to 0 (detect the parameter automatically).
        r   )r   r   N)ÚsuperÚ__init__)Úselfr   r   r   ©Ú	__class__© úb/home/kim/smarthome/.venv/lib/python3.10/site-packages/onnxruntime/transformers/onnx_model_unet.pyr      s   (zUnetOnnxModel.__init__c                 C   s   |   ¡  d S ©N)Úremove_useless_div©r   r   r   r   Ú
preprocess%   s   zUnetOnnxModel.preprocessc                 C   s   |   ¡  |  ¡  d S r   )Zprune_graphZremove_unused_constantr   r   r   r   Úpostprocess(   ó   zUnetOnnxModel.postprocessc                 C   s‚   dd„ |   ¡ D ƒ}g }|D ]}|  |d¡dkr| |¡ q|D ]}|  |jd |jd ¡ q|r?|  |¡ t dt	|ƒ¡ dS dS )zRemove Div by 1c                 S   s   g | ]	}|j d kr|‘qS )ÚDiv)Zop_type)Ú.0Únoder   r   r   Ú
<listcomp>.   s    z4UnetOnnxModel.remove_useless_div.<locals>.<listcomp>g      ð?é   r   zRemoved %d Div nodesN)
ÚnodesZfind_constant_inputÚappendÚreplace_input_of_all_nodesÚoutputÚinputZremove_nodesÚloggerÚinfoÚlen)r   Z	div_nodesÚnodes_to_removeÚdivr"   r   r   r   r   ,   s   
€
þz UnetOnnxModel.remove_useless_divc                 C   s   t | dd}| ¡  d S )NT)Zupdate_weight)r   Úapply)r   Zconv_to_nhwc_convr   r   r   Úconvert_conv_to_nhwc<   s   z"UnetOnnxModel.convert_conv_to_nhwcc                 C   sÜ   t | ƒ}| ¡  d}|  d¡}|D ]I}t |d¡}t|tƒs J ‚|ttt|ƒƒƒkr+q|  	|j
d ¡sC|  |jd ¡sC|  	|jd ¡rEJ ‚|  |j
d |jd ¡ |  |¡ |d7 }qt|jƒ| }|rlt d|¡ d S d S )Nr   Z	TransposeÚpermr$   zRemoved %d Transpose nodes)r
   r/   Úget_nodes_by_op_typer   Zget_node_attributeÚ
isinstanceÚlistÚranger,   Zfind_graph_outputr(   Zfind_graph_inputr)   r'   Úremove_noder-   r*   r+   )r   Úfusion_transposeZremove_countr%   r"   ZpermutationÚtotalr   r   r   Úmerge_adjacent_transposeA   s,   
ÿþý

ÿz&UnetOnnxModel.merge_adjacent_transposeNÚoptionsc                 C   s`   |d u p|j }t| | j| jd|dd}| ¡  |d u p|j}t| | j| jdd|d}| ¡  d S )NF)Zis_cross_attentionÚenable_packed_qkvÚenable_packed_kvT)r;   r   r   r   r/   r<   )r   r:   r;   Zself_attention_fusionr<   Zcross_attention_fusionr   r   r   Úfuse_multi_head_attention]   s(   úúz'UnetOnnxModel.fuse_multi_head_attentionc                 C   s   t | ƒ}| ¡  d S r   )r   r/   )r   Úfusionr   r   r   Úfuse_bias_addv   r   zUnetOnnxModel.fuse_bias_addc                 C   s†   t dƒr6dd l}ddlm} |ƒ  d}|jt|ƒddd}|  ||¡ W d   ƒ d S 1 s/w   Y  d S t d¡ |  |d ¡ d S )NÚtqdmr   )Úlogging_redirect_tqdmé   r>   )ÚinitialZdescz<tqdm is not installed. Run optimization without progress bar)r   r@   Ztqdm.contrib.loggingrA   r5   Ú	_optimizer*   r+   )r   r:   r@   rA   ZstepsÚprogress_barr   r   r   Úoptimizez   s   "ý
zUnetOnnxModel.optimizec                 C   s°  |d ur|j s|  ¡  | j ¡  |r| d¡ | j ¡  |r#| d¡ |d u s*|jr.|  ¡  |r5| d¡ |d u s<|jr@|  	¡  |rG| d¡ |  
¡  |rR| d¡ |  ¡  |r]| d¡ |d u sd|jr||d u pj|j}t| |ƒ}| ¡  t| ƒ}| ¡  |rƒ| d¡ |d u sŠ|jr’t| ƒ}| ¡  |r™| d¡ |d u s |jr¥|  |¡ |r¬| d¡ |d u s³|jr·|  ¡  |r¾| d¡ |  ¡  |rÉ| d¡ | j ¡  |rÕ| d¡ |d u sÜ|jrät| ƒ}| ¡  |rë| d¡ |d u sò|jrö|  ¡  |rý| d¡ |d ur
|jr
|  ¡  |r| d¡ |d u s|jr#|   ¡  |  !¡  |r+| d¡ |d ur8|j"r8|  #¡  |r@| d¡ |  $¡  |rL| d¡ t% &d|  '¡ › ¡ d S )Nr$   zopset version: )(Zenable_shape_inferenceZdisable_shape_inferenceÚutilsZremove_identity_nodesÚupdateZremove_useless_cast_nodesZenable_layer_normZfuse_layer_normZenable_geluZ	fuse_gelur   Zfuse_reshapeZenable_group_normZgroup_norm_channels_lastr   r/   r	   Zenable_bias_splitgelur   Zenable_attentionr=   Zenable_skip_layer_normZfuse_skip_layer_normZ
fuse_shapeZremove_useless_reshape_nodesZenable_skip_group_normr   Zenable_bias_skip_layer_normZfuse_add_bias_skip_layer_normZenable_gelu_approximationZgelu_approximationZenable_nhwc_convr0   r9   Zenable_bias_addr?   r   r*   r+   Zget_opset_version)r   r:   rE   Zchannels_lastZgroup_norm_fusionZinsert_transpose_fusionZbias_split_gelu_fusionZskip_group_norm_fusionr   r   r   rD   ‡   s–   






















zUnetOnnxModel._optimizec                 C   s@   i }g d¢}|D ]}|   |¡}t|ƒ||< qt d|› ¡ |S )z8
        Returns node count of fused operators.
        )	Z	AttentionZMultiHeadAttentionZLayerNormalizationZSkipLayerNormalizationZBiasSplitGeluZ	GroupNormZSkipGroupNormZNhwcConvZBiasAddzOptimized operators:)r2   r,   r*   r+   )r   Zop_countÚopsÚopr%   r   r   r   Úget_fused_operator_statisticsì   s   
z+UnetOnnxModel.get_fused_operator_statistics)r   r   r   )NN)Ú__name__Ú
__module__Ú__qualname__r   Úintr   r   r   r   r0   r9   r   r=   r?   rF   rD   rK   Ú__classcell__r   r   r   r   r      s    er   )ÚloggingZfusion_attention_unetr   Zfusion_bias_addr   Zfusion_biassplitgelur   Zfusion_group_normr   Zfusion_nhwc_convr   Zfusion_optionsr   Zfusion_skip_group_normr   r7   r	   r
   Zimport_utilsr   Zonnxr   Z
onnx_modelr   Zonnx_model_bertr   Ú	getLoggerrL   r*   r   r   r   r   r   Ú<module>   s   
