a
    dl=                  	   @   sR  d dl Z d dlZd dl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mZ edZedkrd d	lmZ ejeZed
ejeddejeddejeddgdZn$zddlmZ W n ey   Y n0 G dd deZG dd deZejZejZG dd dejZ G dd de Z!G dd dejZ"G dd de"Z#dS )    N)nn)Function)once_differentiable)
functional)_pair_singleBASICSR_JITTrue)loaddeform_convsrczdeform_conv_ext.cppzdeform_conv_cuda.cppzdeform_conv_cuda_kernel.cu)sources   )deform_conv_extc                   @   s6   e Zd ZedddZeedd Zedd	 Zd
S )DeformConvFunctionr   r   @   c
                 C   s@  |d ur(|  dkr(td|   dt|| _t|| _t|| _|| _|| _|	| _| 	||| |
t||| j| j| j}
|
d|
dg| _|jstnt| j|jd }|jd | dksJ dt||||
| jd | jd |d|d| jd | jd | jd | jd | jd | jd | j| j| |
S )	N   z!Expected 4D tensor as input, got zD tensor instead.r   !im2col step must divide batchsizer         )dim
ValueErrorr   stridepaddingdilationgroupsdeformable_groupsim2col_stepsave_for_backward	new_emptyr   _output_sizebufs_is_cudaNotImplementedErrorminshaper   Zdeform_conv_forwardsize)ctxinputoffsetweightr   r   r   r   r   r   outputcur_im2col_step r-   d/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/basicsr/ops/dcn/deform_conv.pyforward#   s,    


 zDeformConvFunction.forwardc           	      C   sv  | j \}}}d  } }}|js&tn<t| j|jd }|jd | dksRJ d| jd sf| jd rt|}t|}t	
||||||| jd |d|d| jd | jd | jd | jd | jd | jd | j| j| | jd rbt|}t	||||| jd | jd |d|d| jd | jd | jd | jd | jd | jd | j| jd| |||d d d d d fS )Nr   r   r   r   r   )saved_tensorsr"   r#   r$   r   r%   Zneeds_input_gradtorch
zeros_liker   Zdeform_conv_backward_inputr!   r&   r   r   r   r   r   Zdeform_conv_backward_parameters)	r'   grad_outputr(   r)   r*   
grad_inputgrad_offsetgrad_weightr,   r-   r-   r.   backwardI   s2    

 
zDeformConvFunction.backwardc                 C   s   | d}|  d|f}t|  d D ]^}|  |d }|| }	|| | |d d  d }
|| }||d|	  |
 | d f7 }q(ttdd |stddtt| d|S )	Nr   r   r   c                 S   s   | dkS )Nr   r-   )sr-   r-   r.   <lambda>t       z1DeformConvFunction._output_size.<locals>.<lambda>z0convolution input is too small (output would be x))r&   ranger   allmapr   joinstr)r(   r*   r   r   r   ZchannelsZoutput_sizedZin_sizepadkernelZstride_r-   r-   r.   r    j   s    
 zDeformConvFunction._output_sizeN)r   r   r   r   r   r   )__name__
__module____qualname__staticmethodr/   r   r7   r    r-   r-   r-   r.   r   !   s         %r   c                   @   s6   e Zd Zed
ddZeedd Zedd	 ZdS )ModulatedDeformConvFunctionNr   r   c                 C   s   || _ || _|| _|	| _|
| _|d u| _| js8|d}|jsBt|j	sZ|j	sZ|j	sZ|j	rl| 
||||| |t| ||}|d|dg| _t|||| jd |||| jd |jd |jd | j | j | j| j| j| j| j| j| j |S )Nr   r   r   r   )r   r   r   r   r   	with_biasr   r"   r#   Zrequires_gradr   rI   _infer_shape_bufsr   Zmodulated_deform_conv_forwardr%   )r'   r(   r)   maskr*   biasr   r   r   r   r   r+   r-   r-   r.   r/   {   s(    

