o
    #i,                     @   s"  d dl Z d dlZ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mZmZ d dlZd dlmZ d dlm  mZ d dlmZ d=dedededef d	edef fd
dZd=dedededef d	edef fddZedd ZdefddZdd Zdd Zdd Zdd Zd>d d!Z d"d# Z!G d$d% d%ej"j#Z$d&d' Z%d(d) Z&	*	+	,d?d-ej'd.ej'd/ej'd0ee(ef d1e(d2e(d	eej'eej'ej'f f fd3d4Z)	*	+	,d?d-ej'd.ej'd/ej'd0ee(ef d1e(d2e(d	eej'eej'ej'f f fd5d6Z*	d@d7ed8e(d9ee d:ee+ d	ej'f
d;d<Z,dS )A    N)
isfunctionprint)OptionalTupleUnion)rank_zero_onlydir1dir2dir3returnc                 C   L   | d urt j| r| S |d urt j|r|S |d ur$t j|r$|S d S N)ospathisdir)r	   r
   r    r   2/data/cameron/vidgen/VidTok/vidtok/modules/util.pyget_valid_dirs      r   path1path2path3c                 C   r   r   )r   r   isfile)r   r   r   r   r   r   get_valid_paths   r   r   c                  O   s   t | i | d S r   r   )argskwargsr   r   r   print0&   s   r   seedc                 C   sJ   t | tjd< t|  tj|  t|  tj|  tj	|  d S )NZPYTHONHASHSEED)
strr   environrandomr   nptorchmanual_seedcudamanual_seed_all)r   r   r   r   seed_anything+   s   

r'   c                 C   s   t | tjsdS | jdkS )NF   )
isinstancer#   Tensorndimxr   r   r   	isheatmap4   s   
r.   c                 C   s   | d uS r   r   r,   r   r   r   exists;   s   r/   c                 C   s   t | r| S t|r| S |S r   )r/   r   )valdr   r   r   default?   s   r2   c                 C   sH   d| vr| dkr
d S | dkrd S t dt| d di | dt S )NtargetZ__is_first_stage__Z__is_unconditional__z%Expected key `target` to instantiate.paramsr   )KeyErrorget_obj_from_strgetdict)configr   r   r   instantiate_from_configE   s    r:   FTc                 C   sH   |  dd\}}|rt  |rt|}t| ttj|d d|S )N.   )package)rsplit	importlibinvalidate_cachesimport_modulereloadgetattr)stringrB   invalidate_cachemoduleclsZ
module_impr   r   r   r6   O   s   

r6   c                 C   s4   |rt |t | }tj| t|g|R  S | | S )a  
    Evaluate a function without caching intermediate activations, allowing for
    reduced memory at the expense of extra compute in the backward pass.
    :param func: the function to evaluate.
    :param inputs: the argument sequence to pass to `func`.
    :param params: a sequence of parameters `func` depends on but does not
                   explicitly take as arguments.
    :param flag: if False, disable gradient checkpointing.
    )tupleCheckpointFunctionapplylen)funcinputsr4   flagr   r   r   r   
checkpointY   s   rO   c                   @   s$   e Zd Zedd Zedd ZdS )rI   c                 G   s~   || _ t|d | | _t||d  | _t t t d| _t	  | j | j }W d    |S 1 s8w   Y  |S )N)enableddtypecache_enabled)
run_functionlistinput_tensorsinput_paramsr#   is_autocast_enabledget_autocast_gpu_dtypeis_autocast_cache_enabledgpu_autocast_kwargsno_grad)ctxrS   lengthr   output_tensorsr   r   r   forwardm   s   

zCheckpointFunction.forwardc              	   G   s   dd | j D | _ dd | jD | _t 0 tjjjdi | j dd | j D }| j| }W d    n1 s:w   Y  W d    n1 sIw   Y  tj	j
|| j | j |dd}| ` | `~d| S )	Nc                 S   s   g | ]	}|  d qS T)detachrequires_grad_.0r-   r   r   r   
<listcomp>}   s    z/CheckpointFunction.backward.<locals>.<listcomp>c                 S   s   g | ]}| d qS r`   )rb   )rd   pr   r   r   re          c                 S   s   g | ]}| |qS r   )view_asrc   r   r   r   re      rg   T)allow_unusedNNr   )rU   rV   r#   enable_gradr%   ampautocastrZ   rS   autogradgrad)r\   Zoutput_gradsZshallow_copiesr^   Zinput_gradsr   r   r   backward{   s$   " 
zCheckpointFunction.backwardN)__name__
__module____qualname__staticmethodr_   rp   r   r   r   r   rI   k   s
    
rI   c                 C   sp   |   dkrt| d} |  dksJ t|d}d}tj| | d g dd}dt||  }|jddS )	N   b c t h w -> (b t) c h wg:0yE>r(   )r<   r(      dimir   )ry   einops	rearranger#   meanlog10)r-   yEPSmsepsnrr   r   r   compute_psnr   s   r   c                 C   s   |   dkrt| d} |  dksJ t|d}d}d}d}d}tdtt|  dd  d	 }|dkrEtj| |d
} tj||d
}t	||| j
| jd| dddd}|   dkr`tnt}|| ||d||d\}	}
|	d}|jddS )Nru   rv      g      ?{Gz?Q?r<      )kernel_size)devicerQ   )r-   r~   kernel
data_rangek1k2r   rx   )ry   rz   r{   maxroundminsizeF
avg_pool2dgaussian_filterr   rQ   repeat_ssim_per_channel_complex_ssim_per_channelr|   )r-   r~   r   Zkernel_sigmar   r   fr   Z_compute_ssim_per_channelssim_mapcs_mapssim_valr   r   r   compute_ssim   s"   "&
r         ?r   r   r-   r~   r   r   r   r   c                 C   sF  |  d| dk s|  d| dk r"td|    d|   |d }|d }|  d}tj| |dd|d}	tj||dd|d}
|	d }|
d }|	|
 }tj| d |dd|d| }tj|d |dd|d| }tj| | |dd|d| }d	| | || |  }d	| | || |  | }|jd
