
     Ng;                        d dl Z d dlZd dlZd dlZd dlZd dl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Zd dlZd dlmZmZmZ d dlmZ d dlZ ej        e          ZdZd	Z G d
 de          Zd Zd Zd Zedk    r e             dS dS )    N)deque)datetime)Path)ListOptional)
ModelProtoTensorProtonumpy_helper)	OnnxModelconstant_shape_opt__reshape_input_shape__c                        e Zd ZdZ fdZd Zd Zd Zd Zd Z	dd
Z
	 ddZd Zd ZdefdZdee         fdZ	 	 	 	 ddededededededeee                  fdZ xZS )BertOnnxModelShapeOptimizerz
    This optimizer will replace Shape output or the shape input of Reshape node by initializer. Currently, it requires
    model inputs to have static shape.
    c                 T    t                                          |j                   d S )N)super__init__model)self
onnx_model	__class__s     d/var/www/html/ai-engine/env/lib/python3.11/site-packages/onnxruntime/transformers/shape_optimizer.pyr   z$BertOnnxModelShapeOptimizer.__init__(   s$    )*****    c                 
   t          j        |t           j                  }|                     dt                    }t
          j                            |t          j	        |j
        |          }|                     |           |S )z8
        Add an initializer for constant shape.
        dtypeConstant)name	data_typedimsvals)npasarrayint64create_node_nameCONSTANT_SHAPE_NAME_PREFIXonnxhelpermake_tensorr	   INT64shapeadd_initializer)r   r*   shape_valueconstant_shape_nametensors        r   add_shape_initializerz1BertOnnxModelShapeOptimizer.add_shape_initializer+   sz     jbh777"33J@Z[[(($!'"	 ) 
 
 	V$$$r   c                     |                                  }g }| j        j        j        D ]<}|j        dk    r/|j        d         |v r |                    |j        d                    =|S )zD
        Returns a list of output names of all Shape nodes.
        Shaper   )input_name_to_nodesr   graphnodeop_typeoutputappend)r   r2   outputsr4   s       r   get_shape_outputsz-BertOnnxModelShapeOptimizer.get_shape_outputs:   so     #6688J$) 	3 	3D|w&&;q>%888NN4;q>222r   c                     |                                   g }| j        j        j        D ]-}|j        dk    r |                    |j        d                    .|S )zG
        Returns a list of shape input names of Reshape nodes.
        Reshape   )output_name_to_noder   r3   r4   r5   r7   input)r   shape_inputsr4   s      r   get_reshape_shape_inputsz4BertOnnxModelShapeOptimizer.get_reshape_shape_inputsH   s`     	  """J$) 	3 	3D|y((##DJqM222r   c                 b   g }g }| j         j        j        D ]}|j        dk    rv|j        d         }|                     dt                    }t          j        	                    d|g|g          }|
                    |           |
                    |           |                     |           |S )z
        For each Reshape node, create a Shape node for its first input.
        Returns the output names of these Shape nodes.
        r;   r   Reshape_Inputr1   )inputsr8   )r   r3   r4   r5   r>   r$   RESHAPE_INPUT_SHAPE_PREFIXr&   r'   	make_noder7   	add_nodes)r   output_namesnodes_to_addr4   r>   output_name
shape_nodes          r   add_shape_for_reshape_inputz7BertOnnxModelShapeOptimizer.add_shape_for_reshape_inputU   s    
 J$) 	1 	1D|y((
1"33OE_``![227E7U`Ta2bb
##J///##K000|$$$r   c                 f   g }d | j         j        j        D             }|D ]}|                     |          |                    |           ||vr_t
          j                                        }||_        | j         j        j        	                    |g           |                    |           |S )z=
        Add a list of output names to graph output.
        c                     g | ]	}|j         
