o
    Ih!?                     @  s  d dl mZ d dlZd dlZd dlZd dlmZmZmZm	Z	 d dl
Z
d dlmZ d dlm  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mZ d dlm Z  d dl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' d d	l(m)Z) e	r{d d
l*m+Z+ d dl,m-Z- ddgZ.d:ddZ/d;ddZ0d<ddZ1d=ddZ2ej3					 	!	 d>d?d+dZ4d=d,d-Z5d@d/d0Z6dAd6d7Z7e)dd8G d9d deZ8dS )B    )annotationsN)AnyCallableOptionalTYPE_CHECKING)FakeQuantizeFusedMovingAvgObsFakeQuantize)HistogramObserverMinMaxObserverMovingAverageMinMaxObserver%MovingAveragePerChannelMinMaxObserverPerChannelMinMaxObserverPlaceholderObserver)QuantizationSpec	Quantizer_get_module_name_filter)_convert_scalars_to_attrsOP_TO_ANNOTATOROperatorConfigOperatorPatternTypepropagate_annotationQuantizationConfig)compatibility)"_ObserverOrFakeQuantizeConstructor)NodeXNNPACKQuantizer!get_symmetric_quantization_configfunctionr   returntorch.fx.Graphc                 C  s&   t j| dd| \}}|j  |jS )NT)
aten_graph)torchdynamoexportgrapheliminate_dead_code)r   inputsgm_ r)   e/var/www/vscode/kcb/lib/python3.10/site-packages/torch/ao/quantization/quantizer/xnnpack_quantizer.py_get_dynamo_graph0   s   
r+   
input_size	list[int]c           	      C  s`   | d }d}t ||f}t |f}t | }ddd}t||||f}t|||f}||gS )N   c                 S  s   t | ||S N)Flinear)actweightbiasr)   r)   r*   	linear_op=   s   z'_get_linear_patterns.<locals>.linear_opr0   )torchonesr+   )	r,   in_channelsout_channelsr4   r5   r3   r6   pattern_w_biaspattern_wo_biasr)   r)   r*   _get_linear_patterns6   s   

r=   $dict[str, list[OperatorPatternType]]c                  C  sj   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d} t| S )N)conv2dr2   addadaptive_avg_pool2d)r7   nnConv2dReLUr1   relur?   Linearr2   r@   AdaptiveAvgPool2drA   copydeepcopy)supported_operatorsr)   r)   r*   (_supported_symmetric_quantized_operatorsE   s   

rK   list[OperatorConfig]c                    sX   g } t  t ddt ddt dddfD ] t }|  fdd| D  qt| S )NT)is_qat)is_per_channel)rN   rM   c                 3  s    | ]}t  |V  qd S r0   )r   ).0pattern_listquantization_configr)   r*   	<genexpr>b   s
    
z@_get_supported_symmetric_config_and_operators.<locals>.<genexpr>)r   rK   extendvaluesrH   rI   )supported_config_and_operatorsopsr)   rQ   r*   -_get_supported_symmetric_config_and_operatorsY   s   


rX   F   rN   boolrM   
is_dynamicact_qminintact_qmaxweight_qminweight_qmaxc                 C  s  ddi}|r|rt }tjdd}	|	|d< n
t}n|rt}nt}ttj||tj	||jd
i |d}
| r6tj
ntj}t}|r@t}n| rDt}ddi}|rX|tjkrTt|d< nt|d< ttj|||dd|jd
i |d	}d }|rxt|
d |||}|S t|
|
|||}|S )Nepsg      0?   )averaging_constantobserver)dtype	quant_min	quant_maxqschemer]   observer_or_fake_quant_ctrr   F)rg   rh   ri   rj   ch_axisr]   rk   r)   )r   r   	with_argsr   r   r	   r   r7   int8per_tensor_affineper_channel_symmetricper_tensor_symmetricr
   r   r   r   )rN   rM   r]   r^   r`   ra   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_specrR   r)   r)   r*   r   i   s   



