a
    
d'                     @   s   d Z ddlZddlZddlmZ ddlmZ d)ddZdd	 Ze	d
ddZ
G dd dejjZdd ZG dd dejjZd*ddZdd Zdd Zdd Zdd ZG dd  d ejZG d!d" d"ejZd#d$ Zd%d& Zd'd( ZdS )+a  
adopted from
https://github.com/openai/improved-diffusion/blob/main/improved_diffusion/gaussian_diffusion.py
and
https://github.com/lucidrains/denoising-diffusion-pytorch/blob/7706bdfc6f527f58d33f84b7b522e61e6e3164b3/denoising_diffusion_pytorch/denoising_diffusion_pytorch.py
and
https://github.com/openai/guided-diffusion/blob/0ba878e517b276c45d1195eb29f6f5f72659a05b/guided_diffusion/nn.py

thanks!
    N)repeat-C6?{Gz?c                 C   s0   | dkr(t j|d |d |t jdd }| S )Nlinearg      ?)dtype   )torchlinspacefloat64numpy)scheduleZ
n_timesteplinear_start
linear_endbetas r   h/var/www/html/stable-diffusion-webui/repositories/generative-models/sgm/modules/diffusionmodules/util.pymake_beta_schedule   s    r   c                 C   s4   |j ^}}| d|}|j|gdt|d  R  S )N)   r   )shapegatherreshapelen)atZx_shapeb_outr   r   r   extract_into_tensor#   s    
r   inputsc           	         s   |r fdd D } fdd D } fdd D } fdd D }t |t | t | }tj| t|t|||g|R  S | f i  S dS )a  
    Evaluate a function without caching intermediate activations, allowing for
    reduced memory at the expense of extra compute in the backward pass. This differs from the original checkpoint function
    borrowed from https://github.com/openai/guided-diffusion/blob/0ba878e517b276c45d1195eb29f6f5f72659a05b/guided_diffusion/nn.py in that
    it also works with non-tensor inputs
    :param func: the function to evaluate.
    :param inputs: the argument dictionary 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.
    c                    s    g | ]}t  | tjr|qS r   
isinstancer   Tensor.0keyr   r   r   
<listcomp>6       z$mixed_checkpoint.<locals>.<listcomp>c                    s$   g | ]}t  | tjr | qS r   r!   r$   r   r   r   r'   7   s   c                    s    g | ]}t  | tjs|qS r   r!   r$   r   r   r   r'   :   s   c                    s$   g | ]}t  | tjs | qS r   r!   r$   r   r   r   r'   =   s   N)tupleMixedCheckpointFunctionapplyr   )	funcr    paramsflagtensor_keystensor_inputsnon_tensor_keysZnon_tensor_inputsargsr   r   r   mixed_checkpoint)   s,    


	r3   c                   @   s$   e Zd Zedd Zedd ZdS )r*   c                 G   s   || _ || | _t t t d| _t||krBt||ksFJ dd t|t	|d | j  D | _
dd t|t	|| j | j D | _|| _t	|| jd  | _t ( | jf i | j
| j}W d    n1 s0    Y  |S )Nenabledr   cache_enabledc                 S   s   i | ]\}}||qS r   r   r%   r&   valr   r   r   
<dictcomp>d   s   z3MixedCheckpointFunction.forward.<locals>.<dictcomp>c                 S   s   i | ]\}}||qS r   r   r7   r   r   r   r9   g   s   )end_tensorsend_non_tensorsr   is_autocast_enabledget_autocast_gpu_dtypeis_autocast_cache_enabledgpu_autocast_kwargsr   ziplistinput_tensorsinput_non_tensorsrun_functioninput_paramsno_grad)ctxrD   Zlength_tensorsZlength_non_tensorsr/   r1   r2   output_tensorsr   r   r   forwardN   s6    




$zMixedCheckpointFunction.forwardc              	      s    fdd j D  _ t p tjjjf i  j:  fdd j D } jf i | j}W d    n1 sv0    Y  W d    n1 s0    Y  tj	j
|t j   j |dd} `  `~d|d  j  d j j   | jd   S )Nc                    s"   i | ]}| j |  d qS T)rB   detachrequires_grad_r$   rG   r   r   r9   y   s   z4MixedCheckpointFunction.backward.<locals>.<dictcomp>c                    s$   i | ]}| j |  j | qS r   )rB   view_asr$   rM   r   r   r9      s   Tallow_unused)NNNNNN)rB   r   enable_gradcudaampautocastr?   rD   rC   autogradgradrA   valuesrE   r:   r;   rG   output_gradsZshallow_copiesrH   Zinput_gradsr   rM   r   backwardv   s2    
"
Rz MixedCheckpointFunction.backwardN__name__
__module____qualname__staticmethodrI   r[   r   r   r   r   r*   M   s   
'r*   c                 C   s8   |r,t |t | }tj| t|g|R  S | | S d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.
    N)r)   CheckpointFunctionr+   r   )r,   r    r-   r.   r2   r   r   r   
