U
    yh%3                     @   s   d dl mZ d dlZd dlmZ d dlm  m  mZ d dl	m  m  m  m
Z d dlmZ d dlmZ d dlmZ ddlmZmZmZ dd	gZG d
d dejjZG dd	 d	eZdS )    )IterableN)fuse_linear_bn_weights)type_before_parametrizations)Optional   )_quantize_weight_hide_packed_params_reprWeightedQuantizedModuleLinearPackedParamsLinearc                       s   e Zd ZdZejf fdd	Zejjej	e
ej	 ddddZejjdd	 Zd
d Z fddZ fddZdd Z  ZS )r
      c                    sf   t    || _| jtjkr6tjddgddtjd}n | jtjkrVtjddgtjd}| 	|d  d S )Nr         ?r   scale
zero_pointdtyper   )
super__init__r   torchqint8_empty_affine_quantizedfloat16zerosfloatset_weight_bias)selfr   Zwq	__class__ V/var/www/html/venv/lib/python3.8/site-packages/torch/ao/nn/quantized/modules/linear.pyr      s    
zLinearPackedParams.__init__N)weightbiasreturnc                 C   sL   | j tjkr tjj||| _n(| j tjkr@tjj||| _nt	dd S Nz.Unsupported dtype on dynamic quantized linear!)
r   r   r   ops	quantizedZlinear_prepack_packed_paramsr   Zlinear_prepack_fp16RuntimeError)r   r!   r"   r   r   r    r      s
    z"LinearPackedParams.set_weight_biasc                 C   sD   | j tjkrtjj| jS | j tjkr8tjj| jS t	dd S r$   )
r   r   r   r%   r&   Zlinear_unpackr'   r   Zlinear_unpack_fp16r(   r   r   r   r    _weight_bias(   s
    zLinearPackedParams._weight_biasc                 C   s   |S Nr   r   xr   r   r    forward1   s    zLinearPackedParams.forwardc                    s2   t  ||| | j||d < |  ||d < d S )Nr   r'   )r   _save_to_state_dictr   r*   r   ZdestinationprefixZ	keep_varsr   r   r    r/   D   s    z&LinearPackedParams._save_to_state_dictc              	      s   | dd }|d ks|dk r&tj| _n||d  | _||d  |d ksR|dk r| ||d  ||d   ||d  ||d  |dkr||d  \}	}
||d  | |	|
 t |||d||| d S )	Nversion   r   r   r!   r"   r'   F)getr   r   r   popr   r   _load_from_state_dictr   Z
