
    BVh!;                         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 Zd Zd	 Zd
 ZddZd Zd Zd ZddZd Zd Zd Zd Zd Zd Zd Zd Zd Zy)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                     t         j                  j                  | d      }t         j                  j	                  |      S )zBConverts a tflite model from a bytearray to an object for parsing.r   )	schema_fbModelGetRootAsModelModelTInitFromObj)model_bytearraymodel_objects     V/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/lite/tools/flatbuffer_utils.pyconvert_bytearray_to_objectr   &   s/    //C,				%	%l	33    c                     t        j                  |       st        d| z        t        j                  | d      5 }t	        |j                               }ddd       t        |      S # 1 sw Y   t              S xY w)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   s      r   
read_modelr   ,   so     
'	(
58II
JJ{{$d+ :/@ 1 6 6 89O:	"?	33:	"?	33s   A''A:c                    t        |       }t        j                  dk(  rt        |dd       |j                  D ]H  }|j
                  s| |j
                  |j
                  |j                  z    |_        d|_        d|_        J |j                  D ]Y  }|j                  D ]H  }|j                  s| |j                  |j                  |j                  z    |_        d|_
        d|_        J [ |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ops        r   r   r   @   s     &o
6%]]euh6  f}}#FMMFMMFKK4OPfkfmfk	
 // &h   &		$	$*''"*E*E''+(
 '(#$%!&& 
