o
    Zh#                     @   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   Zwq	__class__ R/var/www/auris/lib/python3.10/site-packages/torch/ao/nn/sparse/quantized/linear.pyr      s   

zLinearPackedParams.__init__c                 C      dS )NZ!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sparseZ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%   Zqlinear_unpackr&   )r   r    r!   Z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prefixZ	keep_varsr   r   r   r+   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_dictr.   local_metadatastrictmissing_keysunexpected_keys
error_msgsr/   r    r!   r   r   r   r   r   r3   =   s    
z(LinearPackedParams._load_from_state_dictc                 C   s   | j | j| jfS r#   r&   Z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   r>   b      zLinearPackedParams.__repr__)__name__
__module____qualname__r1   r   r   r   r   ZjitZexportTensorr   intr   r'   r*   r+   r3   r;   r=   r>   __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_featuresZzerosfloatr   r   r&   r   r   r   )r   rG   rH   r   r   r!   r   qweightr   r   r   r   n   s*   
	

zLinear.__init__c                 C   r   )NZ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=)rG   rH   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%   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   r+   r   Ztensorr   r   r,   r   r   r   r+      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   Zop_typer/   F)	rI   r   r2   rD   r   r0   r1   r   r3   )	r   r4   r.   r5   r6   r7   r8   r9   r/   r   r   r   r3      s    
zLinear._load_from_state_dictc                 C   s
   | j  S r#   )r&   r'   r   r   r   r   r'      rM   zLinear._weight_biasc                 C      |   d S )Nr   r'   r   r   r   r   r       r?   zLinear.weightc                 C   rO   )Nr   rP   r   r   r   r   r!      r?   zLinear.biaswbr   r   Nc                 C   s*   |d ur|d us
J | j |||| d S r#   )r&   r   )r   rQ   rR   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   rF   )type_FLOAT_MODULEr   r@   hasattrrS   r0   
isinstancetuplelistlenactivation_post_processrV   r    r   Zcalculate_qparamsr   r   rC   anyboolr   rI   rG   rH   r   r!   r   rD   r   )rK   modZuse_precomputed_fake_quantrT   r^   Zweight_post_processr    r   Z	act_scaleZact_zpZw_scZw_zprJ   r   r   rN   r   r   r   
from_float   sJ   



zLinear.from_float)F)r@   rA   rB   __doc__r1   r   nnr   rX   r   r   classmethodr   rL   r>   rC   r*   r+   r3   r'   r    r!   r   rD   r   rb   rE   r   r   r   r   r   g   s<    $


)typingr   r   Z#torch.ao.nn.quantized.modules.utilsr   r   __all__rd   Moduler   r   r   r   r   r   <module>   s   W