state_dictr1   Zlocal_metadatastrictZmissing_keysZunexpected_keysZ
error_msgsr2   r!   r"   r   r   r    r6   I   s$    
  z(LinearPackedParams._load_from_state_dictc                 C   s   |    S r+   )r*   __repr__r)   r   r   r    r9   `   s    zLinearPackedParams.__repr__)__name__
__module____qualname___versionr   r   r   ZjitZexportTensorr   r   r*   r.   r/   r6   r9   __classcell__r   r   r   r    r
      s   		
c                       s   e Zd ZdZdZejejjj	fZ
dejf fdd	Zdd Zdd	 Zd
d ZejejdddZ fddZ fddZdd Zdd Zdd Zejeej ddddZed"ddZed d! Z  ZS )#r   a  
    A quantized linear module with quantized tensor as inputs and outputs.
    We adopt the same interface as `torch.nn.Linear`, please see
    https://pytorch.org/docs/stable/nn.html#torch.nn.Linear for documentation.

    Similar to :class:`~torch.nn.Linear`, attributes will be randomly
    initialized at module creation time and will be overwritten later

    Attributes:
        weight (Tensor): the non-learnable quantized weights of the module of
                         shape :math:`(\text{out\_features}, \text{in\_features})`.
        bias (Tensor): the non-learnable bias of the module of shape :math:`(\text{out\_features})`.
                If :attr:`bias` is ``True``, the values are initialized to zero.
        scale: `scale` parameter of output Quantized Tensor, type: double
        zero_point: `zero_point` parameter for output Quantized Tensor, type: long

    Examples::

        >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_QENGINE)
        >>> m = nn.quantized.Linear(20, 30)
        >>> input = torch.randn(128, 20)
        >>> # xdoctest: +SKIP
        >>> input = torch.quantize_per_tensor(input, 1.0, 0, torch.quint8)
        >>> output = m(input)
        >>> print(output.size())
        torch.Size([128, 30])
    r   Tc                    s   t    || _|| _d }|r.tj|tjd}|tjkrRtj||gddtjd}n(|tj	krrtj||gtjd}nt
dt|| _| j|| d| _d| _d S )Nr   r   r   r   z1Unsupported dtype specified for quantized Linear!r   )r   r   in_featuresout_featuresr   r   r   r   r   r   r(   r
   r'   r   r   r   )r   r@   rA   Zbias_r   r"   qweightr   r   r    r      s(    

   

zLinear.__init__c                 C   s   dS )NZQuantizedLinearr   r)   r   r   r    	_get_name   s    zLinear._get_namec                 C   s2   d| j  d| j d| j d| j d|    
S )Nzin_features=z, out_features=z, scale=z, zero_point=z
, qscheme=)r@   rA   r   r   r!   Zqschemer)   r   r   r    
extra_repr   s    zLinear.extra_reprc                 C   s
   t | tS r+   )r   r
   r)   r   r   r    r9      s    zLinear.__repr__)r-   r#   c                 C   s   t jj|| jj| j| jS r+   )r   r%   r&   linearr'   r   r   r,   r   r   r    r.      s       zLinear.forwardc                    s<   t  ||| t| j||d < t| j||d < d S )Nr   r   )r   r/   r   Ztensorr   r   r0   r   r   r    r/      s    zLinear._save_to_state_dictc              	      s   t ||d  | _||d  t||d  | _||d  |dd }|d ks\|dkr||d }	||d }
||d |	|d |
i t |||d	||| d S )
Nr   r   r2   r   r!   r"   z_packed_params.weightz_packed_params.biasF)	r   r   r5   intr   r4   updater   r6   r7   r   r   r    r6      s*          zLinear._load_from_state_dictc                 C   s
   | j  S r+   )r'   r*   r)   r   r   r    r*      s    zLinear._weight_biasc                 C   s   |   d S )Nr   r*   r)   r   r   r    r!      s    zLinear.weightc                 C   s   |   d S )Nr   rH   r)   r   r   r    r"      s    zLinear.biasN)wbr#   c                 C   s   | j || d S r+   )r'   r   )r   rI   rJ   r   r   r    r      s    zLinear.set_weight_biasFc                 C   s  t |drZt|tjkrLt|j|j|jj|jj	|jj
|jj|jj\|_|_|j}|j}nt| jtsp| jg| _ddd | jD }d| j d| dt| }t|| jkst| t |dstd	|j}t|tjkr|d
 }t |ds|j n|j}|s||j |j}| \}}	|tjks:tdt|j |}
| |j|j|d}| |
|j t||_!t"|	|_#|S )a}  Create a quantized module from an observed float module

        Args:
            mod (Module): a float module, either produced by torch.ao.quantization
                          utilities or provided by the user
            use_precomputed_fake_quant (bool): if True, the module will reuse min/max
                          values from the precomputed fake quant module.
        weight_fake_quantz, c                 S   s   g | ]
}|j qS r   )r:   ).0Z	float_modr   r   r    
<listcomp>
  s     z%Linear.from_float.<locals>.<listcomp>znnq.z.from_float only works for z, but got: qconfigz,Input float module must have qconfig definedr   z+Weight observer must have dtype torch.qint8r   )$hasattrr   nniqatZ
LinearBn1dr   r!   r"   ZbnZrunning_meanZrunning_varepsrK   activation_post_process
isinstance_FLOAT_MODULEr   joinr:   typeAssertionErrorformatnniZ
LinearReLUrN   r   Zcalculate_qparamsr   r   r   r   r@   rA   r   r   rF   r   )clsmodZuse_precomputed_fake_quantZweight_post_processrR   Zsupported_modules	error_msgr   Z	act_scaleZact_zprB   qlinearr   r   r    
from_float   sJ    

     



zLinear.from_floatc                 C   s<   | |j |j}| }|||j t||_t||_|S )a  Create a (fbgemm/qnnpack) quantized module from a reference quantized module

        Args:
            ref_qlinear (Module): a reference quantized linear module, either produced by torch.ao.quantization
                          utilities or provided by the user
            output_scale (float): scale for output Tensor
            output_zero_point (int): zero point for output Tensor
        )	r@   rA   Zget_quantized_weightr   r"   r   r   rF   r   )rZ   Zref_qlinearZoutput_scaleZoutput_zero_pointr]   rB   r   r   r    from_reference#  s    


zLinear.from_reference)F)r:   r;   r<   __doc__r=   nnr   modulesrE   ZNonDynamicallyQuantizableLinearrT   r   r   r   rC   rD   r9   r>   r.   r/   r6   r*   r!   r"   r   r   classmethodr^   r_   r?   r   r   r   r    r   d   s(   !/)collections.abcr   r   Ztorch.nnra   Ztorch.ao.nn.intrinsicZaoZ	intrinsicrY   Ztorch.ao.nn.intrinsic.qatZqatrP   Ztorch.nn.utils.fusionr   Ztorch.nn.utils.parametrizer   typingr   utilsr   r   r	   __all__Moduler
   r   r   r   r   r    <module>   s   R