o
    Zh!?                     @  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)Z
aten_graph)torchdynamoZexportgraphZeliminate_dead_code)r   ZinputsZgm_ r$   `/var/www/auris/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_opr+   )torchZonesr&   )	r'   Zin_channelsZout_channelsr/   r0   r.   r1   Zpattern_w_biasZpattern_wo_biasr$   r$   r%   _get_linear_patterns6   s   

r3   $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)conv2dr-   addadaptive_avg_pool2d)r2   nnZConv2dZReLUr,   Zrelur5   ZLinearr-   r6   ZAdaptiveAvgPool2dr7   copydeepcopy)Zsupported_operatorsr$   r$   r%   (_supported_symmetric_quantized_operatorsE   s   

r;   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)r>   r=   c                 3  s    | ]}t  |V  qd S r+   )r   ).0Zpattern_listquantization_configr$   r%   	<genexpr>b   s
    
z@_get_supported_symmetric_config_and_operators.<locals>.<genexpr>)r   r;   extendvaluesr9   r:   )supported_config_and_operatorsopsr$   r@   r%   -_get_supported_symmetric_config_and_operatorsY   s   


rG   F   r>   boolr=   
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 )NZepsg      0?   )Zaveraging_constantZobserver)dtype	quant_min	quant_maxqschemerL   observer_or_fake_quant_ctrr   F)rS   rT   rU   rV   Zch_axisrL   rW   r$   )r   r   Z	with_argsr   r   r	   r   r2   Zint8Zper_tensor_affineZper_channel_symmetricZper_tensor_symmetricr
   r   r   r   )r>   r=   rL   rM   rO   rP   rQ   
extra_argsZact_observer_or_fake_quant_ctrZdynamic_quant_observerZact_quantization_specZweight_qschemeZ!weight_observer_or_fake_quant_ctrZweight_quantization_specZbias_quantization_specrA   r$   r$   r%   r   i   s   



c                   C  s   t  S r+   )rG   r$   r$   r$   r%   #_get_supported_config_and_operators   s   rY   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   rK   c                   sP   | j di }g }| D ]\}}t|tr|jd |j }|| q |v S )Nnn_module_stackr[   )metagetrD   
isinstancetype
__module____qualname__append)r\   r]   typesr#   tZtp_strr$   r%   module_type_filter   s   
z3_get_module_type_filter.<locals>.module_type_filterNr\   r   r   rK   )rb   rc   )rZ   rh   r$   rg   r%   _get_module_type_filter   s   rj   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$   )rj   )r?   rZ   r$   r$   r%   
<listcomp>       z7_get_not_module_type_or_name_filter.<locals>.<listcomp>c                 S  rp   r$   r   )r?   mr$   r$   r%   rq      rr   r\   r   r   rK   c                   s   t  fdd D  S )Nc                 3  s    | ]}| V  qd S r+   r$   )r?   fr\   r$   r%   rB      s    z^_get_not_module_type_or_name_filter.<locals>.not_module_type_or_name_filter.<locals>.<genexpr>)anyru   Zmodule_name_list_filtersZmodule_type_filtersru   r%   not_module_type_or_name_filter   s   zK_get_not_module_type_or_name_filter.<locals>.not_module_type_or_name_filterri   r$   )rk   rm   rx   r$   rw   r%   #_get_not_module_type_or_name_filter   s   ry   )Z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.
    )Zconv_bn_reluZconv_bnZconv_transpose_bn_reluZconv_transpose_bn)Zlinear_relur-   Z	conv_reluconvZconv_transpose_relur7   Zgru_io_onlyZadd_relur6   Zmul_relumulcatr-   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$   )r?   specr#   r$   r$   r%   	<setcomp>#  s    zFXNNPACKQuantizer.get_supported_quantization_configs.<locals>.<setcomp>)rE   list)clsZ
op_configsr$   r$   r%   "get_supported_quantization_configs!  s   z3XNNPACKQuantizer.get_supported_quantization_configsrA   Optional[QuantizationConfig]list[OperatorPatternType]c                 C  sN   |d u rg }| j D ]	\}}|| q	|S | j D ]\}}||kr$|  S qg S r+   )rE   rC   )r   rA   Zall_opsr#   rF   configr$   r$   r%   .get_supported_operator_for_quantization_config(  s   z?XNNPACKQuantizer.get_supported_operator_for_quantization_configr   c                 C  s
   || _ | S r+   )r   )r   rA   r$   r$   r%   
set_global<  s   zXNNPACKQuantizer.set_globaloperator_typetorch._ops.OpOverloadPacketc                 C     || j |< | S r+   )r   )r   r   rA   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   rA   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   rA   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   Zinput_activationrL   )_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 r+   )r=   STATIC_QAT_ONLY_OPSr   
STATIC_OPSr   r   rA   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 r+   )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 r+   )
r   r   keysitemsr   r   r   rj   r   ry   r   r   rm   r   r   rk   r   r$   r$   r%   r         

z9XNNPACKQuantizer._annotate_for_static_quantization_configc                 C  r   r+   )
r   r   r   r   r   r   r   rj   r   ry   r   r$   r$   r%   r     r   z:XNNPACKQuantizer._annotate_for_dynamic_quantization_configc                 C  s   d S r+   r$   r   r$   r$   r%   validate  s   zXNNPACKQuantizer.validater<   c                 C  s   | j S r+   )rE   )r   r$   r$   r%   get_supported_operators  s   z(XNNPACKQuantizer.get_supported_operators)r   r}   )r   r   )rA   r   r   r   )rA   r   r   r   )r   r   rA   r   r   r   )r   r   rA   r   )r   r   rA   r   )r   r   r   r   r+   )r   r   rA   r   r   r   r   r   )r   r   r   r}   r   r<   )r   rb   rc   __doc__rY   rE   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   r4   r   )FFFrH   rI   rJ   rI   )r>   rK   r=   rK   rL   rK   rM   rN   rO   rN   rP   rN   rQ   rN   )rZ   r   )rk   rl   rm   rn   r   ro   )9
__future__r   r9   	functoolsr   typingr   r   r   r   r2   Ztorch._dynamoZ_dynamor!   Ztorch.nn.functionalr8   Z
functionalr,   Z#torch.ao.quantization.fake_quantizer   r   Ztorch.ao.quantization.observerr	   r
   r   r   r   r   Ztorch.ao.quantization.quantizerr   r   Z%torch.ao.quantization.quantizer.utilsr   Z7torch.ao.quantization.quantizer.xnnpack_quantizer_utilsr   r   r   r   r   r   Ztorch.fx._compatibilityr   Ztorch.ao.quantization.qconfigr   Ztorch.fxr   __all__r&   r3   r;   rG   	lru_cacher   rY   rj   ry   r   r$   r$   r$   r%   <module>   sL     




U

!