o
    ߥilJ                     @   s   d Z ddlZddlZddlmZ ddlm  mZ ddl	m
Z
 dddZG dd dejZG d	d
 d
ejZG dd dejZG dd dejZG dd dejZG dd dejZG dd dejZG dd dejZG dd dejZdS )zx
Part of the implementation is borrowed and modified from LaMa, publicly available at
https://github.com/saic-mdal/lama
    N)rotatetanhc                 C   s>   | dkrt  S | dkrt  S | du rt  S td|  )Nr   sigmoidFzUnknown activation kind )nnTanhSigmoidIdentity
ValueError)kind r   e/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/models/cv/image_inpainting/modules/ffc.pyget_activation   s   r   c                       s&   e Zd Zd fdd	Zdd Z  ZS )SELayer   c              	      s\   t t|   td| _ttj||| ddtjddtj|| |ddt	 | _
d S )N   F)biasTinplace)superr   __init__r   AdaptiveAvgPool2davg_pool
SequentialLinearReLUr   fc)selfchannel	reduction	__class__r   r   r      s   

zSELayer.__init__c                 C   sJ   |  \}}}}| |||}| |||dd}||| }|S )Nr   )sizer   viewr   	expand_as)r   xbc_yresr   r   r   forward    s
   zSELayer.forward)r   __name__
__module____qualname__r   r*   __classcell__r   r   r   r   r      s    r   c                       s6   e Zd Z								d
 fdd	Zdd	 Z  ZS )FourierUnitr   NbilinearForthoc              	      s   t t|   || _tjj|d |rdnd |d ddd| jdd| _tj|d | _	tjj
dd| _|| _|rJ|d u r?i }t| jjfi || _|| _|| _|| _|	| _|
| _d S )N   r   r   F)in_channelsout_channelskernel_sizestridepaddinggroupsr   Tr   )r   r0   r   r9   torchr   Conv2d
conv_layerBatchNorm2dbnr   reluuse_ser   r4   sespatial_scale_factorspatial_scale_modespectral_pos_encodingffc3dfft_norm)r   r4   r5   r9   rB   rC   rD   r@   	se_kwargsrE   rF   r   r   r   r   *   s.   
zFourierUnit.__init__c                 C   s  |j d }| jd ur|j dd  }tj|| j| jdd}| jr!dnd}tjj||| j	d}tj
|j|jfdd	}|dd
ddd }||df| dd   }| jr|j dd  \}}tdd
|d d d d d f |d
|||}tdd
|d d d d d f |d
|||}	tj||	|fd
d	}| jr| |}| |}| | |}||ddf| dd   dd
ddd }t|d |d }| jr|j dd  n|j dd  }
tjj||
|| j	d}| jd urtj||| jdd}|S )Nr   F)scale_factormodealign_corners)rH   )rH   rM   )dimnormrM   rN   r      r3      ).r   ).r   rL   )srN   rO   )r!   rJ   rK   )shaperB   FinterpolaterC   rE   r:   fftrfftnrF   stackrealimagpermute
contiguousr"   r!   rD   linspaceexpandtocatr@   rA   r<   r?   r>   complexirfftn)r   r$   batch	orig_sizefft_dimfftedheightwidthcoords_vert
coords_horifft_shape_sliceoutputr   r   r   r*   Q   s   




"

zFourierUnit.forward)r   Nr1   FFNFr2   r+   r   r   r   r   r0   (   s    'r0   c                       s,   e Zd Z			d fdd	Zdd Z  ZS )SpectralTransformr   Tc              	      s   t t|   || _|dkrtjddd| _nt | _|| _t	tj
||d d|ddt|d tjdd| _t|d |d |fi || _| jrWt|d |d || _tjj
|d |d|dd| _d S )	Nr3   )r3   r3   )r6   r7   r   F)r6   r9   r   Tr   )r   rn   r   
enable_lfur   	AvgPool2d
downsampler   r7   r   r;   r=   r   conv1r0   fulfur:   conv2)r   r4   r5   r7   r9   ro   	fu_kwargsr   r   r   r      s>   

zSpectralTransform.__init__c           
      C   s   |  |}| |}| |}| jrW|j\}}}}d}|| }tjtj|d d d |d f |dddd }	tjtj|	|dddd }	| 	|	}	|	
