a
    OSicZ                  	   @   s  d dl mZ d dlmZmZ d dlZd dlmZ d dlm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZ ddlmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' d dl(Z(G dd dedd	d
gZ)G dd dedd	d
gZ*e)e!e$dZ+e)e$edZ,e)e!e"dZ-e)ee$dZ.e)ej/ej0ej1dej/ej1ddZ2e)ej/ej1dej/ej1ddZ3e)ee"dZ4e)e#edZ5e)e#e dZ6e)eedZ7e)eedZ8e)ejj9edZ:e)eejj9dZ;e)eedZ<e)e'edZ=d0ddZ>e)ej/ej?ddde%dZ@e)ej/ej?ddde&dZAe)ej/ej0dedZBe)ej/ej0dedZCd1ddZDe)ej/eddej?dddedZEe)ej/eddej?dddedZFdd ZGd2ddZHd3d d!ZIee) ejjJdd"d#d$ZKee) ZLeLeejJ ed%d&d'ZMeLeLd(d)d*ZNe)d+d,d-ZOee) d+d.d/ZPdS )4    )
namedtuple)OptionalAnyN)FakeQuantizeFakeQuantizeBasedefault_fake_quantdefault_dynamic_fake_quant%default_per_channel_weight_fake_quantdefault_weight_fake_quantdefault_fused_act_fake_quantdefault_fused_wt_fake_quantFusedMovingAvgObsFakeQuantize'default_fused_per_channel_wt_fake_quantdefault_embedding_fake_quant!default_embedding_fake_quant_4bit(fused_wt_fake_quant_range_neg_127_to_1274fused_per_channel_wt_fake_quant_range_neg_127_to_127   )HistogramObserverMovingAverageMinMaxObserverNoopObserverPlaceholderObserverReuseInputObserverdefault_debug_observerdefault_dynamic_quant_observerdefault_float_qparams_observer#default_float_qparams_observer_4bitdefault_observer#default_per_channel_weight_observerdefault_placeholder_observerdefault_weight_observer$weight_observer_range_neg_127_to_1270per_channel_weight_observer_range_neg_127_to_127default_reuse_input_observerc                       s    e Zd ZdZ fddZ  ZS )QConfiga  
    Describes how to quantize a layer or a part of the network by providing
    settings (observer classes) for activations and weights respectively.


    Note that QConfig needs to contain observer **classes** (like MinMaxObserver) or a callable that returns
    instances on invocation, not the concrete observer instances themselves.
    Quantization preparation function will instantiate observers multiple times for each of the layers.


    Observer classes have usually reasonable default arguments, but they can be overwritten with `with_args`
    method (that behaves like functools.partial)::

      my_qconfig = QConfig(
          activation=MinMaxObserver.with_args(dtype=torch.qint8),
          weight=default_observer.with_args(dtype=torch.qint8))

    c                    s4   t |tjst |tjr tdtt| | ||S )NzQConfig received observer instance, please pass observer class instead. Use MyObserver.with_args(x=1) to override arguments to constructor if needed)
isinstancennModule
ValueErrorsuperr$   __new__cls
activationweight	__class__ Y/var/www/html/django/DPS/env/lib/python3.9/site-packages/torch/ao/quantization/qconfig.pyr*   ?   s    zQConfig.__new__)__name__
__module____qualname____doc__r*   __classcell__r1   r1   r/   r2   r$   ,   s   r$   r-   r.   c                       s.   e Zd ZdZejjejjf fdd	Z  ZS )QConfigDynamica  
    Describes how to dynamically quantize a layer or a part of the network by providing
    settings (observer classes) for weights.

    It's like QConfig, but for dynamic quantization.

    Note that QConfigDynamic needs to contain observer **classes** (like MinMaxObserver) or a callable that returns
    instances on invocation, not the concrete observer instances themselves.
    Quantization function will instantiate observers multiple times for each of the layers.

    Observer classes have usually reasonable default arguments, but they can be overwritten with `with_args`
    method (that behaves like functools.partial)::

      my_qconfig = QConfigDynamic(weight=default_observer.with_args(dtype=torch.qint8))
    c                    s2   t |tjrtdtd tt| | ||S )NzQConfigDynamic received observer instance, please pass observer class instead. Use MyObserver.with_args(x=1) to override arguments to constructor if neededzTQConfigDynamic is going to be deprecated in PyTorch 1.12, please use QConfig instead)	r%   r&   r'   r(   warningswarnr)   r8   r*   r+   r/   r1   r2   r*   W   s    
