o
    Zh&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   Zwq	__class__ S/var/www/auris/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	quantizedZlinear_prepack_packed_paramsr   Z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&   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    forward5      zLinearPackedParams.forwardc                    s2   t  ||| | j||d < |  ||d < d S )Nr   r'   )r   _save_to_state_dictr   r*   r   destinationprefixZ	keep_varsr   r   r    r0   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   Z
state_dictr3   Zlocal_metadatastrictZmissing_keysZunexpected_keys
error_msgsr4   r!   r"   r   r   r    r8   M   s0   

z(LinearPackedParams._load_from_state_dictc                 C   s   |    S r+   )r*   __repr__r)   r   r   r    r<   t      zLinearPackedParams.__repr__)__name__
__module____qualname___versionr   r   r   ZjitZexportTensorr   r   r*   r.   r0   r8   r<   __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   rD   rE   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   r/   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=)rD   rE   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    r<         
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   r0   r   Ztensorr   r   r1   r   r   r    r0      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   r4   r   r!   r"   z_packed_params.weightz_packed_params.biasF)	r   r   r7   intr   r6   updater   r8   r9   r   r   r    r8      s,   
zLinear._load_from_state_dictc                 C   s
   | j  S r+   )r'   r*   r)   r   r   r    r*     rI   zLinear._weight_biasc                 C      |   d S )Nr   r*   r)   r   r   r    r!     r=   zLinear.weightc                 C   rM   )Nr   rN   r)   r   r   r    r"     r=   zLinear.biaswbNc                 C   s   | j || d S r+   )r'   r   )r   rO   rP   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   )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_varZepsrQ   activation_post_process
isinstance_FLOAT_MODULEr   joinr>   typeformatnniZ
LinearReLUrT   r   Zcalculate_qparamsr   r   r   r   rD   rE   r   r   rK   r   )clsmodZuse_precomputed_fake_quantZweight_post_processrW   Zsupported_modules	error_msgr   Z	act_scaleZact_zprF   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
        )	rD   rE   Zget_quantized_weightr   r"   r   r   rK   r   )r^   Zref_qlinearZoutput_scaleZoutput_zero_pointra   rF   r   r   r    from_referenceZ  s   


zLinear.from_reference)F)r>   r?   r@   __doc__rA   nnr   modulesrJ   ZNonDynamicallyQuantizableLinearrY   r   r   r   rG   rH   r<   rB   r.   r0   r8   r*   r!   r"   r   r   classmethodrb   rc   rC   r   r   r   r    r   x   s&    ")=)collections.abcr   typingr   r   Ztorch.ao.nn.intrinsicZaore   Z	intrinsicr]   Ztorch.ao.nn.intrinsic.qatZqatrV   Ztorch.nnZtorch.nn.utils.fusionr   Ztorch.nn.utils.parametrizer   utilsr   r   r	   __all__Moduler
   r   r   r   r   r    <module>   s   e