dd|| }	nd}	| || |	 }|S )Nr3   rQ   rH   rP   r   rM   r   )rq   rr   rs   ro   rT   r:   ra   splitr]   rt   repeatru   )
r   r$   rm   nr&   hwsplit_nosplit_sxsr   r   r   r*      s.   


"
zSpectralTransform.forward)r   r   Tr+   r   r   r   r   rn      s    $rn   c                       s<   e Zd Z			d fdd	Zdd Zdd	 Zd
d Z  ZS ) LearnableSpatialTransformWrapper      ?P   Tc                    s@   t    || _td| | _|rtj| jdd| _|| _d S )Nr   T)requires_grad)	r   r   implr:   randangler   	Parameterpad_coef)r   r   r   angle_init_rangetrain_angler   r   r   r      s   

z)LearnableSpatialTransformWrapper.__init__c                    sz   t |r   ||S t|tr4t fdd|D } |}t fddt||D S tdt	| )Nc                 3   s    | ]}  |V  qd S N)	transform).0elemr   r   r   	<genexpr>   s    z;LearnableSpatialTransformWrapper.forward.<locals>.<genexpr>c                 3   s     | ]\}}  ||V  qd S r   )inverse_transform)r   r   orig_xr   r   r   r      s
    

zUnexpected input type )
r:   	is_tensorr   r   r   
isinstancetuplezipr	   type)r   r$   x_transy_transr   r   r   r*      s   


z(LearnableSpatialTransformWrapper.forwardc                 C   s`   |j dd  \}}t|| j t|| j }}tj|||||gdd}t|| j|d}|S )Nr3   reflect)rJ   r   )rT   intr   rU   padr   r   r`   )r   r$   rh   ri   pad_hpad_wx_paddedx_padded_rotatedr   r   r   r      s
   z*LearnableSpatialTransformWrapper.transformc                 C   s   |j dd  \}}t|| j t|| j }}t|| j| d}|j dd  \}}	|d d d d ||| ||	| f }
