o
    )wi$                     @   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__ e/home/ubuntu/sommelier/.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   )prune_graph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)op_type).0noder   r   r   
<listcomp>.   s    z4UnetOnnxModel.remove_useless_div.<locals>.<listcomp>g      ?   r   zRemoved %d Div nodesN)
nodesfind_constant_inputappendreplace_input_of_all_nodesoutputinputremove_nodesloggerinfolen)r   	div_nodesnodes_to_removedivr%   r   r   r   r   ,   s   

z UnetOnnxModel.remove_useless_divc                 C   s   t | dd}|  d S )NT)update_weight)r   apply)r   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   	Transposepermr'   zRemoved %d Transpose nodes)r
   r6   get_nodes_by_op_typer   get_node_attribute
isinstancelistranger1   find_graph_outputr,   find_graph_inputr-   r+   remove_noder3   r/   r0   )r   fusion_transposeremove_countr(   r%   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)is_cross_attentionenable_packed_qkvenable_packed_kvT)rJ   r   r   r   r6   rK   )r   rH   rJ   self_attention_fusionrK   cross_attention_fusionr   r   r   fuse_multi_head_attention]   s(   z'UnetOnnxModel.fuse_multi_head_attentionc                 C   s   t | }|  d S r   )r   r6   )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   rO   )initialdescz<tqdm is not installed. Run optimization without progress bar)r   rQ   tqdm.contrib.loggingrR   r?   	_optimizer/   r0   )r   rH   rQ   rR   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rt| }|  |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rt| }|  |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: )(enable_shape_inferencedisable_shape_inferenceutilsremove_identity_nodesupdateremove_useless_cast_nodesenable_layer_normfuse_layer_normenable_gelu	fuse_gelur   fuse_reshapeenable_group_normgroup_norm_channels_lastr   r6   r	   enable_bias_splitgelur   enable_attentionrN   enable_skip_layer_normfuse_skip_layer_norm
fuse_shaperemove_useless_reshape_nodesenable_skip_group_normr   enable_bias_skip_layer_normfuse_add_bias_skip_layer_normenable_gelu_approximationgelu_approximationenable_nhwc_convr8   rG   enable_bias_addrP   r    r/   r0   get_opset_version)r   rH   rY   channels_lastgroup_norm_fusioninsert_transpose_fusionbias_split_gelu_fusionskip_group_norm_fusionr   r   r   rW      s   






















zUnetOnnxModel._optimizec                 C   s@   i }g d}|D ]}|  |}t|||< qtd|  |S )z8
        Returns node count of fused operators.
        )		AttentionMultiHeadAttentionLayerNormalizationSkipLayerNormalizationBiasSplitGelu	GroupNormSkipGroupNormNhwcConvBiasAddzOptimized operators:)r;   r1   r/   r0   )r   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   r8   rG   r   rN   rP   rZ   rW   r   __classcell__r   r   r   r   r      s    er   )loggingfusion_attention_unetr   fusion_bias_addr   fusion_biassplitgelur   fusion_group_normr   fusion_nhwc_convr   fusion_optionsr   fusion_skip_group_normr   rC   r	   r
   import_utilsr   onnxr   
onnx_modelr   onnx_model_bertr   	getLoggerr   r/   r   r   r   r   r   <module>   s   