d}|jd
d}||fS )aM  Calculate Structural Similarity (SSIM) index for X and Y per channel.

    Args:
        x: An input tensor. Shape :math:`(N, C, H, W)`.
        y: A target tensor. Shape :math:`(N, C, H, W)`.
        kernel: 2D Gaussian kernel.
        data_range: Maximum value range of images (usually 1.0 or 255).
        k1: Algorithm parameter, K1 (small constant, see [1]).
        k2: Algorithm parameter, K2 (small constant, see [1]).
            Try a larger K2 constant (e.g. 0.4) if you get a negative or NaN results.

    Returns:
        Full Value of Structural Similarity (SSIM) index.
    r   AKernel size can't be greater than actual input size. Input size: . Kernel size: r(   r<   r   weightstridepaddinggroups       @)r   r   rx   )r   
ValueErrorr   conv2dr|   )r-   r~   r   r   r   r   c1c2
n_channelsZmu_xZmu_yZmu_xxZmu_yyZmu_xyZsigma_xxZsigma_yyZsigma_xycsssr   r   r   r   r      s0   (
r   c           $      C   sf  |  d}|  d| dk s|  d| dk r'td|    d|   |d }|d }| d }	| d	 }
|d }|d	 }tj|	|dd
|d}tj|
|dd
|d}tj||dd
|d}tj||dd
|d}|d|d }|d|d }|| ||  }|| ||  }d}|	d|
d }|d|d }|	| |
|  }|	| |
|  }tj||dd
|d| }tj||dd
|d| }tj||dd
|d| }tj||dd
|d| }tj||fdd}tj||fdd}|d ||  |d|d ||   } |d ||  |d|d ||   }!|!|  }!|!jdd}"| jdd}#|"|#fS )aa  Calculate Structural Similarity (SSIM) index for Complex X and Y per channel.

    Args:
        x: An input tensor. Shape :math:`(N, C, H, W, 2)`.
        y: A target tensor. Shape :math:`(N, C, H, W, 2)`.
        kernel: 2-D gauss kernel.
        data_range: Maximum value range of images (usually 1.0 or 255).
        k1: Algorithm parameter, K1 (small constant, see [1]).
        k2: Algorithm parameter, K2 (small constant, see [1]).
            Try a larger K2 constant (e.g. 0.4) if you get a negative or NaN results.

    Returns:
        Full Value of Complex Structural Similarity (SSIM) index.
    r<   r   r   r   r   r(   ).r   ).r<   r   r   r   rx   )r   r   )	r   r   r   r   powr#   stack	unsqueezer|   )$r-   r~   r   r   r   r   r   r   r   x_realx_imagZy_realZy_imagZmu1_realZmu1_imagZmu2_realZmu2_imagZmu1_sqZmu2_sqZmu1_mu2_realZmu1_mu2_imagZcompensationx_sqy_sqZx_y_realZx_y_imagZ	sigma1_sqZ	sigma2_sqZsigma12_realZsigma12_imagZsigma12Zmu1_mu2r   r   r   r   r   r   r   r      sL   
(,,r   r   sigmar   rQ   c                 C   sd   t j| ||d}|| d d 8 }|d }|d|d  d|d    }||  }|dS )aG  Returns 2D Gaussian kernel N(0,`sigma`^2)
    Args:
        kernel_size: Size of the kernel
        sigma: Std of the distribution
        device: target device for kernel generation
        dtype: target data type for kernel generation
    Returns:
        gaussian_kernel: Tensor with shape (1, kernel_size, kernel_size)
    )rQ   r   r<   r   r(   r   )r#   aranger   expsum)r   r   r   rQ   coordsgr   r   r   r   1  s   &
r   r   )FT)r   r   r   rj   )-r?   r!   r   rz   numpyr"   inspectr   richr   typingr   r   r   r#   torch.nnnnZtorch.nn.functional
functionalr   %lightning.pytorch.utilities.rank_zeror   r   r   r   r   intr'   r.   r/   r2   r:   r6   rO   rn   FunctionrI   r   r   r*   floatr   r   typer   r   r   r   r   <module>   s    ,,
	


'

9

H