o
    2hoB                     @   s>  d 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mZm	Z	m
Z
 ddlZddlmZ ddlmZ ddlmZ dZdd	 Zd
d Zdd Zdd Zd3ddZdd Zdd Zdd Zd4ddZdd Zdd Zdd  Zd!d" Zd#d$ Z d%d& Z!d'd( Z"d)d* Z#d+d, Z$e	d-Z%d.e
ej&ej'f d/ee% d0ee% fd1d2Z(dS )5zUtility functions for FlatBuffers.

All functions that are commonly used to work with FlatBuffers.

Refer to the tensorflow lite flatbuffer schema here:
tensorflow/lite/schema/schema.fbs
    N)OptionalTypeTypeVarUnion)schema_py_generated)schema_util)gfiles   TFL3c                 C   s   t j| d}t j|S )zBConverts a tflite model from a bytearray to an object for parsing.r   )	schema_fbModelGetRootAsModelModelTInitFromObj)model_bytearraymodel_object r   a/var/www/html/chatgem/venv/lib/python3.10/site-packages/tensorflow/lite/tools/flatbuffer_utils.pyconvert_bytearray_to_object'   s   r   c                 C   s\   t | std|  t | d}t| }W d   t|S 1 s%w   Y  t|S )a2  Reads a tflite model as a python object.

  Args:
    input_tflite_file: Full path name to the input tflite file

  Raises:
    RuntimeError: If input_tflite_file path is invalid.
    IOError: If input_tflite_file cannot be opened.

  Returns:
    A python object corresponding to the input tflite file.
  zInput file not found at %r
rbN)r   ExistsRuntimeErrorGFile	bytearrayreadread_model_from_bytearray)input_tflite_fileinput_file_handler   r   r   r   
read_model-   s   

r   c                 C   s   t | }tjdkrt|dd |jD ]}|jr)| |j|j|j  |_d|_d|_q|jD ]}|j	D ]}|j
rI| |j
|j
|j  |_d|_
d|_q2q-|S )zReads a tflite model as a python object.

  Args:
    model_bytearray: TFLite model in bytearray format.

  Returns:
    A python object corresponding to the input tflite file.
  biglittler   )r   sys	byteorderbyte_swap_tflite_model_objbuffersoffsetsizedata	subgraphs	operatorslargeCustomOptionsOffsetlargeCustomOptionsSizecustomOptions)r   modelbuffersubgraphopr   r   r   r   A   s,   	



	r   c                 C   s   t t| S )aC  Reads a tflite model as a python object with mutable tensors.

  Similar to read_model() with the addition that the returned object has
  mutable tensors (read_model() returns an object with immutable tensors).

  NOTE: This API only works for TFLite generated with
  _experimental_use_buffer_offset=false

  Args:
    input_tflite_file: Full path name to the input tflite file

  Raises:
    RuntimeError: If input_tflite_file path is invalid.
    IOError: If input_tflite_file cannot be opened.

  Returns:
    A mutable python object corresponding to the input tflite file.
  )copydeepcopyr   )r   r   r   r   read_model_with_mutable_tensorsa   s   r1       c                 C   s:   t d}| |}|j|td t| }|| }|S )z@Converts a tflite model from an object to a immutable bytearray.i   )file_identifier)flatbuffersBuilderPackFinish_TFLITE_FILE_IDENTIFIERbytesOutput)r   extra_bufferbuildermodel_offsetr   r   r   r   convert_object_to_bytearrayw   s   

r>   c                 C   sd   t jdkrt| } t| dd t| }t|d}|| W d   dS 1 s+w   Y  dS )as  Writes the tflite model, a python object, into the output file.

  NOTE: This API only works for TFLite generated with
  _experimental_use_buffer_offset=false

  Args:
    model_object: A tflite model as a python object
    output_tflite_file: Full path name to the output tflite file.

  Raises:
    IOError: If output_tflite_file path is invalid or cannot be opened.
  r   r   wbN)	r   r    r/   r0   r!   r>   r   r   write)r   output_tflite_filer   output_file_handler   r   r   write_model   s   

"rC   c                 C   s4   d| _ | jD ]}d|_|jD ]}d|_qqd| _dS )ay  Strips all nonessential strings from the model to reduce model size.

  We remove the following strings:
  (find strings by searching ":string" in the tensorflow lite flatbuffer schema)
  1. Model description
  2. SubGraph name
  3. Tensor names
  We retain OperatorCode custom_code and Metadata name.

  Args:
    model: The model from which to remove nonessential strings.
  N)descriptionr&   nametensorssignatureDefs)r+   r-   tensorr   r   r   strip_strings   s   