zQConfigDynamic.__new__)	r3   r4   r5   r6   torchr&   Identityr*   r7   r1   r1   r/   r2   r8   G   s   r8   r-   r.   )r.   r-   )dtypecompute_dtype)r>   fbgemmc                 C   s   |dkrh| dkr&t tjddtd}q|| dkrDt tjddtd}q|| dkrbt tjddtd}q|t}ntd	t| d
 |S )z
    Returns the default PTQ qconfig for the specified backend.

    Args:
      * `backend`: a string representing the target backend. Currently supports `fbgemm`,
        `qnnpack` and `onednn`.

    Return:
        qconfig
    r   r@   T)reduce_ranger=   qnnpackFonednnVersion number: zB in get_default_qconfig is not supported. Version number must be 0)r$   r   	with_argsr   r    default_qconfigAssertionErrorstrbackendversionqconfigr1   r1   r2   get_default_qconfig   s$    rM   Fg      0?)r>   rA   epsc                 C   s  |dkrx| dkr,t tjtddddtd}nJ| dkrPt tjtddddtd}n&| d	krrt tjtddd
td}nt}n|dkr| dkrt tjtddddtd}nJ| dkrt tjtddddt	d}n&| d	krt tjtddd
td}nt
}ntdt| d |S )a5  
    Returns the default QAT qconfig for the specified backend.

    Args:
      * `backend`: a string representing the target backend. Currently supports `fbgemm`,
        `qnnpack` and `onednn`.
      * `version`: version, for backwards compatibility. Can be `None` or `1`.

    Return:
        qconfig
    r   r@      T)observer	quant_min	quant_maxrA   r=   rB   FrC   )rP   rQ   rR   r   rD   zJin get_default_qat_qconfig is not supported. Version number must be 0 or 1)r$   r   rE   r   r	   r
   default_qat_qconfigr   r   r   default_qat_qconfig_v2rG   rH   rI   r1   r1   r2   get_default_qat_qconfig  sl    rU   i   )rP   rQ   rR   r>   rA   rN   c                 C   s   | dt ftjj| ftjj| ftjj| ftjj|ftjj|ftjj|ftjj	| ftjj
j| ftjj
j| ftjj
j| ftjj
j|ftjj
j|ftjj
j|ftjj
j| ftjj| ftjj
j| ftj| ftjj| ftjj| ftjj| fgdS )Nreshape) Zobject_type)default_reuse_input_qconfigr;   r&   Conv1dConv2dConv3dConvTranspose1dConvTranspose2dConvTranspose3dLinear
functionalconv1dconv2dconv3dconv_transpose1dconv_transpose2dconv_transpose3dlinearReLUreluBatchNorm1dBatchNorm2dBatchNorm3d)rL   qconfig_transposer1   r1   r2    _get_default_qconfig_dict_helperR  s0    










ro   c                 C   s.   t | |}|}| dkr$t|jtd}t||S Nr@   r=   )rM   r$   r-   r    ro   rJ   rK   rL   rn   r1   r1   r2   get_default_qconfig_dictk  s
    
rr   c                 C   s.   t | |}|}| dkr$t|jtd}t||S rp   )rU   r$   r-   r
   ro   rq   r1   r1   r2   get_default_qat_qconfig_dictv  s
    
rs   )rL   modreturnc                 C   s   | du rdS t |tjjp4t |tjjp4t |tjj}|r|| jdu rHdS |  }t |tjjj	pnt |tjjj
}|r|J ddS )z0
    Verifies that this `qconfig` is valid.
    NzGPer channel weight observer is not supported yet for ConvTranspose{n}d.)r%   r;   r&   r]   r^   r_   r.   aoquantizationPerChannelMinMaxObserver%MovingAveragePerChannelMinMaxObserver)rL   rt   Zis_conv_transpose_modZexample_observeris_per_channelr1   r1   r2   assert_valid_qconfig  s"    
