
     NgTY                     X   d dl Z d dlZd dlZd dlmZ d dlmZmZmZ d dl	Z
d dlmZmZmZ d dlmZ dededed	ed
e
j        f
dZdededed
e
j        fdZdedefdZ	 d.dedededededed
e
j        fdZdedeee
j        f         fdZdededed	ededededededededefdZdededededededededededefdZd Z	 	 	 d/d ed!ee         d"ee         d#ee         d
eee
j                 ee
j                 ee
j                 f         f
d$Z	 	 	 d/d%ed!ee         d"ee         d#ee         d
eee
j                 ee
j                 ee
j                 f         f
d&Zd' Zd(ed)edededededed!ee         d"ee         d#ee         d*edededefd+Z d, Z!e"d-k    r e!             dS dS )0    N)Path)DictOptionalTuple)
ModelProtoTensorProtonumpy_helper)	OnnxModel	input_ids
batch_sizesequence_lengthdictionary_sizereturnc                    | j         j        j        t          j        t          j        t          j        fv sJ t          j        	                    |||ft          j
                  }| j         j        j        t          j        k    rt          j        |          }n3| j         j        j        t          j        k    rt          j        |          }|S )a`  Create input tensor based on the graph input of input_ids

    Args:
        input_ids (TensorProto): graph input of the input_ids input tensor
        batch_size (int): batch size
        sequence_length (int): sequence length
        dictionary_size (int): vocabulary size of dictionary

    Returns:
        np.ndarray: the input tensor created
    )sizedtype)typetensor_type	elem_typer   FLOATINT32INT64nprandomrandintint32float32int64)r   r   r   r   datas        c/var/www/html/ai-engine/env/lib/python3.11/site-packages/onnxruntime/transformers/bert_test_data.pyfake_input_ids_datar!      s     >%/4     9_J3PXZX`aaD~!+{/@@@z$		#	-1B	B	Bx~~K    segment_idsc                    | j         j        j        t          j        t          j        t          j        fv sJ t          j        ||ft          j	                  }| j         j        j        t          j        k    rt          j
        |          }n3| j         j        j        t          j        k    rt          j        |          }|S )a,  Create input tensor based on the graph input of segment_ids

    Args:
        segment_ids (TensorProto): graph input of the token_type_ids input tensor
        batch_size (int): batch size
        sequence_length (int): sequence length

    Returns:
        np.ndarray: the input tensor created
    r   )r   r   r   r   r   r   r   r   zerosr   r   r   )r#   r   r   r   s       r    fake_segment_ids_datar'   2   s     '16     8Z1BBBD#-1BBBz$			%	/;3D	D	Dx~~Kr"   max_sequence_lengthaverage_sequence_lengthc                     |dk    r|| k    sJ d|z  | k    rt          j        d|z  | z
  |           S t          j        dd|z  dz
            S )N      )r   r   )r(   r)   s     r    get_random_lengthr-   M   so    "a'',CGZ,Z,Z,Z,Z 	""%888~a"99<OOQdeee~a%<!<q!@AAAr"   r,   