z#ModulatedDeformConvFunction.forwardc                 C   s   |j s
t| j\}}}}}t|}t|}t|}	t|}
t|}t|||| jd ||| jd ||
|||	||jd |jd | j	| j	| j
| j
| j| j| j| j| j | jsd }|||	|
|d d d d d f
S )Nr   r   r   r   )r"   r#   r0   r1   r2   r   Zmodulated_deform_conv_backwardrL   r%   r   r   r   r   r   rJ   )r'   r3   r(   r)   rM   r*   rN   r4   r5   Z	grad_maskr6   Z	grad_biasr-   r-   r.   r7      s"    





z$ModulatedDeformConvFunction.backwardc                 C   s   | d}| d}|jdd \}}|jdd \}}|d| j  | j|d  d  | j d }	|d| j  | j|d  d  | j d }
|||	|
fS )Nr   r   r   r   )r&   r%   r   r   r   )r'   r(   r*   nZchannels_outheightwidthZkernel_hZkernel_wZ
height_outZ	width_outr-   r-   r.   rK      s    

**z(ModulatedDeformConvFunction._infer_shape)Nr   r   r   r   r   )rE   rF   rG   rH   r/   r   r7   rK   r-   r-   r-   r.   rI   y   s         rI   c                       s.   e Zd Zd
 fdd	Zdd Zdd	 Z  ZS )
DeformConvr   r   Fc
           
         s   t t|   |	rJ || dks6J d| d| || dksVJ d| d| || _|| _t|| _t|| _t|| _t|| _	|| _
|| _d| _td| _ttj||| j
 g| jR  | _|   d S )Nr   zin_channels z is not divisible by groups zout_channels F)superrR   __init__in_channelsout_channelsr   kernel_sizer   r   r   r   r   
transposedr   output_paddingr   	Parameterr1   Tensorr*   reset_parameters
selfrU   rV   rW   r   r   r   r   r   rN   	__class__r-   r.   rT      s     
  




$zDeformConv.__init__c                 C   s>   | j }| jD ]}||9 }qdt| }| jj| | d S Ng      ?)rU   rW   mathsqrtr*   datauniform_r^   rO   kZstdvr-   r-   r.   r\      s
    

zDeformConv.reset_parametersc              	   C   s   | d| jd k p&| d| jd k }|rt| jd | d d}t| jd | d d}t|d|d|fdd }t|d|d|fdd }t||| j| j| j	| j
| j| j}|r|d d d d d | d| d | d| f  }|S )Nr   r   r   r   Zconstant)r&   rW   maxFrC   
contiguousr   r*   r   r   r   r   r   )r^   r;   r)   Z	input_padZpad_hZpad_woutr-   r-   r.   r/      s    (8zDeformConv.forward)r   r   r   r   r   F)rE   rF   rG   rT   r\   r/   __classcell__r-   r-   r_   r.   rR      s          rR   c                       s4   e Zd ZdZdZ fddZdd Zdd Z  ZS )	DeformConvPackai  A Deformable Conv Encapsulation that acts as normal Conv layers.

    Args:
        in_channels (int): Same as nn.Conv2d.
        out_channels (int): Same as nn.Conv2d.
        kernel_size (int or tuple[int]): Same as nn.Conv2d.
        stride (int or tuple[int]): Same as nn.Conv2d.
        padding (int or tuple[int]): Same as nn.Conv2d.
        dilation (int or tuple[int]): Same as nn.Conv2d.
        groups (int): Same as nn.Conv2d.
        bias (bool or str): If specified as `auto`, it will be decided by the
            norm_cfg. Bias will be set as True if norm_cfg is None, otherwise
            False.
    r   c              	      sl   t t| j|i | tj| j| jd | jd  | jd  | jt| j	t| j
t| jdd| _|   d S )Nr   r   r   TrW   r   r   r   rN   )rS   rm   rT   r   Conv2drU   r   rW   r   r   r   r   conv_offsetinit_offsetr^   argskwargsr_   r-   r.   rT   
  s    zDeformConvPack.__init__c                 C   s    | j jj  | j jj  d S N)rp   r*   rd   zero_rN   r^   r-   r-   r.   rq     s    zDeformConvPack.init_offsetc              	   C   s,   |  |}t||| j| j| j| j| j| jS ru   )rp   r   r*   r   r   r   r   r   )r^   r;   r)   r-   r-   r.   r/     s    
