o
    ߥi"                     @   sn   d dl Z d dlmZ d dlZd dlmZ d dlmZ dZ	G dd deZ
G dd	 d	eZdddZdd ZdS )    N)abc)Function)
functionalFc                   @   $   e Zd Zedd Zedd ZdS )UpFirDn2dBackwardc
                 C   s   |\}
}|\}}|\}}}}| d|	d |	d d}t|||||
|||||
}||d |d |d |d }| | |\}}}}|
| _|| _|| _|| _|| _	|| _
|| _|| _|| _|	| _|S )Nr            )reshapeupfirdn2d_op	upfirdn2dviewsave_for_backwardup_xup_ydown_xdown_ypad_x0pad_x1pad_y0pad_y1in_sizeout_size)ctxgrad_outputkernelgrad_kernelupdownpadg_padr   r   r   r   r   r   g_pad_x0g_pad_x1g_pad_y0g_pad_y1
grad_inputr   r   r   r    r'   e/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/models/cv/face_generation/op/upfirdn2d.pyforward   s@   
zUpFirDn2dBackward.forwardc                 C   s   | j \}|d| jd | jd d}t||| j| j| j| j| j	| j
| j| j
}|| jd | jd | jd | jd }|d d d d d d d d f	S )Nr   r	   r
   r   r   )saved_tensorsr   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   gradgrad_inputr   gradgrad_outr'   r'   r(   backward9   s(   
zUpFirDn2dBackward.backwardN__name__
__module____qualname__staticmethodr)   r-   r'   r'   r'   r(   r      s
    
)r   c                   @   r   )	UpFirDn2dc                 C   sV  |\}}|\}}	|\}
}}}|j \}}|j \}}}}|j | _|d||d}| |t|ddg || | | | |	 |	 }|| |
 | | | | }||f| _||f| _||	f| _|
|||f| _	||
 d }|| d }|| ||  |
 | d }|| ||	  | | d }||||f| _
t||||||	|
|||
}|d|||}|S )Nr   r   r   )shaper   r   r   torchflipr   r   r   r    r!   r   r   r   )r   inputr   r   r   r    r   r   r   r   r   r   r   r   kernel_hkernel_wbatchchannelin_hin_wout_hout_wr"   r$   r#   r%   outr'   r'   r(   r)   U   s0   



zUpFirDn2d.forwardc                 C   sL   | j \}}d }| jd rt|||| j| j| j| j| j| j		}|d d d d fS )Nr   )
r*   needs_input_gradr   applyr   r   r    r!   r   r   )r   r   r   r   r&   r'   r'   r(   r-   y   s   

zUpFirDn2d.backwardNr.   r'   r'   r'   r(   r3   S   s
    
#r3   r   r   r   c                 C   sr   t |tjs
||f}t |tjs||f}t|dkr(|d |d |d |d f}ts7t| |g|||R  }|S )Nr	   r   r   )
isinstancer   Iterablelendef_libupfirdn2d_native)r7   r   r   r   r    r@   r'   r'   r(   r      s   r   c
                 C   s  | j \}
}}}| d||d} | j \}
}}}|j \}}| d|d|d|}t|ddd|d ddd|d g}|d|| || |}t|ddt|dt|dt|dt|	dg}|d d t| d|j d t|	 d t| d|j d t| d f }|dddd}|dd|| | |	 || | | g}t|ddgdd||}t	||}|d||| | |	 | d || | | | d }|dddd}|d d d d |d d |d d f }|| | |	 | | | }|| | | | | | }|d|||S )Nr   r   r   r	   r
   )
r4   r   r   Fr    maxpermuter5   r6   conv2d)r7   r   r   r   r   r   r   r   r   r   _r;   r<   r=   minorr8   r9   r@   wr>   r?   r'   r'   r(   rH      sJ   
$  "$rH   )r   r   rC   )oscollectionsr   r5   torch.autogradr   torch.nnr   rI   rG   r   r3   r   rH   r'   r'   r'   r(   <module>   s   F
<