o
    h	_                  	   @   s  d dl Z d dlZd dlmZ d dlmZmZmZ d dl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/ g dZ0G d	d
 d
ed
ddgZ1e	de2dG dd dedddgZ3e1e"e&dZ4	 e1e&edZ5	 e1e"e#dZ6	 e1ee&dZ7	 e1e-j8e
j9dde-j8e
j9ddZ:	 e1e-j8e
j9de-j8e
j9ddZ;	 e1ee#dZ<	 e1e$e dZ=	 e1e$e!dZ>e1eedZ?	 e1eedZ@	 e1e
jjAedZB	 e1ee
jjAdZC	 e1eedZD	 e1e%e*dZE	 d>ddZF	 e1e'j8e
jGddde/dZHe1e'j8e
jGddde,dZIe1e*j8e
jJdedZKe1e*j8e
jJdedZLe1e'e(dZMd?ddZN	 e1ej8e)dde
jGddd edZOe1ej8e)dde
jGddd edZPe1e-j8e
jJde-j8e
jJddZQe1e-j8e
jRdddZSe	d!e2dd>d"d#ZTe	d$e2dd?d%d&ZUd'ee1 d(e
jjVd)dfd*d+ZWee1 ZXd,eX_Yd'eXd-eejV d)efd.d/ZZeee[e+ e[e f Z\d0e\d1e\fd2d3Z]d0ed1efd4d5Z^d6eXd7eXfd8d9Z_d'e1fd:d;Z`d'ee1 fd<d=ZadS )@    N)
namedtuple)AnyOptionalUnion)
deprecated)default_dynamic_fake_quantdefault_embedding_fake_quant!default_embedding_fake_quant_4bitdefault_fake_quantdefault_fused_act_fake_quant'default_fused_per_channel_wt_fake_quantdefault_fused_wt_fake_quant%default_per_channel_weight_fake_quantdefault_weight_fake_quantFakeQuantizeFakeQuantizeBase4fused_per_channel_wt_fake_quant_range_neg_127_to_127(fused_wt_fake_quant_range_neg_127_to_127FusedMovingAvgObsFakeQuantize   )_PartialWrapper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_reuse_input_observerdefault_weight_observerHistogramObserverMinMaxObserverMovingAverageMinMaxObserverNoopObserverObserverBase0per_channel_weight_observer_range_neg_127_to_127PlaceholderObserverReuseInputObserver$weight_observer_range_neg_127_to_127)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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__rG   q/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/torch/ao/quantization/qconfig.pyrN   k   s
   zQConfig.__new__)__name__
__module____qualname____doc__	__slots__rN   __classcell__rG   rG   rS   rU   r)   U   s    r)   rQ   rR   zX`QConfigDynamic` is going to be deprecated in PyTorch 1.12, please use `QConfig` instead)categoryc                       s2   e Zd 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))
    rG   c                    s$   t |tjr
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 neededrH   rO   rS   rG   rU   rN      s
   zQConfigDynamic.__new__)
rV   rW   rX   rY   rZ   torchrJ   IdentityrN   r[   rG   rG   rS   rU   r*   u   s    "r*   rQ   rR   )rR   rQ   T)dtype
is_dynamic)r`   x86c                 C   s   g d}| |vrt dt|  d|  |dkrg| dkr)ttjddtd}|S | d	kr9ttjd
dtd}|S | dkrStj	 sGt
d ttjd
dtd}|S | dkrcttjddtd}|S t}|S t dt| d )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
    fbgemmrb   qnnpackonednn	backend: ' not supported. backend must be one of r   rd   T)reduce_ranger_   re   Frf   zDefault qconfig of oneDNN backend with reduce_range of false may have accuracy issues on CPU without Vector Neural Network Instruction support.rb   Version number: zB in get_default_qconfig is not supported. Version number must be 0)AssertionErrorstrr)   r    	with_argsr   r   r]   cpu_is_vnni_supportedwarningswarnr+   backendversionsupported_backendsqconfigrG   rG   rU   rA      s^   
#