input_maskrandom_sequence_length	mask_typec                 z   | j         j        j        t          j        t          j        t          j        fv sJ |dk    rbt          j        |t          j	                  }|r't          |          D ]}t          ||          ||<   nt          |          D ]}|||<   n|dk    rt          j        ||ft          j	                  }|r=t          |          D ]+}t          ||          }t          |          D ]	}	d|||	f<   
,nNt          j        ||ft          j	                  }
|
|d|
j        d         d|
j        d         f<   n	|dk    sJ t          j        |dz  dz   t          j	                  }|rt          |          D ]}t          ||          ||<   t          |dz             D ]X}|dk    r|||z   dz
           ||dz
           z   nd|||z   <   |dk    r|||z   dz
           ||dz
           z   nd|d|z  dz   |z   <   YnHt          |          D ]}|||<   t          |dz             D ]}||z  |||z   <   ||z  |d|z  dz   |z   <   | j         j        j        t          j        k    rt          j        |          }n3| j         j        j        t          j        k    rt          j        |          }|S )a"  Create input tensor based on the graph input of segment_ids.

    Args:
        input_mask (TensorProto): graph input of the attention mask input tensor
        batch_size (int): batch size
        sequence_length (int): sequence length
        average_sequence_length (int): average sequence length excluding paddings
        random_sequence_length (bool): whether use uniform random number for sequence length
        mask_type (int): mask type - 1: mask index (sequence length excluding paddings). Shape is (batch_size).
                                     2: 2D attention mask. Shape is (batch_size, sequence_length).
                                     3: key len, cumulated lengths of query and key. Shape is (3 * batch_size + 2).

    Returns:
        np.ndarray: the input tensor created
    r+   r%   r,   Nr      )r   r   r   r   r   r   r   r   onesr   ranger-   r&   shaper   r   )r.   r   r   r)   r/   r0   r   iactual_seq_lenjtemps              r    fake_input_mask_datar:   W   sV   0 ?&05     A~~w
28444! 	2:&& V V+O=TUUQV :&& 2 21Q2	ax_5RXFFF! 	::&& # #!2?D[!\!\~.. # #A!"DAJJ##
 7J(?@QQQD59D4:a=/DJqM/122A~~~~xa!+BH===! 	K:&& V V+O=TUUQ:>** f fQRUVQVQVtJNQ,>'?$q1u+'M'M\]Z!^$YZ]^Y^Y^tJNQ4F/G$qSTu+/U/UdeQ^a'!+,,f :&& 2 21Q:>** K K'(+B'BZ!^$/03J/JQ^a'!+,,",0AAAz$		$	.+2C	C	Cx~~Kr"   	directoryinputsc           	      b   t           j                            |           sL	 t          j        |            t	          d|  d           n6# t
          $ r t	          d|  d           Y nw xY wt	          d|  d           t          |                                          D ]\  }\  }}t          j	        ||          }t          t           j                            | d| d          d	          5 }|                    |                                           d
d
d
           n# 1 swxY w Y   d
S )zOutput input tensors of test data to a directory

    Args:
        directory (str): path of a directory
        inputs (Dict[str, np.ndarray]): map from input name to value
    z#Successfully created the directory  zCreation of the directory z failedzWarning: directory z$ existed. Files will be overwritten.input_.pbwbN)ospathexistsmkdirprintOSError	enumerateitemsr	   
from_arrayopenjoinwriteSerializeToString)r;   r<   indexnamer   tensorfiles          r    output_test_datarS      s    7>>)$$ U	FHY D	DDDEEEE  	C 	C 	CAyAAABBBBB	C
 	SISSSTTT(88 3 3|d(t44"',,y*=5*=*=*=>>EE 	3JJv//11222	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	33 3s#   A	 	A)(A)/(D##D'	*D'	
test_casesverboserandom_seedc           	         |J t           j                            |           t          j        |           g }t          |          D ]}t	          || ||          }|j        |i}|rt          || |          ||j        <   |rt          || ||	|
|          ||j        <   |r#t          |          dk    rt          d|           |
                    |           |S )a  Create given number of input data for testing

    Args:
        batch_size (int): batch size
        sequence_length (int): sequence length
        test_cases (int): number of test cases
        dictionary_size (int): vocabulary size of dictionary for input_ids
        verbose (bool): print more information or not
        random_seed (int): random seed
        input_ids (TensorProto): graph input of input IDs
        segment_ids (TensorProto): graph input of token type IDs
        input_mask (TensorProto): graph input of attention mask
        average_sequence_length (int): average sequence length excluding paddings
        random_sequence_length (bool): whether use uniform random number for sequence length
        mask_type (int): mask type 1 is mask index; 2 is 2D mask; 3 is key len, cumulated lengths of query and key

    Returns:
        List[Dict[str,numpy.ndarray]]: list of test cases, where each test case is a dictionary
                                       with input name as key and a tensor as value
    Nr   zExample inputs)r   r   seedr4   r!   rP   r'   r:   lenrF   append)r   r   rT   r   rU   rV   r   r#   r.   r)   r/   r0   
