
    Ph@                       d dl mZ d dlZd dlZd dl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c mZ d dlmZmZ d dlmZmZmZmZmZmZ d dlmZ d dlm Z m!Z! d dl"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( d d	l)m*Z* d
dgZ+ddZ,ddZ-ddZ.ddZ/ej`                  	 	 	 d	 	 	 	 	 dd       Z1ddZ2ddZ3ddZ4	 	 	 	 	 	 ddZ5 G d d
e!      Z6y)    )annotationsN)AnyCallableDictListOptionalSet)FakeQuantizeFusedMovingAvgObsFakeQuantize)HistogramObserverMinMaxObserverMovingAverageMinMaxObserver%MovingAveragePerChannelMinMaxObserverPerChannelMinMaxObserverPlaceholderObserver)"_ObserverOrFakeQuantizeConstructor)QuantizationSpec	Quantizer)_convert_scalars_to_attrsOP_TO_ANNOTATOROperatorConfigOperatorPatternTypepropagate_annotationQuantizationConfig)NodeXNNPACKQuantizer!get_symmetric_quantization_configc                     t        j                  | d      | \  }}|j                  j                          |j                  S )NT)
aten_graph)torchdynamoexportgrapheliminate_dead_code)functioninputsgm_s       |C:\Users\daisl\Desktop\realtime-object-detection\venv\Lib\site-packages\torch/ao/quantization/quantizer/xnnpack_quantizer.py_get_dynamo_graphr)   .   s8    9KxD96BEBHH  "88O    c                    | d   }d}t        j                  ||f      }t        j                  |f      }t        j                  |       }dd}t        ||||f      }t        |||f      }||gS )N   c                0    t        j                  | ||      S N)Flinear)actweightbiass      r(   	linear_opz'_get_linear_patterns.<locals>.linear_op;   s    xxVT**r*   r/   )torchonesr)   )	
input_sizein_channelsout_channelsr3   r4   r2   r5   pattern_w_biaspattern_wo_biass	            r(   _get_linear_patternsr=   4   sv    R.KLZZ{34F::|o&D
**Z
 C+ 'y32EFN'	C=AOO,,r*   c                    t         j                  j                  t         j                  j                  gt         j                  j                  t        j
                  gt        j                  t         j                  j                  gt        j                  t        j
                  ggt         j                  j                  gt        j                  ggt         j                  ggt         j                  j                  gt        j                  ggt         j                  j                  gt        j                  ggd} t        j                  |       S )N)conv2dr1   add
max_pool2dadaptive_avg_pool2d)r6   nnConv2dReLUr0   relur?   Linearr1   r@   	MaxPool2drA   AdaptiveAvgPool2drB   copydeepcopy)supported_operatorss    r(   (_supported_symmetric_quantized_operatorsrM   C   s    
 XX__ehhmm,XX__aff%XXuxx}}%XXqvv	
 HHOO$qxxj1}**+all^<XX''(""# 
A" ==,--r*   c                    g } t               t        d      t        d      t        dd      fD ]<  }t               }|j                         D ]  }| j                  t	        ||              > t        j                  |       S )NT)is_qat)is_per_channel)rP   rO   )r   rM   valuesappendr   rJ   rK   )supported_config_and_operatorsquantization_configopspattern_lists       r(   -_get_supported_symmetric_config_and_operatorsrW   X   sz    ;=")+)6)>)dK	  78JJLL*112LA )  ==788r*   c                r   ddi}|r+|r"t         }t        j                  d      }||d<   nt        }n|rt        }nt
        }t        t        j                  ddt        j                  | |j                  di |      }| rt        j                  nt        j                  }t        }|rt        }n| rt        }ddi}|r&|t        j                  k(  r
t        |d<   n	t        |d<   t        t        j                  d	d|d
d |j                  di |      }	d }
|rt        |d |	|
|      }|S t        |||	|
|      }|S )Nepsg      0?   )averaging_constantobserveri   )dtype	quant_min	quant_maxqscheme
is_dynamicobserver_or_fake_quant_ctrir   F)r^   r_   r`   ra   ch_axisrb   rc    )r
   r   	with_argsr   r   r   r   r6   int8per_tensor_affineper_channel_symmetricper_tensor_symmetricr   r   r   r   )rP   rO   rb   
extra_argsact_observer_or_fake_quant_ctrdynamic_quant_observeract_quantization_specweight_qscheme!weight_observer_or_fake_quant_ctrweight_quantization_specbias_quantization_specrT   s               r(   r   r   h   s|    #(J-9*%@%J%J#$&" &<Jz"-J*-@*->*,jj''#K#A#K#K $
$
	 (6##5;U;U  	 & ,I)	,D)"'JU777%@Jz"%JJz"/jj#N#D#N#N $
$

  "0!$"
  1!!$"
 r*   c                     t               S r/   )rW   re   r*   r(   #_get_supported_config_and_operatorsrt      s    8::r*   c                     d fd}|S )a  Get the module_name_filter function for a given module name, the filter accepts
    a node and checks if the node comes from a module that has certain module name

    For example:
        node: linear_op = call_function[...](...)  # comes from a module with name blocks.sub.linear1


    >> module_name_filter = _get_module_name_filter("blocks.sub")
    >> print(module_name_filter(node))
    True  # the node is from "blocks.sub" based on the fully qualified name "blocks.sub.linear1"
    c                    | j                   j                  di       }|j                         D  cg c]   } | t        d      d  j	                  dd      " }} |v S c c} w )Nnn_module_stack
