
    fPi:                        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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)
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         dz  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     |/home/jaya/work/projects/VOICE-AGENT/VIET/agent-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   r0   outputsr2   s       r   get_shape_outputsz-BertOnnxModelShapeOptimizer.get_shape_outputs9   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   r1   r2   r3   r5   input)r   shape_inputsr2   s      r   get_reshape_shape_inputsz4BertOnnxModelShapeOptimizer.get_reshape_shape_inputsG   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.
        r9   r   Reshape_Inputr/   )inputsr6   )r   r1   r2   r3   r<   r"   RESHAPE_INPUT_SHAPE_PREFIXr$   r%   	make_noder5   	add_nodes)r   output_namesnodes_to_addr2   r<   output_name
shape_nodes          r   add_shape_for_reshape_inputz7BertOnnxModelShapeOptimizer.add_shape_for_reshape_inputT   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   .0r4   s     r   
<listcomp>zFBertOnnxModelShapeOptimizer.add_extra_graph_output.<locals>.<listcomp>k   s    JJJJJJr   )
r   r1   r4   get_initializerr5   r$   r%   ValueInfoProtor   extend)r   extra_outputsnames_to_evaluaterE   r   output_infos         r   add_extra_graph_outputz2BertOnnxModelShapeOptimizer.add_extra_graph_outputf   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   r1   r<   r   typetensor_typer(   dimr[   HasField
ValueError)r   rA   
batch_sizemax_seq_lenr<   	dim_protos         r   use_static_inputz,BertOnnxModelShapeOptimizer.use_static_inputz   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:   ri   )r   randomrandintint32oneszerosfloat32r!   )r   	input_idssegment_ids
input_maskrb   sequence_length	elem_typedictionary_sizeinput_1input_2input_3rA   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)	providersri   zshapes=)"bert_inputsrS   r7   r>   rI   lenrW   re   openwriter   SerializeToStringonnxruntimeSessionOptionsGraphOptimizationLevelORT_DISABLE_ALLgraph_optimization_levelInferenceSessionr1   r<   r   r]   r^   ru   rz   run	enumerateloggerdebugupdate_target_shapeitemsr-   replace_input_of_all_nodesprune_graph)r   temp_model_pathrq   rr   rs   rE   rb   rt   enable_shape_optenable_reshape_optverboserT   reshape_shape_inputsreshape_input_shapesrU   outsess_optionssessionru   r<   rA   r6   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=)rQ   r   to_arrayr   r   r5   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 rL   rM   )rO   r<   s     r   rP   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   r1   r<   	Exception)r   r<   valid_namess      r   validate_inputz*BertOnnxModelShapeOptimizer.validate_input  s`    $$U++ 	`JJ4:3C3IJJJK^U^^Q\^^___	` 	`r   rE   c                 x    d | j         j        j        D             }|D ]}||vrt          d| d|           d S )Nc                     g | ]	}|j         
S rL   rM   rN   s     r   rP   z@BertOnnxModelShapeOptimizer.validate_outputs.<locals>.<listcomp>  s    IIIvv{IIIr   zOutput z& does not exist in the graph outputs: )r   r1   r4   r   )r   rE   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_pathrq   rr   rs   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 rL   rM   rN   s     r   rP   z8BertOnnxModelShapeOptimizer.optimize.<locals>.<listcomp>2  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   r1   r   r   
startswithr#   r   infor   r   r   r4   r   'get_graph_inputs_excluding_initializerstempfileTemporaryDirectoryformatr   nowstrftimeospathjoinr   r   warningr   r   r   )r   r   rq   rr   rs   r   r   rE   rb   rt   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:   rX   )rf   )Nr:   rX   F)__name__
__module____qualname____doc__r   r-   r7   r>   rI   rW   re   rz   r   r   strr   listr   boolr   __classcell__)r   s   @r   r   r   !   s        
+ + + + +        $! ! !(   0    BB' B' B'Hw w w:`C ` ` ` `
eT#Y e e e e *.9: 9:9: 9: 	9:
 9: 9: !9: 3i$&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_lengthrX   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   S  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   g  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   rE   splitr   r   r<   ParseFromStringreadr	   r   r   r4   rq   rr   rs   r   r   rb   rt   )r   rE   r   
input_filer   	optimizers         r   mainr   t  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   numpyr   r$   r   r   r   r   r	   r   	getLoggerr   r   r#   rB   r   r   r   r   rL   r   r   <module>r      sf     				 				 



                         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   