
    BVhd]                     t   d Z ddlZddlZddlZddlmZmZmZmZm	Z	m
Z
mZmZmZ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 eZd ej6                  ej8                  d	 d
 dZdZdeeef   deee e!f      fdZ" ej2                  d       G d d             Z# ej2                  d       G d d             Z$y)z$Python TF-Lite QuantizationDebugger.    N)
AnyCallableDictIOIterableListMappingOptionalSequenceTuple)convert)interpreter)metrics)	tf_exportc                     | j                   S N)sizediffss    h/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/lite/tools/optimize/debugging/python/debugger.py<lambda>r   #   s
    %**     c                 R    t        j                  t        j                  |             S r   )npmaxabsr   s    r   r   r   &   s    266"&&-#8 r   c                 2    t        j                  | dz        S )N   )r   averager   s    r   r   r   '   s    

5!8(< r   )num_elementsstddev
mean_errormax_abs_errormean_squared_errorNumericVerifytensor_detailreturnc                 H    | d   }|sy|d   r|d   r|d   d   |d   d   fS y)zBReturns first scale and zero point from tensor detail, if present.quantization_parametersNscaleszero_pointsr    )r&   quant_paramss     r   _get_quant_paramsr.   -   sF     89,	(] ;"1%|M'B1'EFF	r   z*lite.experimental.QuantizationDebugOptionsc                   2   e Zd ZdZ	 	 	 	 	 	 ddeeeeej                  ge
f   f      deeeeeej                     eej                     ge
f   f      deeeeeej                     eej                     e
ege
f   f      deee      deee      ded	dfd
Zy)QuantizationDebugOptionsz5Debug options to set up a given QuantizationDebugger.Nlayer_debug_metricsmodel_debug_metricslayer_direct_compare_metricsdenylisted_opsdenylisted_nodesfully_quantizer'   c                 
   || _         || _        || _        g }|||fD ]$  }||j                  |j	                                & t        |      t        t        |            k7  rt        d      || _        || _	        || _
        y)a<  Initializes debugger options.

    Args:
      layer_debug_metrics: a dict to specify layer debug functions
        {function_name_str: function} where the function accepts result of
          NumericVerify Op, which is value difference between float and
          dequantized op results. The function returns single scalar value.
      model_debug_metrics: a dict to specify model debug functions
        {function_name_str: function} where the function accepts outputs from
          two models, and returns single scalar value for a metric. (e.g.
          accuracy, IoU)
      layer_direct_compare_metrics: a dict to specify layer debug functions
        {function_name_str: function}. The signature is different from that of
          `layer_debug_metrics`, and this one gets passed (original float value,
          original quantized value, scale, zero point). The function's
          implementation is responsible for correctly dequantize the quantized
          value to compare. Use this one when comparing diff is not enough.
          (Note) quantized value is passed as int8, so cast to int32 is needed.
      denylisted_ops: a list of op names which is expected to be removed from
        quantization.
      denylisted_nodes: a list of op's output tensor names to be removed from
        quantization.
      fully_quantize: Bool indicating whether to fully quantize the model.
        Besides model body, the input/output will be quantized as well.
        Corresponding to mlir_quantize's fully_quantize parameter.

    Raises:
      ValueError: when there are duplicate keys
    Nz%Provided metrics have duplicate keys.)r1   r2   r3   extendkeyslenset
