o
    Gi"                     @   s   d dl Z d dlmZ d dlZddlmZmZ ddlmZ ddl	m
Z
 ddlmZ eG d	d
 d
eZ		dddZG dd deeZdS )    N)	dataclass   )ConfigMixinregister_to_config)
BaseOutput)randn_tensor   )SchedulerMixinc                   @   s   e Zd ZU dZejed< dS )DDPMWuerstchenSchedulerOutputaA  
    Output class for the scheduler's step function output.

    Args:
        prev_sample (`torch.Tensor` of shape `(batch_size, num_channels, height, width)` for images):
            Computed sample (x_{t-1}) of previous timestep. `prev_sample` should be used as next model input in the
            denoising loop.
    prev_sampleN)__name__
__module____qualname____doc__torchTensor__annotations__ r   r   c/home/ubuntu/.local/lib/python3.10/site-packages/diffusers/schedulers/scheduling_ddpm_wuerstchen.pyr
      s   
 	r
   +?cosinec                 C   s   |dkr	dd }n|dkrdd }nt d| g }t| D ]}||  }|d |  }|td||||  | qtj|tjdS )	a  
    Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of
    (1-beta) over time from t = [0,1].

    Contains a function alpha_bar that takes an argument t and transforms it to the cumulative product of (1-beta) up
    to that part of the diffusion process.


    Args:
        num_diffusion_timesteps (`int`): the number of betas to produce.
        max_beta (`float`): the maximum beta to use; use values lower than 1 to
                     prevent singularities.
        alpha_transform_type (`str`, *optional*, default to `cosine`): the type of noise schedule for alpha_bar.
                     Choose from `cosine` or `exp`

    Returns:
        betas (`np.ndarray`): the betas used by the scheduler to step the model outputs
    r   c                 S   s    t | d d t j d d S )NMb?gT㥛 ?r   )mathcospitr   r   r   alpha_bar_fnD   s    z)betas_for_alpha_bar.<locals>.alpha_bar_fnexpc                 S   s   t | d S )Ng      ()r   r   r   r   r   r   r   I   s   z"Unsupported alpha_transform_type: r   dtype)
ValueErrorrangeappendminr   tensorfloat32)num_diffusion_timestepsmax_betaalpha_transform_typer   betasit1t2r   r   r   betas_for_alpha_bar+   s   

"r.   c                   @   s   e Zd ZdZe		d"dedefddZdd	 Zd#dej	de
dej	fddZ	
	
	
d$de
dee
 d
B deejB fddZ	
	d%dej	de
dej	dedeeB f
ddZdej	dej	dej	dej	fddZdd Zd d! Zd
S )&DDPMWuerstchenSchedulera  
    Denoising diffusion probabilistic models (DDPMs) explores the connections between denoising score matching and
    Langevin dynamics sampling.

    [`~ConfigMixin`] takes care of storing all config attributes that are passed in the scheduler's `__init__`
    function, such as `num_train_timesteps`. They can be accessed via `scheduler.config.num_train_timesteps`.
    [`SchedulerMixin`] provides general loading and saving functionality via the [`SchedulerMixin.save_pretrained`] and
    [`~SchedulerMixin.from_pretrained`] functions.

    For more details, see the original paper: https://huggingface.co/papers/2006.11239

    Args:
        scaler (`float`): ....
        s (`float`): ....
          ?r   scalersc                 C   sD   || _ t|g| _t| jd| j  tj d d | _d| _d S )Nr         ?r   r0   )r1   r   r%   r2   r   r   _init_alpha_cumprodinit_noise_sigma)selfr1   r2   r   r   r   __init__h   s   &
z DDPMWuerstchenScheduler.__init__c                 C   s~   | j dkrdd| | j   }n
| j dk r|| j  }t|| j| d| j|  tj d d | j| }|ddS )Nr   r3   r   g-C6?gH.?)r1   r   r   r2   tor   r4   clamp)r6   r   devicealpha_cumprodr   r   r   _alpha_cumprodu   s   


(
z&DDPMWuerstchenScheduler._alpha_cumprodNsampletimestepreturnc                 C   s   |S )aP  
        Ensures interchangeability with schedulers that need to scale the denoising model input depending on the
        current timestep.

        Args:
            sample (`torch.Tensor`): input sample
            timestep (`int`, optional): current timestep

        Returns:
            `torch.Tensor`: scaled input sample
        r   )r6   r=   r>   r   r   r   scale_model_input   s   z)DDPMWuerstchenScheduler.scale_model_inputnum_inference_steps	timestepsr:   c                 C   sD   |du rt jdd|d |d}t|t jst ||}|| _dS )a  
        Sets the discrete timesteps used for the diffusion chain. Supporting function to be run before inference.

        Args:
            num_inference_steps (`dict[float, int]`):
                the number of diffusion steps used when generating samples with a pre-trained model. If passed, then
                `timesteps` must be `None`.
            device (`str` or `torch.device`, optional):
                the device to which the timesteps are moved to. {2 / 3: 20, 0.0: 10}
        Nr0   g        r   r:   )r   linspace
isinstancer   r8   rB   )r6   rA   rB   r:   r   r   r   set_timesteps   s
   
z%DDPMWuerstchenScheduler.set_timestepsTmodel_outputreturn_dictc                 C   sD  |j }|j}|}| |}	| ||j|dgdd |jdd D R  }
| |	|j|	dgdd |jdd D R  }|
| }d|  |d| | d|
     }t|j||j|j d}d| d|  d|
   | }|||	dk	 j|	dgd	d |jdd D R    }|s|
|fS t|
|d
S )a~  
        Predict the sample at the previous timestep by reversing the SDE. Core function to propagate the diffusion
        process from the learned model outputs (most often the predicted noise).

        Args:
            model_output (`torch.Tensor`): direct output from learned diffusion model.
            timestep (`int`): current discrete timestep in the diffusion chain.
            sample (`torch.Tensor`):
                current instance of sample being created by diffusion process.
            generator: random number generator.
            return_dict (`bool`): option for returning tuple rather than DDPMWuerstchenSchedulerOutput class

        Returns:
            [`DDPMWuerstchenSchedulerOutput`] or `tuple`: [`DDPMWuerstchenSchedulerOutput`] if `return_dict` is True,
            otherwise a `tuple`. When returning a tuple, the first element is the sample tensor.

        r   c                 S      g | ]}d qS r   r   .0_r   r   r   
<listcomp>       z0DDPMWuerstchenScheduler.step.<locals>.<listcomp>r   Nc                 S   rI   rJ   r   rK   r   r   r   rN      rO   r0   )	generatorr:   r    c                 S   rI   rJ   r   rK   r   r   r   rN      rO   )r   )r    r:   previous_timestepr<   viewsizeshapesqrtr   floatr8   r
   )r6   rG   r>   r=   rP   rH   r    r:   r   prev_tr;   alpha_cumprod_prevalphamu	std_noisestdpredr   r   r   step   s   
44( <zDDPMWuerstchenScheduler.steporiginal_samplesnoisec                 C   sj   |j }|j}| j||dj|dgdd |jdd  D R  }| | d|  |  }|j|dS )NrC   r   c                 S   rI   rJ   r   rK   r   r   r   rN      rO   z5DDPMWuerstchenScheduler.add_noise.<locals>.<listcomp>r   r   )r:   r    r<   rR   rS   rT   rU   r8   )r6   r_   r`   rB   r:   r    r;   noisy_samplesr   r   r   	add_noise   s   z!DDPMWuerstchenScheduler.add_noisec                 C   s   | j jS N)confignum_train_timesteps)r6   r   r   r   __len__   s   zDDPMWuerstchenScheduler.__len__c                 C   s<   | j |d     }| j |d  d  |jd }|S )Nr   r   )rB   absargminitemexpandrT   )r6   r>   indexrW   r   r   r   rQ      s   z)DDPMWuerstchenScheduler.previous_timestep)r0   r   rc   )NNN)NT)r   r   r   r   r   rV   r7   r<   r   r   intr@   liststrr:   rF   boolr
   tupler^   rb   rf   rQ   r   r   r   r   r/   W   s\    



.
r/   )r   r   )r   dataclassesr   r   configuration_utilsr   r   utilsr   utils.torch_utilsr   scheduling_utilsr	   r
   r.   r/   r   r   r   r   <module>   s   
,