a
    Sic                    @   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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dl-m.Z. ddl-m/Z/ ddl-m0Z0 ddl1m2Z3 ddl4m5Z5 ddl4m6Z6 ddl4m7Z7 ddl8m9Z9 ddl:m;Z; ddl:m<Z= ddl:m>Z> dd l?m@ZA dd!lBmCZC dd"lBmDZE dd#lBmFZG dd$lBmHZI dd%lBmJZK dd&lBmLZM dd'lBmNZO dd(lBmPZQ dd)lBmRZS dd*lBmTZU dd+lBmVZW dd,lBmXZY dd-lBmZZ[ dd.lBm\Z] dd/lBm^Z_ dd0lBm`Za dd1lBmbZc dd2ldmeZe dd3lfmgZg dd4lfmhZh dd5limjZk dd6llmmZn dd7lompZp dd8lomqZr dd9lomsZt dd:lumvZw dd;lumxZy dd<lumzZ{ dd=lum|Z| dd>l}m~Z dd?lmZ dd@lmZ ddAlmZ ddBlmZ ddClmZ ddDlmZ ddElmZ ddFlmZ ddGlmZ ddHlmZ ddIlmZ edJG dKdL dLejZedMG dNdO dOeZedPG dQdR dReZG dSdT dTeZG dUdV dVeZdWdX ZG dYdZ dZeZG d[d\ d\eZG d]d^ d^eZG d_d` d`eZG dadb dbeZedcg ddG dedf dfeZG dgdh dheZG didj djeZG dkdl dleZG dmdn dneZedcgddG dodp dpeZedqgddG drds dseZdS )tz-TensorFlow Lite tooling helper functionality.    N)logging)PY2)text_format)DecodeError)	graph_pb2)audio_microfrontend_op)'conversion_metadata_schema_py_generated)lite_constants)convert_graphdef)convert_graphdef_with_arrays)convert_jax_hlo)convert_saved_model)ConverterError)deduplicate_readonly_buffers)mlir_quantize)mlir_sparsify)OpsSet)toco_convert)	Component)convert_phase)SubComponent)freeze_saved_model)Interpreter)load_delegate)OpResolverType)metrics)convert_op_hints_to_stubs)is_ophint_converted)OpHint)
calibrator)_xla_computation)build_debug_info_func)convert_debug_info_func)freeze_graph)get_debug_info)get_grappler_config)get_sparsity_modes)get_tensor_name)get_tensors_from_tensor_names)get_tf_type_name)is_frozen_graph)model_input_signature)modify_model_io_type)populate_conversion_metadata)run_graph_optimizations)set_tensor_shapes)trace_model_call)flatbuffer_utils)QuantizationDebugger)QuantizationDebugOptions)saved_model)session)context)def_function)function)convert_to_constants)dtypes)ops)versions)NotFoundError)import_graph_def)gfile)loader_impl)save_options)signature_constants)tag_constants)load)!parse_saved_model_with_debug_info)deprecation)
keras_deps)	tf_exportzlite.Optimizec                   @   s(   e Zd ZdZdZdZdZdZdd ZdS )	Optimizea  Enum defining the optimizations to apply when generating a tflite model.

  DEFAULT
      Default optimization strategy that quantizes model weights. Enhanced
      optimizations are gained by providing a representative dataset that
      quantizes biases and activations as well.
      Converter will do its best to reduce size and latency, while minimizing
      the loss in accuracy.

  OPTIMIZE_FOR_SIZE
      Deprecated. Does the same as DEFAULT.

  OPTIMIZE_FOR_LATENCY
      Deprecated. Does the same as DEFAULT.

  EXPERIMENTAL_SPARSITY
      Experimental flag, subject to change.

      Enable optimization by taking advantage of the sparse model weights
      trained with pruning.

      The converter will inspect the sparsity pattern of the model weights and
      do its best to improve size and latency.
      The flag can be used alone to optimize float32 models with sparse weights.
      It can also be used together with the DEFAULT optimization mode to
      optimize quantized models with sparse weights.
  DEFAULTOPTIMIZE_FOR_SIZEOPTIMIZE_FOR_LATENCYEXPERIMENTAL_SPARSITYc                 C   s
   t | jS N)strvalueself rS   W/var/www/html/django/DPS/env/lib/python3.9/site-packages/tensorflow/lite/python/lite.py__str__   s    zOptimize.__str__N)	__name__
__module____qualname____doc__rJ   rK   rL   rM   rU   rS   rS   rS   rT   rI   d   s   !rI   zlite.RepresentativeDatasetc                   @   s   e Zd ZdZdd ZdS )RepresentativeDataseta  Representative dataset used to optimize the model.

  This is a generator function that provides a small dataset to calibrate or
  estimate the range, i.e, (min, max) of all floating-point arrays in the model
  (such as model input, activation outputs of intermediate layers, and model
  output) for quantization. Usually, this is a small subset of a few hundred
  samples randomly chosen, in no particular order, from the training or
  evaluation dataset.
  c                 C   s
   || _ dS )ah  Creates a representative dataset.

    Args:
      input_gen: A generator function that generates input samples for the
        model and has the same order, type and shape as the inputs to the model.
        Usually, this is a small subset of a few hundred samples randomly
        chosen, in no particular order, from the training or evaluation dataset.
    N)	input_gen)rR   r[   rS   rS   rT   __init__   s    	zRepresentativeDataset.__init__NrV   rW   rX   rY   r\   rS   rS   rS   rT   rZ      s   
rZ   zlite.TargetSpecc                   @   s   e Zd ZdZdddZdS )
TargetSpeca  Specification of target device used to optimize the model.

  Attributes:
    supported_ops: Experimental flag, subject to change. Set of `tf.lite.OpsSet`
      options, where each option represents a set of operators supported by the
      target device. (default {tf.lite.OpsSet.TFLITE_BUILTINS}))
    supported_types: Set of `tf.dtypes.DType` data types supported on the target
      device. If initialized, optimization might be driven by the smallest type
      in this set. (default set())
    experimental_select_user_tf_ops: Experimental flag, subject to change. Set
      of user's TensorFlow operators' names that are required in the TensorFlow
      Lite runtime. These ops will be exported as select TensorFlow ops in the
      model (in conjunction with the tf.lite.OpsSet.SELECT_TF_OPS flag). This is
      an advanced feature that should only be used if the client is using TF ops
      that may not be linked in by default with the TF ops that are provided
      when using the SELECT_TF_OPS path. The client is responsible for linking
      these ops into the target runtime.
    experimental_supported_backends: Experimental flag, subject to change.
      Set containing names of supported backends. Currently only "GPU" is
      supported, more options will be available later.
  Nc                 C   sT   |d u rt jh}|| _|d u r$t }|| _|d u r8t }|| _|| _g | _d | _d S rN   )	r   TFLITE_BUILTINSsupported_opssetsupported_typesexperimental_select_user_tf_opsexperimental_supported_backends#_experimental_custom_op_registerers)_experimental_supported_accumulation_type)rR   r`   rb   rc   rd   rS   rS   rT   r\      s    zTargetSpec.__init__)NNNNr]   rS   rS   rS   rT   r^      s       r^   c                   @   s   e Zd ZdZd6d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dd Zdd Zdd Zdd Zd d! Zd"d# Zd7d$d%Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 ZdS )8QuantizationModezDQuantizationMode determines the quantization type from user options.FNc	           
      C   sl   || _ tjtjfD ]}	|	| j v rtd|	 q|| _|| _|| _| 	  || _
|| _|| _|| _|   d S )NzZOptimization option %s is deprecated, please use optimizations=[Optimize.DEFAULT] instead.)_optimizationsrI   rK   rL   r   warning_target_spec_representative_dataset
_graph_def_validate_int8_required_disable_per_channel#_enable_new_dynamic_range_quantizer_experimental_low_bit_qat$_full_integer_quantization_bias_type-_validate_full_integer_quantization_bias_type)
rR   optimizationstarget_specrepresentative_dataset	graph_defdisable_per_channel(experimental_new_dynamic_range_quantizerZexperimental_low_bit_qatZ#full_integer_quantization_bias_typeZdeprecated_optimizationrS   rS   rT   r\      s$    	
zQuantizationMode.__init__c                 C   s.   |   o,| jd uo,|   o,|   o,|  S rN   )is_any_optimization_enabledrk   _is_int16x8_target_requiredis_allow_float_is_int8_target_requiredrQ   rS   rS   rT   'is_post_training_int8_only_quantization  s    z8QuantizationMode.is_post_training_int8_only_quantizationc                 C   s2   |   o0| jd uo0|   o0|  o0|  tjkS rN   )ry   rk   rz   r{   _smallest_supported_type_dtypesint8rQ   rS   rS   rT   6is_post_training_int8_quantization_with_float_fallback  s    zGQuantizationMode.is_post_training_int8_quantization_with_float_fallbackc                 C   s   |   p|  S rN   )r}   r   rQ   rS   rS   rT   "is_post_training_int8_quantization  s    z3QuantizationMode.is_post_training_int8_quantizationc                 C   s$   |   o"| jd uo"|  o"|   S rN   ry   rk   rz   r{   rQ   rS   rS   rT   *is_post_training_int16x8_only_quantization  s    z;QuantizationMode.is_post_training_int16x8_only_quantizationc                 C   s"   |   o | jd uo |  o |  S rN   r   rQ   rS   rS   rT   9is_post_training_int16x8_quantization_with_float_fallback%  s    zJQuantizationMode.is_post_training_int16x8_quantization_with_float_fallbackc                 C   s   |   p|  S rN   )r   r   rQ   rS   rS   rT   %is_post_training_int16x8_quantization+  s    z6QuantizationMode.is_post_training_int16x8_quantizationc                 C   s   |   p|  S rN   )r   r   rQ   rS   rS   rT   %is_post_training_integer_quantization/  s    z6QuantizationMode.is_post_training_integer_quantizationc                 C   s   |   o|  o| jS rN   )ry   #is_quantization_aware_trained_modelrp   rQ   rS   rS   rT   "is_low_bit_quantize_aware_training3  s
    z3QuantizationMode.is_low_bit_quantize_aware_trainingc                 C   s   |   o|  o|   S rN   )ry   r   r   rQ   rS   rS   rT   is_quantization_aware_training8  s
    z/QuantizationMode.is_quantization_aware_trainingc                 C   s   |   p|  p|  S rN   )r   r   r   rQ   rS   rS   rT   is_integer_quantization=  s
    z(QuantizationMode.is_integer_quantizationc                 C   s*   |   o(| jd u o(|   o(|  tjkS rN   )ry   rk   r   r~   r   r   rQ   rS   rS   rT   +is_post_training_dynamic_range_quantizationB  s    z<QuantizationMode.is_post_training_dynamic_range_quantizationc                 C   s$   |   o"|  jdko"tj| jjv S N   )ry   r~   sizer   float16rj   rb   rQ   rS   rS   rT   %is_post_training_float16_quantizationJ  s
    z6QuantizationMode.is_post_training_float16_quantizationc                 C   s$   |   o"|  jdko"tj| jjv S r   )ry   r~   r   r   bfloat16rj   rb   rQ   rS   rS   rT   is_bfloat16_quantizationO  s
    z)QuantizationMode.is_bfloat16_quantizationc                 C   s(   |   r|  rtjS tjS ntjS d S rN   )r   rz   r   int16r   float32rQ   rS   rS   rT   activations_typeT  s
    z!QuantizationMode.activations_typec                 C   s>   | j r| j S |  tjkr tjS |  tjkr4tjS tjS d S rN   )rq   r   r   r   int64r   int32r   rQ   rS   rS   rT   	bias_type]  s    zQuantizationMode.bias_typec                 C   s   |   r4|  }|dur|n|  tjdd||dS |  rVtjtjdd| j| jdS |  rtjtjdd| j	j