r{   )rL   moduleru   c                    sT   du s| du s| j dkr| S fdd  fdd}|| j}|| j}t||S )aP  This is a helper function for use in quantization prepare that updates a qconfig so that
    the constructors stored in the qconfig will create observers on the same device that
    'module' is on. This is intended to be used when the qconfigs are propagated to each
    module in order to avoid potential device alignment issues.

    Args:
        qconfig: QConfig with obs constructors stored in activation and weight
        module: module which the qconfig is related to

    Return:
        qconfig: configured so that obs constructors set to construct on the same device as module
    Nr=   c                     sf   t  tjjsJ dd   D dd   D B } t| dkrNtt| nd }|d u r^d S d|iS )Nc                 S   s   h | ]
}|j qS r1   device.0pr1   r1   r2   	<setcomp>      zcadd_module_to_qconfig_obs_ctr.<locals>.get_factory_kwargs_based_on_module_device.<locals>.<setcomp>c                 S   s   h | ]
}|j qS r1   r}   r   r1   r1   r2   r     r   r   r~   )	r%   r;   r&   r'   
parametersbufferslennextiter)devicesr~   )r|   r1   r2   )get_factory_kwargs_based_on_module_device  s    zPadd_module_to_qconfig_obs_ctr.<locals>.get_factory_kwargs_based_on_module_devicec                    sP   z | j d d}|  | j dW S  ty6   |  Y S  tyJ   |  Y S 0 d S )N)factory_kwargs)rE   with_callable_argsAttributeError	TypeError)Zoriginal_constructorcheck)r   r1   r2   1configure_constructor_to_put_obs_on_module_device  s    zXadd_module_to_qconfig_obs_ctr.<locals>.configure_constructor_to_put_obs_on_module_device)_fieldsr-   r.   r$   )rL   r|   r   r-   r.   r1   )r   r|   r2   add_module_to_qconfig_obs_ctr  s    

r   )q1q2c                 C   s   dd }| du s|du r | |kS | dur0|dus4J zrt | jtjjjjr^|| jj|jj}n| j|jk}t | jtjjjjr|| jj|jj}n| j|jk}|o|W S  t	y   | |k Y S 0 dS )zD
    Returns `True` if `q1` equals `q2`, and `False` otherwise.
    c                 S   s,   | j |j k}|o| j|jk}|o*| j|jkS N)funcargskeywords)p1p2samer1   r1   r2   partial_equals  s    z&qconfig_equals.<locals>.partial_equalsN)
r%   r-   r;   rv   rw   rP   _PartialWrapperr   r.   r   )r   r   r   Zactivation_sameZweight_samer1   r1   r2   qconfig_equals  s    
r   rL   c                 C   s:   dd }|   }t|tr.t|dr.||jS ||S dS )z
    Return whether the observer for activations defined in the given QConfig is memoryless.
    This means a MovingAverage observer with averaging constant equal to 1.
    c                 S   s   t | do| jdkS )Naveraging_constantr   )hasattrr   )rP   r1   r1   r2   _is_memoryless  s    z0activation_is_memoryless.<locals>._is_memorylessactivation_post_processN)r-   r%   r   r   r   )rL   r   Zactr1   r1   r2   activation_is_memoryless  s
    
r   c                 C   s$   | d uo"t |  to"t |  tS r   )r%   r-   r   r.   r   r   r1   r1   r2   is_reuse_input_qconfig  s
    r   )r@   r   )r@   r   )r@   r   )r@   r   )Qcollectionsr   typingr   r   r;   torch.nnr&   Z#torch.ao.quantization.fake_quantizer   r   r   r   r	   r
   r   r   r   r   r   r   r   r   rP   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r9   r$   r8   rF   Zdefault_debug_qconfigZdefault_per_channel_qconfigdefault_dynamic_qconfigrE   float32float16float16_dynamic_qconfigZfloat16_static_qconfigZper_channel_dynamic_qconfig!float_qparams_weight_only_qconfigZ&float_qparams_weight_only_qconfig_4bitrS   Zdefault_dynamic_qat_qconfigr<   Zdefault_weight_only_qconfigZdefault_activation_only_qconfigrT   rY   rM   qint8Z!default_symmetric_qnnpack_qconfigZ-default_per_channel_symmetric_qnnpack_qconfigZdefault_embedding_qat_qconfigZ"default_embedding_qat_qconfig_4bitrU   Z%default_symmetric_qnnpack_qat_qconfigZ1default_per_channel_symmetric_qnnpack_qat_qconfigro   rr   rs   r'   r{   Z
QConfigAnyr   r   r   r   r1   r1   r1   r2   <module>   s   @H
7


?		


*