ValueErrorr4   r5   r6   )	selfr1   r2   r3   r4   r5   r6   r9   r   s	            r   __init__z!QuantizationDebugOptions.__init__<   s    T  3D2D(DD%D02N $ 
	GLLN#	$
 4yCD	N">??(D,D(Dr   )NNNNNF)__name__
__module____qualname____doc__r
   r	   strr   r   ndarrayfloatr   intr   boolr>   r,   r   r   r0   r0   8   s'   =
 JN -1 #597;&+9)$,WS5=rzzl>C?D 6E6E .F %G9) %-W(2::"68L!M!&"' ( (.) %*	9) .6gc8RZZ((2::*>sKD ? 7 .9)  (S	29) "*$s)!49)  $9) 159)r   r0   z&lite.experimental.QuantizationDebuggerc                   `   e Zd ZdZ	 	 	 	 	 	 	 d&dee   dee   dee   dee   deeg ee	e
j                        f      dee   d	ee   d
dfdZed
efd       Zej"                  ded
dfd       Zd Zded
efdZd
efdZd
efdZ	 	 d'ded	edee   dee   d
df
dZd	ed
efdZd	ed
efdZd(dZd
eeeeef   f   fdZd
eeef   fdZdej@                  de	e
j                     ded
dfdZ!dej@                  d
e"e
j                     fd Z#d
e"e   fd!Z$d"ed
e%ee&f   fd#Z'd$e(e   d
dfd%Z)y))QuantizationDebuggera  Debugger for Quantized TensorFlow Lite debug mode models.

  This can run the TensorFlow Lite converted models equipped with debug ops and
  collect debug information. This debugger calculates statistics from
  user-defined post-processing functions as well as default ones.
  Nquant_debug_model_pathquant_debug_model_contentfloat_model_pathfloat_model_contentdebug_datasetdebug_options	converterr'   c                    || _         |xs
 t               | _        d| _        d| _        d| _        d| _        || j                  j                  rH|j                  }| j                  |      | _        | j                  j                         | _        ||_        | j                  |      | _        | j                  j                         | _        | j                  | j                  | j                  | j                  | j
                         ndt        j                  ||| j                  j                  du      | _        | j                  j                  rt        j                  ||      | _        | j#                          y)aH  Runs the TFLite debugging model with given debug options.

    Args:
      quant_debug_model_path: Path to the quantized debug TFLite model file.
      quant_debug_model_content: Content of the quantized debug TFLite model.
      float_model_path: Path to float TFLite model file.
      float_model_content: Content of the float TFLite model.
      debug_dataset: a factory function that returns dataset generator which is
        used to generate input samples (list of np.ndarray) for the model. The
        generated elements must have same types and shape as inputs to the
        model.
      debug_options: Debug options to debug the given model.
      converter: Optional, use converter instead of quantized model.

    Raises:
      ValueError: If the debugger was unable to be created.

    Attributes:
      layer_statistics: results of error metrics for each NumericVerify op
        results. in {layer_name: {metric_name: metric}} format.
      model_statistics: results of error metrics for difference between float
        and quantized models. in {metric_name: metric} format.
    Nfloat_model)!experimental_preserve_all_tensors)	_data_genr0   _debug_optionsrP   calibrated_modelrS   _float_interpreterr2   optimizations _set_converter_options_for_floatr   &_set_converter_options_for_calibration_init_from_converter_interpreterInterpreterr3   _quant_interpreter_initialize_stats)	r=   rJ   rK   rL   rM   rN   rO   rP   old_optimizationss	            r   r>   zQuantizationDebugger.__init__   sN   @ #DN'E+C+EDDN DD"D				0	0%33>>yI>>113"3	BB9Mdn"nn446d




..


&&	   ( !- 8 8
 
#!!>>dJ	!Md
 
			0	0".":":1#3r   c                     | j                   S r   )rV   r=   s    r   optionszQuantizationDebugger.options   s    r   rd   c                     || _         | j                  r| j                  sy | j                  | j                   | j                  | j                  | j                         | j                          y )NrR   )rV   rP   rW   r\   rS   r`   )r=   rd   s     r   rd   zQuantizationDebugger.options   s_    !D>>!6!6$$	  &
 	r   c           	      Z   t               | _        | j                  j                         D ]2  }| j                  j	                  |d   D ci c]  }||d   
 c}       4 d| _        d| _        | j                         st        d      t        j                         | _        | j                  j                  r/| j                  j	                  | j                  j                         d| _        d| _        t!        j"                         | _        | j$                  j'                          yc c}w )z"Helper function initializes stats.outputsindexNz4Please check if the quantized model is in debug mode)dict_defining_opr_   _get_ops_detailsupdate_numeric_verify_tensor_details_numeric_verify_op_details"_get_numeric_verify_tensor_detailsr<   _DEFAULT_LAYER_DEBUG_METRICScopy_layer_debug_metricsrV   r1   layer_statisticsmodel_statisticsmetrics_stubTFLiteMetrics_metrics"increase_counter_debugger_creation)r=   op_info