|  | jdS |dur|ntj|dd|  dS dS )zFlags to the converter.NF)inference_typeinference_input_typepost_training_quantizequantize_to_float16disable_infer_tensor_rangeuse_fake_quant_num_bitsT)r   r   r   r    disable_per_channel_quantization#enable_mlir_dynamic_range_quantizer)r   r   r   r   accumulation_typeallow_bfloat16r   )r   r   r   r   r   )r   r   r   r   r   r   rn   ro   r   rj   rf   r   )rR   Zinference_tyZinference_input_tyZis_low_bit_qatrS   rS   rT   converter_flagsh  sB    	z QuantizationMode.converter_flagsc                 C   s   |   sdS t| jjtjhkrNt| jjt ksNt| jjtjhksNt	dt| jjtjhkrntjh| j_| j
s|  st	d| j
rt| j
tst| j
| _
dS )zAInt8 mode requires certain parameters to exist and be compatible.NzAs full integer quantization has been enabled by setting `target_spec.supported_ops`={tf.lite.OpsSet.TFLITE_BUILTINS_INT8}, thus `target_spec.supported_types` should be left uninitizalized or set to {tf.int8}.zLFor full integer quantization, a `representative_dataset` must be specified.)r|   ra   rj   r`   r   TFLITE_BUILTINS_INT8rb   r   r   
ValueErrorrk   r   
isinstancerZ   rQ   rS   rS   rT   rm     s*    z(QuantizationMode._validate_int8_requiredc                 C   s~   | j }|sdS |  tjkr$td|  tjkrJ|tjkrJtd| |  tjkrz|tjkrz|tjkrztd| dS )z3Validates bias type for full interger quantization.NzV`full_integer_quantization_bias_type` is only supported for full integer quantization.zRExpected bias type to be `dtypes.int32` for Int8Quant. Current setting bias type: zeExpected bias type to be `dtypes.int32` or `dtypes.int64` for Int16Quant. Current setting bias type: )	rq   r   r   r   r   r   r   r   r   )rR   r   rS   rS   rT   rr     s2    z>QuantizationMode._validate_full_integer_quantization_bias_typec                 C   s*   t jt| jjv p(t| jjttjgkS rN   )r   r   ra   rj   r`   rb   r   r   rQ   rS   rS   rT   r|     s    
z)QuantizationMode._is_int8_target_requiredc                 C   s   t jt| jjv S rN   )r   ;EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8ra   rj   r`   rQ   rS   rS   rT   rz     s    
z,QuantizationMode._is_int16x8_target_requiredc                 C   s$   t jt| jjv p"t jt| jjv S rN   )r   r_   ra   rj   r`   SELECT_TF_OPSrQ   rS   rS   rT   r{     s    zQuantizationMode.is_allow_floatc                 C   s    t t| jtjtjtjgS rN   )boolra   rh   intersectionrI   rL   rK   rJ   rQ   rS   rS   rT   ry     s    
z,QuantizationMode.is_any_optimization_enabledc                 C   s&   | j jrt| j jdd dS tjS d S )Nc                 S   s   | j S rN   )r   )xrS   rS   rT   <lambda>      z;QuantizationMode._smallest_supported_type.<locals>.<lambda>)key)rj   rb   minr   r   rQ   rS   rS   rT   r~     s    z)QuantizationMode._smallest_supported_typec                 C   sb   t h d}| jr^| jjD ]}|j|v r dS q| jjjD ]"}|jD ]}|j|v rD  dS qDq:dS )z@Checks if the graph contains any training-time quantization ops.>   !FakeQuantWithMinMaxVarsPerChannelFakeQuantWithMinMaxArgsQuantizeAndDequantizeV3QuantizeAndDequantizeV2FakeQuantWithMinMaxVarsTF)	frozensetrl   nodeoplibraryr8   node_def)rR   Ztraining_quant_opsr   r8   rS   rS   rT   r     s    


z4QuantizationMode.is_quantization_aware_trained_model)FFFN)NN)rV   rW   rX   rY   r\   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rm   rr   r|   rz   r{   ry   r~   r   rS   rS   rS   rT   rg      s<       
"	
5rg   c                   @   s   e Zd ZdZejjZdd Zd%ddZ	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edd Zdd Zd'ddZdd Zeejd(d!d"Zd#d$ ZdS ))TFLiteConverterBasezGConverter subclass to share functionality between V1 and V2 converters.c                 C   s   t  | _d | _t | _d| _d| _d| _d| _d| _	d| _
d| _d | _d | _d | _d| _g | _t | _i | _d| _d| _d| _d| _d | _d | _d| _t | _t | j_ t! | j_"t#j$| jj _%| & | jj _'d| _(d| _)d| _*d| _+d| _,d S )NFTr   )-ra   rs   ru   r^   rt   allow_custom_opsexperimental_new_converterexperimental_new_quantizer&experimental_enable_resource_variables_experimental_calibrate_onlyZ_experimental_sparsify_model!_experimental_disable_per_channel_debug_infosaved_model_dir_saved_model_tags_saved_model_version_saved_model_exported_namesr   TFLiteConverterMetrics_tflite_metrics_collected_converter_params(_experimental_disable_batchmatmul_unfold#_experimental_lower_tensor_list_ops8_experimental_default_to_single_batch_in_tensor_list_ops)_experimental_unfold_large_splat_constant"_experimental_tf_quantization_mode1_experimental_full_integer_quantization_bias_typeexclude_conversion_metadataconversion_metdata_fbConversionMetadataT	_metadataEnvironmentTenvironmentConversionOptionsToptionsr<   __version__tensorflowVersion_get_original_model_type	modelType)_experimental_enable_dynamic_update_slice _experimental_preserve_assert_op)_experimental_guarantee_all_funcs_one_userx   rp   rQ   rS   rS   rT   r\     sD    

zTFLiteConverterBase.__init__Nc                 C   sF   |sg }| j s|d ttjgt| jjk}|r>|d t|S )zCreates a tf.compat.v1.ConfigProto for configuring Grappler.

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

    Returns:
      tf.ConfigProto.
    	constfoldlayout)r   appendra   r   r   rt   r`   _get_grappler_config)rR   
optimizersZis_only_flex_enabledrS   rS   rT   _grappler_config5  s    	

z$TFLiteConverterBase._grappler_configc              	   C   s   dd | j jD }dd | j jD }t| jts<t| j| _t|}t|||}	| js`| j	rn|	
| jj}
| jrx|
S | j	r|tjkrt|
| j||dS |	j| jj|||||| jdS dS )zQuantize the model.c                 S   s   g | ]}t |tr|qS rS   r   rO   .0r   rS   rS   rT   
<listcomp>Q  s   
z1TFLiteConverterBase._quantize.<locals>.<listcomp>c                 S   s   g | ]}t |ts|qS rS   r   r   rS   rS   rT   r   U  s   
)input_data_typeoutput_data_type)rw   N)rt   re   r   ru   rZ   _calibratorZadd_intermediate_tensorsZ
Calibratorr   r   	calibrater[   r   r   _mlir_quantizer   Zcalibrate_and_quantize)rR   result
input_typeoutput_typer   r   Zallow_floatZcustom_op_registerers_by_nameZcustom_op_registerers_by_funcZcalibrate_quantizeZ
calibratedrS   rS   rT   	_quantizeM  sN    
zTFLiteConverterBase._quantizec                 C   s   | j S rN   )r   rQ   rS   rS   rT   _is_unknown_shapes_allowed|  s    z.TFLiteConverterBase._is_unknown_shapes_allowedc                 C   st   t j| j| j| jj| j| jj| jj| j	 | j
| j| j| j| j| j| j| jd}| jrp|| j| j| j| jd |S )zHReturns the base converter args.

    Returns:
      {key str: val}
    )input_formatr   