,r   c                 >    t        j                  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   s    r   read_model_with_mutable_tensorsr2   `   s    & 
z"34	55r   c                     t        j                  d      }| j                  |      }|j                  |t               t        |j                               }||z   }|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   s        r   convert_object_to_bytearrayr?   v   sV     %'""7+,	../F.G'..*+/#l2/	r   c                     t         j                  dk(  r"t        j                  |       } t	        | dd       t        |       }t        j                  |d      5 }|j                  |       ddd       y# 1 sw Y   yxY w)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    r0   r1   r!   r?   r   r   write)r   output_tflite_filer   output_file_handles       r   write_modelrE      si     	]]e==.L|UH=/=/{{%t, .0B_-. . .s   A22A;c                     d| _         | j                  D ]!  }d|_        |j                  D ]	  }d|_         # d| _        y)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-   tensors      r   strip_stringsrL      sL     %// hHM"" fk
 %r   c                 v    t         j                  j                  j                         D ]  \  }}|| k(  s|c S  y)z4Converts a numerical enum to a readable tensor type.N)r   
TensorType__dict__items)tensor_typerH   values      r   type_to_namerS      s<    ))2288: kdEk 
r   c                 8   t        j                  |       | j                  }t        dt	        |            }||D cg c]	  }||vs| }}i }| j
                  D ]c  }|j                  D ]R  }|j                    |j                  D ]3  }	|j                  |	   }
t        |
j                        ||
j                  <   5 T e |D ]  }||   j                  }|dn|j                  }|dk(  r(|j                  |d      }|j                  d      r]|dk(  rdnd}t        d|t!        j"                  |            D ]0  }t        j$                  d	d
      }t!        j&                  ||||       2 t        |      D ]  }t        j(                  dd      ||<     yc c}w )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.
     Nr   INT8FLOATFLOAT16efg      g      ?   )randomseedr"   rangelenr&   r'   inputsrI   rS   typer,   r%   r$   get
startswithstructcalcsizeuniform	pack_intorandint)r+   random_seedbuffers_to_skipr"   
buffer_idsidxbuffer_typesgraphr.   	input_idxrK   ibuffer_i_databuffer_i_sizebuffer_typeformat_coder#   rR   js                      r   randomize_weightsrv      s    	++k MM'QG%* !+J#s//I#JJJ, @eoo @		yy @)y)&26;;&?V]]#@@@  2aAJOOM&.AM4F4FM ""1f-Kg&&)3Ck!]FOOK,HI D&tS)mVUCD ]# 2!!>>!S1a2'2 Ks   	FFc                     | j                   D ]H  }|j                  s|j                  j                  d      }||v s0||   j                  d      |_        J y)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_strs       r   rename_custom_opsr      s[     $$ Pg&&--g6k	-	-2;?FFwO	Pr   c                     | j                   |   }t        |j                  |j                        }t	        t
        j                        j                         D ]  \  }}||k(  s|c S  y)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)ry   maxbuiltinCodedeprecatedBuiltinCodevarsr   BuiltinOperatorrP   )r+   r~   r.   coderH   rR   s         r   opcode_to_namer      sb     7#"	R^^R55	6$)334::< kdE}k 
r   c           	         t        j                  d      }t               }t        |       5 }|D ]m  }|j	                  |      }||j                  d      }t        d|j                  d            }|D cg c]  }t        |d       }	}|j                  |	       o 	 ddd       t        |      S c c}w # 1 sw Y   t        |      S xY w)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 ]+).*NrU   ,   )base)recompiler   openmatchgroupfiltersplitintextendr:   )
input_cc_filepatternr   file_handlelinevalues_match	list_textvalues_textxvaluess
             r   xxd_output_to_bytesr     s     JJ23'K/M %k %]]4(l		 $$Q'i 4!56k *55AAB5f5V$%%$ 
	 6%$ 
	s   A
B75B2	B72B77C
c                 .    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_bytess     r   xxd_output_to_objectr   /  s     $M2+	$[	11r   c           	      "   t        dt        | j                        |      D cg c]  }| j                  |||z     }}dj                  |D cg c](  }t        j                  ||      j                  ||      * c}      | _        yc c}w c c}w )z4Helper function for byte-swapping the buffers field.r   r   N)r^   r_   r%   joinr   
from_bytesto_bytes)r,   	chunksizefrom_endinessto_endinessrp   to_swapbyteswaps          r   byte_swap_buffer_contentr   @  s     QFKK()4
 kk!a)m$'  
 
nnX}-66y+N &+	s   B-Bc                 r   t         j                  | j                  dd |      }t        | j                  d|dz   z  d       }dj	                  t        d|dz   dz  dz   d      D cg c]8  }t         j                  | j                  ||dz    |      j                  d|      : c}      }||z   | _        yc c}w )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         Nr   rU   )r   r   r%   r   r   r^   r   )r,   r   r   num_of_stringsstring_contentrp   prefix_datas          r   byte_swap_string_contentr   L  s     >>&++a"2MB.V[[nq.@)A)CDE. Q!+q014a8	  
nnV[[QU+];DD
[ + n,&+s   %=B4c                 b   | y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 ]n  }|j                  dkD  s|j                  t!        | j"                        k  s7|j                  |vsF| j"                  |j                     j$                  j|j&                  t         j                  j(                  k(  r%t+        | j"                  |j                     ||       n|j&                  |v r&t-        | j"                  |j                     d||       nj|j&                  |v r&t-        | j"                  |j                     d||       n6|j&                  |v r&t-        | j"                  |j                     d||       nT|j/                  |j                         q  y)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   rN   rX   INT16UINT16FLOAT32INT32	COMPLEX64UINT32INT64FLOAT64
COMPLEX128UINT64r&   rI   r,   r_   r"   r%   ra   STRINGr   r   append)	r+   r   r   buffer_swappedtypes_of_16_bitstypes_of_32_bitstypes_of_64_bitsr-   rK   s	            r   r!   r!   _  s    ]
.""  !! ""  $$!!	   ""%%!!	 // -h"" -
--!
mmc%--00mm>1mmFMM*//;;;)..555
"mmFMM*M; [[,,
"mmFMM*A}k [[,,
"mmFMM*A}k [[,,
"mmFMM*A}k fmm,3--r   c                 N    | y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+   s       r   byte_swap_tflite_bufferr     s2     
%l
3% UM;? 
%U	++r   c                    t        | t        j                        st        |       } t	               }| j
                  D ]  }|j                  |j                  D ]q  }t        j                  | j                  |j                           }|t        j                  j                  k(  sM|j                  |j                  j                         s  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.
  )
isinstancer   r
   r   setr&   r'   r   #get_builtin_code_from_operator_codery   opcodeIndexr   
VAR_HANDLEaddbuiltinOptions
sharedNamer_   )r+   unique_shared_namesr-   r.   builtin_codes        r   count_resource_variablesr     s     
E9++	,'.E// >h!   > DD


bnn
-l 
22==	= 1 1 < <=>> 
 	!!r   )r   )r   N) __doc__r0   r\   r   rd   r   r5   tensorflow.lite.pythonr   r   r   tensorflow.python.platformr   r9   r   r   r   r2   r?   rE   rL   rS   rv   r   r   r   r   r   r   r!   r   r    r   r   <module>r      s      	  
  C . ,! 44(@6,.*.02fP$$ N2"	-&7-t,2"r   