o
    i e%                     @   s|   d 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 ed	e d
Zdd ZG dd dZdS )z?Python wrapper for post training quantization with calibration.    N)	Component)convert_phase)SubComponent)Interpreter)dtypes)
LazyLoader_calibration_wrapperzKtensorflow.lite.python.optimize._pywrap_tensorflow_lite_calibration_wrapperc                 C   s
   t | S )z0Adds intermediate tensors to fused op if needed.)r   AddIntermediateTensorsmodel_content r   Y/var/www/myenv/lib/python3.10/site-packages/tensorflow/lite/python/optimize/calibrator.pyadd_intermediate_tensors&   s   
r   c                   @   s   e Zd ZdZ		dddZdd Zdd Zeej	e
jejejd	d
fddZeej	e
j		dddZeej	e
jdd ZdS )
CalibratorzqCalibrates a floating point model and then quantizes it.

  This is an internal class, not a public interface.
  Nc              
   C   s|   |st d|du rg }|du rg }zt|||| _|| _W n ty1 } zt d| d}~ww | js9t dd| _dS )a  Constructor.

    Args:
      model_content: Content of a TF-Lite Flatbuffer file.
      custom_op_registerers_by_name: List of str (symbol names) that take a
        pointer to a MutableOpResolver and register custom ops.
      custom_op_registerers_by_func: List of functions that take a pointer to a
        MutableOpResolver and register custom ops.

    Raises:
      ValueError: If the calibrator was unable to open the model.
    z"`model_content` must be specified.NzFailed to parse the model: %s.zFailed to parse the model.)
ValueErrorr   CalibrationWrapper_calibrator_model_content	Exception_interpreter)selfr   custom_op_registerers_by_namecustom_op_registerers_by_funcer   r   r   __init__1   s(   

zCalibrator.__init__c                 C   sH   g }| j |}t|  dd d}|D ]\}}|||  q|S )Nc                 S   s   | d d S )N   indexr   )itemr   r   r   <lambda>[   s    z:Calibrator._create_input_array_from_dict.<locals>.<lambda>)key)r   get_signature_runnersortedget_input_detailsitemsappend)r   signature_keyinputsinput_arraysignature_runnerinput_details
input_name_r   r   r   _create_input_array_from_dictV   s   
z(Calibrator._create_input_array_from_dictc                 C   sN  i }| D ]}t |tr0t |d tstd| jdu r#t| jd| _|d }| ||d }n+t |trJ| jdu rAt| jd| _d}| d|}nt |trTd}|}ntd	|||vrd||< |r|durv| j
dd	 |D | n| j
d
d	 |D  n|dur| j
| n| j
  |dur| j
|| q| j
| qdS )zFeed tensors to the calibrator.r   zgYou need to provide either a dictionary with input names and values in the second arugment in the tupleNr
   r   a"  You need to provide either a dictionary with input names and values, a tuple with signature key and a dictionary with input names and values, or an array with input values in the order of input tensors of the graph in the representative_dataset function. Unsupported value from dataset: {}.Tc                 S      g | ]}t |jqS r   listshape.0sr   r   r   
<listcomp>       z,Calibrator._feed_tensors.<locals>.<listcomp>c                 S   r-   r   r.   r1   r   r   r   r4      r5   )
isinstancetupledictr   r   r   r   r,   r/   formatr   Prepare
FeedTensor)r   dataset_genresize_inputinitializedsampler%   r'   r   r   r   _feed_tensorsa   sP   





	
zCalibrator._feed_tensorsTFc	           	   
   C   sR   |  || | jt| jt| j|t| jt| j|S )aB  Calibrates the model with specified generator and then quantizes it.

    The input shapes of the calibrator are resized with the calibration data if
    `resize_input` is set.

    Returns:
      A quantized model.

    Args:
      dataset_gen: A generator that generates calibration samples.
      input_type: A tf.dtype representing the desired real-value input type.
      output_type: A tf.dtype representing the desired real-value output type.
      allow_float: A boolean. False if the resulting model cannot perform float
        computation, useful when targeting an integer-only backend. If False, an
        error will be thrown if an operation cannot be quantized, otherwise the
        model will fallback to float ops.
      activations_type: A tf.dtype representing the desired type for
        activations.
      bias_type: A tf.dtype representing the desired type for bias.
      resize_input: A boolean. True if the shape of the sample data is different
        from the input.
      disable_per_channel: A boolean. True if disabling per-channel
        quantization.
    r@   r   QuantizeModelnpdtypeas_numpy_dtypenum)	r   r<   
input_typeoutput_typeallow_floatactivations_type	bias_typer=   disable_per_channelr   r   r   calibrate_and_quantize   s   'z!Calibrator.calibrate_and_quantizec                 C   s6   |  || | jt| jt| j||S )a  Calibrates the model with specified generator and then quantizes it.

    Only the single op with output op_output_name will be quantized.
    The input shapes of the calibrator are resized with the calibration data.

    Returns:
      A quantized model.

    Args:
      dataset_gen: A generator that generates calibration samples.
      input_type: A tf.dtype representing the desired real-value input type.
      output_type: A tf.dtype representing the desired real-value output type.
      allow_float: A boolean. False if the resulting model cannot perform float
        computation, useful when targeting an integer-only backend. If False, an
        error will be thrown if an operation cannot be quantized, otherwise the
        model will fallback to float ops.
      op_output_name: A string, only this op will be quantized.
      resize_input: A boolean. True if the shape of the sample data is different
        from the input.
    rA   )r   r<   rG   rH   rI   op_output_namer=   r   r   r   calibrate_and_quantize_single   s   !z(Calibrator.calibrate_and_quantize_singlec                 C   s   | j |dd | j S )zCalibrates the model with specified generator.

    Returns:
      A model with min and max calibration stats.

    Args:
      dataset_gen: A generator that generates calibration samples.
    T)r=   )r@   r   	Calibrate)r   r<   r   r   r   	calibrate   s   

zCalibrator.calibrate)NN)T)__name__
__module____qualname____doc__r   r,   r@   r   r   OPTIMIZE_TFLITE_MODELr   #QUANTIZE_USING_DEPRECATED_QUANTIZERr   int8int32rM   rO   	CALIBRATErQ   r   r   r   r   r   +   s0    
%9
-%r   )rU   numpyrC   $tensorflow.lite.python.convert_phaser   r   r   "tensorflow.lite.python.interpreterr   tensorflow.python.frameworkr   "tensorflow.python.util.lazy_loaderr   globalsr   r   r   r   r   r   r   <module>   s   