debug_info
target_opsenable_mlir_converterselect_user_tf_opssupported_backendsunfold_batchmatmullower_tensor_list_opsunfold_large_splat_constant*default_to_single_batch_in_tensor_list_opstf_quantization_moder   enable_dynamic_update_slicepreserve_assert_opguarantee_all_funcs_one_use)r   saved_model_versionsaved_model_tagssaved_model_exported_names)	constantsTENSORFLOW_GRAPHDEFr   r   rt   r`   r   rc   rd   r   r   r   r   r   r   r   r   r   r   updater   r   r   )rR   argsrS   rS   rT   _get_base_converter_args  s2    #z,TFLiteConverterBase._get_base_converter_argsc                 C   s@   |j d }|jjjD ]&}|jdd s4|jdd r dS qdS )Nr   _implementsapi_implementsTF)meta_graphsrv   r   r8   attrget)rR   saved_model_proto
meta_graphr8   rS   rS   rT   '_contains_function_with_implements_attr  s    
z;TFLiteConverterBase._contains_function_with_implements_attrFc                 C   s   | j sd| _dS | jrzt| j\}}W n tyB   d| _Y dS 0 |s\| |s\d| _dS | jshg | _|j| _| jdkrd| _t	d dS | jdvrt
d| jdS )zParses SavedModel arguments from the given Keras/RNN SavedModel.

    Args:
      always_enable_saved_model_import: Bool. When the value is true, it enables
        MLIR saved model import path regardless of checking the conditions.
    Nr   z"SavedModel schema version is zero.)   r   z,SavedModel file format({0}) is not supported)r   r   "_parse_saved_model_with_debug_infoOSErrorr  r   saved_model_schema_versionr   r   ri   r   format)rR    always_enable_saved_model_importr  _rS   rS   rT   _parse_saved_model_args  s4    



z+TFLiteConverterBase._parse_saved_model_argsc                 C   s   t j| jv S rN   )rI   rM   rs   rQ   rS   rS   rT   _sparsify_model  s    z#TFLiteConverterBase._sparsify_modelc                 C   s   | j   d S rN   )r   "increase_counter_converter_attemptrQ   rS   rS   rT   #_increase_conversion_attempt_metric  s    z7TFLiteConverterBase._increase_conversion_attempt_metricc                 C   s   | j   d S rN   )r   "increase_counter_converter_successrQ   rS   rS   rT   #_increase_conversion_success_metric  s    z7TFLiteConverterBase._increase_conversion_success_metricc                 C   s   |t jjkrtd|| _dS )zStores the original model type.z,The original model type should be specified.N)r   	ModelTypeNONEr   _original_model_type)cls
model_typerS   rS   rT   _set_original_model_type  s    z,TFLiteConverterBase._set_original_model_typec                 C   s   t j}tjjt _|S )zAOne-time getter to return original model type and set it to NONE.)r   r   r   r  r  )rR   r"  rS   rS   rT   r     s    
z,TFLiteConverterBase._get_original_model_typec           	         s  | j }||   t| j| j| j|| j| j| j	| j
}|| jjj| jjj| jjj| | | | | | |  | d |||| | jjr|d| jji dd   fdd}| D ]\}}| j||| q| j  | j| jj_ t!j"| jj#v | jj_$t%t!j"gt%| jj#k| jj_&g | jj_'| r`| jjj'(t)j*j+ | r~| jjj'(t)j*j, |- r| jjj'(t)j*j. |/ r| jjj'(t)j*j0 | r| jjj'(t)j*j1 dS )z!Set conversion parameter metrics.)
tf_versionapi_versionZoriginal_model_formatZoptimization_defaultZ(optimization_post_training_dynamic_rangeZ"optimization_post_training_float16Z+optimization_post_training_integer_quantizeZoptimization_qatZoptimization_low_bit_qatZoptimization_sparsifyr   r   c                 S   s    t | tjrt| jS t| S rN   )r   enumEnumrO   rP   pprintpformat)elemrS   rS   rT   format_element&  s    
zJTFLiteConverterBase._save_conversion_params_metric.<locals>.format_elementc                    s@   t | tttfr8| sdS  fdd| D }dt|S  | S )NNonec                    s   g | ]} |qS rS   rS   r   r+  rS   rT   r   /  r   z\TFLiteConverterBase._save_conversion_params_metric.<locals>.format_param.<locals>.<listcomp>,)r   listtuplera   joinsorted)paramZstring_listr-  rS   rT   format_param+  s    zHTFLiteConverterBase._save_conversion_params_metric.<locals>.format_paramN)2r   r  r  rg   rs   rt   ru   r   rx   rp   r   r   r   r   
apiVersionr   ry   r   r   r   r   r   r  r   r   rf   itemsr   set_converter_paramset_export_requiredr   r   allowCustomOpsr   r   r`   enableSelectTfOpsra   forceSelectTfOpsmodelOptimizationModesr   r   ModelOptimizationModePTQ_FLOAT16PTQ_DYNAMIC_RANGEr   PTQ_FULL_INTEGERr   	PTQ_INT16QUANTIZATION_AWARE_TRAINING)	rR   rv   r   r   converter_kwargs
quant_moder4  r   rP   rS   r-  rT   _save_conversion_params_metric  sz    












z2TFLiteConverterBase._save_conversion_params_metricc                 C   s   | j | d S rN   )r   set_converter_latency)rR   rP   rS   rS   rT   _set_conversion_latency_metricT  s    z2TFLiteConverterBase._set_conversion_latency_metricTc                 C   s  |  r| j| j }}| rn|r*|r*|ntj}|r<|r<|ntj}| }| }	| }
| 	|||||	|
}|rv|ntj}|r|ntj}| r| j
r|r|tjtjtjfv r|tjtjtjfv st|||}|  rt|}zt|}W n ty
   td Y n0 |S )z&Apply optimizations on a TFLite model.z]Buffer deduplication procedure will be skipped when flatbuffer library is not properly loaded)r   r   inference_output_typer   r   r   r   r   r{   r   r   r   uint8_modify_model_io_typer  _mlir_sparsify_deduplicate_readonly_buffers	Exceptionr   ri   )rR   modelrD  quant_ioZin_typeout_typeZ	q_in_typeZ
q_out_typeZq_activations_typeZq_bias_typeZq_allow_floatZ	m_in_typeZ
m_out_typerS   rS   rT   _optimize_tflite_modelW  s@    
z*TFLiteConverterBase._optimize_tflite_modelc           	      O   s   |    |   t }|| g|R i |}t | d }|rJ|   | t| | j  | j	rl|S t
|}t|}| jjj| t|| j}t
|S )a,  Wraps around convert function to export metrics.

    Args:
      convert_func: The convert function to wrap.
      *args: Positional arguments of the convert function.
      **kwargs: The keyword arguments of the convert function.

    Returns:
      The decorator to wrap the convert function.
    i  )r  rE  timeprocess_timer  rG  roundr   export_metricsr   r1   convert_bytearray_to_object_get_sparsity_modesr   r   r<  extend_populate_conversion_metadataconvert_object_to_bytearray)	rR   convert_funcr  kwargs
start_timer   Zelapsed_time_msmodel_objectZsparsity_modesrS   rS   rT   _convert_and_export_metrics~  s     

z/TFLiteConverterBase._convert_and_export_metrics)N)F)NNN)T)rV   rW   rX   rY   r   r  r  r   r\   r   r   r   r  r  r  r  r  r  classmethodr#  r   rE  rG  r   r   OPTIMIZE_TFLITE_MODELrQ  r_  rS   rS   rS   rT   r     s.   -
/3
#
   
`&r   c                    s   t   fdd}|S )z8The decorator around convert function to export metrics.c                    s   | j  g|R i |S rN   )r_  )rR   r  r\  r[  rS   rT   wrapper  s    z _export_metrics.<locals>.wrapper)	functoolswraps)r[  rc  rS   rb  rT   _export_metrics  s    rf  c                       sz   e Zd ZdZ fddZdd Zeeje	j
dd Zeeje	jdd	 Zeeje	jd
d Zdd Zdd Z  ZS )TFLiteConverterBaseV2z@Converter subclass to share functionality between V2 converters.c                    s,   t t|   tj| _tj| _d| jj_	dS )z Constructor for TFLiteConverter.r   N)
superrg  r\   r   r   r   rH  r   r   r5  rQ   	__class__rS   rT   r\     s    zTFLiteConverterBaseV2.__init__c                 C   s   t jg}| rh| r&|t jg }n|t jt jg }| j|vsJ| j|vrdd |D }t	d
|n| j|vs|| j|vrt	ddS )z>Validate inference_input_type and inference_output_type flags.c                 S   s   g | ]}d |j  qS )ztf.name)r   trS   rS   rT   r     r   zPTFLiteConverterBaseV2._validate_inference_input_output_types.<locals>.<listcomp>zAThe inference_input_type and inference_output_type must be in {}.zFThe inference_input_type and inference_output_type must be tf.float32.N)r   r   r   r   r   r   rI  r   rH  r   r  )rR   rD  default_types	all_typesZall_types_namesrS   rS   rT   &_validate_inference_input_output_types  s     

z<TFLiteConverterBaseV2._validate_inference_input_output_typesc                    sr   t   t|}|j |d ||}|j}|jtj	  fddj
D } fddjD }|||fS )a  Load graph_def from saved model with the default serving signature key.

    Args:
      saved_model_dir: Directory of the SavedModel.
      saved_model_tags: Set of tags identifying the MetaGraphDef within the
        SavedModel to analyze.

    Returns:
      graph_def: The loaded GraphDef.
      input_tensors: List of input tensors.
      output_tensors: List of output tensors.
    )tagsc                    s   g | ]}  j| jqS rS   )get_tensor_by_nameinputsrl  r   r   graphsignature_defrS   rT   r     s   z;TFLiteConverterBaseV2._load_saved_model.<locals>.<listcomp>c                    s   g | ]}  j| jqS rS   )rr  outputsrl  rt  ru  rS   rT   r     s   )_opsGraph_loader_implSavedModelLoader
load_graphget_meta_graph_def_from_tagsrv   rw  _signature_constants!DEFAULT_SERVING_SIGNATURE_DEF_KEYrs  rx  )rR   r   r  r4   r  rv   input_tensorsoutput_tensorsrS   ru  rT   _load_saved_model  s    

