U
    ,-ed                     @   s  d dl m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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)m*Z*m+Z+m,Z, d dl-Z-d dl.Z.ddd	d
dddddddddddddddddddddd d!d"d#d$gZ/G d%d dedd&d'gZ0G d(d dedd&d'gZ1e0e%e(d)Z2e0e(e!d*Z3e0e%e&d)Z4e0e"e(d)Z5e0ej6ej7d+d,ej6ej7d-d)Z8e0ej6ej7d-ej6ej7d-d)Z9e0e"e&d)Z:e0e'e#d)Z;e0e'e$d)Z<e0eed)Z=e0eed)Z>e0ej	j?ed)Z@e0eej	j?d)ZAe0eed)ZBe0e+ed)ZCdLd/dZDe0ej6ejEd0d1d2e)d)ZFe0ej6ejEd0d1d2e*d)ZGe0ej6ejHd-ed)ZIe0ej6ejHd-ed)ZJe0eed)ZKdMd3d ZLe0ej6ed4d5ejEd0d1d6ed)ZMe0ej6ed4d5ejEd0d1d6ed)ZNe0ej6ejHd-ej6ejHd-d)ZOe0ej6ejPd-dd)ZQdNd7d!ZRdOd8d"ZSee0 ej	jTdd9d:d;ZUee0 ZVd<eV_WeVee	jT ed=d>d?ZXeeee, ee f ZYeYeYd@dAdBZZeed@dCdDZ[eVeVdEdFd$Z\e0dGdHdIZ]ee0 dGdJdKZ^dS )P    )
namedtuple)OptionalAnyUnionTypeN)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   )_PartialWrapperMinMaxObserver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_observerObserverBaseQConfigQConfigDynamicdefault_qconfigdefault_debug_qconfigdefault_per_channel_qconfigdefault_dynamic_qconfigfloat16_dynamic_qconfigfloat16_static_qconfigper_channel_dynamic_qconfig!float_qparams_weight_only_qconfig&float_qparams_weight_only_qconfig_4bitdefault_quint8_weight_qconfigdefault_qat_qconfigdefault_dynamic_qat_qconfigdefault_weight_only_qconfigdefault_activation_only_qconfigdefault_qat_qconfig_v2default_reuse_input_qconfig!default_symmetric_qnnpack_qconfig-default_per_channel_symmetric_qnnpack_qconfig%default_symmetric_qnnpack_qat_qconfig1default_per_channel_symmetric_qnnpack_qat_qconfigdefault_embedding_qat_qconfig"default_embedding_qat_qconfig_4bitget_default_qconfigget_default_qat_qconfigget_default_qconfig_dictget_default_qat_qconfig_dict
QConfigAnyqconfig_equalsc                       s    e Zd ZdZ fddZ  ZS )r)   a  
    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                    s0   t |tjst |tjr td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super__new__cls
activationweight	__class__ ^/var/www/html/Darija-Ai-Train/env/lib/python3.8/site-packages/torch/ao/quantization/qconfig.pyrL   e   s    zQConfig.__new__)__name__
__module____qualname____doc__rL   __classcell__rS   rS   rQ   rT   r)   R   s   rO   rP   c                       s.   e Zd ZdZejjejjf fdd	Z  ZS )r*   a  
    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                    s.   t |tjrtdtd 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)rG   rH   rI   rJ   warningswarnrK   rL   rM   rQ   rS   rT   rL   }   s    
zQConfigDynamic.__new__)	rU   rV   rW   rX   torchrH   IdentityrL   rY   rS   rS   rQ   rT   r*   m   s   rO   rP   )rP   rO   T)dtypeZ
is_dynamic)r_   x86c                 C   s   ddddg}| |kr.t dt|  d|  |dkr| dkrTttjdd	td
}q| dkrrttjdd	td
}q| dkrtj	 st
d ttjdd	td
}q| dkrttjdd	td
}qt}nt dt| d |S )z
    Returns the default PTQ qconfig for the specified backend.

    Args:
      * `backend` (str): a string representing the target backend. Currently supports
        `x86` (default), `fbgemm`, `qnnpack` and `onednn`.

    Return:
        qconfig
    fbgemmr`   qnnpackonednn	backend: ' not supported. backend must be one of r   T)reduce_ranger^   FzDefault qconfig of oneDNN backend with reduce_range of false may have accuracy issues on CPU without Vector Neural Network Instruction support.Version number: zB in get_default_qconfig is not supported. Version number must be 0)AssertionErrorstrr)   r   	with_argsr"   r$   r\   cpuZ_is_cpu_support_vnnirZ   r[   r+   backendversionZsupported_backendsqconfigrS   rS   rT   rA      sB    

Fg      0?)r_   rf   epsc                 C   s  ddddg}| |kr.t dt|  d|  |dkr| dkrZttjtddd	d
td}nn| dkr~ttjtdddd
td}nJ| dkrttjtdddtd}n(| dkrttjtddd	d
td}nt}n|dkrn| dkrtt	jtddd	d
t
d}nt| dkrtt	jtdddd
td}nN| dkrBtt	jtdddt
d}n*| dkrhtt	jtddd	d
t
d}nt}nt dt| d |S )aL  
    Returns the default QAT qconfig for the specified backend.

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

    Return:
        qconfig
    ra   r`   rb   rc   rd   re   r      T)observer	quant_min	quant_maxrf   r^   F)rr   rs   rt   r   rg   zJin get_default_qat_qconfig is not supported. Version number must be 0 or 1)rh   ri   r)   r   rj   r   r   r   r5   r   r   r   r9   rl   rS   rS   rT   rB   9  s    




