o
    Gi3                     @   s   d dl mZ d dlZd dlZddlmZmZ ddlm	Z	m
Z
 ddlmZ ddlmZ e
eZeG d	d
 d
e	ZG dd deeZdS )    )	dataclassN   )ConfigMixinregister_to_config)
BaseOutputlogging)randn_tensor   )SchedulerMixinc                   @   s   e Zd ZU dZejed< dS )$FlowMatchHeunDiscreteSchedulerOutputaJ  
    Output class for the scheduler's `step` function output.

    Args:
        prev_sample (`torch.FloatTensor` 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FloatTensor__annotations__ r   r   l/home/ubuntu/.local/lib/python3.10/site-packages/diffusers/schedulers/scheduling_flow_match_heun_discrete.pyr      s   
 	r   c                   @   sj  e Zd ZdZg ZdZe		d4dedefddZ	e
d	d
 Ze
dd Zd5defddZdejdeejB dejdejfddZdedefddZ	d6dedeejB ddfddZ	d6deejB dejdB defd d!ZdeejB ddfd"d#Ze
defd$d%Zd&d&ed'ddd(fd)ejdeejB dejd*ed+ed,ed-ed.ejdB d/edeeB fd0d1Zdefd2d3ZdS )7FlowMatchHeunDiscreteSchedulera  
    Heun scheduler.

    This model inherits from [`SchedulerMixin`] and [`ConfigMixin`]. Check the superclass documentation for the generic
    methods the library implements for all schedulers such as loading and saving.

    Args:
        num_train_timesteps (`int`, defaults to 1000):
            The number of diffusion steps to train the model.
        shift (`float`, defaults to 1.0):
            The shift value for the timestep schedule.
    r           ?num_train_timestepsshiftc                 C   s   t jd||t jdd d d  }t|jtjd}|| }|| d|d |   }|| | _d | _d | _	|d| _
| j
d  | _| j
d  | _d S )Nr	   )dtypecpur   )nplinspacefloat32copyr   
from_numpyto	timesteps_step_index_begin_indexsigmasitem	sigma_min	sigma_max)selfr   r   r$   r'   r   r   r   __init__<   s   "
z'FlowMatchHeunDiscreteScheduler.__init__c                 C      | j S )zg
        The index counter for current timestep. It will increase 1 after each scheduler step.
        )r%   r+   r   r   r   