z'TFLiteConverterBaseV2._load_saved_modelc              	   C   s   |  | t| j| j| j|| j| j| j| j| _	| 
| j	 |  s|D ]`}|j }d|dd v r|tdt||qH|rH|d du rH|j }d|d< || qH| jdu st| jdstt| jd j|| _ntt| jj|| _dS )zValidate the input parameters.

    Args:
      graph_def: The TensorFlow GraphDef.
      input_tensors: List of input tensors.
    Raise:
      ValueError:
        Input shape is not specified.
        Invalid quantization parameters.
    Nr  RNone is only supported in the 1st dimension. Tensor '{0}' has invalid shape '{1}'.r   graph_debug_info)rE  rg   rs   rt   ru   r   rx   rp   r   _quant_moderp  r   shapeas_listr   r  _get_tensor_name	set_shape_trackable_objhasattr_get_debug_info_build_debug_info_func_funcsrv  r   _convert_debug_info_funcr  )rR   rv   r  tensor
shape_listr  rS   rS   rT   _validate_inputs  s@    





z&TFLiteConverterBaseV2._validate_inputsc                 C   s*   |   }|jjjr&t|||||jd}|S )a*  Run a Grappler pass to optimize the TensorFlow graph.

    Args:
      graph_def: Frozen GraphDef to be optimized.
      input_tensors: List of input tensors.
      output_tensors: List of output tensors.
      frozen_func: TensorFlow Graph.

    Returns:
      The optimized TensorFlow graph.
    )configrv  )r   graph_optionsrewrite_optionsr   _run_graph_optimizationsrv  )rR   rv   r  r  frozen_funcZgrappler_configrS   rS   rT   _optimize_tf_model  s    
z(TFLiteConverterBaseV2._optimize_tf_modelc              	   C   s~   |  | t| j| j| j|| j| j| j| j}| 	| d| j
i}||   ||  tf i |}| j||| jdS )zHelper method that converts saved model.

    Args:
      graph_def: GraphDef object for the model, used only for stats.

    Returns:
      The converted TFLite model.
     enable_tflite_resource_variablesrO  )rE  rg   rs   rt   ru   r   rx   rp   r   rp  r   r  r  r   _convert_saved_modelrQ  r   )rR   rv   rD  rC  r   rS   rS   rT   _convert_from_saved_model.  s$    


z/TFLiteConverterBaseV2._convert_from_saved_modelc                 C   sj   |  || |  }|| j  | js6td n
td t	f |||d|}| j
|| j| jdS )a  Converts a TensorFlow GraphDef based on instance variables.

    Args:
      graph_def: Frozen TensorFlow GraphDef.
      input_tensors: List of input tensors.
      output_tensors: List of output tensors.

    Returns:
      The converted data in serialized format.

    Raises:
      ValueError:
        No concrete functions is specified.
        Multiple concrete functions are specified.
        Input shape is not specified.
        Invalid quantization parameters.
    {Please consider switching to the new converter by setting experimental_new_converter=True. The old converter is deprecated.z~Using new converter: If you encounter a problem please file a bug. You can opt-out by setting experimental_new_converter=False
input_datar  r  r  )r  r  r  r  r   r   r   ri   info_convert_graphdefrQ  r   )rR   rv   r  r  rC  r   rS   rS   rT   convertL  s$    

zTFLiteConverterBaseV2.convert)rV   rW   rX   rY   r\   rp  r   r   PREPARE_TF_MODELr   LOAD_SAVED_MODELr  VALIDATE_INPUTSr  OPTIMIZE_TF_MODELr  r  r  __classcell__rS   rS   ri  rT   rg    s   

.
rg  c                       s2   e Zd ZdZd fdd	Ze fddZ  ZS )TFLiteSavedModelConverterV2Converts the given SavedModel into TensorFlow Lite model.

  Attributes:
      saved_model_dir: Directory of the SavedModel.
  Nc                    s6   t t|   || _|| _|| _|| _| jdd dS )a  Constructor for TFLiteConverter.

    Args:
      saved_model_dir: Directory of the SavedModel.
      saved_model_tags: Set of tags identifying the MetaGraphDef within the
        SavedModel to analyze. All tags in the tag set must be present. (default
        {tf.saved_model.SERVING}).
      saved_model_exported_names: Names to be exported when the saved model
        import path is on.
      trackable_obj: tf.AutoTrackable object associated with `funcs`. A
        reference to this object needs to be maintained so that Variables do not
        get garbage collected since functions have a weak reference to
        Variables. This is only required when the tf.AutoTrackable object is not
        maintained by the user (e.g. `from_saved_model`).
    Tr  N)rh  r  r\   r   r   r   r  r  )rR   r   r  r  trackable_objri  rS   rT   r\   }  s    z$TFLiteSavedModelConverterV2.__init__c                    s   |  | j| j\}}}| jdu s&| js`t| jddd| jtj\}}}}d| _tt| 	|||S | j
du rtt| jd j|| _ntt| j
j|| _| |S )J  Converts a TensorFlow GraphDef based on instance variables.

    Returns:
      The converted data in serialized format.

    Raises:
      ValueError:
        No concrete functions is specified.
        Multiple concrete functions are specified.
        Input shape is not specified.
        Invalid quantization parameters.
    Nr   )r  r   r   r   _freeze_saved_modelr  r  rh  r  r  r  r  r  r  rv  r   r  r  r  )rR   rv   r  r  r  ri  rS   rT   r    s.    


z#TFLiteSavedModelConverterV2.convert)NNNrV   rW   rX   rY   r\   rf  r  r  rS   rS   ri  rT   r  v  s      r  c                       sj   e Zd ZdZd fdd	Zeejej	dd Z
eejejdd Z fd	d
Ze fddZ  ZS )TFLiteKerasModelConverterV2z:Converts the given Keras model into TensorFlow Lite model.Nc                    s$   t t|   || _|| _d| _dS )a  Constructor for TFLiteConverter.

    Args:
      keras_model: tf.Keras.Model.
      trackable_obj: tf.AutoTrackable object associated with `funcs`. A
        reference to this object needs to be maintained so that Variables do not
        get garbage collected since functions have a weak reference to
        Variables. This is only required when the tf.AutoTrackable object is not
        maintained by the user (e.g. `from_saved_model`).
    TN)rh  r  r\   _keras_modelr  !experimental_lower_to_saved_model)rR   keras_modelr  ri  rS   rT   r\     s    z$TFLiteKerasModelConverterV2.__init__c                 C   s   zt j| j|tjddd W n ty2   Y dS 0 || _ttj	g| _
tjg| _| j| jd | jr| | j| j
\}}}t| j| j
| _|||fS dS )a  Save Keras model to the SavedModel format.

    Args:
      output_dir: The output directory to save the SavedModel.

    Returns:
      graph_def: The frozen GraphDef.
      input_tensors: List of input tensors.
      output_tensors: List of output tensors.
    Tsave_debug_info)r   NNNr  )_saved_modelsaver  _save_optionsSaveOptionsrM  r   ra   _tag_constantsSERVINGr   r  r  r   r  r  r  _loadr  )rR   
output_dirrv   r  r  rS   rS   rT   _convert_keras_to_saved_model  s,    



z9TFLiteKerasModelConverterV2._convert_keras_to_saved_modelc                 C   sx   d}t | jjtjs"t| jdd}t| j|}| }|g| _t	j
| jd dd\}}dd |jD }|j}||||fS )	zFreeze Keras model to frozen graph.

    Returns:
      graph_def: The frozen GraphDef.
      input_tensors: List of input tensors.
      output_tensors: List of output tensors.
      frozen_func: The frozen ConcreteFunction.
    NT)keep_original_batch_sizer   Flower_control_flowc                 S   s   g | ]}|j tjkr|qS rS   dtyper   resourcer   r  rS   rS   rT   r     s   zCTFLiteKerasModelConverterV2._freeze_keras_model.<locals>.<listcomp>)r   r  call_def_functionFunction_model_input_signature_trace_model_callget_concrete_functionr  _convert_to_constants*convert_variables_to_constants_v2_as_graphrs  rx  )rR   input_signaturefuncconcrete_funcr  rv   r  r  rS   rS   rT   _freeze_keras_model  s"    

z/TFLiteKerasModelConverterV2._freeze_keras_modelc              
      sd   t  }zH| |\}}}| jrBtt| |||W t|d S W t|d nt|d 0 dS zjConverts a Keras model as a saved model.

    Returns:
      The converted data in serialized format.
    TN)	tempfilemkdtempr  r   rh  r  r  shutilrmtree)rR   temp_dirrv   r  r  ri  rS   rT   _convert_as_saved_model  s    z3TFLiteKerasModelConverterV2._convert_as_saved_modelc                    sD   |   }|r|S |  \}}}}| ||||}tt| |||S )a  Converts a keras model based on instance variables.

    Returns:
      The converted data in serialized format.

    Raises:
      ValueError:
        Multiple concrete functions are specified.
        Input shape is not specified.
        Invalid quantization parameters.
    )r  r  r  rh  r  r  rR   saved_model_convert_resultrv   r  r  r  ri  rS   rT   r  .  s    
z#TFLiteKerasModelConverterV2.convert)N)rV   rW   rX   rY   r\   r   r   r  r   CONVERT_KERAS_TO_SAVED_MODELr  FREEZE_KERAS_MODELr  r  rf  r  r  rS   rS   ri  rT   r    s   
"
&r  c                       sf   e Zd ZdZd fdd	Zeejej	dd Z
eejejdd Zd	d
 Ze fddZ  ZS )TFLiteFrozenGraphConverterV2z;Converts the given frozen graph into TensorFlow Lite model.Nc                    s$   t t|   || _|| _d| _dS )  Constructor for TFLiteConverter.

    Args:
      funcs: List of TensorFlow ConcreteFunctions. The list should not contain
        duplicate elements.
      trackable_obj: tf.AutoTrackable object associated with `funcs`. A
        reference to this object needs to be maintained so that Variables do not
        get garbage collected since functions have a weak reference to
        Variables. This is only required when the tf.AutoTrackable object is not
        maintained by the user (e.g. `from_saved_model`).
    TN)rh  r  r\   r  r  r  rR   funcsr  ri  rS   rT   r\   L  s    z%TFLiteFrozenGraphConverterV2.__init__c                 C   sf   t | jdkrtdt | jdkr,tdtj| jd dd\}}dd |jD }|j}||||fS )	aB  Convert the given ConcreteFunction to frozen graph.

    Returns:
      graph_def: The frozen GraphDef.
      input_tensors: List of input tensors.
      output_tensors: List of output tensors.
      frozen_func: The frozen ConcreteFunction.

    Raises:
      ValueError: none or multiple ConcreteFunctions provided.
    r   !No ConcreteFunction is specified.r  znThis converter can only convert a single ConcreteFunction. Converting multiple functions is under development.Fr  c                 S   s   g | ]}|j tjkr|qS rS   r  r  rS   rS   rT   r   y  s   zJTFLiteFrozenGraphConverterV2._freeze_concrete_function.<locals>.<listcomp>)lenr  r   r  r  rs  rx  )rR   r  rv   r  r  rS   rS   rT   _freeze_concrete_function]  s    
z6TFLiteFrozenGraphConverterV2._freeze_concrete_functionc                 C   s,  t | jdkrtd| js dS | jr:t| jtjtj	fr>dS i }g }znt | jdkrp| jd |t
j< t
jg}n&| jD ]}|||jj< ||jj qvtj| j||tjddd W n ty   Y dS 0 || _ttjg| _|| _| jdd | jr(| | j| j\}}}t| j| j| _|||fS dS )	a  Save concrete functions to the SavedModel format.

    Args:
      output_dir: The output directory to save the SavedModel.

    Returns:
      graph_def: The frozen GraphDef.
      input_tensors: List of input tensors.
      output_tensors: List of output tensors.
    r   r  r  r  Tr  )
