o
    Ih&5                     @   s   d dl mZ d dlmZ d dl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 )    )Iterable)OptionalN)fuse_linear_bn_weights)type_before_parametrizations   )_hide_packed_params_repr_quantize_weightWeightedQuantizedModuleLinearPackedParamsLinearc                       s   e Zd ZdZejf fdd	Zejjdej	de
ej	 ddf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rtjddgddtjd}n| jtjkr+t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   wq	__class__ X/var/www/vscode/kcb/lib/python3.10/site-packages/torch/ao/nn/quantized/modules/linear.pyr      s   
zLinearPackedParams.__init__weightbiasreturnNc                 C   sL   | j tjkrtjj||| _d S | j tjkr"tjj||| _d S t	dNz.Unsupported dtype on dynamic quantized linear!)
r   r   r   ops	quantizedlinear_prepack_packed_paramsr   linear_prepack_fp16RuntimeError)r   r"   r#   r    r    r!   r   !   s
   z"LinearPackedParams.set_weight_biasc                 C   s@   | j tjkrtjj| jS | j tjkrtjj| jS t	dr%   )
r   r   r   r&   r'   linear_unpackr)   r   linear_unpack_fp16r+   r   r    r    r!   _weight_bias,   s
   zLinearPackedParams._weight_biasc                 C   s   |S Nr    r   xr    r    r!   forward5      zLinearPackedParams.forwardc                    s2   t  ||| | j||d < |  ||d < d S )Nr   r)   )r   _save_to_state_dictr   r/   r   destinationprefix	keep_varsr   r    r!   r5   H   s   z&LinearPackedParams._save_to_state_dictc              	      s   | dd }|d u s|dk rtj| _n||d  | _||d  |d u s)|dk rE| ||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   
state_dictr8   local_metadatastrictmissing_keysunexpected_keys
error_msgsr:   r"   r#   r   r    r!   r>   M   s0   

z(LinearPackedParams._load_from_state_dictc                 C   s   |    S r0   )r/   __repr__r.   r    r    r!   rF   t      zLinearPackedParams.__repr__)__name__
__module____qualname___versionr   r   r   jitexportTensorr   r   r/   r3   r5   r>   rF   __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dejdejfddZ fddZ fddZdd Zdd Zdd Zdejdeej ddf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r)tj||gddtjd}n|tj	kr9t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   rP   rQ   bias_r   r#   qweightr   r    r!   r      s"   




zLinear.__init__c                 C   s   dS )NQuantizedLinearr    r.   r    r    r!   	_get_name   r4   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=)rP   rQ   r   r   r"   qschemer.   r    r    r!   
extra_repr   s   
zLinear.extra_reprc                 C   s
   t | tS r0   )r   r
   r.   r    r    r!   rF         
zLinear.__repr__r2   r$   c                 C   s   t jj|| jj| j| jS r0   )r   r&   r'   linearr)   r   r   r1   r    r    r!   r3      s   zLinear.forwardc                    s<   t  ||| t| j||d < t| j||d < d S )Nr   r   )r   r5   r   tensorr   r   r6   r   r    r!   r5      s   zLinear._save_to_state_dictc              	      s   t ||d  | _||d  t||d  | _||d  |dd }|d u s.|dkrI||d }	||d }
||d |	|d |
i t |||d	||| d S )
Nr   r   r:   r   r"   r#   z_packed_params.weightz_packed_params.biasF)	r   r   r=   intr   r<   updater   r>   r?   r   r    r!   r>      s,   
zLinear._load_from_state_dictc                 C   s
   | j  S r0   )r)   r/   r.   r    r    r!   r/     rX   zLinear._weight_biasc                 C      |   d S )Nr   r/   r.   r    r    r!   r"     rG   zLinear.weightc                 C   r]   )Nr   r^   r.   r    r    r!   r#     rG   zLinear.biaswbNc                 C   s   | j || d S r0   )r)   r   )r   r_   r`   r    r    r!   r     s   zLinear.set_weight_biasFc                 C   s~  t |dr-t|tjkr&t|j|j|jj|jj	|jj
|jj|jj\|_|_|j}|j}nUt| jts8| jg| _ddd | jD }d| j d| dt| }t|| jv s^J | t |dsgJ d	|j}t|tjkru|d
 }t |ds|j n|j}|s||j |j}| \}}	|tjksJ 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    )rH   ).0	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   nniqat
LinearBn1dr   r"   r#   bnrunning_meanrunning_varepsra   activation_post_process
isinstance_FLOAT_MODULEr   joinrH   typeformatnni
LinearReLUre   r   calculate_qparamsr   r   r   r   rP   rQ   r   r   r[   r   )clsmoduse_precomputed_fake_quantweight_post_processrm   supported_modules	error_msgr   	act_scaleact_zprS   qlinearr    r    r!   
from_float  sZ   

	



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
        )	rP   rQ   get_quantized_weightr   r#   r   r   r[   r   )rv   ref_qlinearoutput_scaleoutput_zero_pointr~   rS   r    r    r!   from_referenceZ  s   


zLinear.from_reference)F)rH   rI   rJ   __doc__rK   nnr   modulesrY   NonDynamicallyQuantizableLinearro   r   r   r   rU   rW   rF   rN   r3   r5   r>   r/   r"   r#   r   r   classmethodr   r   rO   r    r    r   r!   r   x   s&    ")=)collections.abcr   typingr   r   torch.ao.nn.intrinsicaor   	intrinsicrs   torch.ao.nn.intrinsic.qatqatrg   torch.nntorch.nn.utils.fusionr   torch.nn.utils.parametrizer   utilsr   r   r	   __all__Moduler
   r   r    r    r    r!   <module>   s   e