all_inputs
_test_caseinput_1r<   s                   r    fake_test_datar^      s	   D    INN;
KJJ'' " "
%i_o^^.'* 	g'<[*Ve'f'fF;#$ 	&:J9PRhjs' 'F:?#  	,s:!++"F+++&!!!!r"   rX   c                     d}t          | ||||||||||	|
          }t          |          |k    rt          d           |S )a  Create given number of input data for testing

    Args:
        batch_size (int): batch size
        sequence_length (int): sequence length
        test_cases (int): number of test cases
        seed (int): random seed
        verbose (bool): print more information or not
        input_ids (TensorProto): graph input of input IDs
        segment_ids (TensorProto): graph input of token type IDs
        input_mask (TensorProto): graph input of attention mask
        average_sequence_length (int): average sequence length excluding paddings
        random_sequence_length (bool): whether use uniform random number for sequence length
        mask_type (int): mask type 1 is mask index; 2 is 2D mask; 3 is key len, cumulated lengths of query and key

    Returns:
        List[Dict[str,numpy.ndarray]]: list of test cases, where each test case is a dictionary
                                       with input name as key and a tensor as value
    i'  z$Failed to create test data for test.)r^   rY   rF   )r   r   rT   rX   rU   r   r#   r.   r)   r/   r0   r   r[   s                r    generate_test_datar`      se    @ O J :*$$4555r"   c                    |t          |j                  k    rd S |j        |         }|                     |          }|C|                     ||          }|+|j        dk    r |                     |j        d                   }|S )NCastr   )rY   inputfind_graph_input
get_parentop_type)
onnx_model
embed_nodeinput_indexrc   graph_inputparent_nodes         r    get_graph_input_from_embed_noderl   %  s    c**++++t[)E--e44K ++JDD"{':f'D'D$55k6G6JKKKr"   rg   input_ids_namesegment_ids_nameinput_mask_namec                    |                                  }||                     |          }|t          d|           d}|r)|                     |          }|t          d|           d}|r)|                     |          }|t          d|           d|rdndz   |rdndz   }t          |          |k    r"t          d| dt          |                     |||fS t          |          dk    rt          dt          |                     |                     d	          }	t          |	          dk    rw|	d         }
t          | |
d          }t          | |
d          }t          | |
d
          }|$|D ]!}|j                                        }d|v r|}"|t          d          |||fS d}d}d}|D ]/}|j                                        }d|v r|}"d|v sd|v r|}-|}0|r	|r|r|||fS t          d          )a  Find graph inputs for BERT model.
    First, we will deduce inputs from EmbedLayerNormalization node.
    If not found, we will guess the meaning of graph inputs based on naming.

    Args:
        onnx_model (OnnxModel): onnx model object
        input_ids_name (str, optional): Name of graph input for input IDs. Defaults to None.
        segment_ids_name (str, optional): Name of graph input for segment IDs. Defaults to None.
        input_mask_name (str, optional): Name of graph input for attention mask. Defaults to None.

    Raises:
        ValueError: Graph does not have input named of input_ids_name or segment_ids_name or input_mask_name
        ValueError: Expected graph input number does not match with specified input_ids_name, segment_ids_name
                    and input_mask_name

    Returns:
        Tuple[Optional[np.ndarray], Optional[np.ndarray], Optional[np.ndarray]]: input tensors of input_ids,
                                                                                 segment_ids and input_mask
    Nz Graph does not have input named r+   r   zExpect the graph to have z inputs. Got r2   z'Expect the graph to have 3 inputs. Got EmbedLayerNormalization   maskz#Failed to find attention mask inputtokensegmentz?Fail to assign 3 inputs. You might try rename the graph inputs.)'get_graph_inputs_excluding_initializersrd   