signaturesr   r  )r  r  r   r  r  r   	_functionConcreteFunctionr  r  r  r  rv  rl  r   r  r  r  r  rM  r   ra   r  r  r   r   r  r  r  )rR   r  r  signature_keysr  rv   r  r  rS   rS   rT   *_convert_concrete_functions_to_saved_model  sP    





zGTFLiteFrozenGraphConverterV2._convert_concrete_functions_to_saved_modelc              
   C   sf   t  }zJ| |\}}}| jrD| || | |W t|d S W t|d nt|d 0 dS )zConverts the given concrete functions as a saved model format.

    Returns:
      The converted data in serialized format.
    TN)r  r  r  r   r  r  r  r  )rR   r  rv   r  r  rS   rS   rT   r    s    
z4TFLiteFrozenGraphConverterV2._convert_as_saved_modelc                    sJ   | j r|  }|r|S |  \}}}}| ||||}tt| |||S r  )r  r  r  r  rh  r  r  r  ri  rS   rT   r    s    
z$TFLiteFrozenGraphConverterV2.convert)N)rV   rW   rX   rY   r\   r   r   r  r   FREEZE_CONCRETE_FUNCTIONr  )CONVERT_CONCRETE_FUNCTIONS_TO_SAVED_MODELr  r  rf  r  r  rS   rS   ri  rT   r  I  s   
!
<r  c                       s,   e Zd ZdZ fddZedd Z  ZS )TFLiteJaxConverterV2z8Converts the given jax model into TensorFlow Lite model.c                    s   t t|   || _|| _dS )a  Constructor for TFLiteConverter.

    Args:
      serving_funcs: A list functions of the serving func of the jax module, the
        model params should already be inlined. (e.g., `serving_func =
        functools.partial(model, params=params)`)
      inputs: Array of input tensor placeholders tuple,s like `jnp.zeros`. For
        example, wrapped in an array like
        "[('input1', input1), ('input2', input2)]]".
    Jax function is polymorphic, for example:
    ```python
    def add(a, b):
      return a + b
    ```
    Will yield different computations if different input signatures are passed
    in: Pass `add(10.0, 20.0)` will yield a scalar `add` while pass
      `add(np.random((100, 1)), np.random(100, 100))` will yield a broadcasting
      add.  We will need the input information to do tracing for the converter
      to properly convert the model. So it's important to pass in the desired
      `input placeholders` with the correct input shape/type.

    In the converted tflite model:
    Currently: the function name will be default to main, the output names will
    be the traced outputs. The output ordering shall match the serving function.
    N)rh  r  r\   _serving_funcs_inputs)rR   serving_funcsrs  ri  rS   rT   r\     s    zTFLiteJaxConverterV2.__init__c                 C   s|  t std| jstd| js(tdt| jt| jkr\dt| jt| j}t|t| jtt	fsttdt| jdkrtdt| jd tt	fstd	g }g }| jd D ]\}}|
| |
| qz"t | jd d
d}||  }W n ty   tdY n0 ||dd}||   t| j| j| jd}	| |	 ||	  tf i |}
| j|
|	| jdS )a  Converts a Jax serving func based on instance variables.

    Returns:
      The converted data in serialized format.

    Raises:
      ImportError:
        If cannot import the xla_computation from jax.
      ValueError:
        No serving function is specified.
        Input tensors are not specified.
        The truth value of an array with more than one element is ambiguous.
        Failed to convert the given Jax function to hlo.

    z'Cannot import xla_computation from jax.zNo serving func is specified.z Input tensors are not specified.z?Input tensor mapping len {} does not match serving func len {}.zAInput tensors should be pass in a tuple list wrapped in an array.r  z/Currently only support single serving function.r   z,The input placeholders are not a dictionary.cpu)backendz0Failed to convert the given Jax function to hlo.T)input_contentinput_namesis_proto_formatNr  )r    ImportErrorr  r   r  r  r  r   r0  r/  r   Zas_serialized_hlo_module_protorM  r  r  rg   rs   rt   ru   rp  r   _convert_jax_hlorQ  r   )rR   msgr  Zordered_inputs
input_namer  Zxla_compuationZ	hlo_protorC  rD  r   rS   rS   rT   r    sZ    


zTFLiteJaxConverterV2.convertr  rS   rS   ri  rT   r    s   r  zlite.TFLiteConverter)v1c                       sb   e Zd ZdZd fdd	ZedddZedddZed	d
 Zedd Z	 fddZ
  ZS )TFLiteConverterV2a  Converts a TensorFlow model into TensorFlow Lite model.

  Attributes:
    optimizations: Experimental flag, subject to change. Set of optimizations to
      apply. e.g {tf.lite.Optimize.DEFAULT}. (default None, must be None or a
      set of values of type `tf.lite.Optimize`)
    representative_dataset: A generator function used for integer quantization
      where each generated sample has the same order, type and shape as the
      inputs to the model. Usually, this is a small subset of a few hundred
      samples randomly chosen, in no particular order, from the training or
      evaluation dataset. This is an optional attribute, but required for full
      integer quantization, i.e, if `tf.int8` is the only supported type in
      `target_spec.supported_types`. Refer to `tf.lite.RepresentativeDataset`.
      (default None)
    target_spec: Experimental flag, subject to change. Specifications of target
      device, including supported ops set, supported types and a set of user's
      defined TensorFlow operators required in the TensorFlow Lite runtime.
      Refer to `tf.lite.TargetSpec`.
    inference_input_type: Data type of the input layer. Note that integer types
      (tf.int8 and tf.uint8) are currently only supported for post training
      integer quantization and quantization aware training. (default tf.float32,
      must be in {tf.float32, tf.int8, tf.uint8})
    inference_output_type: Data type of the output layer. Note that integer
      types (tf.int8 and tf.uint8) are currently only supported for post
      training integer quantization and quantization aware training. (default
      tf.float32, must be in {tf.float32, tf.int8, tf.uint8})
    allow_custom_ops: Boolean indicating whether to allow custom operations.
      When False, any unknown operation is an error. When True, custom ops are
      created for any op that is unknown. The developer needs to provide these
      to the TensorFlow Lite runtime with a custom resolver. (default False)
    exclude_conversion_metadata: Whether not to embed the conversion metadata
      into the converted model. (default False)
    experimental_new_converter: Experimental flag, subject to change. Enables
      MLIR-based conversion. (default True)
    experimental_new_quantizer: Experimental flag, subject to change. Enables
      MLIR-based quantization conversion instead of Flatbuffer-based conversion.
      (default True)
    experimental_enable_resource_variables: Experimental flag, subject to
      change. Enables 
      [resource variables](https://tensorflow.org/guide/migrate/tf1_vs_tf2#resourcevariables_instead_of_referencevariables)
      to be converted by this converter. This is only allowed if the
      from_saved_model interface is used. (default True)

  Example usage:

  ```python
  # Converting a SavedModel to a TensorFlow Lite model.
    converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
    tflite_model = converter.convert()

  # Converting a tf.Keras model to a TensorFlow Lite model.
  converter = tf.lite.TFLiteConverter.from_keras_model(model)
  tflite_model = converter.convert()

  # Converting ConcreteFunctions to a TensorFlow Lite model.
  converter = tf.lite.TFLiteConverter.from_concrete_functions([func], model)
  tflite_model = converter.convert()

  # Converting a Jax model to a TensorFlow Lite model.
  converter = tf.lite.TFLiteConverter.experimental_from_jax([func], [[
      ('input1', input1), ('input2', input2)])
  tflite_model = converter.convert()
  ```
  Nc                    s   t t| || dS )r  N)rh  r  r\   r  ri  rS   rT   r\     s    zTFLiteConverterV2.__init__c                 C   s`   t tjj |du r td |D ]0}t|tj	s$d}t|t
jrL|d7 }t|q$| ||S )a  Creates a TFLiteConverter object from ConcreteFunctions.

    Args:
      funcs: List of TensorFlow ConcreteFunctions. The list should not contain
        duplicate elements. Currently converter can only convert a single
        ConcreteFunction. Converting multiple functions is under development.
      trackable_obj:   An `AutoTrackable` object (typically `tf.module`)
        associated with `funcs`. A reference to this object needs to be
        maintained so that Variables do not get garbage collected since
        functions have a weak reference to Variables.

    Returns:
      TFLiteConverter object.

    Raises:
      Invalid input type.
    NzPlease consider providing the trackable_obj argument in the from_concrete_functions. Providing without the trackable_obj argument is deprecated and it will use the deprecated conversion path.z2This function takes in a list of ConcreteFunction.zI To get the ConcreteFunction from a Function, call get_concrete_function.)r   r#  r   r  TF_CONCRETE_FUNCTIONSr   ri   r   r  r  r  r  r   )r!  r  r  r  messagerS   rS   rT   from_concrete_functions  s    
z)TFLiteConverterV2.from_concrete_functionsc           	      C   s  t tjj t sVd}|r<t|dkr4tdn|d }t	
d tj|||dS |du rjttjg}t  t||}W d   n1 s0    Y  |s|j}|stdg }|D ]6}||jvrtd|d	|j||j|  qt||||}|jr|S | ||S )
a  Creates a TFLiteConverter object from a SavedModel directory.

    Args:
      saved_model_dir: SavedModel directory to convert.
      signature_keys: List of keys identifying SignatureDef containing inputs
        and outputs. Elements should not be duplicated. By default the
        `signatures` attribute of the MetaGraphdef is used. (default
        saved_model.signatures)
      tags: Set of tags identifying the MetaGraphDef within the SavedModel to
        analyze. All tags in the tag set must be present. (default
        {tf.saved_model.SERVING} or {'serve'})

    Returns:
      TFLiteConverter object.

    Raises:
      Invalid signature keys.
    Nr  $Only support a single signature key.r   zfInvoking the TF1 implementation of TFLiteConverter because eager is disabled. Consider enabling eager.)signature_keytag_setz(Only support at least one signature key.z6Invalid signature key '{}' found. Valid keys are '{}'.r.  )r   r#  r   r  TF_SAVED_MODELr6   executing_eagerlyr  r   r   ri   TFLiteConverterfrom_saved_modelra   r  r  
eager_moder  r  r  r1  r   r  r   )	r!  r   r  rq  r   r4   r  r   saved_model_converterrS   rS   rT   r    sF    


(
z"TFLiteConverterV2.from_saved_modelc                 C   s   t tjj t|S )zCreates a TFLiteConverter object from a Keras model.

    Args:
      model: tf.Keras.Model

    Returns:
      TFLiteConverter object.
    )r   r#  r   r  KERAS_MODELr  )r!  rN  rS   rS   rT   from_keras_model  s    z"TFLiteConverterV2.from_keras_modelc                 C   s   t tjj t||S )a  Creates a TFLiteConverter object from a Jax model with its inputs.

    Args:
      serving_funcs: A array of Jax functions with all the weights applied
        already.
      inputs: A array of Jax input placeholders tuples list, e.g.,
        jnp.zeros(INPUT_SHAPE). Each tuple list should correspond with the
        serving function.

    Returns:
      TFLiteConverter object.
    )r   r#  r   r  JAXr  )r!  r  rs  rS   rS   rT   experimental_from_jax#  s    z'TFLiteConverterV2.experimental_from_jaxc                    s   t t|  S r  )rh  r  r  rQ   ri  rS   rT   r  :  s    zTFLiteConverterV2.convert)N)N)NN)rV   rW   rX   rY   r\   r`  r  r  r	  r  r  r  rS   rS   ri  rT   r  Y  s   B%A

