U
    (dN                     @   s   d dl Z d dlmZmZ d dlZd dlmZmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZ dd	lmZ deeeee eeef eeef eeef ee ed	ddZG dd dejZdS )    N)OptionalTuple)nnTensor)init)_pair)	Parameter)_assert_has_ops   )_log_api_usage_once   r   r   r   )	inputoffsetweightbiasstridepaddingdilationmaskreturnc                 C   s2  t j st j stt t  |jd }|dk	}	|dkrZt j| jd df| j	| j
d}|dkrvt j|| j	| j
d}t|\}
}t|\}}t|\}}|jdd \}}| j\}}}}|jd d| |  }||jd  }|dkr
td|jd  dd| |  t jj| |||||
||||||||	S )	a?  
    Performs Deformable Convolution v2, described in
    `Deformable ConvNets v2: More Deformable, Better Results
    <https://arxiv.org/abs/1811.11168>`__ if :attr:`mask` is not ``None`` and
    Performs Deformable Convolution, described in
    `Deformable Convolutional Networks
    <https://arxiv.org/abs/1703.06211>`__ if :attr:`mask` is ``None``.

    Args:
        input (Tensor[batch_size, in_channels, in_height, in_width]): input tensor
        offset (Tensor[batch_size, 2 * offset_groups * kernel_height * kernel_width, out_height, out_width]):
            offsets to be applied for each position in the convolution kernel.
        weight (Tensor[out_channels, in_channels // groups, kernel_height, kernel_width]): convolution weights,
            split into groups of size (in_channels // groups)
        bias (Tensor[out_channels]): optional bias of shape (out_channels,). Default: None
        stride (int or Tuple[int, int]): distance between convolution centers. Default: 1
        padding (int or Tuple[int, int]): height/width of padding of zeroes around
            each image. Default: 0
        dilation (int or Tuple[int, int]): the spacing between kernel elements. Default: 1
        mask (Tensor[batch_size, offset_groups * kernel_height * kernel_width, out_height, out_width]):
            masks to be applied for each position in the convolution kernel. Default: None

    Returns:
        Tensor[batch_sz, out_channels, out_h, out_w]: result of convolution

    Examples::
        >>> input = torch.rand(4, 3, 10, 10)
        >>> kh, kw = 3, 3
        >>> weight = torch.rand(5, 3, kh, kw)
        >>> # offset and mask should have the same spatial size as the output
        >>> # of the convolution. In this case, for an input of 10, stride of 1
        >>> # and kernel size of 3, without padding, the output size is 8
        >>> offset = torch.rand(4, 2 * kh * kw, 8, 8)
        >>> mask = torch.rand(4, kh * kw, 8, 8)
        >>> out = deform_conv2d(input, offset, weight, mask=mask)
        >>> print(out.shape)
        >>> # returns
        >>>  torch.Size([4, 5, 8, 8])
    r   N)devicedtyper   r
   zthe shape of the offset tensor at dimension 1 is not valid. It should be a multiple of 2 * weight.size[2] * weight.size[3].
Got offset.shape[1]=z,, while 2 * weight.size[2] * weight.size[3]=)torchZjitZis_scripting
is_tracingr   deform_conv2dr	   shapezerosr   r   r   RuntimeErroropsZtorchvision)r   r   r   r   r   r   r   r   out_channelsZuse_maskZstride_hZstride_wZpad_hZpad_wZdil_hZdil_wZ	weights_hZ	weights_w_Zn_in_channelsZn_offset_grpsZn_weight_grps r$   ?/tmp/pip-unpacked-wheel-vx7f76es/torchvision/ops/deform_conv.pyr      sH    1

r   c                
       sl   e Zd ZdZdeeeeeeeed fddZdd	d
dZdeee	e edddZ
ed	ddZ  ZS )DeformConv2dz$
    See :func:`deform_conv2d`.
    r   r   T)in_channelsr"   kernel_sizer   r   r   groupsr   c	           	         s   t    t|  || dkr&td|| dkr:td|| _|| _t|| _t|| _t|| _	t|| _
|| _tt||| | jd | jd | _|rtt|| _n| dd  |   d S )Nr   z'in_channels must be divisible by groupsz(out_channels must be divisible by groupsr   r   )super__init__r   
ValueErrorr'   r"   r   r(   r   r   r   r)   r   r   emptyr   r   Zregister_parameterreset_parameters)	selfr'   r"   r(   r   r   r   r)   r   	__class__r$   r%   r+   s   s(    




zDeformConv2d.__init__N)r   c                 C   sT   t j| jtdd | jd k	rPt | j\}}dt| }t | j| | d S )N   )ar   )r   Zkaiming_uniform_r   mathsqrtr   Z_calculate_fan_in_and_fan_outZuniform_)r/   Zfan_inr#   boundr$   r$   r%   r.      s
    
zDeformConv2d.reset_parameters)r   r   r   r   c              
   C   s"   t ||| j| j| j| j| j|dS )a  
        Args:
            input (Tensor[batch_size, in_channels, in_height, in_width]): input tensor
            offset (Tensor[batch_size, 2 * offset_groups * kernel_height * kernel_width, out_height, out_width]):
                offsets to be applied for each position in the convolution kernel.
            mask (Tensor[batch_size, offset_groups * kernel_height * kernel_width, out_height, out_width]):
                masks to be applied for each position in the convolution kernel.
        )r   r   r   r   )r   r   r   r   r   r   )r/   r   r   r   r$   r$   r%   forward   s    	zDeformConv2d.forwardc              	   C   s   | j j d| j d| j d| j d| j 	}|| jdkrDd| j nd7 }|| jdkrbd	| j nd7 }|| jd
krd| j nd7 }|| j	d krdnd7 }|d7 }|S )N(z, z, kernel_size=z	, stride=r   z
, padding= r   z, dilation=r   z	, groups=z, bias=False))
r1   __name__r'   r"   r(   r   r   r   r)   r   )r/   sr$   r$   r%   __repr__   s    *zDeformConv2d.__repr__)r   r   r   r   T)N)r;   
__module____qualname____doc__intboolr+   r.   r   r   r7   strr=   __classcell__r$   r$   r0   r%   r&   n   s&   	     &r&   )Nr   r   r   N)r4   typingr   r   r   r   r   Ztorch.nnr   Ztorch.nn.modules.utilsr   Ztorch.nn.parameterr   Ztorchvision.extensionr	   utilsr   rA   r   Moduler&   r$   r$   r$   r%   <module>   s2        


`