U
    Kc                     @   sl   d dl mZ d dlZd dlm  mZ d dlmZ d dl	m
Z
 d dlmZmZ dgZG dd dejjZdS )    )OptionalN)linear)LinearBlockSparsePattern)_quantize_weighthide_packed_params_reprLinearc                       s   e Zd ZdZdZdZejj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 ee ee ddddZedd Z  ZS ) r   z_
    A dynamically quantized sparse linear module with float tensor as inputs and outputs.
       Zsparse_dynamicTc                    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
j|||d| _| j|||| d S )Nz;Only QINT8 is supported for Sparse Quantized Linear Dynamicdtyper   r   )ZscaleZ
zero_pointr
   )row_block_sizecol_block_sizer
   )super__init__torchqint8NotImplementedErrorin_featuresout_featureszerosfloatZ_empty_affine_quantizedr   LinearPackedParams_packed_paramsset_weight_bias)selfr   r   r   r   biasr
   qweight	__class__ O/tmp/pip-unpacked-wheel-gikjz4vx/torch/ao/nn/sparse/quantized/dynamic/linear.pyr      s$    


  zLinear.__init__c                 C   s   dS )NZSparseQuantizedDynamicLinearr   r   r   r   r   	_get_name)   s    zLinear._get_namec                 C   s   d | j| j|   S )Nz+in_features={}, out_features={}, qscheme={})formatr   r   weightZqschemer    r   r   r   
extra_repr,   s
      
zLinear.extra_reprc                 C   s   t | tjS N)r   r   r   r    r   r   r   __repr__1   s    zLinear.__repr__)xreturnc                 C   s   t jj|| jjS r%   )r   opssparseZqlinear_dynamicr   )r   r'   r   r   r   forward4   s    zLinear.forwardc                    s"   t  ||| | j||d < d S )Nop_type)r   _save_to_state_dict_op_type)r   ZdestinationprefixZ	keep_varsr   r   r   r-   7   s    zLinear._save_to_state_dictc              	      s   t ||d  }|dks*td|| j||d  |dd }	|	| jksRt||d }
||d }||d |
|d |i t 	|||d	||| d S )
Nr,   r*   z-Cannot load from op_type [{}], expecting [{}]versionr#   r   z_packed_params.weightz_packed_params.biasF)
intAssertionErrorr"   r.   popget_versionupdater   _load_from_state_dict)r   Z
state_dictr/   Zlocal_metadatastrictZmissing_keysZunexpected_keysZ
error_msgsr,   r0   r#   r   r   r   r   r7   ;   s,    
      zLinear._load_from_state_dictc                 C   s
   | j  S r%   )r   _weight_biasr    r   r   r   r9   P   s    zLinear._weight_biasc                 C   s   |   d S )Nr   r9   r    r   r   r   r#   S   s    zLinear.weightc                 C   s   |   d S )Nr   r:   r    r   r   r   r   V   s    zLinear.biasN)wbr   r   r(   c                 C   sB   |d k	r|d k	st |jd | _|jd | _| j|||| d S )Nr   r   )r2   shaper   r   r   r   )r   r;   r<   r   r   r   r   r   r   Y   s    zLinear.set_weight_biasc                 C   sP  t || jks(td| j d | jj t|ds:tdt |tjkrP|d }|jdk	rr|jjdk	rr|j }nddl	m
} | }|j}t|jdd	r|jj|j }|| |j}|tjkstd
| \}}t|tjrt| rtdn|dks
tdt| |}t \}	}
| |j|j|	|
|d}|||j|	|
 |S )zCreate a quantized sparse dynamic module from a float module.

        We only care about the convert at this stage, no need for observers just yet.
        z nnq.z.from_float only works for qconfigz,Input float module must have qconfig definedr   N)default_dynamic_qconfigmaskFz+Weight observer must have dtype torch.qint8z$All weight zero points must map to 0zWeight zero point must map to 0r	   )type_FLOAT_MODULEr2   __name__hasattrnniZ
LinearReLUr>   r#   Ztorch.ao.quantization.qconfigr?   getattrr@   r
   r   r   Zcalculate_qparams
isinstanceTensoranyboolr   r   r   
block_sizer   r   r   r   )clsmodZweight_observerr?   r#   r
   Zw_scZw_zpr   r   r   Zqlinearr   r   r   
from_float`   s<    zLinear.from_float)rC   
__module____qualname____doc__r5   r.   r   nnr   rB   r   r   r!   r$   r&   rH   r+   r-   r7   r9   r#   r   r   r1   r   classmethodrN   __classcell__r   r   r   r   r      s*     )typingr   r   Ztorch.nn.intrinsicrR   Z	intrinsicrE   Ztorch.ao.nn.sparse.quantizedr   Z"torch.ao.nn.sparse.quantized.utilsr   Z#torch.ao.nn.quantized.modules.utilsr   r   __all__Moduler   r   r   r   r   <module>   s   