r  c                       s   e Zd ZdZ fddZdd Zdd Zdd	 Zee	j
ejd
d Zee	j
ejdd Zdd Zdd Zdd Zdd Z fddZ fddZ  ZS )TFLiteConverterBaseV1z@Converter subclass to share functionality between V1 converters.c                    st   t t|   tj| _d| _d| _tj	| _
i | _d| _d| _d| _d| _d| _d| _d| _|| _d| _d| jj_dS )zConstructor for TFLiteConverter.

    Args:
      experimental_debug_info_func: An experimental function to retrieve the
        graph debug info for a set of nodes from the `graph_def`.
    NTFr  )rh  r  r\   r   r   r   r   rH  r  TFLITEoutput_formatquantized_input_statsdefault_ranges_statsdrop_control_dependencyreorder_across_fake_quantchange_concat_input_rangesdump_graphviz_dirdump_graphviz_videoconversion_summary_dir_debug_info_func%_experimental_allow_all_select_tf_opsr   r   r5  )rR   experimental_debug_info_funcri  rS   rT   r\   M  s     zTFLiteConverterBaseV1.__init__c                 C   sd   |dkr0t d|  |r&tjg| _ng | _d S |dkrRt d|  || j_d S t| || d S Nr   zOProperty %s is deprecated, please use optimizations=[Optimize.DEFAULT] instead.r   zHProperty %s is deprecated, please use target_spec.supported_ops instead.)	warningswarnrI   rJ   rs   rt   r`   object__setattr__)rR   rl  rP   rS   rS   rT   r  e  s    z!TFLiteConverterBaseV1.__setattr__c                 C   sP   |dkr&t d|  tjt| jv S |dkrDt d|  | jjS t	| |S r  )
r  r  rI   rJ   ra   rs   rt   r`   r  __getattribute__)rR   rl  rS   rS   rT   r  v  s    z&TFLiteConverterBaseV1.__getattribute__c                 C   sb   t tjtjh}|d |v s(|d |v o0|  }|r^|d s^tdt|d t|d dS )z@Ensure the `quantized_input_stats` flag is provided if required.r   r   r  zThe `quantized_input_stats` flag must be defined when either `inference_type` flag or `inference_input_type` flag is set to tf.int8 or tf.uint8. Currently, `inference_type={}` and `inference_input_type={}`.N)r   r   r   rI  r   r   r  _get_tf_type_name)rR   rC  rD  Zquantized_typesZrequires_quantized_input_statsrS   rS   rT   _validate_quantized_input_stats  s    


z5TFLiteConverterBaseV1._validate_quantized_input_statsc                 C   s   |   s|  r|D ]j}|j}|s4tdt|| }d|dd v rbtdt||q|r|d du r| jdd q|rg | _g }| 	 D ](}||v r| j
||  q|
| q|rtdd|nd| _dS )	aq  Validate input parameters.

    Args:
      input_tensors: List of input tensors.
      quantized_input_stats: Map of input tensor names to a tuple of floats
        representing the mean and standard deviation of the training data.

    Raises:
      ValueError:
        Input shape is not specified.
        Quantization input stats is required but not provided.
    z-Provide an input shape for input array '{0}'.Nr  r  r   )
batch_sizezCQuantization input stats are not available for input tensors '{0}'.r.  )r   _has_valid_tensorsr  r   r  r  r  _set_batch_size_quantized_statsget_input_arraysr   r1  )rR   r  r  r  r  r  Zinvalid_statsrl  rS   rS   rT   r    s8    z&TFLiteConverterBaseV1._validate_inputsc                 C   sV   | j s| r|S z(t|}t|||| dgd}|W S  tyP   | Y S 0 dS )a.  Run a Grappler pass to optimize the TensorFlow graph.

    Args:
      graph_def: Frozen GraphDef to be optimized.
      input_tensors: List of input tensors.
      output_tensors: List of output tensors.
      quant_mode: the quantization mode.

    Returns:
      The optimized TensorFlow graph.
    r8   )r  N)r   r   r   disable_lower_using_switch_merger  r   rM  )rR   rv   r  r  rD  rv  optimized_graphrS   rS   rT   r    s    

z(TFLiteConverterBaseV1._optimize_tf_modelc                 C   s(  |  | j| j t| j| j| j| j| j| j	| j
| j}| | j| j| j|}t| j|| _|  }||| j| j || j| j| j| j| j| j| j| j| j| jd
 |  || | j!st"#d n
t"$d | % rt&f || j| jd|}nt'f || j(| j)| j*d|}| j+||| j,dS )P  Converts a TensorFlow GraphDef based on instance variables.

    Returns:
      The converted data in serialized format. Either a TFLite Flatbuffer or a
      Graphviz graph depending on value in `output_format`.

    Raises:
      ValueError:
        Input shape is not specified.
        None value for dimension in input_tensor.
    )
r  r  r  r  r  r  r  r  r  allow_all_select_tf_opsr  zUsing experimental converter: If you encountered a problem please file a bug. You can opt-out by setting experimental_new_converter=Falser  )r  input_arrays_with_shapeoutput_arrayscontrol_output_arraysr  )-r  _input_tensorsr  rg   rs   rt   ru   rl   r   rx   rp   r   r  _output_tensorsr  r  r   r  r  r   r   r   r  r%  r  r  r  r  r  r  r  r  r!  r   r   ri   r  r#  r  _convert_graphdef_with_arrays_input_arrays_with_shape_output_arrays_control_output_arraysrQ  r   )rR   rD  r(  rC  r   rS   rS   rT   r    sp    
zTFLiteConverterBaseV1.convertc                 C   s,   |   rdd | jD S dd | jD S dS )z[Returns a list of the names of the input tensors.

    Returns:
      List of strings.
    c                 S   s   g | ]}t |qS rS   )r  r  rS   rS   rT   r   9  r   z:TFLiteConverterBaseV1.get_input_arrays.<locals>.<listcomp>c                 S   s   g | ]\}}|qS rS   rS   )r   rl  r  rS   rS   rT   r   ;  r   N)r#  r.  r1  rQ   rS   rS   rT   r&  2  s    z&TFLiteConverterBaseV1.get_input_arraysc                 C   s   | j duo| jS )z\Checks if the input and output tensors have been initialized.

    Returns:
      Bool.
    N)r.  r/  rQ   rS   rS   rT   r#  =  s    z(TFLiteConverterBaseV1._has_valid_tensorsc                 C   sH   |   std| jD ],}|j }|d du r||d< || qdS )a  Sets the first dimension of the input tensor to `batch_size`.

    Args:
      batch_size: Batch size for the model. Replaces the first dimension of an
        input size array if undefined. (default 1)

    Raises:
      ValueError: input_tensor is not defined.
    zOThe batch size cannot be set for this model. Please use input_shapes parameter.r   N)r#  r   r.  r  r  r  )rR   r"  r  r  rS   rS   rT   r$  E  s    


z%TFLiteConverterBaseV1._set_batch_sizec                    s8   t | jrdS tt|  s dS | jr4td dS dS )NFz`conversion_summary_dir` does not work with unknown shapes. Graphs with unknown shapes might be different than when this flag is disabled.T)_is_ophint_convertedrl   rh  r  r   r  r   ri   rQ   ri  rS   rT   r   Y  s    
z0TFLiteConverterBaseV1._is_unknown_shapes_allowedc                    sL   | j | j| j| j| j| j| j| j| j	d t
t| | j| j| j d S )N)r  r  r  r  r  r  r  r  )r   r  r  r  r  r  r  r  r  r  rh  r  rE  rl   r   r   rQ   ri  rS   rT   rE  k  s"    
z4TFLiteConverterBaseV1._save_conversion_params_metric)rV   rW   rX   rY   r\   r  r  r!  r   r   r  r   r  r  r  r  r  r&  r#  r$  r   rE  r  rS   rS   ri  rT   r  J  s   
0
"Hr  c                       s2   e Zd ZdZd fdd	Ze fddZ  ZS )TFLiteSavedModelConverterr  Nc                    s   t t| | || _|| _|| _tj}t| jdkr>t	d| jd }t
| jddd| j|}|d | _|d | _|d | _|   dS )aL  Constructor for TFLiteConverter.

    Args:
      saved_model_dir: Directory of the SavedModel.
      saved_model_tags: Set of tags identifying the MetaGraphDef within the
        SavedModel to analyze. All tags in the tag set must be present. (default
        {tf.saved_model.SERVING}).
      saved_model_exported_names: Names to be exported when the saved model
        import path is on.
      experimental_debug_info_func: An experimental function to retrieve the
        graph debug info for a set of nodes from the `graph_def`.

    Raises:
      ValueError: Invalid arguments.
    r  r  r   Nr   )rh  r5  r\   r   r   r   r  r  r  r   r  rl   r.  r/  r  )rR   r   r  r  r  r   r   ri  rS   rT   r\     s&    



