U
    yhH-                     @   s   d dl Z d dlmZ ddddddd	d
gZG dd de jjZG dd de jjZG dd de jjZG dd de jj	Z	G dd de jj
Z
G dd de jjZG dd	 d	e jjjjZG dd
 d
e jjZdS )    N)warnReLU6	HardswishELU	LeakyReLUSigmoidSoftmaxMultiheadAttentionPReLUc                       s@   e Zd ZdZd fdd	Zdd Zdd Zedd	d
Z  Z	S )r   a  Applies the element-wise function:

    :math:`\text{ReLU6}(x) = \min(\max(x_0, x), q(6))`, where :math:`x_0` is the
    zero_point, and :math:`q(6)` is the quantized representation of number 6.

    Args:
        inplace: can optionally do the operation in-place. Default: ``False``

    Shape:
        - Input: :math:`(N, *)` where `*` means, any number of additional
          dimensions
        - Output: :math:`(N, *)`, same shape as the input

    .. image:: ../scripts/activation_images/ReLU6.png

    Examples::

        >>> m = nn.quantized.ReLU6()
        >>> input = torch.randn(2)
        >>> # xdoctest: +SKIP
        >>> input = torch.quantize_per_tensor(input, 1.0, 0, dtype=torch.qint32)
        >>> output = m(input)
    Fc                    s   t  | || _d S N)super__init__inplace)selfr   	__class__ Z/var/www/html/venv/lib/python3.8/site-packages/torch/ao/nn/quantized/modules/activation.pyr   '   s    zReLU6.__init__c                 C   s   t jj|| jS r   )torchops	quantizedZrelu6r   r   inputr   r   r   forward+   s    zReLU6.forwardc                 C   s   dS )NZQuantizedReLU6r   r   r   r   r   	_get_name.   s    zReLU6._get_namec                 C   s
   t | jS r   )r   r   )moduse_precomputed_fake_quantr   r   r   
from_float1   s    zReLU6.from_float)F)F)
__name__
__module____qualname____doc__r   r   r   staticmethodr   __classcell__r   r   r   r   r      s   c                       sL   e Zd ZdZd fdd	Zdd Zdd Zedd
dZe	dd Z
  ZS )r   zThis is the quantized version of :class:`~torch.nn.Hardswish`.

    Args:
        scale: quantization scale of the output tensor
        zero_point: quantization zero point of the output tensor
    Nc                    sD   ||d}t    | dtj|f| | dtj|f| d S N)devicedtypescale
zero_pointr   r   Zregister_bufferr   Ztensor)r   r(   r)   r&   r'   factory_kwargsr   r   r   r   <   s    

zHardswish.__init__c                 C   s   t jj|| j| jS r   )r   r   r   Z	hardswishr(   r)   r   r   r   r   r   B   s    zHardswish.forwardc                 C   s   dS )NZQuantizedHardswishr   r   r   r   r   r   E   s    zHardswish._get_nameFc                 C   s    | j  \}}tt|t|S r   )activation_post_processcalculate_qparamsr   floatintr   r   r(   r)   r   r   r   r   H   s    zHardswish.from_floatc                 C   s   | t |t|S r   )r.   r/   clsr   r(   r)   r   r   r   from_referenceM   s    zHardswish.from_reference)NN)Fr   r    r!   r"   r   r   r   r#   r   classmethodr3   r$   r   r   r   r   r   5   s   c                       sL   e Zd ZdZd fdd	Zdd Zdd Zedd
dZe	dd Z
  ZS )r   zThis is the quantized equivalent of :class:`~torch.nn.ELU`.

    Args:
        scale: quantization scale of the output tensor
        zero_point: quantization zero point of the output tensor
        alpha: the alpha constant
          ?c                    s   t  | || _|| _d S r   )r   r   r(   r)   )r   r(   r)   alphar   r   r   r   Y   s    zELU.__init__c                 C   s   t jjjj|| j| j| jS r   )	r   aonnr   