i   )rr   rs   rt   r_   rf   rp   c                 C   s   t d tjj| | S )Nztorch.ao.quantization.get_default_qconfig_dict is deprecated and will be removed in a future version. Please use torch.ao.quantization.get_default_qconfig_mapping instead.)rZ   r[   r\   aoquantizationZget_default_qconfig_mappingto_dictrm   rn   rS   rS   rT   rC     s    c                 C   s   t d tjj| | S )Nztorch.ao.quantization.get_default_qat_qconfig_dict is deprecated and will be removed in a future version. Please use torch.ao.quantization.get_default_qat_qconfig_mapping instead.)rZ   r[   r\   rv   rw   Zget_default_qat_qconfig_mappingrx   ry   rS   rS   rT   rD     s    )ro   modreturnc                 C   sl   | dkrdS t |tjjtjjtjjf}|rh| jdkr:dS |  }t |tjjj	tjjj
f}|rhtddS )z0
    Verifies that this `qconfig` is valid.
    NzGPer channel weight observer is not supported yet for ConvTranspose{n}d.)rG   r\   rH   ZConvTranspose1dZConvTranspose2dZConvTranspose3drP   rv   rw   ZPerChannelMinMaxObserverZ%MovingAveragePerChannelMinMaxObserverrh   )ro   rz   Zis_conv_transpose_modZexample_observerZis_per_channelrS   rS   rT   _assert_valid_qconfig  s    
r|   ztorch.ao.quantization.qconfig)ro   moduler{   c                    sT   dks| dk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tdd   D dd   D B } t| dkrNtt	| nd }|d kr^d S d|iS )Nc                 S   s   h | ]
}|j qS rS   device.0prS   rS   rT   	<setcomp>  s     zd_add_module_to_qconfig_obs_ctr.<locals>.get_factory_kwargs_based_on_module_device.<locals>.<setcomp>c                 S   s   h | ]
}|j qS rS   r~   r   rS   rS   rT   r     s     r   r   )
rG   r\   rH   rI   rh   
parametersbufferslennextiter)Zdevicesr   )r}   rS   rT   )get_factory_kwargs_based_on_module_device  s    zQ_add_module_to_qconfig_obs_ctr.<locals>.get_factory_kwargs_based_on_module_devicec                    sT   z | j d d}|  | j dW S  tk
r8   |  Y S  tk
rN   |  Y S X d S )N)Zfactory_kwargs)rj   Zwith_callable_argsAttributeError	TypeError)Zoriginal_constructorcheck)r   rS   rT   1configure_constructor_to_put_obs_on_module_device  s    zY_add_module_to_qconfig_obs_ctr.<locals>.configure_constructor_to_put_obs_on_module_device)_fieldsrO   rP   r)   )ro   r}   r   rO   rP   rS   )r   r}   rT   _add_module_to_qconfig_obs_ctr  s    

r   
obs_or_fq1
obs_or_fq2c                 C   s&   t | trt |trt| |S | |kS N)rG   r   _partial_wrapper_equalsr   rS   rS   rT   _obs_or_fq_ctr_equals  s    
r   c                 C   s   t  | jj}t  |jj}d}d|krZd|krZ|oDt|d |d }|d |d |od||k}| jj|jjko| jj|jjko|S )z<
    Return whether the two partial wrappers are equal,
    Trr   )copyr   keywordsr   popfuncargs)r   r   Zobs_or_fq1_keywordsZobs_or_fq2_keywordsZkeywords_equalrS   rS   rT   r     s    

r   )q1q2c                 C   st   | dks|dkr| |kS | dk	r(|dk	s,t z&t| j|j}t| j|j}|oP|W S  tk
rn   | |k Y S X dS )zD
    Returns `True` if `q1` equals `q2`, and `False` otherwise.
    N)rh   r   rO   rP   r   )r   r   Zactivation_sameZweight_samerS   rS   rT   rF     s    
ro   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   )rr   rS   rS   rT   _is_memoryless%  s    z1_activation_is_memoryless.<locals>._is_memorylessactivation_post_processN)rO   rG   r   r   r   )ro   r   ZactrS   rS   rT   _activation_is_memoryless   s
    
r   c                 C   s$   | d k	o"t |  to"t |  tS r   )rG   rO   r   rP   r   r   rS   rS   rT   _is_reuse_input_qconfig-  s
    r   )r`   r   )r`   r   )r`   r   )r`   r   )_collectionsr   typingr   r   r   r   r\   Ztorch.nnrH   Z#torch.ao.quantization.fake_quantizer   r   r	   r
   r   r   r   r   r   r   r   r   r   r   rr   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   rZ   r   __all__r)   r*   r+   r,   r-   r.   rj   Zfloat16r/   r0   r1   r2   r3   r5   r6   r]   r7   r8   r9   r:   rA   Zqint8r;   r<   Zfloat32r?   r@   r4   rB   r=   r>   Z!_default_fp32_placeholder_qconfigZquint8Z#_default_quint8_placeholder_qconfigrC   rD   rI   r|   rE   rV   r   Z"_ObserverOrFakeQuantizeConstructorr   r   rF   r   r   rS   rS   rS   rT   <module>   s0  @T#
G


S		

  *