z"TFLiteSavedModelConverter.__init__c                    s   t t|  S r)  )rh  r5  r  rQ   ri  rS   rT   r    s    z!TFLiteSavedModelConverter.convert)Nr  rS   rS   ri  rT   r5  |  s
   
 (r5  c                       sT   e Zd ZdZd fdd	Zeejej	dd Z
 fddZe fd	d
Z  ZS )TFLiteKerasModelConverterz9Converts the given SavedModel into TensorFlow Lite model.Nc                    s$  t t| jdd t r|s"|r*tdt ||}t|}|	 }t
j|dd}	t|	j| || _|	j | _|	j| _|	j| _t|	j| _dS t   t ||}t  }
|rt|
j|}n|j}|rt|
j|}n|j}t|| t|
||}|| _|| _|| _|| _t|
j| _dS )aw  Constructor for TFLiteConverter.

    Args:
      model_file: Full filepath of HDF5 file containing the tf.keras model.
      input_arrays: List of input tensors to freeze graph with. Uses input
        arrays from SignatureDef when none are provided. (default None)
      input_shapes: Dict of strings representing input tensor names to list of
        integers representing input shapes (e.g., {"foo" : [1, 16, 16, 3]}).
        Automatically determined when input shapes is None (e.g., {"foo" :
          None}). (default None)
      output_arrays: List of output tensors to freeze graph with. Uses output
        arrays from SignatureDef when none are provided. (default None)
      custom_objects: Dict mapping names (strings) to custom classes or
        functions to be considered during model deserialization. (default None)

    Raises:
      ValueError: Invalid arguments.
    Nr  z`input_arrays` and `output_arrays` are unsupported with Eager mode. If your model requires any of these parameters, please use disable_eager_execution().Fr  )rh  r7  r\   r6   r  r   rG   get_load_model_functionr  r  r  !convert_variables_to_constants_v2_set_tensor_shapesrs  r  rv  as_graph_defrl   r.  rx  r/  r  r  get_clear_session_functionget_get_session_function_get_tensors_from_tensor_names_freeze_graph)rR   
model_fileinput_arraysinput_shapesr,  custom_objectsr  r8   r  r  sessr  r  rv   ri  rS   rT   r\     sR    


z"TFLiteKerasModelConverter.__init__c                 C   s   z| j j|dd W n ty(   Y dS 0 ttjg}tj}t|ddd||\}}}}|| _	|| _
|g| _|   | j	r|| _|| _|| _t|| _dS )zvSave Keras model to Saved Model format.

    Args:
      output_dir: The output directory to save the SavedModel.
    tf)save_formatN)r  r  rM  ra   r  r  r  r  r  r   r   r   r  rl   r.  r/  r  r  )rR   r  r  r   rv   r  r  Z
sess_graphrS   rS   rT   r  	  s$    z-TFLiteKerasModelConverter._freeze_keras_modelc              
      sX   t  }z<| | | jr6tt|  W t|d S W t|d nt|d 0 dS r  )	r  r  r  r   rh  r7  r  r  r  )rR   r  ri  rS   rT   r  #	  s    
z1TFLiteKerasModelConverter._convert_as_saved_modelc                    s   |   }|r|S tt|  S )aH  Converts a Keras model based on instance variables.

    Returns:
      The converted data in serialized format. Either a TFLite Flatbuffer or a
      Graphviz graph depending on value in `output_format`.

    Raises:
      ValueError:
        Input shape is not specified.
        None value for dimension in input_tensor.
    )r  rh  r7  r  )rR   r  ri  rS   rT   r  1	  s    z!TFLiteKerasModelConverter.convert)NNNN)rV   rW   rX   rY   r\   r   r   r  r   r  r  r  rf  r  r  rS   rS   ri  rT   r7    s       I
r7  c                       s2   e Zd ZdZd fdd	Ze fddZ  ZS )TFLiteFrozenGraphConverterz?Converts the given frozen graph def into TensorFlow Lite model.Nc                    st   t t| | || _|| _|| _d| _|  s<|| _|| _	|durV|durVt
d |durp|durpt
d dS )a  Constructor for TFLiteConverter.

    Args:
      graph_def: Frozen TensorFlow GraphDef.
      input_tensors: List of input tensors. Type and shape are computed using
        `foo.shape` and `foo.dtype`.
      output_tensors: List of output tensors (only .name is used from this).
      input_arrays_with_shape: Tuple of strings representing input tensor names
        and list of integers representing input shapes
        (e.g., [("foo", [1, 16, 16, 3])]). Use only when graph cannot be loaded
          into TensorFlow and when `input_tensors` and `output_tensors` are
          None. (default None)
      output_arrays: List of output tensors to freeze graph with. Use only when
        graph cannot be loaded into TensorFlow and when `input_tensors` and
        `output_tensors` are None. (default None)
      experimental_debug_info_func: An experimental function to retrieve the
        graph debug info for a set of nodes from the `graph_def`.

    Raises:
      ValueError: Invalid arguments.
    Nzsinput_arrays_with_shape will be ignored when both the given input_tensors and input_arrays_with_shape are not None.z`output_arrays will be ignored when both the given output_tensors and output_arrays are not None.)rh  rH  r\   rl   r.  r/  r3  r#  r1  r2  r   ri   rR   rv   r  r  r+  r,  r  ri  rS   rT   r\   H	  s     
z#TFLiteFrozenGraphConverter.__init__c                    s0   |   s"| jr| js"| js"tdtt|  S )r)  zIf input_tensors and output_tensors are None, both input_arrays_with_shape and output_arrays|control_output_arrays must be defined.)r#  r1  r2  r3  r   rh  rH  r  rQ   ri  rS   rT   r  y	  s    z"TFLiteFrozenGraphConverter.convert)NNNr  rS   rS   ri  rT   rH  E	  s      1rH  c                       sd   e Zd ZdZd fdd	Zedd ZedddZedd	d
ZedddZ	 fddZ
  ZS )r  a  Convert a TensorFlow model into `output_format`.

  This is used to convert from a TensorFlow GraphDef, SavedModel or tf.keras
  model into either a TFLite FlatBuffer or graph visualization.

  Attributes:
    optimizations: Experimental flag, subject to change. Set of optimizations to
      apply. e.g {tf.lite.Optimize.DEFAULT}. (default None, must be None or a
      set of values of type `tf.lite.Optimize`)
    representative_dataset: A generator function used for integer quantization
      where each generated sample has the same order, type and shape as the
      inputs to the model. Usually, this is a small subset of a few hundred
      samples randomly chosen, in no particular order, from the training or
      evaluation dataset. This is an optional attribute, but required for full
      integer quantization, i.e, if `tf.int8` is the only supported type in
      `target_spec.supported_types`. Refer to `tf.lite.RepresentativeDataset`.
      (default None)
    target_spec: Experimental flag, subject to change. Specifications of target
      device, including supported ops set, supported types and a set of user's
      defined TensorFlow operators required in the TensorFlow Lite runtime.
      Refer to `tf.lite.TargetSpec`.
    inference_type: Data type of numeric arrays, excluding the input layer.
      (default tf.float32, must be in {tf.float32, tf.int8, tf.uint8})
    inference_input_type: Data type of the numeric arrays in the input layer. If
      `inference_input_type` is in {tf.int8, tf.uint8}, then
      `quantized_input_stats` must be provided. (default is the value assigned
      to `inference_type`, must be in {tf.float32, tf.int8, tf.uint8})
    inference_output_type: Data type of the numeric arrays in the output layer.
      (default is the value assigned to `inference_type`, must be in
      {tf.float32, tf.int8, tf.uint8})
    quantized_input_stats: Map of input tensor names to a tuple of floats
      representing the mean and standard deviation of the training data.
      (e.g., {"foo" : (0., 1.)}). Required if `inference_input_type` is tf.int8
        or tf.uint8. (default None)
    default_ranges_stats: Tuple of integers (min, max) representing range values
      for all numeric arrays without a specified range. Intended for
      experimenting with quantization via "dummy quantization". (default None)
    allow_custom_ops: Boolean indicating whether to allow custom operations.
      When False any unknown operation is an error. When True, custom ops are
      created for any op that is unknown. The developer will need to provide
      these to the TensorFlow Lite runtime with a custom resolver. (default
      False)
    drop_control_dependency: Boolean indicating whether to drop control
      dependencies silently. This is due to TFLite not supporting control
      dependencies. (default True)
    reorder_across_fake_quant: Boolean indicating whether to reorder FakeQuant
      nodes in unexpected locations. Used when the location of the FakeQuant
      nodes is preventing graph transformations necessary to convert the graph.
      Results in a graph that differs from the quantized training graph,
      potentially causing differing arithmetic behavior. (default False)
    change_concat_input_ranges: Boolean to change behavior of min/max ranges for
      inputs and outputs of the concat operator for quantized models. Changes
      the ranges of concat operator overlap when true. (default False)
    output_format: Output file format. (default
      tf.compat.v1.lite.constants.TFLITE, must be in
      {tf.compat.v1.lite.constants.TFLITE,
      tf.compat.v1.lite.constants.GRAPHVIZ_DOT})
    dump_graphviz_dir: Full filepath of folder to dump the graphs at various
      stages of processing GraphViz .dot files. Preferred over
      `output_format=tf.compat.v1.lite.constants.GRAPHVIZ_DOT` in order to keep
      the requirements of the output file. (default None)
    dump_graphviz_video: Boolean indicating whether to dump the GraphViz .dot
      files after every graph transformation. Requires the `dump_graphviz_dir`
      flag to be specified. (default False)
    conversion_summary_dir: Full path of the directory to store conversion logs.
      (default None)
    exclude_conversion_metadata: Whether not to embed the conversion metadata
      into the converted model. (default False)
    target_ops: Deprecated. Please use `target_spec.supported_ops` instead.
    post_training_quantize: Deprecated. Please use `optimizations` instead and
      set it to `{tf.lite.Optimize.DEFAULT}`. (default False)
    experimental_new_converter: Experimental flag, subject to change. Enables
      MLIR-based conversion. (default True)
    experimental_new_quantizer: Experimental flag, subject to change. Enables
      MLIR-based quantization conversion instead of Flatbuffer-based conversion.
      (default True)

  Example usage:

    ```python
    # Converting a GraphDef from session.
    converter = tf.compat.v1.lite.TFLiteConverter.from_session(
      sess, in_tensors, out_tensors)
    tflite_model = converter.convert()
    open("converted_model.tflite", "wb").write(tflite_model)

    # Converting a GraphDef from file.
    converter = tf.compat.v1.lite.TFLiteConverter.from_frozen_graph(
      graph_def_file, input_arrays, output_arrays)
    tflite_model = converter.convert()
    open("converted_model.tflite", "wb").write(tflite_model)

    # Converting a SavedModel.
    converter = tf.compat.v1.lite.TFLiteConverter.from_saved_model(
        saved_model_dir)
    tflite_model = converter.convert()
    open("converted_model.tflite", "wb").write(tflite_model)

    # Converting a tf.keras model.
    converter = tf.compat.v1.lite.TFLiteConverter.from_keras_model_file(
        keras_model)
    tflite_model = converter.convert()
    open("converted_model.tflite", "wb").write(tflite_model)
    ```
  Nc                    s   t t| |||||| dS )a  Constructor for TFLiteConverter.

    Args:
      graph_def: Frozen TensorFlow GraphDef.
      input_tensors: List of input tensors. Type and shape are computed using
        `foo.shape` and `foo.dtype`.
      output_tensors: List of output tensors (only .name is used from this).
      input_arrays_with_shape: Tuple of strings representing input tensor names
        and list of integers representing input shapes
        (e.g., [("foo" : [1, 16, 16, 3])]). Use only when graph cannot be loaded
          into TensorFlow and when `input_tensors` and `output_tensors` are
          None. (default None)
      output_arrays: List of output tensors to freeze graph with. Use only when
        graph cannot be loaded into TensorFlow and when `input_tensors` and
        `output_tensors` are None. (default None)
      experimental_debug_info_func: An experimental function to retrieve the
        graph debug info for a set of nodes from the `graph_def`.

    Raises:
      ValueError: Invalid arguments.
    N)rh  r  r\   rI  ri  rS   rT   r\   	  s    zTFLiteConverter.__init__c                 C   s0   t tjj t|||}| |||t|jdS )aU  Creates a TFLiteConverter class from a TensorFlow Session.

    Args:
      sess: TensorFlow Session.
      input_tensors: List of input tensors. Type and shape are computed using
        `foo.shape` and `foo.dtype`.
      output_tensors: List of output tensors (only .name is used from this).

    Returns:
      TFLiteConverter class.
    r8  )r   r#  r   r  
TF_SESSIONr@  r  rv  )r!  rE  r  r  rv   rS   rS   rT   from_session
  s    zTFLiteConverter.from_sessionc                    s\  t tjj t  * t	 }t
|sBtd|t
|d}| }W d   n1 sl0    Y  zt }|| W n tjtfy   zHtd t|tstrt|d}nt|d}t }t|| W n( tjtfy   td|Y n0 Y n0 d}	zt|dd	 W n tyF   d
}	Y n0 |	rt |s`t!dt"|j#|}
t"|j#|}t$|
  | |j%|