c                   C  s   t  S r0   )rX   r)   r)   r)   r*   #_get_supported_config_and_operators   s   rz   tpc                   s"   | j d | j  d	 fd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)
    .nr   r   r\   c                   sP   | j di }g }| D ]\}}t|tr|jd |j }|| q |v S )Nnn_module_stackr|   )metagetrU   
isinstancetype
__module____qualname__append)r}   r~   typesr(   ttp_strr)   r*   module_type_filter   s   
z3_get_module_type_filter.<locals>.module_type_filterNr}   r   r   r\   )r   r   )r{   r   r)   r   r*   _get_module_type_filter   s   r   tp_listlist[Callable]module_name_list	list[str]Callable[[Node], bool]c                   s0   dd | D dd |D  d
 fdd	}|S )Nc                 S     g | ]}t |qS r)   )r   )rO   r{   r)   r)   r*   
<listcomp>       z7_get_not_module_type_or_name_filter.<locals>.<listcomp>c                 S  r   r)   r   )rO   mr)   r)   r*   r      r   r}   r   r   r\   c                   s   t  fdd D  S )Nc                 3  s    | ]}| V  qd S r0   r)   )rO   fr}   r)   r*   rS      s    z^_get_not_module_type_or_name_filter.<locals>.not_module_type_or_name_filter.<locals>.<genexpr>)anyr   module_name_list_filtersmodule_type_filtersr   r*   not_module_type_or_name_filter   s   zK_get_not_module_type_or_name_filter.<locals>.not_module_type_or_name_filterr   r)   )r   r   r   r)   r   r*   #_get_not_module_type_or_name_filter   s   r   )is_backward_compatiblec                      s   e Zd ZdZe Zg dZg dZdgZd6 fddZ	e
d7d
dZe
d8ddZd9ddZd:ddZd;ddZd<ddZd=d"d#Zd=d$d%Z	&d>d?d)d*Z	&d>d?d+d,Zd=d-d.Zd=d/d0Zd@d1d2Ze
dAd4d5Z  ZS )Br   z
    !!! DEPRECATED !!!
    XNNPACKQuantizer is a marked as deprected. It will be removed in the future.
    It has been moved to executorch.backends.xnnpack.quantizer.xnnpack_quantizer.XNNPACKQuantizer.
    Please use the new quantizer instead.
    )conv_bn_reluconv_bnconv_transpose_bn_reluconv_transpose_bn)linear_relur2   	conv_reluconvconv_transpose_relurA   gru_io_onlyadd_relur@   mul_relumulcatr2   r   Nonec                   s:   t    t| jj d d | _i | _i | _i | _	d S )Nz is deprecated!)
super__init__warningswarn	__class____name__global_configoperator_type_configmodule_type_configmodule_name_config)selfr   r)   r*   r     s   

zXNNPACKQuantizer.__init__list[QuantizationConfig]c                 C  s   dd | j D }t|S )Nc                 S  s   h | ]\}}|qS r)   r)   )rO   specr(   r)   r)   r*   	<setcomp>#  s    zFXNNPACKQuantizer.get_supported_quantization_configs.<locals>.<setcomp>)rV   list)cls
op_configsr)   r)   r*   "get_supported_quantization_configs!  s   z3XNNPACKQuantizer.get_supported_quantization_configsrR   Optional[QuantizationConfig]list[OperatorPatternType]c                 C  sN   |d u rg }| j D ]	\}}|| q	|S | j D ]\}}||kr$|  S qg S r0   )rV   rT   )r   rR   all_opsr(   rW   configr)   r)   r*   .get_supported_operator_for_quantization_config(  s   z?XNNPACKQuantizer.get_supported_operator_for_quantization_configr   c                 C  s
   || _ | S r0   )r   )r   rR   r)   r)   r*   
