U
    d$                     @   s   d dl Z d dlmZ d dlmZmZmZ d dlmZ d dl	m
Z
mZmZ d dlmZmZmZ edejjjdZG dd	 d	ejjjZG d
d deejZG dd deejZG dd deejZdS )    N)_single_pair_triple)_FusedModule)TupleTypeVarUnion)	_size_1_t	_size_2_t	_size_3_tMOD)boundc                   @   sz   e Zd ZeZdeeeedf eedf eedf eedf eeedf eeeddddZ	dd Z
edd	 Zd
d ZdS )_ConvNdN.)in_channelsout_channelskernel_sizestridepaddingdilation
transposedoutput_paddinggroupsbiaspadding_modereturnc                 C   sX   ||d}t jjjj| |||||||||	|
|f| |s@td|| _|j|d| _d S )N)devicedtypez'qconfig must be provided for QAT module)factory_kwargs)	nnmodulesconvr   __init__AssertionErrorqconfigweightweight_fake_quant)selfr   r   r   r   r   r   r   r   r   r   r   r#   r   r   r    r'   =/tmp/pip-unpacked-wheel-ua33x9lu/torch/nn/qat/modules/conv.pyr!      s     
      z_ConvNd.__init__c                 C   s   |  || | j| jS NZ_conv_forwardr%   r$   r   r&   inputr'   r'   r(   forward%   s    z_ConvNd.forwardc                 C   s   t || jks(td| j d | jj t|ds:td|jsHtdtt |tr^|d }|j}| |j|j	|j
|j|j|j|j|jdk	|j|d
}|j|_|j|_|S )	zCreate a qat module from a float module

            Args:
               `mod`: a float module, either produced by torch.ao.quantization utilities
               or directly from user
        zqat.z.from_float only works for r#   z,Input float module must have qconfig definedz,Input float module must have a valid qconfigr   N)r   r   r   r   r   r   r#   )type_FLOAT_MODULEr"   __name__hasattrr#   
issubclassr   r   r   r   r   r   r   r   r   r   r$   )clsmodr#   Zqat_convr'   r'   r(   
from_float(   s4        z_ConvNd.from_floatc                 C   s   t | }|| j| j| j| j| j| j| j| j	dk	| j
	}tj| j |_| j	dk	rjtj| j	 |_	t|tr|g}t|dst| }|| |j| }|| j |S |S dS )z This works for both single qat conv, and the qat conv - relu modules
        to convert the qat module to a floating point module
        N_FLOAT_RELU_MODULE)r.   _FLOAT_CONV_MODULEr   r   r   r   r   r   r   r   r   torchr   	Parameterr$   detachr2   r   r1   r"   r6   appendr/   ZtrainZtraining)r&   r3   r    r   ZreluZfusedr'   r'   r(   to_floatC   s0    




z_ConvNd.to_float)NNN)r0   
__module____qualname__r   r/   intr   boolstrr!   r-   staticmethodr5   r<   r'   r'   r'   r(   r   
   s,      





r   c                       s^   e Zd ZdZejZejZdeee	e	e
ee	f e	eeedd
 fdd	Ze fd
dZ  ZS )Conv1daZ  
    A Conv1d module attached with FakeQuantize modules for weight,
    used for quantization aware training.

    We adopt the same interface as :class:`~torch.nn.Conv1d`

    Similar to :class:`~torch.nn.Conv2d`, with FakeQuantize modules initialized to
    default.

    Attributes:
        weight_fake_quant: fake quant module for weight
       r   TzerosN
r   r   r   r   r   r   r   r   r   r   c                    s^   t |}t |}t|tr|nt |}t |}t j||||||dt d|||	|
||d d S NFr   )r   r   r   r   r   r   r   r   r#   r   r   )r   
isinstancerA   superr!   r&   r   r   r   r   r   r   r   r   r   r#   r   r   Zkernel_size_Zstride_Zpadding_Z	dilation_	__class__r'   r(   r!   q   s(    zConv1d.__init__c                    s   t  | |S r)   rI   r5   r3   r4   rK   r'   r(   r5      s    zConv1d.from_float)	rD   r   rD   rD   TrE   NNN)r0   r=   r>   __doc__r   rC   r/   r7   r?   r	   r   rA   r@   r!   classmethodr5   __classcell__r'   r'   rK   r(   rC   a   s4            
!rC   c                       sf   e Zd ZdZejZejZdeee	e	e
ee	f e	eeedd
 fdd	Zd
d Ze fddZ  ZS )Conv2da  
    A Conv2d module attached with FakeQuantize modules for weight,
    used for quantization aware training.

    We adopt the same interface as `torch.nn.Conv2d`, please see
    https://pytorch.org/docs/stable/nn.html?highlight=conv2d#torch.nn.Conv2d
    for documentation.

    Similar to `torch.nn.Conv2d`, with FakeQuantize modules initialized to
    default.

    Attributes:
        weight_fake_quant: fake quant module for weight
    rD   r   TrE   NrF   c                    s^   t |}t |}t|tr|nt |}t |}t j||||||dt d|||	|
||d d S rG   )r   rH   rA   rI   r!   rJ   rK   r'   r(   r!      s(    zConv2d.__init__c                 C   s   |  || | j| jS r)   r*   r+   r'   r'   r(   r-      s    zConv2d.forwardc                    s   t  | |S r)   rM   rN   rK   r'   r(   r5      s    zConv2d.from_float)	rD   r   rD   rD   TrE   NNN)r0   r=   r>   rO   r   rR   r/   r7   r?   r
   r   rA   r@   r!   r-   rP   r5   rQ   r'   r'   rK   r(   rR      s6            
!rR   c                       sf   e Zd ZdZejZejZdeee	e	e
ee	f e	eeedd
 fdd	Zd
d Ze fddZ  ZS )Conv3da  
    A Conv3d module attached with FakeQuantize modules for weight,
    used for quantization aware training.

    We adopt the same interface as `torch.nn.Conv3d`, please see
    https://pytorch.org/docs/stable/nn.html?highlight=conv3d#torch.nn.Conv3d
    for documentation.

    Similar to `torch.nn.Conv3d`, with FakeQuantize modules initialized to
    default.

    Attributes:
        weight_fake_quant: fake quant module for weight
    rD   r   TrE   NrF   c                    s^   t |}t |}t|tr|nt |}t |}t j||||||dt d|||	|
||d d S rG   )r   rH   rA   rI   r!   rJ   rK   r'   r(   r!      s(    zConv3d.__init__c                 C   s   |  || | j| jS r)   r*   r+   r'   r'   r(   r-     s    zConv3d.forwardc                    s   t  | |S r)   rM   rN   rK   r'   r(   r5     s    zConv3d.from_float)	rD   r   rD   rD   TrE   NNN)r0   r=   r>   rO   r   rS   r/   r7   r?   r   r   rA   r@   r!   r-   rP   r5   rQ   r'   r'   rK   r(   rS      s6            
!rS   )r8   Ztorch.nnr   Ztorch.nn.modules.utilsr   r   r   Ztorch.nn.intrinsicr   typingr   r   r   Ztorch.nn.common_typesr	   r
   r   r   r    r   r   rC   rR   rS   r'   r'   r'   r(   <module>   s   W5: