a
    Sic6                     @   s  d Z ddlZddlZddlZddlmZ ddlZddlmZ ddl	Z	ddl
mZ ddl
mZ ddl
mZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm Z! ddlm"Z" ddlm#Z$ ddlm%Z& ddl'm(Z( ddl)m*Z+ dZ,ej-Z-ej.Z.zddl/m0Z1 W n e2yH   dZ1Y n0 e"j3e"j4e"j5e"j6e"j7e"j8e"j9e"j:e"j;e"j<e"j=e"j>e"j?dZ@dZAe"j<e"j<e"j6he"j:e"j:hiZBdd ZCdd ZDdd ZEd d! ZFd"d# ZGd$d% ZHdXd&d'ZId(d) ZJd*d+ ZKd,d- ZLd.d/ ZMd0d1 ZNd2d3 ZOdYd6d7ZPd8d9 ZQd:d; ZRd<d= ZSd>d? ZTd@dA ZUdBdC ZVe"j3fdDdEZWdFdG ZXe"j3fdHdIZYdJdK ZZdLdM Z[dNdO Z\e"j3e"j3fdPdQZ]dRdS Z^dTdU Z_dVdW Z`dS )Zz+Functions used by multiple converter files.    N)logging)range)
config_pb2)graph_debug_info_pb2)meta_graph_pb2)'conversion_metadata_schema_py_generated)schema_py_generated)schema_util)tflite_keras_util)convert_op_hints_to_stubs)find_all_hinted_output_nodes)flatbuffer_utils)function)convert_to_constants)dtypes)error_interpolation)
graph_util)tf_optimizer)export_meta_graphZCONVERSION_METADATA)xla_computation)r                           	   
         s   TFL3c                 C   s&   t | }|du r"td| t |S )a  Converts tflite enum type (eg: 0) to tf type (eg: tf.float32).

  Args:
    tflite_enum_type: tflite enum type (eg: 0, that corresponds to float32)

  Raises:
    ValueError: If an invalid tflite enum type is provided.

  Returns:
    tf type (eg: tf.float32)
  Nz>Unsupported enum {}. The valid map of enum to tf types is : {})_MAP_TFLITE_ENUM_TO_TF_TYPESget
ValueErrorformat)Ztflite_enum_typetf_type r'   W/var/www/html/django/DPS/env/lib/python3.9/site-packages/tensorflow/lite/python/util.py$_convert_tflite_enum_type_to_tf_typeV   s    
r)   c                 C   s   | rd| j  S dS )z=Converts tf.dtype (eg: tf.float32) to str (eg: "tf.float32").ztf.N)name)r&   r'   r'   r(   get_tf_type_namej   s    r+   c                 C   sZ   t | jd}t|dkr4tdt|d t|dkrR|d dkrR| jS |d S )zWReturns name of the input tensor.

  Args:
    tensor: tf.Tensor

  Returns:
    str
  :r   z1Tensor name invalid. Expect 0 or 1 colon, got {0}r   0r   )six
ensure_strr*   splitlenr$   r%   )tensorpartsr'   r'   r(   get_tensor_nameo   s    	
r4   c                 C   s   i }|   D ]}| D ]}||t|< qqg }g }|D ]L}t|tjs\tdt|||	|}|du rz|
| q8|
| q8|rtdd||S )ae  Gets the Tensors associated with the `tensor_names` in the provided graph.

  Args:
    graph: TensorFlow Graph.
    tensor_names: List of strings that represent names of tensors in the graph.

  Returns:
    A list of Tensor objects in the same order the names are provided.

  Raises:
    ValueError:
      tensor_names contains an invalid tensor name.
  zInvalid type for a tensor name in the provided graph. Expected type for a tensor name is 'str', instead got type '{}' for tensor name '{}'Nz Invalid tensors '{}' were found.,)get_operationsvaluesr4   
isinstancer.   string_typesr$   r%   typer#   appendjoin)graphtensor_namesZtensor_name_to_tensoropr2   tensorsZinvalid_tensorsr*   r'   r'   r(   get_tensors_from_tensor_names   s(    
rA   c                 C   s   |rdd | D }|  D ]\}}||vr8td||dur|| }z|| W q ty } z*d||j|t|}t|W Y d}~qd}~0 0 qdS )a  Sets Tensor shape for each tensor if the shape is defined.

  Args:
    tensors: TensorFlow ops.Tensor.
    shapes: Dict of strings representing input tensor names to list of
      integers representing input shapes (e.g., {"foo": : [1, 16, 16, 3]}).

  Raises:
    ValueError:
      `shapes` contains an invalid tensor.
      `shapes` contains an invalid shape for a valid tensor.
  c                 S   s   i | ]}t ||qS r'   r4   .0r2   r'   r'   r(   
<dictcomp>   s   z%set_tensor_shapes.<locals>.<dictcomp>z/Invalid tensor '{}' found in tensor shapes map.Nz@The shape of tensor '{0}' cannot be changed from {1} to {2}. {3})itemsr$   r%   	set_shapeshapestr)r@   shapesZtensor_names_to_tensorr*   rH   r2   errormessager'   r'   r(   set_tensor_shapes   s$    rM   c                 C   s*   t  }|jj}| D ]}|j| q|S )zCreates a tf.compat.v1.ConfigProto for configuring Grappler.

  Args:
    optimizers_list: List of strings that represents the list of optimizers.

  Returns:
    tf.ConfigProto.
  )_config_pb2ConfigProtograph_optionsrewrite_options
optimizersr;   )Zoptimizers_listconfigrQ   	optimizerr'   r'   r(   get_grappler_config   s
    	rU   c           	      C   s   t | |d}t }|D ]@}|j|j|j _|jj|j|j _|j|j j|j	
  q|D ]@}|j|j|j _|jj|j|j _|j|j j|j	
  q^|jd | t }|| D ]}|jj|j q|jd | t||S )a  Apply standard TensorFlow optimizations to the graph_def.

  Args:
    graph_def: Frozen GraphDef to be optimized.
    input_arrays: List of arrays that are considered inputs of the graph.
    output_arrays: List of arrays that are considered outputs of the graph.
    config: tf.ConfigProto.
    graph: TensorFlow Graph. Required when Eager mode is enabled. (default None)

  Returns:
    A new, optimized GraphDef.
  )	graph_defr=   Znot_used_keytrain_op)_export_meta_graph_meta_graph_pb2SignatureDefr*   inputsdtypeas_datatype_enumtensor_shapeCopyFromrH   as_protooutputssignature_defCollectionDef	node_listvaluer;   collection_defr   OptimizeGraph)	rV   input_arraysoutput_arraysrS   r=   
meta_graph	signaturearrayfetch_collectionr'   r'   r(   run_graph_optimizations   s     rn   c                 C   s>   t | rtddd |D }t| ||| }t|d}|S )Nz.Try to convert op hints, needs unfrozen graph.c                 S   s   g | ]}t |qS r'   rB   rC   r'   r'   r(   
<listcomp>      z0_convert_op_hints_if_present.<locals>.<listcomp>)rV   )is_frozen_graphr$   tf_graph_utilconvert_variables_to_constantsr   )sessrV   output_tensorshinted_outputs_nodesri   r'   r'   r(   _convert_op_hints_if_present  s    

rw   c                 C   sr   t | j}tdg}t||||| jd}t| }|rDt| |||S t| shdd |D }t	
| ||S | jS dS )a  Returns a frozen GraphDef.

  Runs a Grappler pass and freezes a graph with Variables in it. Otherwise the
  existing GraphDef is returned. The Grappler pass is only run on models that
  are frozen in order to inline the functions in the graph.
  If OpHints is present, it will try to convert the OpHint graph.

  Args:
    sess: TensorFlow Session.
    input_tensors: List of input tensors.
    output_tensors: List of output tensors (only .name is used from this).

  Returns:
    Frozen GraphDef.
  r   )r=   c                 S   s   g | ]}|j d d qS )r,   r   )r*   r0   rC   r'   r'   r(   ro   4  rp   z freeze_graph.<locals>.<listcomp>N)_convert_to_constants disable_lower_using_switch_mergerV   rU   rn   r=   r   rw   rq   rr   rs   )rt   input_tensorsru   rV   rS   rv   output_node_namesr'   r'   r(   freeze_graph  s$    
r|   c                 C   s>   | j  D ].}t|jds2t|jdr
 dS q