|W  d   W  d   S  st!dt&|t& ' krt!d fdd|D }| |dd||dW  d   W  d   S W d   n1 s.0    Y  W d   n1 sN0    Y  dS )ad  Creates a TFLiteConverter class from a file containing a frozen GraphDef.

    Args:
      graph_def_file: Full filepath of file containing frozen GraphDef.
      input_arrays: List of input tensors to freeze graph with.
      output_arrays: List of output tensors to freeze graph with.
      input_shapes: Dict of strings representing input tensor names to list of
        integers representing input shapes (e.g., {"foo" : [1, 16, 16, 3]}).
        Automatically determined when input shapes is None (e.g., {"foo" :
          None}). (default None)

    Returns:
      TFLiteConverter class.

    Raises:
      IOError:
        File not found.
        Unable to parse input file.
      ValueError:
        The graph is not frozen.
        input_arrays or output_arrays contains an invalid tensor name.
        input_shapes is not correctly defined when required
    zFile '{0}' does not exist.rbNz(Ignore 'tcmalloc: large alloc' warnings.zutf-8z Unable to parse input file '{}'.T rk  Fz.Please freeze the graph using freeze_graph.py.z,input_shapes must be defined for this model.z?input_shapes must contain a value for each item in input_array.c                    s   g | ]}| | fqS rS   rS   )r   rl  rC  rS   rT   r   
  s   z5TFLiteConverter.from_frozen_graph.<locals>.<listcomp>)r  r  r+  r,  )(r   r#  r   r  TF_GRAPH_DEFry  rz  
as_default_sessionSessionr?   ExistsIOErrorr  GFileread
_graph_pb2GraphDefParseFromString_text_format
ParseErrorr   printr   rO   r   sixensure_binaryensure_textMerge_import_graph_def_NotFoundError_is_frozen_graphr   r?  rv  r;  rv   ra   keys)r!  graph_def_filerB  r,  rC  rE  ffile_contentrv   Zload_model_in_sessionr  r  r+  rS   rN  rT   from_frozen_graph6
  sn    
&



*
z!TFLiteConverter.from_frozen_graphc           	      C   s~   t tjj |du r"ttjg}|du r0tj	}t
|||g}|jrH|S t||||||}| |d |d |d t|d dS )a   Creates a TFLiteConverter class from a SavedModel.

    Args:
      saved_model_dir: SavedModel directory to convert.
      input_arrays: List of input tensors to freeze graph with. Uses input
        arrays from SignatureDef when none are provided. (default None)
      input_shapes: Dict of strings representing input tensor names to list of
        integers representing input shapes (e.g., {"foo" : [1, 16, 16, 3]}).
        Automatically determined when input shapes is None (e.g., {"foo" :
          None}). (default None)
      output_arrays: List of output tensors to freeze graph with. Uses output
        arrays from SignatureDef when none are provided. (default None)
      tag_set: Set of tags identifying the MetaGraphDef within the SavedModel to
        analyze. All tags in the tag set must be present. (default
        {tf.saved_model.SERVING})
      signature_key: Key identifying SignatureDef containing inputs and outputs.
        (default tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY)

    Returns:
      TFLiteConverter class.
    Nr   r  r      )rv   r  r  r  )r   r#  r   r  r  ra   r  r  r  r  r5  r   r  r  )	r!  r   rB  rC  r,  r  r   r  r   rS   rS   rT   r  
  s*    
z TFLiteConverter.from_saved_modelc                 C   s   t tjj t|||||S )a  Creates a TFLiteConverter class from a tf.keras model file.

    Args:
      model_file: Full filepath of HDF5 file containing the tf.keras model.
      input_arrays: List of input tensors to freeze graph with. Uses input
        arrays from SignatureDef when none are provided. (default None)
      input_shapes: Dict of strings representing input tensor names to list of
        integers representing input shapes (e.g., {"foo" : [1, 16, 16, 3]}).
        Automatically determined when input shapes is None (e.g., {"foo" :
          None}). (default None)
      output_arrays: List of output tensors to freeze graph with. Uses output
        arrays from SignatureDef when none are provided. (default None)
      custom_objects: Dict mapping names (strings) to custom classes or
        functions to be considered during model deserialization. (default None)

    Returns:
      TFLiteConverter class.
    )r   r#  r   r  r  r7  )r!  rA  rB  rC  r,  rD  rS   rS   rT   from_keras_model_file
  s    z%TFLiteConverter.from_keras_model_filec                    s   t t|  S r6  )rh  r  r  rQ   ri  rS   rT   r  
  s    zTFLiteConverter.convert)NNN)N)NNNNN)NNNN)rV   rW   rX   rY   r\   r`  rK  rh  r  rj  r  r  rS   rS   ri  rT   r  	  s0   o   !
 `     3     r  zlite.TocoConverterc                   @   sv   e Zd ZdZeedddd ZeedddddZeedd	dd
dZ	eedddddZ
dS )TocoConverterzConvert a TensorFlow model into `output_format`.

  This class has been deprecated. Please use `lite.TFLiteConverter` instead.
  Nz0Use `lite.TFLiteConverter.from_session` instead.c                 C   s   t |||S )z8Creates a TocoConverter class from a TensorFlow Session.)r  rK  )r!  rE  r  r  rS   rS   rT   rK    s    zTocoConverter.from_sessionz5Use `lite.TFLiteConverter.from_frozen_graph` instead.c                 C   s   t ||||S )zDCreates a TocoConverter class from a file containing a frozen graph.)r  rh  )r!  re  rB  r,  rC  rS   rS   rT   rh  	  s    	zTocoConverter.from_frozen_graphz4Use `lite.TFLiteConverter.from_saved_model` instead.c                 C   s   t ||||||S )z0Creates a TocoConverter class from a SavedModel.)r  r  )r!  r   rB  rC  r,  r  r   rS   rS   rT   r    s    zTocoConverter.from_saved_modelz9Use `lite.TFLiteConverter.from_keras_model_file` instead.c                 C   s   t ||||S )z9Creates a TocoConverter class from a tf.keras model file.)r  rj  )r!  rA  rB  rC  r,  rS   rS   rT   rj  $  s    	z#TocoConverter.from_keras_model_file)N)NNNNN)NNN)rV   rW   rX   rY   r`  _deprecation
deprecatedrK  rh  r  rj  rS   rS   rS   rT   rk  
  s<    	        rk  )rY   r&  rd  r(  r  r  rR  r  abslr   r]  r   google.protobufr   rZ  Zgoogle.protobuf.messager   tensorflow.core.frameworkr   rW  Z5tensorflow.lite.experimental.microfrontend.python.opsr   tensorflow.lite.pythonr   r   r	   r  Ztensorflow.lite.python.convertr
   r  r   r0  r   r  r   r  r   r   rL  r   r   r   rK  r   r   $tensorflow.lite.python.convert_phaser   r   r   Z*tensorflow.lite.python.convert_saved_modelr   r  Z"tensorflow.lite.python.interpreterr   r   r   tensorflow.lite.python.metricsr   tensorflow.lite.python.op_hintr   r   r4  r   Ztensorflow.lite.python.optimizer   r   Ztensorflow.lite.python.utilr    r!   r  r"   r  r#   r@  r$   r  r%   r   r&   rW  r'   r  r(   r?  r)   r   r*   rc  r+   r  r,   rJ  r-   rY  r.   r  r/   r;  r0   r  tensorflow.lite.toolsr1   Z8tensorflow.lite.tools.optimize.debugging.python.debuggerr2   r3   tensorflow.pythonr4   r  tensorflow.python.clientr5   rQ  tensorflow.python.eagerr6   r7   r  r8   r  tensorflow.python.frameworkr9   r  r:   r   r;   ry  r<   'tensorflow.python.framework.errors_implr=   rb  $tensorflow.python.framework.importerr>   ra  tensorflow.python.platformr?   Ztensorflow.python.saved_modelr@   r{  rA   r  rB   r  rC   r  Z"tensorflow.python.saved_model.loadrD   r  Z)tensorflow.python.saved_model.loader_implrE   r  tensorflow.python.utilrF   rl  rG    tensorflow.python.util.tf_exportrH   
_tf_exportr'  rI   r  rZ   r^   rg   r   rf  rg  r  r  r  r  r  r  r5  r7  rH  r  rk  rS   rS   rS   rT   <module>   s   ;/      OJ 
 $m
 q  4? K
  l