ValueErrorrY   get_nodes_by_op_typerl   rP   lower)rg   rm   rn   ro   graph_inputsr   r#   r.   expected_inputsembed_nodesrh   rc   input_name_lowers                r    find_bert_inputsr~   2  s   4 EEGGL!//??	PPPQQQ 	X$556FGGK" !VDT!V!VWWW
 	W#44_EEJ! !UO!U!UVVVK6qqQ7
;Q11PQR|//jjjWZ[gWhWhjjkkk+z11
<AV3|CTCTVVWWW112KLLK
;1 ^
3J
ANN	5j*aPP4ZQOO
% ' '#(:#3#3#5#5 ---!&JBCCC+z11 IKJ 	 	 :++--%%%JJ'''98H+H+HKKII 2[ 2Z 2+z11
V
W
WWr"   	onnx_filec                     t                      }t          | d          5 }|                    |                                           ddd           n# 1 swxY w Y   t	          |          }t          ||||          S )a  Find graph inputs for BERT model.
    First, we will deduce inputs from EmbedLayerNormalization node.
    If not found, we will guess the meaning of graph inputs based on naming.

    Args:
        onnx_file (str): onnx model path
        input_ids_name (str, optional): Name of graph input for input IDs. Defaults to None.
        segment_ids_name (str, optional): Name of graph input for segment IDs. Defaults to None.
        input_mask_name (str, optional): Name of graph input for attention mask. Defaults to None.

    Returns:
        Tuple[Optional[np.ndarray], Optional[np.ndarray], Optional[np.ndarray]]: input tensors of input_ids,
                                                                                 segment_ids and input_mask
    rbN)r   rK   ParseFromStringreadr
   r~   )r   rm   rn   ro   modelrR   rg   s          r    get_bert_inputsr     s    ( LLE	i		 +$diikk***+ + + + + + + + + + + + + + + 5!!JJ8H/ZZZs   (AAAc                     t          j                    } |                     ddt          d           |                     ddt          d d           |                     d	dt          d
d           |                     ddt          dd           |                     ddt          d d           |                     ddt          d d           |                     ddt          d d           |                     ddt          d
d           |                     ddt          dd           |                     dddd           |                     d           |                     dddd            |                     d!           |                     d"d#d$t          d%&           |                     d'd(ddd)           |                     d*           |                     d+dt          d,d-           |                                 }|S ).Nz--modelTzbert onnx model path.)requiredr   helpz--output_dirFz4output test data path. Default is current directory.)r   r   defaultr   z--batch_sizer+   zbatch size of inputz--sequence_length   z maximum sequence length of inputz--input_ids_namezinput name for input idsz--segment_ids_namezinput name for segment idsz--input_mask_namezinput name for attention maskz	--samplesz$number of test cases to be generatedz--seedr2   zrandom seedz	--verbose
store_truezprint verbose information)r   actionr   )rU   z--only_input_tensorsz-only save input tensors and no output tensors)only_input_tensorsz-az--average_sequence_lengthz)average sequence length excluding padding)r   r   r   z-rz--random_sequence_lengthz3use uniform random instead of fixed sequence length)r/   z--mask_typer,   z^mask type: (1: mask index, 2: raw 2D mask, 3: key lengths, cumulated lengths of query and key))argparseArgumentParseradd_argumentstrintset_defaults
parse_args)parserargss     r    parse_argumentsr     s   $&&F
	DsAXYYY