S  r   .0r6   s     r   
<listcomp>zFBertOnnxModelShapeOptimizer.add_extra_graph_output.<locals>.<listcomp>l   s    JJJJJJr   )
r   r3   r6   get_initializerr7   r&   r'   ValueInfoProtor   extend)r   extra_outputsnames_to_evaluaterG   r   output_infos         r   add_extra_graph_outputz2BertOnnxModelShapeOptimizer.add_extra_graph_outputg   s     JJ$*2B2IJJJ! 		* 		*D##D))5$$T***<''"k88::#' 
 '..}===##D)))  r   r<      c                    | j         j        j        D ]}|j        |v r|j        j        j        j        d         }||_        |j        j        j        j        d         }|	                    d          r||_        g|	                    d          r1|j        |k    r&t          d| dd d|j         d|j         d		          d
S )z_
        Update the model to use static axes instead of dynamic axes for graph inputs.
        r   r<   	dim_param	dim_valuez!Unable to set dimension value to z
 for axis z of z'. Contradicts existing dimension value .N)r   r3   r>   r   typetensor_typer*   dimr]   HasField
ValueError)r   rC   
batch_sizemax_seq_lenr>   	dim_protos         r   use_static_inputz,BertOnnxModelShapeOptimizer.use_static_input{   s    Z%+ 
	 
	EzV##!J28<Q?	&0	#!J28<Q?	%%k22 *5I''''44 9LP[9[9[$ dK  d  dST  d  dZ_Zd  d  d  NW  Na  d  d  d  
	 
	r      c                    |dv sJ t           j                            |||ft           j                  }t          j        ||ft           j                  }	t          j        ||ft           j                  }
|dk    r=t          j        |          }t          j        |	          }	t          j        |
          }
nB|dk    r<t          j        |          }t          j        |	          }	t          j        |
          }
||||	||
i}|S )z
        Create dummy data for model inputs. If the model has more than 3 inputs, please update this function accordingly before running the tool.
        )r<         )sizer   r   r<   rk   )r!   randomrandintint32oneszerosfloat32r#   )r   	input_idssegment_ids
input_maskrd   sequence_length	elem_typedictionary_sizeinput_1input_2input_3rC   s               r   create_dummy_inputsz/BertOnnxModelShapeOptimizer.create_dummy_inputs   s     I%%%% )##O::W_a_g#hh':7rxHHH(J8III >>j))Gj))Gj))GG!^^hw''Ghw''Ghw''GWj';Pr   c                 >   |||g| _         g }|r'|                    |                                            |	rR|                                 }|                                 }|                    |           |                    |           t          |          dk    rd S |                     |          }|                     | j         ||           t          |d          5 }|	                    | j
                                                   d d d            n# 1 swxY w Y   t          j                    }t          j        j        |_        t          j        ||ddg          }d}| j
        j        j        D ]}|j        |k    r|j        j        j        }|                     ||||||          }|                    ||          }i }t5          |          D ]\  }}||         ||<   t6                              d|            |	r5t5          |          D ]%\  }}||         }|                     ||||
           &|                                D ]5\  }}|                     |          }|                      ||j                   6| !                    |           d S )Nr   wbCUDAExecutionProviderCPUExecutionProvider)	providersrk   zshapes=)"bert_inputsrU   r9   r@   rK   lenrY   rg   openwriter   SerializeToStringonnxruntimeSessionOptionsGraphOptimizationLevelORT_DISABLE_ALLgraph_optimization_levelInferenceSessionr3   r>   r   r_   r`   rw   r|   run	enumerateloggerdebugupdate_target_shapeitemsr/   replace_input_of_all_nodesprune_graph)r   temp_model_pathrs   rt   ru   rG   rd   rv   enable_shape_optenable_reshape_optverboserV   reshape_shape_inputsreshape_input_shapesrW   outsess_optionssessionrw   r>   rC   r8   shapesir   shape_inputinput_shaper*   r.   s                                r   shape_optimizationz.BertOnnxModelShapeOptimizer.shape_optimization   s    &{J? 	;  !7!7!9!9::: 	7#'#@#@#B#B #'#C#C#E#E   !5666  !5666}""F 77FF 	d.