L__self___r'   .)metagetkeyslenreplace)nrw   namesmodule_names      r(   module_name_filterz3_get_module_name_filter.<locals>.module_name_filter   sl     &&**%6;>M>R>R>T
>TAc,!"**34>T 	 
 e##
s   %Ar   r   returnboolre   )r   r   s   ` r(   _get_module_name_filterr      s    
$ r*   c                     d fd}|S )a  Get the module_type_filter function for a given module type, the filter accepts
    a node and checks if the node comes from a module that has certain module type

    For example:
        node: linear_op = call_function[...](...)  # comes from a module with type Block -> Sub -> Linear


    >> module_type_filter = _get_module_type_filter(Sub)  # submodule with type `Sub`, under the `Block` submodule
    >> print(module_type_filter(node))
    True  # the node is from the submodule `Sub` (same for `Block` and `Linear` as well)
    c                    | j                   j                  di       }|j                         D cg c]  \  }}|	 }}}|v S c c}}w )Nrw   )rz   r{   rQ   )r   rw   r'   ttypestps        r(   module_type_filterz3_get_module_type_filter.<locals>.module_type_filter   sL    
 &&**%6;.55787tq!78U{ 9s   Ar   re   )r   r   s   ` r(   _get_module_type_filterr      s     r*   c                    | D cg c]  }t        |       c}|D cg c]  }t        |       c}dfd}|S c c}w c c}w )Nc                6     t         fdz   D               S )Nc              3  .   K   | ]  } |        y wr/   re   ).0fr   s     r(   	<genexpr>z^_get_not_module_type_or_name_filter.<locals>.not_module_type_or_name_filter.<locals>.<genexpr>   s     T%Sqt%Ss   )any)r   module_name_list_filtersmodule_type_filterss   `r(   not_module_type_or_name_filterzK_get_not_module_type_or_name_filter.<locals>.not_module_type_or_name_filter   s    T%8;S%STTTTr*   r   )r   r   )tp_listmodule_name_listr   mr   r   r   s        @@r(   #_get_not_module_type_or_name_filterr      sV     BII2226IDTUDTq 7 :DTUU *) JUs	   >Ac                  0    e Zd Z e       ZddgZg dZdgZ fdZe	dd       Z
e		 	 	 	 dd       ZddZ	 	 	 	 	 	 dd	Z	 	 	 	 dd
Z	 	 	 	 ddZ	 	 	 	 ddZddZ	 d	 	 	 	 	 	 	 ddZ	 d	 	 	 	 	 	 	 ddZ	 	 	 	 ddZ	 	 	 	 ddZddZe	dd       Z xZS )r   conv_bn_reluconv_bn)r1   	conv_reluconvrB   gru_io_onlyrA   add_relur@   mul_relumulcatr1   c                Z    t         |           d | _        i | _        i | _        i | _        y r/   )super__init__global_configoperator_type_configmodule_type_configmodule_name_config)self	__class__s    r(   r   zXNNPACKQuantizer.__init__  s7    ;?  	! QSKMr*   c                x    t        i       }| j                  D ]  \  }}|j                  |        t        |      S r/   )setrS   r@   list)cls
op_configsspecr'   s       r(   "get_supported_quantization_configsz3XNNPACKQuantizer.get_supported_quantization_configs#  s6    .1"g
99GD!NN4  :Jr*   c                    |)g }| j                   D ]  \  }}|j                  |        |S | j                   D ]  \  }}||k(  s|c S  g S r/   )rS   extend)r   rT   all_opsr'   rU   configs         r(   .get_supported_operator_for_quantization_configz?XNNPACKQuantizer.get_supported_operator_for_quantization_config*  s_     &G<<3s# =N==KFC ,,
 > 	r*   c                    || _         | S r/   )r   )r   rT   s     r(   
set_globalzXNNPACKQuantizer.set_global>  s    0r*   c                $    || j                   |<   | S r/   )r   )r   operator_typerT   s      r(   set_operator_typez"XNNPACKQuantizer.set_operator_typeB  s    
 4G!!-0r*   c                $    || j                   |<   | S )a5  Set quantization_config for a submodule with type: `module_type`, for example:
        quantizer.set_module_name(Sub) or quantizer.set_module_name(nn.Linear), it will quantize all supported operator/operator
        patterns in the submodule with this module type with the given `quantization_config`
        )r   )r   module_typerT   s      r(   set_module_typez XNNPACKQuantizer.set_module_typeJ  s     0C,r*   c                6    |J d       || j                   |<   | S )a  Set quantization_config for a submodule with name: `module_name`, for example:
        quantizer.set_module_name("blocks.sub"), it will quantize all supported operator/operator
        patterns in the submodule with this module name with the given `quantization_config`
        z1 quantization_config == None is not supported yet)r   )r   r   rT   s      r(   set_module_namez XNNPACKQuantizer.set_module_nameT  s/      +	?>	?+/B,r*   c                    t        |      S )z-Transforms scalar values to tensor attributes)r   r   models     r(   transform_for_annotationz)XNNPACKQuantizer.transform_for_annotationa  s     )//r*   c                    | j                   r2| j                   j                  j                  r| j                  |      }n| j	                  |      }t        |       |S )z!just handling global spec for now)r   input_activationrb   )_annotate_for_dynamic_quantization_config(_annotate_for_static_quantization_configr   r   s     r(   annotatezXNNPACKQuantizer.annotateg  sN     $"4"4"E"E"P"PBB5IEAA%HEU#r*   c                    ||S |j                   r!| j                  D ]  }t        |   |||        | j                  D ]  }t        |   |||        |S r/   )rO   STATIC_QAT_ONLY_OPSr   
STATIC_OPSr   r   rT   	filter_fnops        r(   _annotate_all_static_patternsz.XNNPACKQuantizer._annotate_all_static_patternsq  s_     &L%%..#E+>	J ///BB':IF "r*   c                P    ||S | j                   D ]  }t        |   |||        |S r/   )DYNAMIC_OPSr   r   s        r(   _annotate_all_dynamic_patternsz/XNNPACKQuantizer._annotate_all_dynamic_patterns  s6     &L""BB':IF #r*   c                   t        | j                  j                               }| j                  j                         D ]!  \  }}| j	                  ||t        |             # t        | j                  j                               }| j                  j                         D ]!  \  }}| j	                  ||t        |             # | j	                  || j                  t        ||             |S r/   )
r   r   r|   itemsr   r   r   r   r   r   r   r   r   r   r   r   r   s          r(   r   z9XNNPACKQuantizer._annotate_for_static_quantization_config  s       7 7 < < >?#'#:#:#@#@#BK..v6{C $C
 t..3356#'#:#:#@#@#BK..v6{C $C
 	**/9IJ	

 r*   c                   t        | j                  j                               }| j                  j                         D ]!  \  }}| j	                  ||t        |             # t        | j                  j                               }| j                  j                         D ]!  \  }}| j	                  ||t        |             # | j	                  || j                  t        ||             |S r/   )
r   r   r|   r   r   r   r   r   r   r   r   s          r(   r   z:XNNPACKQuantizer._annotate_for_dynamic_quantization_config  s       7 7 < < >?#'#:#:#@#@#BK//v6{C $C
 t..3356#'#:#:#@#@#BK//v6{C $C
 	++/9IJ	

 r*   c                     y r/   re   r   s     r(   validatezXNNPACKQuantizer.validate  s    r*   c                    | j                   S r/   )rS   )r   s    r(   get_supported_operatorsz(XNNPACKQuantizer.get_supported_operators  s    111r*   )r   zList[QuantizationConfig])rT   Optional[QuantizationConfig]r   zList[OperatorPatternType])rT   r   r   r   )r   ztorch._ops.OpOverloadPacketrT   r   r   r   )r   r   rT   r   )r   strrT   r   )r   torch.fx.GraphModuler   r   r/   )r   r   rT   r   r   z Optional[Callable[[Node], bool]]r   r   )r   r   r   Noner   zList[OperatorConfig])__name__
__module____qualname__rt   rS   r   r   r   r   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__)r   s   @r(   r   r      sx   %H%J"J  	KN     ">	" &2 0 
	#:L5Q0)0	0 7;	# : 4	
 
* 7;	# : 4	
 
)	,)	, 2 2r*   )r$   r   r   ztorch.fx.Graph)r8   z	List[int])r   z$Dict[str, List[OperatorPatternType]]r   )FFF)rP   r   rO   r   rb   r   )r   r   )r   r   )r   zList[Callable]r   z	List[str]r   zCallable[[Node], bool])7
__future__r   rJ   	functoolstypingr   r   r   r   r   r	   r6   torch._dynamo_dynamor    torch.nn.functionalrC   
functionalr0   #torch.ao.quantization.fake_quantizer
   r   torch.ao.quantization.observerr   r   r   r   r   r   torch.ao.quantization.qconfigr   torch.ao.quantization.quantizerr   r   7torch.ao.quantization.quantizer.xnnpack_quantizer_utilsr   r   r   r   r   r   torch.fxr   __all__r)   r=   rM   rW   	lru_cacher   rt   r   r   r   r   re   r*   r(   <module>r      s    "   ; ;  #    M G   '-.*9   NNN N Nb;82	*	*/8	*	*B2y B2r*   