B
    d&                 @   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   ZAddIntermediateTensors)model_content r
   \/var/www/html/venv/lib/python3.7/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krg }|dkr$g }yt|||| _|| _W n. tk
rl } zt d| W dd}~X Y nX | js|t 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   ZCalibrationWrapper_calibrator_model_content	Exception_interpreter)selfr	   Zcustom_op_registerers_by_nameZcustom_op_registerers_by_funcer
   r
   r   __init__-   s     
zCalibrator.__init__c             C   sL   g }| j |}t|  dd d}x|D ]\}}|||  q.W |S )Nc             S   s   | d d S )N   indexr
   )itemr
   r
   r   <lambda>T       z:Calibrator._create_input_array_from_dict.<locals>.<lambda>)key)r   Zget_signature_runnersortedZget_input_detailsitemsappend)r   signature_keyinputsinput_arrayZsignature_runnerZinput_detailsZ
input_name_r
   r
   r   _create_input_array_from_dictO   s    
z(Calibrator._create_input_array_from_dictc             C   s^  i }xR| D ]F}t |trft |d ts4td| jdkrLt| jd| _|d }| ||d }nVt |tr| jdkrt| jd| _d}| d|}n"t |trd}|}ntd	|||kr0d||< |r|dk	r| j
dd	 |D | n| j
d
d	 |D  n"|dk	r&| j
| n
| j
  |dk	rJ| j
|| q| j
| qW 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 tupleN)r	   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   s   g | ]}t |jqS r
   )listshape).0sr
   r
   r   
<listcomp>~   s    z,Calibrator._feed_tensors.<locals>.<listcomp>c             S   s   g | ]}t |jqS r
   )r$   r%   )r&   r'   r
   r
   r   r(      s    )
isinstancetupledictr   r   r   r   r#   r$   formatr   ZPrepareZ
FeedTensor)r   dataset_genresize_inputZinitializedsampler   r!   r
   r
   r   _feed_tensorsY   sB    








zCalibrator._feed_tensorsTFc	       	   
   C   sR   |  || | jt| jt| j|t| jt| j|S )ay  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.
    )r0   r   QuantizeModelnpdtypeas_numpy_dtypenum)	r   r-   
input_typeoutput_typeallow_floatZactivations_typeZ	bias_typer.   Z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.
    )r0   r   r1   r2   r3   r4   r5   )r   r-   r6   r7   r8   Z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.   )r0   r   Z	Calibrate)r   r-   r
   r
   r   	calibrate   s    
zCalibrator.calibrate)NN)T)__name__
__module____qualname____doc__r   r#   r0   r   r   ZOPTIMIZE_TFLITE_MODELr   Z#QUANTIZE_USING_DEPRECATED_QUANTIZERr   Zint8Zint32r9   r:   Z	CALIBRATEr;   r
   r
   r
   r   r   '   s    

3 r   )r?   numpyr2   Z$tensorflow.lite.python.convert_phaser   r   r   Z"tensorflow.lite.python.interpreterr   Ztensorflow.python.frameworkr   Z"tensorflow.python.util.lazy_loaderr   globalsr   r   r   r
   r
   r
   r   <module>   s   