tensor_idxs      r   r`   z&QuantizationDebugger._initialize_stats   s    
 D**;;= O
:A):L
MJ:ww''
MOO +/D'&*D#224MNN < A A CD..
&&t':':'N'NO D D ..0DMMM446 Ns   	D(
is_debugc                    | j                   st        d      t        j                  | j                  | j                   j
                  | j                  j                  || j                  j                  | j                  j                        S )NzSNo converter found, use this function with the converter option in the constructor.disable_per_channelr6   enable_numeric_verifyr4   r5   )
rP   r<   r   mlir_quantizerW   !_experimental_disable_per_channelrV   r6   r4   r5   )r=   r{   s     r   _get_quantized_modelz)QuantizationDebugger._get_quantized_model   sv    >> > ? ?    NNLL**99&**99,,==? ?r   c                 &    | j                  d      S )al  Returns a non-instrumented quantized model.

    Convert the quantized model with the initialized converter and
    return bytes for nondebug model. The model will not be instrumented with
    numeric verification operations.

    Returns:
      Model bytes corresponding to the model.
    Raises:
      ValueError: if converter is not passed to the debugger.
    Fr{   r   rc   s    r   get_nondebug_quantized_modelz1QuantizationDebugger.get_nondebug_quantized_model   s     $$e$44r   c                 &    | j                  d      S )a  Returns an instrumented quantized model.

    Convert the quantized model with the initialized converter and
    return bytes for model. The model will be instrumented with numeric
    verification operations and should only be used for debugging.

    Returns:
      Model bytes corresponding to the model.
    Raises:
      ValueError: if converter is not passed to the debugger.
    Tr   r   rc   s    r   get_debug_quantized_modelz.QuantizationDebugger.get_debug_quantized_model  s     $$d$33r   rW   rS   c                 (   t        j                  ||j                  |j                  d|j                  |j
                        | _        t        j                  | j                        | _	        d| _
        |t        j                  |      | _
        yy)a  Convert the model and apply options.

    Converts the quantized model and initializes a quantized model interpreter
    with the quantized model. Returns a float model interpreter if float model
    is provided.

    Args:
      options: a QuantizationDebugOptions object.
      converter: an initialized tf.lite.TFLiteConverter.
      calibrated_model: Calibrated model bytes.
      float_model: Float model bytes.
    Tr}   )model_contentN)r   r   r   r6   r4   r5   quant_modelr]   r^   r_   rX   )r=   rd   rP   rW   rS   s        r   r\   z)QuantizationDebugger._init_from_converter  s    " ,,%GG--"-- 113D +66&&(D"D , 8 8#!%d r   c                 ,    |j                   rg |_         |S )?Verify converter options and set required experimental options.)rY   r=   rP   s     r   rZ   z5QuantizationDebugger._set_converter_options_for_float2  s      "ir   c                 ~    |j                   st        d      |j                  st        d      d|_        d|_        |S )r   z@converter object must set optimizations to lite.Optimize.DEFAULTz0converter object must set representative_datasetT)rY   r<   representative_datasetexperimental_mlir_quantizer_experimental_calibrate_onlyr   s     r   r[   z;QuantizationDebugger._set_converter_options_for_calibration9  sJ     ""
LN N++IJJ,0I)-1I*r   c                     | j                         | _        | j                  j                  r| j	                         | _        yy)zRuns models and gets metrics.N)_collect_layer_statisticsrs   rV   r2   _collect_model_statisticsrt   rc   s    r   runzQuantizationDebugger.runF  s8     ::<D.."<<>d /r   c                 X   t        j                  d       }d}| j                         D ]  }| j                  | j                  ||       d}| j                  j                          | j                         D ]d  }|d   }| j                  j                  |d         }| j                  j                         D ]"  \  }}||   |   j                   ||             $ f | j                  j                  | j                         D ]  }|d   }| j                  |d      }	| j                  j                  |	      }
|
d   \  }}| j                  j                  |d      }| j                  j                  j                         D ]i  \  }}||   |   j                   || j                  j                  |      | j                  j                  |      |d	   d
   d   |d	   d   d                k   |j!                         D ]$  }|D ]  }t#        j$                  ||         ||<    & |S )a  Collects layer statistics by applying layer debug metrics.

    For all data from the given RepresentativeDataset, collect statistics per
    example by getting the NumericVerify op results in _quant_interpreter
    and calculating layer debug metrics on the results.

    Returns:
      aggregated per-layer statistics of NumericVerify results.
      {layer_name: {metric_name: metric}}
    c                  4    t        j                  t              S r   )collectionsdefaultdictlistr,   r   r   r   z@QuantizationDebugger._collect_layer_statistics.<locals>.<lambda>X  s    ''- r   TFnamerh   inputsr   subgraph_indexr)   r*   r+   )r   r   rU   _set_input_tensorsr_   invokero   
get_tensorrr   itemsappendrV   r3   rj   _get_op_details_get_tensor_detailsvaluesr   nanmean)r=   rs   
initializetensor_datar&   tensor_namer   metric_name	metric_fnop_idx	op_detailq_idxf_idxquant_input_detailr   s                  r   r   z.QuantizationDebugger._collect_layer_statisticsL  sf    #..-/ J~~' 
d55{JOj $$&  BBD N-#F+''22=3IJ&*&?&?&E&E&G 	N"K
;
'
4
;
;Ie<L
M	NN 
			9	9	E!DDF 	M%f-+$$]7%;<&--==fE)"8,,%#66JJA  K  '
 &&CCIIK {I[)+6==++66u=++66u=&'@A(KAN&'@A-P		B $**, @  @+!zz'+*>?@@ r   c                    t        j                  t              }d}| j                         D ]  }| j	                  | j
                  ||       | j
                  j                          | j                  | j
                        }g }| j                  rR| j	                  | j                  ||       | j                  j                          | j                  | j                        }d}| j                  j                  j                         D ]   \  }}||   j                   |||             "  |j                         D ci c]  \  }}|t        j                  |       c}}S c c}}w )a  Collects model output metrics.

    For all data from the given RepresentativeDataset, collect all model output
    results from float model & quantized debug model, and calculate metrics
    by using model output functions. As a result, self.model_results is filled,

    where self.model_results[model_output_function_name] = `aggregated model
    output function value` (a scalar).

    Returns:
      aggregated per-model output discrepancy metrics.
      {metric_name: aggregated_metric}
    TF)r   r   r   rU   r   r_   r   _get_output_tensorsrX   rV   r2   r   r   r   mean)	r=   rt   r   r   quant_tensor_datafloat_tensor_datar   r   metrics	            r   r   z.QuantizationDebugger._collect_model_statistics  sT    #..t4J~~' =
d55{JO
$$&2243J3JK 		 	 ##[*	>&&( 44T5L5LMj ,,@@FFH= ;%,,'):;	==#=2 $4#9#9#;K 	RWWV_$  s   ? E#r   r   r   c                    |j                         }t        |      t        |      k7  r-t        dj                  t        |      t        |                  |rCt	        ||      D ]$  \  }}|j                  |d   |j                         & |j                          t	        ||      D ]  \  }}|j                  t        j                  k(  r`|d   t        j                  k(  rJt        |      }|r=|\  }}	t        j                  ||z  |	z         j                  t        j                        }|j                  |d   |        y)a  Sets input tensors into TFLite model Interpreter.

    Args:
      interpreter: a tf.lite.Interpreter object with allocated tensors.
      tensor_data: a list of Numpy array data.
      initialize: set to true when input is first set for the interpreter, to
        set input shapes and allocate tensors.

    Raises:
      ValueError: when inputs can't be set, or size of provided inputs does not
      match size of model inputs.
    zPNumber of inputs provided ({}) does not match number of inputs to the model ({})rh   dtypeN)get_input_detailsr:   r<   formatzipresize_tensor_inputshapeallocate_tensorsr   r   float32int8r.   roundastype