zDeformConvPack.forward)	rE   rF   rG   __doc___versionrT   rq   r/   rl   r-   r-   r_   r.   rm      s
   rm   c                       s.   e Zd Zd
 fdd	Zdd Zdd	 Z  ZS )ModulatedDeformConvr   r   Tc
           
         s   t t|   || _|| _t|| _|| _|| _|| _	|| _
|| _|	| _d| _td| _ttj||| g| jR  | _|	rtt|| _n| dd  |   d S )NFr   rN   )rS   rz   rT   rU   rV   r   rW   r   r   r   r   r   rJ   rX   r   rY   r   rZ   r1   r[   r*   rN   Zregister_parameterinit_weightsr]   r_   r-   r.   rT   #  s"    


"zModulatedDeformConv.__init__c                 C   sT   | j }| jD ]}||9 }qdt| }| jj| | | jd urP| jj  d S ra   )	rU   rW   rb   rc   r*   rd   re   rN   rv   rf   r-   r-   r.   r{   B  s    


z ModulatedDeformConv.init_weightsc                 C   s(   t |||| j| j| j| j| j| j| j
S ru   )modulated_deform_convr*   rN   r   r   r   r   r   )r^   r;   r)   rM   r-   r-   r.   r/   K  s    zModulatedDeformConv.forward)r   r   r   r   r   T)rE   rF   rG   rT   r{   r/   rl   r-   r-   r_   r.   rz   !  s         	rz   c                       s8   e Zd ZdZdZ fddZ fddZdd Z  ZS )	ModulatedDeformConvPackar  A ModulatedDeformable Conv Encapsulation that acts as normal Conv layers.

    Args:
        in_channels (int): Same as nn.Conv2d.
        out_channels (int): Same as nn.Conv2d.
        kernel_size (int or tuple[int]): Same as nn.Conv2d.
        stride (int or tuple[int]): Same as nn.Conv2d.
        padding (int or tuple[int]): Same as nn.Conv2d.
        dilation (int or tuple[int]): Same as nn.Conv2d.
        groups (int): Same as nn.Conv2d.
        bias (bool or str): If specified as `auto`, it will be decided by the
            norm_cfg. Bias will be set as True if norm_cfg is None, otherwise
            False.
    r   c              	      sl   t t| j|i | tj| j| jd | jd  | jd  | jt| j	t| j
t| jdd| _|   d S )Nr   r   r   Trn   )rS   r}   rT   r   ro   rU   r   rW   r   r   r   r   rp   r{   rr   r_   r-   r.   rT   b  s    z ModulatedDeformConvPack.__init__c                    s8   t t|   t| dr4| jjj  | jjj  d S )Nrp   )	rS   r}   r{   hasattrrp   r*   rd   rv   rN   rw   r_   r-   r.   r{   o  s    
z$ModulatedDeformConvPack.init_weightsc                 C   sd   |  |}tj|ddd\}}}tj||fdd}t|}t|||| j| j| j| j	| j
| j| j
S )Nr   r   )r   )rp   r1   chunkcatZsigmoidr|   r*   rN   r   r   r   r   r   )r^   r;   rk   Zo1Zo2rM   r)   r-   r-   r.   r/   u  s    

zModulatedDeformConvPack.forward)	rE   rF   rG   rx   ry   rT   r{   r/   rl   r-   r-   r_   r.   r}   P  s
   r}   )$rb   osr1   r   Ztorch.autogradr   Ztorch.autograd.functionr   Ztorch.nnr   ri   Ztorch.nn.modules.utilsr   r   getenvr   Ztorch.utils.cpp_extensionr
   pathdirname__file__module_pathr@   r    ImportErrorr   rI   applyr   r|   ModulerR   rm   rz   r}   r-   r-   r-   r.   <module>   s<   
	XB9)/