rA   Fg      0?)r`   ri   epsc                 C   s  g d}| |vrt dt|  d|  |dkrh| dkr,ttjtddddtd	}|S | d
kr?ttjtddddtd	}|S | dkrQttjtdddtd	}|S | dkrdttjtddddtd	}|S t}|S |dkr| dkrtt	jtddddt
d	}|S | d
krtt	jtddddtd	}|S | dkrtt	jtdddt
d	}|S | dkrtt	jtddddt
d	}|S t}|S t dt| d )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
    rc   rg   rh   r   rd      T)observer	quant_min	quant_maxri   r_   re   Frf   )ry   rz   r{   rb   r   rj   zJin get_default_qat_qconfig is not supported. Version number must be 0 or 1)rk   rl   r)   r   rm   r"   r   r   r5   r   r   r   r9   rr   rG   rG   rU   rB   r  s   WMC<2.#rB   i   )ry   rz   r{   r`   ri   rw   z`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.c                 C      t jj| | S N)r]   aoquantizationget_default_qconfig_mappingto_dictrs   rt   rG   rG   rU   rC   
  s   rC   z`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.c                 C   r}   r~   )r]   r   r   get_default_qat_qconfig_mappingr   r   rG   rG   rU   rD     s
   rD   rv   modreturnc                 C   sp   | du rdS t |tjjtjjtjjf}|r4| jdu rdS |  }t |tjjj	tjjj
f}|r6J ddS dS )z0
    Verifies that this `qconfig` is valid.
    NzGPer channel weight observer is not supported yet for ConvTranspose{n}d.)rI   r]   rJ   ConvTranspose1dConvTranspose2dConvTranspose3drR   r   r   PerChannelMinMaxObserver%MovingAveragePerChannelMinMaxObserver)rv   r   is_conv_transpose_modexample_observeris_per_channelrG   rG   rU   _assert_valid_qconfig  s,   
r   ztorch.ao.quantization.qconfigmodulec                    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r'tt| nd }|d u r/d S d|iS )Nc                 S   s   h | ]}|j qS rG   )device).0prG   rG   rU   	<setcomp>R  s    zd_add_module_to_qconfig_obs_ctr.<locals>.get_factory_kwargs_based_on_module_device.<locals>.<setcomp>r   r   )	rI   r]   rJ   rK   
parametersbufferslennextiter)devicesr   )r   rG   rU   )get_factory_kwargs_based_on_module_deviceP  s   zQ_add_module_to_qconfig_obs_ctr.<locals>.get_factory_kwargs_based_on_module_devicec                    sL   z| j d d}|  | j dW S  ty   |  Y S  ty%   |  Y S w )N)factory_kwargs)rm   with_callable_argsAttributeError	TypeError)original_constructorcheck)r   rG   rU   1configure_constructor_to_put_obs_on_module_deviceX  s   zY_add_module_to_qconfig_obs_ctr.<locals>.configure_constructor_to_put_obs_on_module_device)_fieldsrQ   rR   r)   )rv   r   r   rQ   rR   rG   )r   r   rU   _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 r~   )rI   r   _partial_wrapper_equals)r   r   rG   rG   rU   _obs_or_fq_ctr_equalsp  s
   
r   c                 C   s   t  | jj}t  |jj}d}d|v r-d|v r-|o"t|d |d }|d |d |o2||k}| jj|jjkoD| jj|jjkoD|S )z<
    Return whether the two partial wrappers are equal,
    Try   )copyr   keywordsr   popfuncargs)r   r   obs_or_fq1_keywordsobs_or_fq2_keywordskeywords_equalrG   rG   rU   r   {  s   

r   q1q2c                 C   sn   | du s|du r| |kS | dur|dusJ zt | j|j}t | j|j}|o(|W S  ty6   | |k Y S w )zD
    Returns `True` if `q1` equals `q2`, and `False` otherwise.
    N)r   rQ   rR   r   )r   r   activation_sameweight_samerG   rG   rU   rF     s   
rF   c                 C   s6   dd }|   }t|trt|dr||jS ||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   )ry   rG   rG   rU   _is_memoryless  s   z1_activation_is_memoryless.<locals>._is_memorylessactivation_post_process)rQ   rI   r   r   r   )rv   r   actrG   rG   rU   _activation_is_memoryless  s
   
r   c                 C   s$   | d uot |  tot |  tS r~   )rI   rQ   r'   rR   r#   )rv   rG   rG   rU   _is_reuse_input_qconfig  s
   r   )rb   r   )rb   r   )br   rp   collectionsr   typingr   r   r   typing_extensionsr   r]   torch.nnrJ   #torch.ao.quantization.fake_quantizer   r   r	   r
   r   r   r   r   r   r   r   r   r   r   ry   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   __all__r)   FutureWarningr*   r+   r,   r-   r.   rm   float16r/   r0   r1   r2   r3   r5   r6   r^   r7   r8   r9   r:   rA   qint8r;   r<   float32r?   r@   r4   rB   r=   r>   !_default_fp32_placeholder_qconfigquint8#_default_quint8_placeholder_qconfigrC   rD   rK   r   rE   rW   r   type"_ObserverOrFakeQuantizeConstructorr   r   rF   r   r   rG   rG   rG   rU   <module>   sJ  @T# 
;
q
.
