o
    i e|4                     @   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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dZdd Zdd Zdd Zd)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dS )*zUtility 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)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   U/var/www/myenv/lib/python3.10/site-packages/tensorflow/lite/tools/flatbuffer_utils.pyconvert_bytearray_to_object&   s   r   c                 C   sp   t | std|  t | d}t| }W d   n1 s"w   Y  t|}tjdkr6t	|dd |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biglittle)
r   ExistsRuntimeErrorGFile	bytearrayreadr   sys	byteorderbyte_swap_tflite_model_obj)input_tflite_fileinput_file_handler
   modelr   r   r   
read_model,   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_tensorsC   s   r        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_bytearrayY   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   r   r   r-   r   r   write)r   output_tflite_filer
   output_file_handler   r   r   write_modeld   s   

"r2   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)description	subgraphsnametensorssignatureDefs)r   subgraphtensorr   r   r   strip_stringsy   s   


r:   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_typer5   valuer   r   r   type_to_name   s
   r@   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seedbuffersrangelenr4   	operatorsinputsr6   r@   typebufferdatasizeget
startswithstructcalcsizeuniform	pack_intorandint)r   random_seedrE   rP   
buffer_idsbuffer_typesgraphop	input_idxr9   ibuffer_i_databuffer_i_sizebuffer_typeformat_codeoffsetr?   jr   rD   r   randomize_weights   s>   







rm   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   
rv   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)ro   maxbuiltinCodedeprecatedBuiltinCodevarsr   BuiltinOperatorr=   )r   rt   rd   coder5   r?   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 ]+).*NrA   ,c                 S   s   g | ]}t |d dqS )   )base)int)rB   xr   r   r   rF     rG   z'xxd_output_to_bytes.<locals>.<listcomp>)
recompiler   openmatchgroupfiltersplitextendr(   )	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_object  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   )rW   )rB   rf   )rV   	chunksizer   r   rF   %  s    z,byte_swap_buffer_content.<locals>.<listcomp>r   r!   c                    s    g | ]}t | qS r   )r   
from_bytesto_bytes)rB   byteswap)r   from_endinessto_endinessr   r   rF   *  s    N)rQ   rR   rW   join)rV   r   r   r   to_swapr   )rV   r   r   r   r   byte_swap_buffer_content#  s   
r   c           	      C   s$  | 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 ]]}|jD ]W}|jdkr|jt| jk r|j|vr| j|j jdur|j|v ret| j|j d|| n#|j|v rvt| 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;   rJ   INT16UINT16FLOAT32INT32	COMPLEX64UINT32INT64FLOAT64
COMPLEX128UINT64r4   r6   rV   rR   rP   rW   rU   r   append)	r   r   r   buffer_swappedtypes_of_16_bitstypes_of_32_bitstypes_of_64_bitsr8   r9   r   r   r   r   3  sP   






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_bufferi  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   setr4   rS   r   #get_builtin_code_from_operator_codero   opcodeIndexr{   
VAR_HANDLEaddbuiltinOptions
sharedNamerR   )r   unique_shared_namesr8   rd   builtin_coder   r   r   count_resource_variables  s   	



r   )r!   )r   N)__doc__r   rN   r   r[   r   r#   tensorflow.lite.pythonr   r   r   tensorflow.python.platformr   r'   r   r   r    r-   r2   r:   r@   rm   rv   r}   r   r   r   r   r   r   r   r   r   r   <module>   s6   

3'6