OLLL/4(( 	6CIIdj2244555	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6"1330;0R0b-..0FG
 
 
 	Z%+ 	= 	=EzY&&!J2<	)))[*jZiktuu++/88 !233 	& 	&GAt"1:F4LL'v''((( 	T"+,@"A"A T T;215((k7SSSS!<<>> 	? 	?KD%//66F++D&+>>>> 	&&&&&s    -DD Dc                     ||v r	||         }n-|                      |          }|J t          j        |          }||v r	||         }n-|                      |          }|J t          j        |          }g }t          |          D ]O\  }	}
|	t	          |          k     r"||	         |
k    r|                    d           :|                    |
           P|||<   t                              d| d| d|            dS )z
        Update the target shape to use 0 to represent that dimension value does not change.
        For example, shape of source data is (2, 5, 8) and target shape is (2, 5, 4, 2), the target shape will be updated to (0, 0, 4, 2).
        Nr   zsource_shape=z, target_shape=z, new_target_shape=)rS   r
   to_arrayr   r   r7   r   r   )r   r   r   r   r   target_shapeinitializersource_shapenew_target_shaper   r]   s              r   r   z/BertOnnxModelShapeOptimizer.update_target_shape   s<   
 &  !+.LL..{;;K***'0==L&  !+.LL..{;;K***'0==L%l33 	3 	3LAy3|$$$$aI)E)E ''**** ''	2222.{u\uu,uucsuuvvvvvr   r>   c                     |                      |          s0d | j        j        j        D             }t	          d| d|           d S )Nc                     g | ]	}|j         
S rN   rO   )rQ   r>   s     r   rR   z>BertOnnxModelShapeOptimizer.validate_input.<locals>.<listcomp>  s    JJJ%5:JJJr   zInput z% does not exist in the graph inputs: )find_graph_inputr   r3   r>   	Exception)r   r>   valid_namess      r   validate_inputz*BertOnnxModelShapeOptimizer.validate_input  s`    $$U++ 	`JJ4:3C3IJJJK^U^^Q\^^___	` 	`r   rG   c                 x    d | j         j        j        D             }|D ]}||vrt          d| d|           d S )Nc                     g | ]	}|j         
S rN   rO   rP   s     r   rR   z@BertOnnxModelShapeOptimizer.validate_outputs.<locals>.<listcomp>  s    IIIvv{IIIr   zOutput z& does not exist in the graph outputs: )r   r3   r6   r   )r   rG   r   r   s       r   validate_outputsz,BertOnnxModelShapeOptimizer.validate_outputs  sj    II1A1HIII  	e 	eD;&& c$ c cVa c cddd '	e 	er   NFoutput_pathrs   rt   ru   r   r   c                    | j         j        j        D ]>}|j                            t
                    rt                              d            d S ?|                     |           |                     |           |                     |           |*| 	                    |           | 
                    |           d | j         j        j        D             }|s|r&t          |                                           dk    rt                              d           d S t          j                    5 }d                    t#          j                                        d                    }|
rdn|}t(          j                            ||          }|                     |||||||	|||

  
         d d d            n# 1 swxY w Y   t                              d|            t                              d	| d