functionalZelur(   r)   r7   r   r   r   r   r   ^   s       zELU.forwardc                 C   s   dS )NZQuantizedELUr   r   r   r   r   r   b   s    zELU._get_nameFc                 C   s$   | j  \}}tt|t|| jS r   )r,   r-   r   r.   r/   r7   r0   r   r   r   r   e   s    zELU.from_floatc                 C   s   | t |t||jS r   )r.   r/   r7   r1   r   r   r   r3   j   s    zELU.from_reference)r6   )Fr4   r   r   r   r   r   Q   s   c                       sZ   e Zd ZdZdeeeedd fddZdd	 Zd
d Z	e
dddZe
dd Z  ZS )r   a  This is the quantized equivalent of :class:`~torch.nn.LeakyReLU`.

    Args:
        scale: quantization scale of the output tensor
        zero_point: quantization zero point of the output tensor
        negative_slope: Controls the angle of the negative slope. Default: 1e-2
    {Gz?FN)r(   r)   negative_sloper   returnc                    sH   ||d}t  || | dtj|f| | dtj|f| d S r%   r*   )r   r(   r)   r<   r   r&   r'   r+   r   r   r   r   v   s    
zLeakyReLU.__init__c                 C   s   t jj|| j| j| j| jS r   )r   r   r   Z
leaky_relur<   r   r(   r)   r   r   r   r   r   }   s        zLeakyReLU.forwardc                 C   s   dS )NZQuantizedLeakyReLUr   r   r   r   r   r      s    zLeakyReLU._get_namec                 C   s(   |j  \}}| t|t||j|jS r   )r,   r-   r.   r/   r<   r   )r2   r   r   r(   r)   r   r   r   r      s    zLeakyReLU.from_floatc                 C   s   | t |t||j|jS r   )r.   r/   r<   r   r1   r   r   r   r3      s    zLeakyReLU.from_reference)r;   FNN)F)r   r    r!   r"   r.   r/   boolr   r   r   r5   r   r3   r$   r   r   r   r   r   n   s          c                       s>   e Zd ZdZeed fddZdd Zed
dd	Z	  Z
S )r   zThis is the quantized equivalent of :class:`~torch.nn.Sigmoid`.

    Args:
        scale: quantization scale of the output tensor
        zero_point: quantization zero point of the output tensor
    )output_scaleoutput_zero_pointc                    s   t    || _|| _d S r   )r   r   r?   r@   )r   r?   r@   r   r   r   r      s    
zSigmoid.__init__c                 C   s   t jj|| j| jS r   )r   r   r   Zsigmoidr?   r@   r   r   r   r   r      s    zSigmoid.forwardFc                 C   s    |j  \}}| t|t|S r   )r,   r-   r.   r/   )r2   r   r   r?   r@   r   r   r   r      s    zSigmoid.from_float)F)r   r    r!   r"   r.   r/   r   r   r5   r   r$   r   r   r   r   r      s
   c                       sL   e Zd ZdZd fdd	Zdd Zd	d
 ZedddZe	dd Z
  ZS )r   a,  This is the quantized version of :class:`~torch.nn.Softmax`.

    Args:
        dim: A dimension along which Softmax will be computed (so every slice along dim will sum to 1).
        scale: quantization scale of the output tensor
        zero_point: quantization zero point of the output tensor
    Nr6   r   c                    s    t    || _|| _|| _d S r   )r   r   dimr(   r)   )r   rA   r(   r)   r   r   r   r      s    