set_tensor)
r=   r   r   r   input_detailsinput_detailtensorr-   scale
zero_points
             r   r   z'QuantizationDebugger._set_input_tensors  s"     113M
=S--!6#k"2C4FGI I "%m["A M
,''W(=v||LM""$ #M; ? <f		#W(=(H(6*
%88Ve^z9:AA"''J&\'2F;<r   c                 R   g }|j                         D ]  }|j                  |d         }|d   t        j                  k(  rTt	        |      }|rG|\  }}|j                  t        j                        |z
  |z  j                  t        j                        }|j                  |        |S )zReturns output tensors of given TFLite model Interpreter.

    Args:
      interpreter: a tf.lite.Interpreter object with allocated tensors.

    Returns:
      a list of numpy arrays representing output tensor results.
    rh   r   )get_output_detailsr   r   r   r.   r   r   r   )r=   r   rg   output_detailr   r-   r   r   s           r   r   z(QuantizationDebugger._get_output_tensors  s     G$779 %%mG&<=f	w	277	*(7*
%]]2::.;uDLLjj&nnV Nr   c                 `   | j                   sg | _         i | _        | j                  j                         D ]l  }|d   t        k(  s| j                   j                  | j                  j                  |d   d   d             | j                   d   d   }|| j                  |<   n | j                   S )z7Returns all names of all tensors from NumericVerify op.op_namerg   r   r   r   )rm   rn   r_   rk   _NUMERIC_VERIFY_OP_NAMEr   r   )r=   ry   r   s      r   ro   z7QuantizationDebugger._get_numeric_verify_tensor_details  s     ..,.d)(*d%,,==? A'9!88

-
-
4
4%%99)$Q' : ;< ;;B?G+9@$
)
)+
6A ...r   numeric_verify_namec                     |j                  dd      \  }}|t        t              dz   d }t        j                  d|d         r|dd }|t        |      fS )aO  Gets the index and name of NumericVerify Op's quantized input tensor.

    Args:
      numeric_verify_name: name of the NumericVerify op's output tensor. It has
        format of `NumericVerify/{quantized_tensor_name}:{quantized_tensor_idx}`

    Returns:
      Tuple of (tensor_name, tensor_idx) for quantized op's output tensor.
    :   Nz\dr   )rsplitr:   r   rematchrF   )r=   r   r   rz   float_tensor_names        r   _get_operand_name_and_indexz0QuantizationDebugger._get_operand_name_and_index  sd     288a@K#C(?$@1$D$EF	xx(,-+CR0s://r   filec                    ddgt        | j                  j                               z   }| j                  j                  0|t        | j                  j                  j                               z  }|g dz  }t        j                  ||      }|j                          | j                  r| j                  j                         D ]  \  }}|j                         }| j                  |      \  |d<   }| j                  |   d   d   |d<   | j                  j                  | j                  |d            d   |d<   | j                  j!                  |d   d      }|d	   d
   d   |d	   d   d   c|d<   |d<   |j#                  |        yy)zpDumps layer statistics into file, in csv format.

    Args:
      file: file, or file-like object to write.
    r   rz   N)r   r   r   r   r   r   r   r)   r*   r+   r   r   )r   rr   r9   rV   r3   csv
DictWriterwriteheaderrs   r   rq   r   rn   r_   r   rj   r   writerow)	r=   r   fieldswriterr   r   data_detailss	            r   layer_statistics_dumpz*QuantizationDebugger.layer_statistics_dump  s    &d.G.G.L.L.N)OOF77CT((EEJJLMMf
44F^^D&)F
00668 -$||~#'#C#CD#I m	a!<<TB8LQO\11AAd<0133<>Y))==q > 2 -.x8;-.}=a@ 	*WtL) 	 r   )NNNNNNN)NN)r'   N)*r?   r@   rA   rB   r
   rC   bytesr   r   r   r   rD   r0   TFLiteConverterr>   propertyrd   setterr`   rG   r   r   r   r\   rZ   r[   r   r   rE   r   r   r]   r^   r   r   r   ro   r   rF   r   r   r   r,   r   r   rI   rI   x   sj    8<<@156::>CG6:>'/}>*25/> "*#> %-UO	>
 'xx 455(7 8> ''?@> #?3> @D>@ /   >>	5 	$ 	 	72?4 ?E ?5E 54 4" @D:>	%$<%&5% .6e_% )1	% DH	%>&+:&+:?4c4U
3C.C)D 4l,c5j)9 ,\ <L,D,D  <&.rzz&: <%) <.2 <D%116:2::6F0/$s) / 07:0?DS#X0$3 D r   rI   )%rB   r   r   r   typingr   r   r   r   r   r   r	   r
   r   r   numpyr   tensorflow.lite.pythonr   r   r]   tensorflow.lite.python.metricsr   ru   tensorflow.python.utilr   r   stdr   rp   r   rC   rE   rF   r.   r0   rI   r,   r   r   <module>r      s    +  
 	% % %  * > B ,  -ff**8<   * 38$)1%s
2C)D AB<) <) C<)~ =>l l ?lr   