|	            |Wt5          |d          5 }|                    | j                                                    d d d            d S # 1 swxY w Y   d S d S )Nz5Skip shape optimization since it has been done beforec                     g | ]	}|j         
S rN   rO   rP   s     r   rR   z8BertOnnxModelShapeOptimizer.optimize.<locals>.<listcomp>3  s    OOOVV[OOOr      z9Skip shape optimization since graph input number is not 3ztemp_{}.onnxz%m_%d-%H_%M_%Sr^   z$Temp model with additional outputs: zZShape optimization is done. The optimized model might only work for input with batch_size=z sequence_length=r~   )r   r3   r   r   
startswithr%   r   infor   r   r   r6   r   'get_graph_inputs_excluding_initializerstempfileTemporaryDirectoryformatr   nowstrftimeospathjoinr   r   warningr   r   r   )r   r   rs   rt   ru   r   r   rG   rd   rv   r   r.   remaining_outputstemp_dirtemp_file_namedir	temp_filer   s                     r   optimizez$BertOnnxModelShapeOptimizer.optimize  s     j&2 	 	F{%%&@AA STTT 	I&&&K(((J'''#!!,///\***OOtz7G7NOOO 	1 	4??AABBaGGWXXX,.. (!/!6!6x|~~7N7NO_7`7`!a!a$2cc(GLLn==	''%#$&  	                LLK	KKLLLNN \mw  \  \  KZ  \  \   "k4(( :C		$*6688999: : : : : : : : : : : : : : : : : : #"s%   0A>F::F>F>-III)r<   rZ   )rh   )Nr<   rZ   F)__name__
__module____qualname____doc__r   r/   r9   r@   rK   rY   rg   r|   r   r   strr   r   r   boolr   r   __classcell__)r   s   @r   r   r   "   s        
+ + + + +        $! ! !(   0    BB' B' B'Hw w w:`C ` ` ` `
eT#Y e e e e -19: 9:9: 9: 	9:
 9: 9: !9: tCy)9: 9: 9: 9: 9: 9: 9: 9:r   r   c                  >   t          j                    } |                     ddt                     |                     ddt                     |                     ddt                     |                     ddt                     |                     ddt                     |                     dd	t          d 
           |                     dd	t          d
           |                     dd	t          d
           |                     dd	d           |                     d	           |                     dd	d           |                     d	           |                     dd	d           |                     d	           |                                 }|S )Nz--inputT)requiredr_   z--outputz--input_idsz--segment_idsz--input_maskz--output_namesF)r   r_   defaultz--batch_sizer<   z--sequence_lengthrZ   z--enable_shape_opt
store_true)r   action)r   z--enable_reshape_opt)r   z	--verbose)r   )argparseArgumentParseradd_argumentr   intset_defaults
parse_args)parserargss     r   parse_argumentsr   T  s   $&&F
	Ds;;;

T<<<
3???
$SAAA
C@@@
(5sDQQQ
S!LLL
+e#sSSS
,u\RRR
///
.|TTT
5111
eLIII
&&&DKr   c                    t          j        t          j                  }| r4|                    t          j        d                     t           j        }n3|                    t          j        d                     t           j        }|                    |           t          
                    |           t                              |           d S )Nz8[%(filename)s:%(lineno)s - %(funcName)20s()] %(message)sz%(filename)20s: %(message)s)loggingStreamHandlersysstdoutsetFormatter	FormatterDEBUGINFOsetLevelr   
addHandler)r   log_handlerlogging_levels      r   setup_loggingr   h  s    '
33K %  !23m!n!nooo  !23P!Q!QRRR'''
k"""
OOM"""""r   c                  &   t                      } t          | j                   | j        d n| j                            d          }t                      }t          | j        d          5 }|                    |	                                           d d d            n# 1 swxY w Y   t          |          }t          |          }|                    | j        | j        | j        | j        | j        | j        || j        | j        | j        
  
         d S )N;rb)r   r   r   rG   splitr   r   r>   ParseFromStringreadr   r   r   r6   rs   rt   ru   r   r   rd   rv   )r   rG   r   
input_filer   	optimizers         r   mainr   u  s;   D$,,444$:K:Q:QRU:V:VLLLE	dj$		 1:joo//0001 1 1 1 1 1 1 1 1 1 1 1 1 1 15!!J+J77I    s   )(BB!$B!__main__) r   r   r   rer   r   collectionsr   r   pathlibr   typingr   r   numpyr!   r&   r   r	   r
   r   r   r   	getLoggerr   r   r%   rD   r   r   r   r   rN   r   r   <module>r      s~     				 				 



                    ! ! ! ! ! ! ! !      6 6 6 6 6 6 6 6 6 6                		8	$	$3 4 o: o: o: o: o:) o: o: o:d	  (
# 
# 
#  6 zDFFFFF r   