zSoftmax.__init__c                 C   s@   | j }|d kr(d}tjjd|  |}tjj||| j| j	S )N   softmax)
rA   r   r9   r:   Z_get_softmax_dimr   r   rC   r(   r)   )r   r   rA   
stacklevelr   r   r   r      s         zSoftmax.forwardc                 C   s   dS )NZQuantizedSoftmaxr   r   r   r   r   r      s    zSoftmax._get_nameFc                 C   s$   | j  \}}t| jt|t|S r   )r,   r-   r   rA   r.   r/   r0   r   r   r   r      s    zSoftmax.from_floatc                 C   s   | |j t|t|S r   )rA   r.   r/   r1   r   r   r   r3      s    zSoftmax.from_reference)Nr6   r   )Fr4   r   r   r   r   r      s   c                   @   s8   e Zd ZejjjjZdd Z	e
dd Ze
dd ZdS )r	   c                 C   s   dS )NZQuantizedMultiheadAttentionr   r   r   r   r   r      s    zMultiheadAttention._get_namec                 C   s   t dd S )NzpIt looks like you are trying to convert a non-observed MHA module. Please, see the examples on quantizable MHAs.)NotImplementedError)r2   otherr   r   r   r      s    zMultiheadAttention.from_floatc                 C   s   t jjj|d ddd d}| |_|jd k	rd|jd}t j|dd\}}t 	|||t j
}t|d| |jd k	r|jd}t j|dd\}}t 	|||t j
}t|d| |`|`|S )NFT)mappingr   Zremove_qconfigZconvert_custom_config_dictbias_k)Zreduce_rangebias_v)r   r8   Zquantizationconvertr   rH   _parameterspopZ_choose_qparams_per_tensorquantize_per_tensorquint8setattrrI   Zin_proj_weightZin_proj_bias)r2   rF   Z	convertedrH   scZzprI   r   r   r   from_observed   s.    



z MultiheadAttention.from_observedN)r   r    r!   r   r8   r9   quantizabler	   Z_FLOAT_MODULEr   r5   r   rQ   r   r   r   r   r	      s   
c                       sv   e Zd ZdZdeeedd fddZejdddd	Z	ejejd
ddZ
dd ZedddZedd Z  ZS )r
   a%  This is the quantized equivalent of :class:`~torch.nn.PReLU`.

    Args:
        scale: quantization scale of the output tensor
        zero_point: quantization zero point of the output tensor
        num_parameters: number of parameters: 1, or the number of channels at input. Default: 1
       N)r?   r@   num_parametersr=   c                    sN   t    || _|| _|| _tj|tjd}tj|ddtj	d}| 
| d S )N)r'   r6   r   )r(   r)   r'   )r   r   rT   r(   r)   r   Zrandnr.   rM   rN   
set_weight)r   r?   r@   rT   wZqwr   r   r   r      s    
zPReLU.__init__)rV   r=   c                 C   s
   || _ d S r   )weight)r   rV   r   r   r   rU     s    zPReLU.set_weight)r   r=   c                 C   s   t jj|| j| j| jS r   )r   r   r   ZprelurW   r(   r)   r   r   r   r   r   
  s    zPReLU.forwardc                 C   s   dS )NZQuantizedPReLUr   r   r   r   r   r     s    zPReLU._get_nameFc                 C   s   |j  \}}| t|t||j}|j }|j }|| |jtj	kr\t
d|j  | \}}	t|t|t|	tj	}
||
 |S Nz9PReLU's weight observer should have dtype quint8 but got )r,   r-   r.   r/   rT   rW   qconfigr'   r   rN   r   rM   rU   )r2   r   r   r(   r)   qprelufloat_wtobserverwt_scalewt_zpqweightr   r   r   r     s$    


   
zPReLU.from_floatc           
      C   s   | t |t||j}|j  }|j }|| |jtjkrNtd|j  |	 \}}t
|t |t|tj}	||	 |S rX   )r.   r/   rT   rW   rY   r'   r   rN   r   r-   rM   rU   )
r2   r   r(   r)   rZ   r[   r\   r]   r^   r_   r   r   r   r3   !  s"    


   
zPReLU.from_reference)rS   )F)r   r    r!   r"   r.   r/   r   r   ZTensorrU   r   r   r5   r   r3   r$   r   r   r   r   r
      s     
)r   warningsr   __all__r9   ZReLUr   r   r   r   r   r   r8   rR   r	   Moduler
   r   r   r   r   <module>   s$   &&-