U
    ©Ê¹jàd  ã                   @   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_127Ú4fused_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_127Ú0per_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_qconfigÚ1default_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 )Nz”QConfig 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/bwave/python/venv/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 )Nz›QConfigDynamic 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r¤tj 	¡ sŽt
 d¡ ttjdd	�td
�}qÜ| dkrÂt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` (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^   Fz�Default 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r ttjtddd�td�}n(| dkrÄttjtddd	d
�td�}nt}n¸|dk�rn| dkrøt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 )Nz«torch.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 )Nz³torch.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ûù	ûù	þý

 ÿ þ*