C     S!Rghhh
/     '     )     ,     3     5sAMZZZ
(	     &&&
<	     5111
#8     "B     u555
m     DKr"   r   
output_dirr   c                    t          | |||	          \  }}}t          |||||||||||          }t          |          D ]E\  }}t          j                            |dt          |          z             }t          ||           F|
rdS ddl}d|	                                v rddgndg}|
                    | |          }d |                                D             }t          |          D ]\  }}t          j                            |dt          |          z             }|                    ||          }t          |          D ]\  }}t          j        t          j        ||                   |          }t#          t          j                            |d| d	          d
          5 }|                    |                                           ddd           n# 1 swxY w Y   dS )aI  Create test data for a model, and save test data to a directory.

    Args:
        model (str): path of ONNX bert model
        output_dir (str): output directory
        batch_size (int): batch size
        sequence_length (int): sequence length
        test_cases (int): number of test cases
        seed (int): random seed
        verbose (bool): whether print more information
        input_ids_name (str): graph input name of input_ids
        segment_ids_name (str): graph input name of segment_ids
        input_mask_name (str): graph input name of input_mask
        only_input_tensors (bool): only save input tensors,
        average_sequence_length (int): average sequence length excluding paddings
        random_sequence_length (bool): whether use uniform random number for sequence length
        mask_type(int): mask type
    test_data_set_Nr   CUDAExecutionProviderCPUExecutionProvider)	providersc                     g | ]	}|j         
S  )rP   ).0outputs     r    
<listcomp>z-create_and_save_test_data.<locals>.<listcomp>O  s    DDDFFKDDDr"   output_r@   rA   )r   r`   rH   rB   rC   rL   r   rS   onnxruntimeget_available_providersInferenceSessionget_outputsrunr	   rJ   r   asarrayrK   rM   rN   )r   r   r   r   rT   rX   rU   rm   rn   ro   r   r)   r/   r0   r   r#   r.   r[   r6   r<   r;   r   r   sessionoutput_namesresultoutput_nametensor_resultrR   s                                r    create_and_save_test_datar     s\   D *9P`bq)r)r&I{J# J z** , ,	6GLL-=A-FGG	F++++  #k&I&I&K&KKK 
!"899$% 
 **5I*FFGDDg.A.A.C.CDDDLz** > >	6GLL-=A-FGG	\622'55 	> 	>NA{(3BJvay4I4I;WWMbgll9.>.>.>.>??FF >$

=::<<===> > > > > > > > > > > > > > >	>> >s   ,(G  G$'G$c                  >   t                      } | j        dk    r| j        | _        | j        }|It	          | j                  }t          j                            |j	        d| j
         d| j                   }|'t	          |          }|                    dd           nt          d           t          | j        || j
        | j        | j        | j        | j        | j        | j        | j        | j        | j        | j        | j                   t          d|           d S )Nr   batch__seq_T)parentsexist_okz7Directory existed. test data files will be overwritten.z Test data is saved to directory:)r   r)   r   r   r   r   rB   rC   rL   parentr   rE   rF   r   samplesrX   rU   rm   rn   ro   r   r/   r0   )r   r   prC   s       r    mainr   Z  s    D#q(('+';$JW\\!(,aT_,a,a4K_,a,abb
J

4$
////GHHH
	$#  " 

,j99999r"   __main__)r,   )NNN)#r   rB   r   pathlibr   typingr   r   r   numpyr   onnxr   r   r	   rg   r
   r   ndarrayr!   r'   r-   boolr:   r   rS   r^   r`   rl   r~   r   r   r   r   __name__r   r"   r    <module>r      s    				        ( ( ( ( ( ( ( ( ( (     6 6 6 6 6 6 6 6 6 6            (+>ATWZ   <{  VY ^`^h    6B3 B B B B B  F FFF F !	F
 !F F ZF F F FR3 3T#rz/-B 3 3 3 3.777 7 	7
 7 7 7 7 7 !7 !7 7 7 7 7t111 1 	1
 1 1 1 1 !1 !1 1 1 1 1h
 
 
 %)&*%)	YX YXYXSMYX smYX c]	YX
 8BJ"*!5x
7KKLYX YX YX YX| %)&*%)	[ [[SM[ sm[ c]	[
 8BJ"*!5x
7KKL[ [ [ [8a a aHI>I>I> I> 	I>
 I> I> I> SMI> smI> c]I> I> !I> !I> I> I> I> I>X$: $: $:N zDFFFFF r"   