|
S )Nr3   r   )rT   r   r   r   r   r`   )r   y_padded_rotatedr   rh   ri   r   r   y_paddedy_heighty_widthr(   r   r   r   r      s   (z2LearnableSpatialTransformWrapper.inverse_transform)r   r   T)r,   r-   r.   r   r*   r   r   r/   r   r   r   r   r      s    r   c                       s6   e Zd Z								d
 fdd	Zdd	 Z  ZS )FFCr   r   FTr   c                    s  t t|   |dks|dksJ d|| _t|| }|| }t|| }|| }|| _|| _|| _|dks;|dkr>tj	ntj
}||||||||	|
|d	| _|dksW|dkrZtj	ntj
}||||||||	|
|d	| _|dkss|dkrvtj	ntj
}||||||||	|
|d	| _|dks|dkrtj	nt}|||||	dkrdn|	d |fi || _|| _|dks|dks| jstj	ntj
}||dd| _d S )Nr   r3   zStride should be 1 or 2.r   )padding_mode)r   r   r   r7   r   	ratio_gin
ratio_goutglobal_in_numr   r   r;   convl2lconvl2gconvg2lrn   convg2ggatedgate)r   r4   r5   r6   r   r   r7   r8   dilationr9   r   ro   padding_typer   spectral_kwargsin_cgin_clout_cgout_clmoduler   r   r   r      sn   


"zFFC.__init__c                 C   s   t |tu r|n|df\}}d\}}| jr;|g}t|r"|| tj|dd}t| |}|j	ddd\}	}
nd\}	}
| j
dkrP| || ||	  }| j
dkra| ||
 | | }||fS )Nr   )r   r   r   rP   r3   )r   r   )r   r   r   r:   r   appendra   r   r   chunkr   r   r   r   r   )r   r$   x_lx_gout_xlout_xgtotal_input_partstotal_inputgatesg2l_gatel2g_gater   r   r   r*   A  s   



zFFC.forward)r   r   r   r   FTr   Fr+   r   r   r   r   r      s    Gr   c                	       s<   e Zd Zdddddejejddf	 fdd	Zdd	 Z  ZS )

FFC_BN_ACTr   r   Fr   Tc                    s   t t|   t|||||||||	|
|fd|i|| _|dkr#tjn|}|dkr,tjn|}t|| }||| | _||| _	|dkrGtjn|}|dkrPtjn|}|dd| _
|dd| _d S )Nr   r   r   Tr   )r   r   r   r   ffcr   r   r   bn_lbn_gact_lact_g)r   r4   r5   r6   r   r   r7   r8   r   r9   r   
norm_layeractivation_layerr   ro   kwargslnormgnormglobal_channelslactgactr   r   r   r   Z  s6   
zFFC_BN_ACT.__init__c                 C   s6   |  |\}}| | |}| | |}||fS r   )r   r   r   r   r   r   r$   r   r   r   r   r   r*     s   zFFC_BN_ACT.forward)	r,   r-   r.   r   r=   r   r   r*   r/   r   r   r   r   r   X  s    *r   c                       s0   e Zd Zejdddf fdd	Zdd Z  ZS )FFCResnetBlockr   NFc           	   	      s   t    t||fd|||||d|| _t||fd|||||d|| _|d ur?t| jfi || _t| jfi || _|| _d S )NrR   )r6   r8   r   r   r   r   )r   r   r   rr   ru   r   inline)	r   rN   r   r   r   r   spatial_transform_kwargsr   conv_kwargsr   r   r   r     sN   
		
	

zFFCResnetBlock.__init__c                 C   s   | j r!|d d d | jjj f |d d | jjj d f }}nt|tu r)|n|df\}}||}}| ||f\}}| ||f\}}|| || }}||f}| j r]tj|dd}|S )Nr   r   rP   )	r   rr   r   r   r   r   ru   r:   ra   )r   r$   r   r   id_lid_goutr   r   r   r*     s   
zFFCResnetBlock.forward)r,   r-   r.   r   r   r   r*   r/   r   r   r   r   r     s    %r   c                   @   s   e Zd Zdd ZdS )ConcatTupleLayerc                 C   sJ   t |tsJ |\}}t|st|sJ t|s|S tj|ddS )Nr   rP   )r   r   r:   r   ra   r   r   r   r   r*     s   
zConcatTupleLayer.forwardN)r,   r-   r.   r*   r   r   r   r   r     s    r   c                       sp   e Zd Zdddddejdejejeddddd	dddd	d
d
dd	di dddi f fdd	Zdd Z  ZS )FFCResNetGeneratorrQ   rR   @      r   Tr   F)r   r   ro   g      ?Nr   i   c              
      s  |dksJ t    tdt||fdd||d|g}t|D ]9}d| }||d kr;t|}|dd|d< n|}|tt||| t||| d fddd||d	|g7 }q"d| }t||| }t|D ]#}t	|f|||d
|}|d ur||v rt
|fi |}||g7 }qk|t g7 }t|D ]1}d||  }|tjt||| t|t|| d ddddd|	t|t|| d |
g7 }q|r|t	|f|||dd|g7 }|tdtj||dddg7 }|r|t|du rdn| tj| | _d S )Nr   rR      )r6   r8   r   r   r3   r   r   r   )r6   r7   r8   r   r   )r   r   r   )r6   r7   r8   output_paddingT)r   r   r   r   )r6   r8   r   )r   r   r   ReflectionPad2dr   rangedictgetminr   r   r   ConvTranspose2dr   r;   r   r   r   model)r   input_nc	output_ncngfn_downsamplingn_blocksr   r   r   up_norm_layerup_activationinit_conv_kwargsdownsample_conv_kwargsresnet_conv_kwargsspatial_transform_layersr   add_out_actmax_featuresout_ffcout_ffc_kwargsr   imultcur_conv_kwargsfeats_num_bottleneckcur_resblockr   r   r   r     s    


zFFCResNetGenerator.__init__c                 C   s
   |  |S r   )r   )r   inputr   r   r   r*   K  s   
zFFCResNetGenerator.forward)	r,   r-   r.   r   r=   r   r   r*   r/   r   r   r   r   r     s>    yr   )r   )__doc__numpynpr:   torch.nnr   torch.nn.functional
functionalrU   kornia.geometry.transformr   r   Moduler   r0   rn   r   r   r   r   r   r   r   r   r   r   <module>   s     

e?,`3: