o
    Ih#                     @   sX   d dl mZ d dlZd dlmZmZ ddgZG dd dejjZ	G dd dejjZ
dS )    )OptionalN)_hide_packed_params_repr_quantize_weightLinearPackedParamsLinearc                       s   e Zd ZdZddejf fdd	Zdd Zejj	dej
deej
 d	ee d
ee ddf
ddZejj	dd Zdd Z fddZ fddZejj	dd Zejj	dd Zdd Z  ZS )r         c                    sN   t    |tjkrtd|| _tjddgddtjd}| |d || d S )Nz%Linear prepacking only supports QINT8r         ?r   scale
zero_pointdtype)super__init__torchqint8NotImplementedErrorr   _empty_affine_quantizedset_weight_bias)selfrow_block_sizecol_block_sizer   wq	__class__ W/var/www/vscode/kcb/lib/python3.10/site-packages/torch/ao/nn/sparse/quantized/linear.pyr      s   

zLinearPackedParams.__init__c                 C      dS )N!SparseQuantizedLinearPackedParamsr   r   r   r   r   	_get_name      zLinearPackedParams._get_nameweightbiasr   r   returnNc                 C   s.   |d ur|d us
J t jj||||| _d S N)r   opssparseqlinear_prepack_packed_params)r   r"   r#   r   r   r   r   r   r   !   s   
z"LinearPackedParams.set_weight_biasc                 C   s*   t jj| j\}}}|||d |d fS )Nr   r   )r   r&   r'   qlinear_unpackr)   )r   r"   r#   block_sizesr   r   r   _weight_bias.   s   
zLinearPackedParams._weight_biasc                 C   s   |S r%   r   r   xr   r   r   forward5   r!   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   r0   8   s   z&LinearPackedParams._save_to_state_dictc              	      sl   | dd }|| jksJ ||d | _||d \}	}
}}| |	|
|| t |||d||| d S )Nversionr   r)   F)get_versionpopr   r   r   _load_from_state_dict)r   
state_dictr3   local_metadatastrictmissing_keysunexpected_keys
error_msgsr5   r"   r#   r   r   r   r   r   r9   =   s    
z(LinearPackedParams._load_from_state_dictc                 C   s   | j | j| jfS r%   r)   trainingr   r   r   r   r   __getstate__Z   s   zLinearPackedParams.__getstate__c                 C   s   |\| _ | _| _d S r%   r@   )r   stater   r   r   __setstate__^   s   zLinearPackedParams.__setstate__c                 C   s   |    S r%   )r,   __repr__r   r   r   r   rE   b      zLinearPackedParams.__repr__)__name__
__module____qualname__r7   r   r   r   r    jitexportTensorr   intr   r,   r/   r0   r9   rB   rD   rE   __classcell__r   r   r   r   r      s4    


c                
       s   e Zd ZdZdZejjZdej	f fdd	Z
e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ee dee ddf
dd Zed$d"d#Z  ZS )%r   zW
    A quantized sparse linear module with quantized tensor as inputs and outputs.
    r   Tc                    s   t    |tjkrtd|| _|| _|r tj| jtjd}nd }tj	||gddtjd}t
|||d| _| j|||| d| _d| _d S )Nz3Only QINT8 is supported for Sparse Quantized Linearr   r   r   r
   )r   r   r   r	   )r   r   r   r   r   in_featuresout_featureszerosfloatr   r   r)   r   r   r   )r   rP   rQ   r   r   r#   r   qweightr   r   r   r   n   s*   
	

zLinear.__init__c                 C   r   )NSparseQuantizedLinearr   )clsr   r   r   r       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=)rP   rQ   r   r   r"   qschemer   r   r   r   
extra_repr   s   
zLinear.extra_reprc                 C   s
   t | tS r%   )r   r   r   r   r   r   rE         
zLinear.__repr__r.   r$   c                 C   s   t jj|| jj| j| jS r%   )r   r&   r'   qlinearr)   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   tensorr   r   r1   r   r   r   r0      s   zLinear._save_to_state_dictc           	   	      s   t ||d  | _||d  t||d  | _||d  ||d  |dd }|| jks4J t |||d||| d S )Nr   r   op_typer5   F)	rS   r   r8   rM   r   r6   r7   r   r9   )	r   r:   r3   r;   r<   r=   r>   r?   r5   r   r   r   r9      s    
zLinear._load_from_state_dictc                 C   s
   | j  S r%   )r)   r,   r   r   r   r   r,      rY   zLinear._weight_biasc                 C      |   d S )Nr   r,   r   r   r   r   r"      rF   zLinear.weightc                 C   r]   )Nr   r^   r   r   r   r   r#      rF   zLinear.biaswbr   r   Nc                 C   s*   |d ur|d us
J | j |||| d S r%   )r)   r   )r   r_   r`   r   r   r   r   r   r      s   zLinear.set_weight_biasFc                 C   sf  t || jksJ |  d | jj t|dsJ d|jdd}t|tt	fs,J t
|dks4J t|ds=J d|j}|j }|j}|| |j}| \}}	|tjks^J d	| \}
}t|tjrvt| ruJ d
n|dks~J dt| |}|jd d }|jd d }| |j|j|||d}|||j|| t||_t|	|_|S )zCreate a quantized sparse module from a float module.

        We only care about the convert at this stage, no need for observers just yet.

        TODO(zaf): Need to add the sparse params to the qconfig
        z.from_float only works for sparse_paramszExpecting the Linear to have `sparse_params`. Make sure you have provided arguments in the `sparsifier.squash_mask(params_to_save=("sparse_block_shape",))` method.sparse_block_shapeN   qconfigz,Input float module must have qconfig definedz+Weight observer must have dtype torch.qint8z$All weight zero points must map to 0r   zWeight zero point must map to 0r   rO   )type_FLOAT_MODULEr    rG   hasattrra   r6   
isinstancetuplelistlenactivation_post_processrd   r"   r   calculate_qparamsr   r   rL   anyboolr   rS   rP   rQ   r   r#   r   rM   r   )rV   moduse_precomputed_fake_quantrb   rl   weight_post_processr"   r   	act_scaleact_zpw_scw_zprT   r   r   rZ   r   r   r   
from_float   sJ   



zLinear.from_float)F)rG   rH   rI   __doc__r7   r   nnr   rf   r   r   classmethodr    rX   rE   rL   r/   r0   r9   r,   r"   r#   r   rM   r   rw   rN   r   r   r   r   r   g   s<    $


)typingr   r   #torch.ao.nn.quantized.modules.utilsr   r   __all__ry   Moduler   r   r   r   r   r   <module>   s   W