dS )zDetermines if the graph is frozen.

  Determines if a graph has previously been frozen by checking for any
  operations of type Variable*. If variables are found, the graph is not frozen.

  Args:
    sess: TensorFlow Session.

  Returns:
    Bool.
  VariableZ
VariableOpFT)r=   r6   r.   r/   r:   
startswithendswith)rt   r?   r'   r'   r(   rq   ;  s    rq   c                    s    fdd}|S )a=  Returns a method to retrieve the `GraphDebugInfo` from the original graph.

  Args:
    original_graph: The original `Graph` containing all the op stack traces.

  Returns:
    A function which retrieves the stack traces from the original graph and
    converts them to a `GraphDebugInfo` for a given set of nodes.
  c              	      s    sdS g }| D ]|\}}z\|s4| | |f n> |}t|tjrb| ||j|f ntj	d W qW q t
y   Y qY q0 qt|S )CFunction to create `GraphDebugInfo` for the given `original_nodes`.Nz9Use '@tf.function' or '@defun' to decorate the function.
)r;   get_operation_by_name_get_functionr8   r   _EagerDefinedFunctionr=   sysstderrwriteKeyError_error_interpolationcreate_graph_debug_info_def)original_nodesZ
useful_opsfuncr*   Zsub_funcoriginal_graphr'   r(   fY  s&    
z build_debug_info_func.<locals>.fr'   )r   r   r'   r   r(   build_debug_info_funcN  s    r   c                    s    fdd}|S )a:  Returns a method to retrieve the `GraphDebugInfo` from the original graph.

  Args:
    saved_debug_info: The `GraphDebugInfo` containing all the debug info.

  Returns:
    A function which retrieves the stack traces from the original graph and
    converts them to a `GraphDebugInfo` for a given set of nodes.
  c                    sT    sdS t  } j|jdd< | D ]*\}}|d | }|j|  j|  q$|S )r   N@)r   GraphDebugInfofilestracesr_   )r   output_debug_infor   nodeZ	debug_keysaved_debug_infor'   r(   r     s    
z"convert_debug_info_func.<locals>.fr'   )r   r   r'   r   r(   convert_debug_info_funcu  s    r   c                 C   s   | sdS t  }|jD ]f}|jj}|jj}|s>|d|jf qtt|D ].}|t|kr^dn|| }|||| f qJq| |S )aI  Returns the debug info for the original nodes in the `converted_graph`.

  Args:
    nodes_to_debug_info_func: The method to collect the op debug info for the
      nodes.
    converted_graph: A `GraphDef` after optimization and transformation.

  Returns:
    `GraphDebugInfo` for all the original nodes in `converted_graph`.
  N )	setr   experimental_debug_infooriginal_node_namesoriginal_func_namesaddr*   r   r1   )Znodes_to_debug_info_funcconverted_graphr   r   Zdebug_nodesZdebug_funcsiZ