step_indexQ      z)FlowMatchHeunDiscreteScheduler.step_indexc                 C   r-   )zq
        The index for the first timestep. It should be set from pipeline with `set_begin_index` method.
        r&   r.   r   r   r   begin_indexX   r0   z*FlowMatchHeunDiscreteScheduler.begin_indexr   r2   c                 C   s
   || _ dS )z
        Sets the begin index for the scheduler. This function should be run from pipeline before the inference.

        Args:
            begin_index (`int`, defaults to `0`):
                The begin index for the scheduler.
        Nr1   )r+   r2   r   r   r   set_begin_index`   s   
z.FlowMatchHeunDiscreteScheduler.set_begin_indexsampletimestepnoisereturnc                 C   s8   | j du r
| | | j| j  }|| d| |  }|S )a  
        Forward process in flow-matching

        Args:
            sample (`torch.FloatTensor`):
                The input sample.
            timestep (`float` or `torch.FloatTensor`):
                The current timestep in the diffusion chain.
            noise (`torch.FloatTensor`):
                The noise tensor.

        Returns:
            `torch.FloatTensor`:
                A scaled input sample.
        Nr   )r/   _init_step_indexr'   )r+   r4   r5   r6   sigmar   r   r   scale_noisej   s
   

z*FlowMatchHeunDiscreteScheduler.scale_noiser9   c                 C   s   || j j S Nconfigr   )r+   r9   r   r   r   _sigma_to_t   s   z*FlowMatchHeunDiscreteScheduler._sigma_to_tNnum_inference_stepsdevicec                 C   s
  || _ t| | j| | j|}|| jj }| jj| d| jjd |   }t	
|jt	j|d}|| jj }t	|dd |dd dg}|j|d| _t	|t	jd|jdg}t	|dd |dd d|dd g| _d| _d| _d| _d| _dS )a  
        Sets the discrete timesteps used for the diffusion chain (to be run before inference).

        Args:
            num_inference_steps (`int`):
                The number of diffusion steps used when generating samples with a pre-trained model.
            device (`str` or `torch.device`, *optional*):
                The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
        r	   )r   r@   Nr   )r@   r   )r?   r   r   r>   r*   r)   r=   r   r   r   r"   r#   r    catrepeat_interleaver$   zerosr@   r'   prev_derivativedtr%   r&   )r+   r?   r@   r$   r'   r   r   r   set_timesteps   s$   

 $0
z,FlowMatchHeunDiscreteScheduler.set_timestepsschedule_timestepsc                 C   s:   |du r| j }||k }t|dkrdnd}||  S )a  
        Find the index of a given timestep in the timestep schedule.

        Args:
            timestep (`float` or `torch.FloatTensor`):
                The timestep value to find in the schedule.
            schedule_timesteps (`torch.FloatTensor`, *optional*):
                The timestep schedule to search in. If `None`, uses `self.timesteps`.

        Returns:
            `int`:
                The index of the timestep in the schedule.
        Nr	   r   )r$   nonzerolenr(   )r+   r5   rG   indicesposr   r   r   index_for_timestep   s
   z1FlowMatchHeunDiscreteScheduler.index_for_timestepc                 C   s@   | j d u rt|tjr|| jj}| || _d S | j	| _d S r;   )
r2   
isinstancer   Tensorr#   r$   r@   rL   r%   r&   )r+   r5   r   r   r   r8      s
   
z/FlowMatchHeunDiscreteScheduler._init_step_indexc                 C   s
   | j du S )zL
        Returns whether the scheduler is in the first-order state.
        N)rE   r.   r   r   r   state_in_first_order   s   
z3FlowMatchHeunDiscreteScheduler.state_in_first_order        infTmodel_outputs_churns_tmins_tmaxs_noise	generatorreturn_dictc
                 C   s  t |tst |tjst |tjrtd| jdu r| | |tj	}| j
r7| j| j }
| j| jd  }n| j| jd  }
| j| j }||
  krO|kr]n nt|t| jd  dnd}|
|d  }|dkrt|j|j|j|d}|| }|||d |
d  d	   }| j
r|||
  }|| | }|| }|| _|| _|| _n"|||  }|| | }d	| j|  }| j}| j}d| _d| _d| _|||  }||j}|  jd7  _|	s|fS t|d
S )a[  
        Predict the sample from the previous timestep by reversing the SDE. This function propagates the diffusion
        process from the learned model outputs (most often the predicted noise).

        Args:
            model_output (`torch.FloatTensor`):
                The direct output from learned diffusion model.
            timestep (`float` or `torch.FloatTensor`):
                The current discrete timestep in the diffusion chain.
            sample (`torch.FloatTensor`):
                A current instance of a sample created by the diffusion process.
            s_churn (`float`):
                Stochasticity parameter that controls the amount of noise added during sampling. Higher values increase
                randomness.
            s_tmin (`float`):
                Minimum timestep threshold for applying stochasticity. Only timesteps above this value will have noise
                added.
            s_tmax (`float`):
                Maximum timestep threshold for applying stochasticity. Only timesteps below this value will have noise
                added.
            s_noise (`float`, defaults to 1.0):
                Scaling factor for noise added to the sample.
            generator (`torch.Generator`, *optional*):
                A random number generator.
            return_dict (`bool`):
                Whether or not to return a
                [`~schedulers.scheduling_flow_match_heun_discrete.FlowMatchHeunDiscreteSchedulerOutput`] tuple.

        Returns:
            [`~schedulers.scheduling_flow_match_heun_discrete.FlowMatchHeunDiscreteSchedulerOutput`] or `tuple`:
                If return_dict is `True`,
                [`~schedulers.scheduling_flow_match_heun_discrete.FlowMatchHeunDiscreteSchedulerOutput`] is returned,
                otherwise a tuple is returned where the first element is the sample tensor.
        zPassing integer indices (e.g. from `enumerate(timesteps)`) as timesteps to `FlowMatchHeunDiscreteScheduler.step()` is not supported. Make sure to pass one of the `scheduler.timesteps` as a timestep.Nr	   g4y?rP   r   )r   r@   rW   r   g      ?)r   )rM   intr   	IntTensor
LongTensor
ValueErrorr/   r8   r#   r    rO   r'   minrI   r   shaper   r@   rD   rE   r4   r%   r   )r+   rR   r5   r4   rS   rT   rU   rV   rW   rX   r9   
sigma_nextgamma	sigma_hatr6   epsdenoised
derivativerE   r   r   r   r   step   sb   0



4
z#FlowMatchHeunDiscreteScheduler.stepc                 C   s   | j jS r;   r<   r.   r   r   r   __len__b  s   z&FlowMatchHeunDiscreteScheduler.__len__)r   r   )r   r;   )r   r   r   r   _compatiblesorderr   rY   floatr,   propertyr/   r2   r3   r   r   r:   r>   strr@   rF   rL   r8   boolrO   	Generatorr   tuplere   rf   r   r   r   r   r   +   s    




+
	

 r   )dataclassesr   numpyr   r   configuration_utilsr   r   utilsr   r   utils.torch_utilsr   scheduling_utilsr
   
get_loggerr   loggerr   r   r   r   r   r   <module>   s   