checkpoint   s    
rb   c                   @   s$   e Zd Zedd Zedd ZdS )ra   c                 G   s|   || _ t|d | | _t||d  | _t t t d| _t	  | j | j }W d    n1 sn0    Y  |S )Nr4   )
rD   rA   rB   rE   r   r<   r=   r>   r?   rF   )rG   rD   lengthr2   rH   r   r   r   rI      s    
*zCheckpointFunction.forwardc              	   G   s   dd | j D | _ t ` tjjjf i | j* dd | j D }| j| }W d    n1 sb0    Y  W d    n1 s0    Y  tjj	|| j | j
 |dd}| ` | `
~d| S )Nc                 S   s   g | ]}|  d qS rJ   )rK   rL   r%   xr   r   r   r'      r(   z/CheckpointFunction.backward.<locals>.<listcomp>c                 S   s   g | ]}| |qS r   )rN   rd   r   r   r   r'      r(   TrO   )NN)rB   r   rR   rS   rT   rU   r?   rD   rV   rW   rE   rY   r   r   r   r[      s    "F
zCheckpointFunction.backwardNr\   r   r   r   r   ra      s   
ra   '  Fc                 C   s   |s|d }t t| t jd|t jd | j| jd}| dddf  |d  }t j	t 
|t |gdd}|d rt j	|t |ddddf gdd}nt| d	|d
}|S )aX  
    Create sinusoidal timestep embeddings.
    :param timesteps: a 1-D Tensor of N indices, one per batch element.
                      These may be fractional.
    :param dim: the dimension of the output.
    :param max_period: controls the minimum frequency of the embeddings.
    :return: an [N x dim] Tensor of positional embeddings.
    r   r   )startendr   )deviceNr   dimr   zb -> b d)d)r   expmathlogarangefloat32tori   floatcatcossin
zeros_liker   )	timestepsrk   Z
max_periodZrepeat_onlyhalffreqsr2   	embeddingr   r   r   timestep_embedding   s&    	
r|   c                 C   s   |   D ]}|   q| S )z<
    Zero out the parameters of a module and return it.
    )
parametersrK   zero_)modulepr   r   r   zero_module   s    r   c                 C   s    |   D ]}| | q| S )z9
    Scale the parameters of a module and return it.
    )r}   rK   mul_)r   scaler   r   r   r   scale_module   s    r   c                 C   s   | j ttdt| jdS )z6
    Take the mean over all non-batch dimensions.
    r   rj   )meanrA   ranger   r   )tensorr   r   r   	mean_flat   s    r   c                 C   s
   t d| S )z
    Make a standard normalization layer.
    :param channels: number of input channels.
    :return: an nn.Module for normalization.
        )GroupNorm32)channelsr   r   r   normalization  s    r   c                   @   s   e Zd Zdd ZdS )SiLUc                 C   s   |t | S rQ   )r   sigmoidselfre   r   r   r   rI     s    zSiLU.forwardN)r]   r^   r_   rI   r   r   r   r   r     s   r   c                       s   e Zd Z fddZ  ZS )r   c                    s   t  | |jS rQ   )superrI   rs   typer   r   	__class__r   r   rI     s    zGroupNorm32.forward)r]   r^   r_   rI   __classcell__r   r   r   r   r     s   r   c                 O   sZ   | dkrt j|i |S | dkr0t j|i |S | dkrHt j|i |S td|  dS )z4
    Create a 1D, 2D, or 3D convolution module.
    r   r      unsupported dimensions: N)nnConv1dConv2dConv3d
ValueErrordimsr2   kwargsr   r   r   conv_nd  s    r   c                  O   s   t j| i |S )z!
    Create a linear module.
    )r   Linear)r2   r   r   r   r   r   #  s    r   c                 O   sZ   | dkrt j|i |S | dkr0t j|i |S | dkrHt j|i |S td|  dS )z8
    Create a 1D, 2D, or 3D average pooling module.
    r   r   r   r   N)r   	AvgPool1d	AvgPool2d	AvgPool3dr   r   r   r   r   avg_pool_nd*  s    r   )r   r   )rf   F)__doc__rn   r   torch.nnr   einopsr   r   r   dictr3   rV   Functionr*   rb   ra   r|   r   r   r   r   Moduler   	GroupNormr   r   r   r   r   r   r   r   <module>   s,     
$L$
		
