U
    ­Ê¹jN  ã                   @   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   Nr   )ÚdeviceÚdtypeéþÿÿÿr
   z�the 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	   ÚshapeZzerosr   r   r   ÚRuntimeErrorZ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"   úZ/var/www/html/bwave/python/venv/lib/python3.8/site-packages/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 ¡ƒ| _|r°t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r€d| j› �nd7 }|| j	d kr–d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ú))
r/   Ú__name__r%   r    r&   r   r   r   r'   r   )r-   Úsr"   r"   r#   Ú__repr__µ   s    *ÿzDeformConv2d.__repr__)r   r   r   r   T)N)r9   Ú
__module__Ú__qualname__Ú__doc__ÚintÚboolr)   r,   r   r   r5   Ústrr;   Ú__classcell__r"   r"   r.   r#   r$   n   s&   	     ÷÷&r$   )Nr   r   r   N)r2   Útypingr   r   r   r   r   Ztorch.nnr   Ztorch.nn.modules.utilsr   Ztorch.nn.parameterr   Ztorchvision.extensionr	   Úutilsr   r?   r   ÚModuler$   r"   r"   r"   r#   Ú<module>   s2        ø


÷`