rI   c                 C   s*   t jj D ]\}}|| kr|  S qdS )z4Converts a numerical enum to a readable tensor type.N)r	   
TensorType__dict__items)tensor_typerE   valuer   r   r   type_to_name   s
   rO   c                    s6  t | | j}tdt|} dur fdd|D }i }| jD ]"}|jD ]}|jdu r/ n|jD ]}|j| }	t	|	j
||	j< q2q&q!|D ]R}
||
 j}|du rSdn|j}|dkr[qF||
d}|dr|dkrld	nd
}td|t|D ]}t dd}t|||| qwqFt|D ]
}t dd||< qqFdS )a  Randomize weights in a model.

  Args:
    model: The model in which to randomize weights.
    random_seed: The input to the random number generator (default value is 0).
    buffers_to_skip: The list of buffer indices to skip. The weights in these
      buffers are left unmodified.
     Nc                    s   g | ]}| vr|qS r   r   ).0idxbuffers_to_skipr   r   
<listcomp>       z%randomize_weights.<locals>.<listcomp>r   INT8FLOATFLOAT16efg      g      ?   )randomseedr"   rangelenr&   r'   inputsrF   rO   typer,   r%   r$   get
startswithstructcalcsizeuniform	pack_intorandint)r+   random_seedrT   r"   
buffer_idsbuffer_typesgraphr.   	input_idxrH   ibuffer_i_databuffer_i_sizebuffer_typeformat_coder#   rN   jr   rS   r   randomize_weights   s>   







ru   c                 C   s:   | j D ]}|jr|jd}||v r|| d|_qdS )zRename custom ops so they use the same naming style as builtin ops.

  Args:
    model: The input tflite model.
    map_custom_op_renames: A mapping from old to new custom op names.
  asciiN)operatorCodes
customCodedecodeencode)r+   map_custom_op_renamesop_codeop_code_strr   r   r   rename_custom_ops   s   
r~   c                 C   sD   | j | }t|j|j}ttj D ]\}}||kr|  S qdS )zConverts a TFLite op_code to the human readable name.

  Args:
    model: The input tflite model.
    op_code: The op_code to resolve to a readable name.

  Returns:
    A string containing the human readable op name, or None if not resolvable.
  N)rw   maxbuiltinCodedeprecatedBuiltinCodevarsr	   BuiltinOperatorrL   )r+   r|   r.   coderE   rN   r   r   r   opcode_to_name   s   

r   c           	      C   s   t d}t }t| 3}|D ]%}||}|du rq|d}td|d}dd |D }|| qW d   t	|S 1 sBw   Y  t	|S )a@  Converts xxd output C++ source file to bytes (immutable).

  Args:
    input_cc_file: Full path name to th C++ source file dumped by xxd

  Raises:
    RuntimeError: If input_cc_file path is invalid.
    IOError: If input_cc_file cannot be opened.

  Returns:
    A bytearray corresponding to the input cc file array.
  z\W*(0x[0-9a-fA-F,x ]+).*NrP   ,c                 S   s   g | ]}t |d dqS )   )base)int)rQ   xr   r   r   rU   *  rV   z'xxd_output_to_bytes.<locals>.<listcomp>)
recompiler   openmatchgroupfiltersplitextendr9   )	input_cc_filepatternr   file_handlelinevalues_match	list_textvalues_textvaluesr   r   r   xxd_output_to_bytes	  s    




r   c                 C   s   t | }t|S )a7  Converts xxd output C++ source file to object.

  Args:
    input_cc_file: Full path name to th C++ source file dumped by xxd

  Raises:
    RuntimeError: If input_cc_file path is invalid.
    IOError: If input_cc_file cannot be opened.

  Returns:
    A python object corresponding to the input tflite file.
  )r   r   )r   model_bytesr   r   r   xxd_output_to_object0  s   r   c                    sD    fddt dt jD }dfdd|D  _dS )z4Helper function for byte-swapping the buffers field.c                    s   g | ]} j ||  qS r   )r%   rQ   ro   )r,   	chunksizer   r   rU   C  s    z,byte_swap_buffer_content.<locals>.<listcomp>r   r2   c                    s    g | ]}t | qS r   )r   
from_bytesto_bytes)rQ   byteswap)r   from_endinessto_endinessr   r   rU   G  s    N)r_   r`   r%   join)r,   r   r   r   to_swapr   )r,   r   r   r   r   byte_swap_buffer_contentA  s   r   c                    sn   t  jdd }t jd|d  d }d fddtd|d d d dD }||  _dS )	a  Helper function for byte-swapping the string buffer.

  Args:
    buffer: TFLite string buffer of from_endiness format.
    from_endiness: The original endianness format of the string buffer.
    to_endiness: The destined endianness format of the string buffer.
  r         Nr2   c                    s.   g | ]}t  j||d   d qS )r   )r   r   r%   r   r   r,   r   r   r   r   rU   W  s    z,byte_swap_string_content.<locals>.<listcomp>rP   )r   r   r%   r   r   r_   )r,   r   r   num_of_stringsstring_contentprefix_datar   r   r   byte_swap_string_contentM  s   r   c           	      C   sH  | du rdS g }t jjt jjt jjg}t jjt jjt jjt jjg}t jj	t jj
t jjt jjg}| jD ]o}|jD ]i}|jdkr|jt| jk r|j|vr| j|j jdur|jt jjkrft| j|j || n4|j|v rwt| j|j d|| n#|j|v rt| j|j d|| n|j|v rt| j|j d|| nq7||j q7q2dS )a  Byte swaps the buffers field in a TFLite model.

  Args:
    model: TFLite model object of from_endiness format.
    from_endiness: The original endianness format of the buffers in model.
    to_endiness: The destined endianness format of the buffers in model.
  Nr   r   r      )r	   rJ   rY   INT16UINT16FLOAT32INT32	COMPLEX64UINT32INT64FLOAT64
COMPLEX128UINT64r&   rF   r,   r`   r"   r%   rb   STRINGr   r   append)	r+   r   r   buffer_swappedtypes_of_16_bitstypes_of_32_bitstypes_of_64_bitsr-   rH   r   r   r   r!   `  sX   






r!   c                 C   s(   | du rdS t | }t||| t|S )a  Generates a new model byte array after byte swapping its buffers field.

  Args:
    tflite_model: TFLite flatbuffer in a byte array.
    from_endiness: The original endianness format of the buffers in
      tflite_model.
    to_endiness: The destined endianness format of the buffers in tflite_model.

  Returns:
    TFLite flatbuffer in a byte array, after being byte swapped to to_endiness
    format.
  N)r   r!   r>   )tflite_modelr   r   r+   r   r   r   byte_swap_tflite_buffer  s
   r   c                 C   sr   t | tjs
t| } t }| jD ]$}|jdu rq|jD ]}t| j	|j
 }|tjjkr3||jj qqt|S )zCalculates the number of unique resource variables in a model.

  Args:
    model: the input tflite model, either as bytearray or object.

  Returns:
    An integer number representing the number of unique resource variables.
  N)
isinstancer	   r   r   setr&   r'   r   #get_builtin_code_from_operator_coderw   opcodeIndexr   
VAR_HANDLEaddbuiltinOptions
sharedNamer`   )r+   unique_shared_namesr-   r.   builtin_coder   r   r   count_resource_variables  s   	



r   OptsTr.   	opts_typereturnc                 C   s   t d| }|j}|ds||d}ttj|}|s&ttj|s&|t| tj	r`|s@t
tj|}tj}|  }|  }	nt
tj|}tj}|  }|  }	|du sY|	|kr[dS |||S t| tjr||rl| j}
n| j}
|
du sxt|
|szdS |
S dS )a  Get the options of an operator as the specified type.

  Requested type must be an object-api type (ends in 'T').

  Args:
    op: The operator to get the options from.
    opts_type: The type of the options to get.

  Returns:
    The options as the specified type, or None if the options are not of the
    specified type.

  Raises:
    ValueError: If the specified type is not a valid options type.
  zUnsupported options type: TN)
ValueError__name__endswithremovesuffixhasattrr	   BuiltinOptionsBuiltinOptions2r   OperatorgetattrBuiltinOptions2CreatorBuiltinOptions2TypeBuiltinOptionsCreatorBuiltinOptionsType	OperatorTr   builtinOptions2)r.   r   err	type_namebase_type_nameis_opt_1_typeenum_valopts_creatorraw_opsactual_enum_val	raw_ops_tr   r   r   get_options_as  s>   



r   )r2   )r   N))__doc__r/   r]   r   re   r   typingr   r   r   r   r4   tensorflow.lite.pythonr   r	   r   tensorflow.python.platformr   r8   r   r   r   r1   r>   rC   rI   rO   ru   r~   r   r   r   r   r   r!   r   r   r   r   r   r   r   r   r   r   <module>   sL    

3':