debug_funcr'   r'   r(   get_debug_info  s    
r   P   Fc                 C   s   d}g }|}t | D ]4}	t|d |kr:||d  |}|d|	f 7 }qt|t|krh||d  d|}
|du rd|  d }|durd	j|d
}nd}|rdjtj j	d}nd}d}|j|t| |
||d}d}|j|||d}||fS )a  Returns strings representing a C constant array containing `data`.

  Args:
    data: Byte array that will be converted into a C constant.
    array_name: String to use as the variable name for the constant array.
    max_line_width: The longest line length, for formatting purposes.
    include_guard: Name to use for the include guard macro definition.
    include_path: Optional path to include in the source file.
    use_tensorflow_license: Whether to include the standard TensorFlow Apache2
      license in the generated files.

  Returns:
    Text that can be compiled as a C source file to link in the data as a
    literal array of values.
    Text that can be used as a C header file to reference the literal array.
  z   r   
z 0x%02x,r   NZTENSORFLOW_LITE_UTIL_Z_DATA_H_z#include "{include_path}"
)include_patha  
/* Copyright {year} The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
)yeara  {license_text}
// This is a TensorFlow Lite model file that has been converted into a C data
// array using the tensorflow.lite.util.convert_bytes_to_c_source() function.
// This form is useful for compiling into a binary for devices that don't have a
// file system.

{include_line}
// We need to keep the data array aligned on some architectures.
#ifdef __has_attribute
#define HAVE_ATTRIBUTE(x) __has_attribute(x)
#else
#define HAVE_ATTRIBUTE(x) 0
#endif
#if HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__))
#define DATA_ALIGN_ATTRIBUTE __attribute__((aligned(4)))
#else
#define DATA_ALIGN_ATTRIBUTE
#endif

const unsigned char {array_name}[] DATA_ALIGN_ATTRIBUTE = {{
{array_values}}};
const int {array_name}_len = {array_length};
)
array_nameZarray_lengtharray_valueslicense_textinclude_linea  
{license_text}

// This is a TensorFlow Lite model file that has been converted into a C data
// array using the tensorflow.lite.util.convert_bytes_to_c_source() function.
// This form is useful for compiling into a binary for devices that don't have a
// file system.

#ifndef {include_guard}
#define {include_guard}

extern const unsigned char {array_name}[];
extern const int {array_name}_len;

#endif  // {include_guard}
)r   include_guardr   )
	bytearrayr1   r;   r<   upperr%   datetimedatetodayr   )datar   max_line_widthr   r   Zuse_tensorflow_licenseZstarting_padarray_linesZ
array_linere   r   r   r   Zsource_templatesource_textZheader_templateZheader_textr'   r'   r(   convert_bytes_to_c_source  sL    

r   c                 C   s(   t j| d}t j|}t|}|S )z@Converts a tflite model from a bytearray into a parsable object.r   )	schema_fbModelZGetRootAsModelZModelTInitFromObjcopydeepcopy)Zmodel_bytearraymodel_objectr'   r'   r(   '_convert_model_from_bytearray_to_object)  s    
r   c                 C   s.   t d}| |}|j|td t| S )z@Converts a tflite model from a parsable object into a bytearray.i   )Zfile_identifier)flatbuffersBuilderPackFinish_TFLITE_FILE_IDENTIFIERbytesOutput)r   builderZmodel_offsetr'   r'   r(   '_convert_model_from_object_to_bytearray1  s    

r   c                 C   s<   g }t | jD ](\}}t|}|tjjkr|| q|S zReturns the quantize op idx.)	enumerateoperatorCodesr	   #get_builtin_code_from_operator_coder   BuiltinOperatorQUANTIZEr;   modelquant_opcode_idxsidxopcodebuiltin_coder'   r'   r(   get_quantize_opcode_idx:  s    
r   c                 C   s<   g }t | jD ](\}}t|}|tjjkr|| q|S r   )r   r   r	   r   r   r   Z
DEQUANTIZEr;   r   r'   r'   r(   get_dequantize_opcode_idxD  s    
r   c                 C   s8   t t| D ]&}| | j|v r|| | j | | _qdS )z4Update the tensors in the SignatureDef's TensorMaps.N)r   r1   tensorIndex)Ztensor_mapsZmap_old_to_new_tensorsr   r'   r'   r(   _update_signature_def_tensorsN  s    r   c           
         s^  |sdS t | jdkr$td dS | jd }|j}|j}td| t|t |t | krxtd |t|d= ntd i  d}tt |D ]"}||v r|d7 }q||  |< qtd 	   fd	d
}||j
 ||j |D ]}||j
 ||j q| jr2| jd }	t|	j
  t|	j  t|ddD ]}|| q>td dS )zRemove tensors from model.Nr   zSkipping the removal of dangled tensors since the model has multiple subgraphs and tensors can be used in the different subgraph(s)r   z Removing tensors at indices : %sz3Removing tensors only at the end of the tensor listz,Removing tensors requires updating the modelzOld to new tensors map: %sc                    s&   t | D ]\}} |d| |< qd S )N)r   r#   )Ztensor_idxsr   tiZd_old_to_new_tensorsr'   r(   update_tensorsu  s    z2_remove_tensors_from_model.<locals>.update_tensorsT)reversez#Removed tensors marked for deletion)r1   	subgraphsr   infor@   	operatorsdebugminr   __str__r[   ra   signatureDefsr   sortedpop)
r   remove_tensors_idxssubgraphr@   r   Zleft_shift_byr   r   r?   rb   r'   r   r(   _remove_tensors_from_modelV  sB    








r   c                 C   sN   |t jkrdS | js&t| dd| dS t| jD ]\}}t| |j|| q0dS )zModify model input type.Nr   r   )r   float32r   %_modify_model_input_type_per_subgraphr   subgraphIndex)r   inference_input_typesignature_indexrb   r'   r'   r(   _modify_model_input_type  s    
r   c              	   C   s  | j | }|j}|j}t| }|rV|sV|jD ]$}t|| j}	|	tjkr,t	dq,dS g }
|D ]}|j
|v r^|jd |jv r^||jd  ||jd   }}t|j}|tjkr||krq^nt	d|jt|t|j}|tvrt	d|jtdd t D t|n4t| }||vrDt	dtd	d |D t||
| q^t|jt|
krntd
 |tjkr|
D ]b}||jd  j}t }|jd g|_|jd d g|_|||jd  _tjj||jd  _q~n|tv rt }|
D ]}|jd |j|j|jd k< |dkrl| j| }t t|jD ]0}|j| j!|jd kr:|jd |j| _!q:|"|jd  |#| qt$| | nt	dt|dS )z%Modify model input type per subgraph.zModel input is not dequantized.Nr   zvInitial model input type must be tf.float32. Expected type for tensor with name '{}' is tf.float32, instead type is {}zqInitial model input is not quantized. Expected type for tensor with name '{}' should be in {}, instead type is {}c                 s   s   | ]}t |V  qd S Nr+   rD   tr'   r'   r(   	<genexpr>  rp   z8_modify_model_input_type_per_subgraph.<locals>.<genexpr>zOUnsupported `inference_input_type` value. Expected to be in {}, instead got {}.c                 s   s   | ]}t |V  qd S r   r   r   r'   r'   r(   r     rp   zFor model inputs containing unsupported operations which cannot be quantized, the `inference_input_type` attribute will default to the original type.   z,Unsupported `inference_input_type` value {}.)%r   r@   r   r   r[   r)   r:   r   r   r$   opcodeIndexra   r%   r*   r+   _MAP_QUANT_TO_IO_TYPEStuplekeysr;   r1   r   warninguint8quantizationr   QuantizationParametersTscale	zeroPoint
TensorTypeUINT8r   r   r   r   r   remover   )r   subgraph_indexr   r   r   r@   r   r   	input_idx
input_typeZinput_quant_opsr?   float_tensorquant_tensor
float_type
quant_typeinference_io_typesint8_quantizationuint8_quantizationr   rb   r   r'   r'   r(   r     s    












r   c                 C   sN   |t jkrdS | js&t| dd| dS t| jD ]\}}t| |j|| q0dS )zModify model output type.Nr   r   )r   r   r   &_modify_model_output_type_per_subgraphr   r   )r   inference_output_typer   rb   r'   r'   r(   _modify_model_output_type  s    
r  c              	   C   s.  | j | }|j}|j}t| }|rV|sV|jD ]$}t|| j}	|	tjkr,t	dq,dS g }
|D ]}|j
|v r^|jd |jv r^||jd  ||jd   }}t|j}|tjkr||krq^nt	d|jt|t|j}|tvrt	d|jtdd t D t|n4t| }||vrDt	dtd	d |D t||
| q^t|jt|
krntd
 |tjkrfd}t| jD ],\}}t|}|tjjkr|} qq|dkrt }tjj|_tjj|_ | j| t| jd }|
D ]h}||_
||jd  j!}t" }|j#d g|_#|j$d d g|_$|||jd  _!tj%j&||jd  _qn|tv rt' }|
D ]}|jd |j|j|jd k< |dkr| j(| }t)t|jD ]0}|j| j*|jd kr|jd |j| _*q|+|jd  |,| qzt-| | nt	dt|dS )z&Modify model output type per subgraph.z Model output is not dequantized.Nr   zwInitial model output type must be tf.float32. Expected type for tensor with name '{}' is tf.float32, instead type is {}ztInitial model output is not dequantized. Expected type for tensor with name '{}' should be in {}, instead type is {}c                 s   s   | ]}t |V  qd S r   r   r   r'   r'   r(   r   +  rp   z9_modify_model_output_type_per_subgraph.<locals>.<genexpr>zPUnsupported `inference_output_type` value. Expected to be in {}, instead got {}.c                 s   s   | ]}t |V  qd S r   r   r   r'   r'   r(   r   4  rp   zFor model outputs containing unsupported operations which cannot be quantized, the `inference_output_type` attribute will default to the original type.r   r   r   z-Unsupported `inference_output_type` value {}.).r   r@   r   r   ra   r)   r:   r   r   r$   r   r[   r%   r*   r+   r   r   r   r;   r1   r   r   r   r   r   r	   r   r   r   r   ZOperatorCodeTZbuiltinCodeZdeprecatedBuiltinCoder   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r
  r   r@   r   dequant_opcode_idxsoutputoutput_typeZoutput_dequant_opsr?   r  r  r  r  r  Zquant_opcode_idxr   r   r   Zquant_opr  r  r   rb   r   r'   r'   r(   r	     s    


















r	  c                 C   s<   | j st| dd dS t| j D ]\}}t| |j| q dS )zAFinds back to back quantize ops and remove the first quantize op.r   r   N)r   +_remove_redundant_quantize_ops_per_subgraphr   r   )r   r   rb   r'   r'   r(   _remove_redundant_quantize_opsl  s    r  c                 C   s  | j | }|j}|j}t| }t| }g }i }	i }
|D ]}|j|v r|| ||jd  }||jd  }t	|j
}t	|j
}|tjkr|tjkr||	|jd < |j|v r6|jd |jv r6||
|jd < q6|D ]v}|jd }||	v r|	| }| jr*| jd }|jD ]$}|j|jd kr|jd |_q|jd |jd< || q|D ]}|jd }||
v rJ|
| }|jd |j|j|jd k< |dkr| j| }|jD ]$}|j|jd kr|jd |_q|| || qJdS )z+Remove redundant quantize ops per subgraph.r   N)r   r@   r   r   r   r   r;   r[   ra   r)   r:   r   r   r   r   r   )r   r   r   r   r@   r   r   r  Zall_quant_opsZredundant_quant_tensorsZoutput_dequant_tensorsr?   input_tensoroutput_tensorr  r  output_tensor_idxZrequantize_oprb   r  Z
dequant_opr'   r'   r(   r  x  sX    














r  c                 C   sD   |t jkr|t jkr| S t| }t|| t|| t| t|S )a  Modify the input/output type of a tflite model.

  Args:
    model: A tflite model.
    inference_input_type: tf.DType representing modified input type.
      (default tf.float32. If model input is int8 quantized, it must be in
      {tf.float32, tf.int8,tf.uint8}, else if model input is int16 quantized,
      it must be in {tf.float32, tf.int16}, else it must be tf.float32)
    inference_output_type: tf.DType representing modified output type.
      (default tf.float32. If model output is int8 dequantized, it must be in
      {tf.float32, tf.int8,tf.uint8}, else if model output is int16 dequantized,
      it must be in {tf.float32, tf.int16}, else it must be tf.float32)
  Returns:
    A tflite model with modified input/output type.

  Raises:
    ValueError: If `inference_input_type`/`inference_output_type` is unsupported
      or a supported integer type is specified for a model whose input/output is
      not quantized/dequantized.
    RuntimeError: If the modification was unsuccessful.

  )r   r   r   r   r  r  r   )r   r   r
  r   r'   r'   r(   modify_model_io_type  s    


r  c                 C   sb   | r
| j sg S t }| jD ]>}|jD ]2}|js0q$|jjsH|tjj	 q$|tjj
 q$qt|S )zGet sparsity modes used in a tflite model.

  The sparsity modes are listed in conversion_metadata.fbs file.

  Args:
    model_object: A tflite model in object form.

  Returns:
    The list of sparsity modes used in the model.
  )metadatar   r   r@   sparsityZblockMapr   conversion_metadata_fbZModelOptimizationModeZRANDOM_SPARSITYZBLOCK_SPARSITYlist)r   resultr   r2   r'   r'   r(   get_sparsity_modes  s    


r  c                 C   s   zt d}||| t }| |_| js<g | _n2| jD ]*}|j	
dtkrB|| j|j< |   W S qB| jszg | _| j| t }t|_	t| jd |_| j| | W S  ty   |  Y S 0 dS )zAdd or update conversion metadata to a tflite model.

  Args:
    model_object: A tflite model in object form.
    metadata: The conversion metadata.

  Returns:
    A tflite model object with embedded conversion metadata.
  r   utf-8r   N)r   r   r   r   r   ZBufferTr   r   r  r*   decodeCONVERSION_METADATA_FIELD_NAMEbuffersbufferr;   Z	MetadataTr1   	Exception)r   r  Zmetadata_builderZbuffer_fieldmetaZmetadata_fieldr'   r'   r(   populate_conversion_metadata  s*    



r"  c                 C   sd   t | }|r|jsdS |jD ]@}|jdtkr|j|j j	 }t
jt
j|d  S qdS )zRead conversion metadata from a tflite model.

  Args:
    model_buffer: A tflite model.

  Returns:
    The conversion metadata or None if it is not populated.
  Nr  r   )r   convert_bytearray_to_objectr  r*   r  r  r  r  r   tobytesr  ZConversionMetadataTr   ZConversionMetadataZGetRootAsConversionMetadata)Zmodel_bufferr   r!  Zmetadata_bufr'   r'   r(   get_conversion_metadata!  s    	



r%  )N)r   NNF)a__doc__r   r   r   abslr   r.   	six.movesr   r   tensorflow.core.protobufr   rN   r   r   rY   tensorflow.lite.pythonr   r  r   r   r	   r
   Z_tflite_keras_utilZtensorflow.lite.python.op_hintr   r   tensorflow.lite.toolsr   tensorflow.python.eagerr   tensorflow.python.frameworkr   rx   r   r   r   r   rr   tensorflow.python.grapplerr    tensorflow.python.training.saverr   rX   r  model_input_signaturetrace_model_calljaxr   Z_xla_computationImportErrorr   float16int32r   int64stringboolint16	complex64int8float64
complex128uint32r"   r   r   r)   r+   r4   rA   rM   rU   rn   rw   r|   rq   r   r   r   r   r   r   r   r   r   r   r   r   r  r	  r  r  r  r  r"  r%  r'   r'   r'   r(   <module>   s   

+ 
*('!    
x	

1\l;
( '