set_global<  s   zXNNPACKQuantizer.set_globaloperator_typetorch._ops.OpOverloadPacketc                 C     || j |< | S r0   )r   )r   r   rR   r)   r)   r*   set_operator_type@  s   
z"XNNPACKQuantizer.set_operator_typemodule_typer   c                 C  r   )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   r   rR   r)   r)   r*   set_module_typeH  s   
z XNNPACKQuantizer.set_module_typemodule_namestrc                 C  s   |dus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`
        Nz1 quantization_config == None is not supported yet)r   )r   r   rR   r)   r)   r*   set_module_nameR  s
   

z XNNPACKQuantizer.set_module_namemodeltorch.fx.GraphModulec                 C  s   t |S )z-Transforms scalar values to tensor attributes)r   r   r   r)   r)   r*   transform_for_annotation_  s   z)XNNPACKQuantizer.transform_for_annotationc                 C  s2   | j r| j jjr| |}n| |}t| |S )z!just handling global spec for now)r   input_activationr]   )_annotate_for_dynamic_quantization_config(_annotate_for_static_quantization_configr   r   r)   r)   r*   annotatee  s
   
zXNNPACKQuantizer.annotateN	filter_fn Optional[Callable[[Node], bool]]c                 C  sN   |d u r|S |j r| jD ]
}t| ||| q| jD ]
}t| ||| q|S r0   )rM   STATIC_QAT_ONLY_OPSr   
STATIC_OPSr   r   rR   r   opr)   r)   r*   _annotate_all_static_patternso  s   

z.XNNPACKQuantizer._annotate_all_static_patternsc                 C  s,   |d u r|S | j D ]
}t| ||| q	|S r0   )DYNAMIC_OPSr   r   r)   r)   r*   _annotate_all_dynamic_patterns  s
   
z/XNNPACKQuantizer._annotate_all_dynamic_patternsc                 C     t | j }| j D ]\}}| ||t| qt | j }| j D ]\}}| ||t| q&| || jt	|| |S r0   )
r   r   keysitemsr   r   r   r   r   r   r   r   r   r   r   r   r   r)   r)   r*   r         

z9XNNPACKQuantizer._annotate_for_static_quantization_configc                 C  r   r0   )
r   r   r   r   r   r   r   r   r   r   r   r)   r)   r*   r     r   z:XNNPACKQuantizer._annotate_for_dynamic_quantization_configc                 C  s   d S r0   r)   r   r)   r)   r*   validate  s   zXNNPACKQuantizer.validaterL   c                 C  s   | j S r0   )rV   )r   r)   r)   r*   get_supported_operators  s   z(XNNPACKQuantizer.get_supported_operators)r   r   )r   r   )rR   r   r   r   )rR   r   r   r   )r   r   rR   r   r   r   )r   r   rR   r   )r   r   rR   r   )r   r   r   r   r0   )r   r   rR   r   r   r   r   r   )r   r   r   r   r   rL   )r   r   r   __doc__rz   rV   r   r   r   r   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r)   r)   r   r*   r      s6    	










)r   r   r   r    )r,   r-   )r   r>   r   )FFFrY   rZ   r[   rZ   )rN   r\   rM   r\   r]   r\   r^   r_   r`   r_   ra   r_   rb   r_   )r{   r   )r   r   r   r   r   r   )9
__future__r   rH   	functoolsr   typingr   r   r   r   r7   torch._dynamo_dynamor"   torch.nn.functionalrB   
functionalr1   #torch.ao.quantization.fake_quantizer   r   torch.ao.quantization.observerr	   r
   r   r   r   r   torch.ao.quantization.quantizerr   r   %torch.ao.quantization.quantizer.utilsr   7torch.ao.quantization.quantizer.xnnpack_quantizer_utilsr   r   r   r   r   r   torch.fx._compatibilityr   torch.ao.quantization.qconfigr   torch.fxr   __all__r+   r=   rK   rX   	lru_cacher   rz   r   r   r   r)   r)   r)   r*   <module>   sL     




U

!