
    biX,                         d dl mZ d dlmZmZmZ d dlZd dlZddl	m
Z
mZ ddlmZ ddlmZmZ ddlmZ  ej&                  e      Ze G d	 d
e             Z G d dee
      Zy)    )	dataclass)OptionalTupleUnionN   )ConfigMixinregister_to_config)SchedulerMixin)
BaseOutputlogging)randn_tensorc                   X    e Zd ZU dZej
                  ed<   dZeej
                     ed<   y)SCMSchedulerOutputaq  
    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.
        pred_original_sample (`torch.Tensor` of shape `(batch_size, num_channels, height, width)` for images):
            The predicted denoised sample `(x_{0})` based on the model output from the current timestep.
            `pred_original_sample` can be used to preview progress or for guidance.
    prev_sampleNpred_original_sample)	__name__
__module____qualname____doc__torchTensor__annotations__r   r        ^/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/diffusers/schedulers/scheduling_scm.pyr   r   !   s'    
 37(5<<07r   r   c                   @   e Zd ZdZdZe	 	 	 ddededefd       Z	e
d        Ze
d        Zdd	efd
Z	 	 	 	 ddedej                  deeej"                  f   dedef
dZd ZddZ	 	 d dej*                  dedej*                  dej,                  dedeeef   fdZd Zy)!SCMSchedulera  
    `SCMScheduler` extends the denoising procedure introduced in denoising diffusion probabilistic models (DDPMs) with
    non-Markovian guidance. 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.
        prediction_type (`str`, defaults to `trigflow`):
            Prediction type of the scheduler function. Currently only supports "trigflow".
        sigma_data (`float`, defaults to 0.5):
            The standard deviation of the noise added during multi-step inference.
       num_train_timestepsprediction_type
sigma_datac                     d| _         d| _        t        j                  t	        j
                  d|      ddd   j                         j                  t        j                              | _	        d| _
        d| _        y)a  
        Initialize the SCM scheduler.

        Args:
            num_train_timesteps (`int`, defaults to 1000):
                The number of diffusion steps to train the model.
            prediction_type (`str`, defaults to `trigflow`):
                Prediction type of the scheduler function. Currently only supports "trigflow".
            sigma_data (`float`, defaults to 0.5):
                The standard deviation of the noise added during multi-step inference.
        g      ?Nr   )init_noise_sigmanum_inference_stepsr   
from_numpynparangecopyastypeint64	timesteps_step_index_begin_index)selfr   r    r!   s       r   __init__zSCMScheduler.__init__F   sh    & !$ $( ))"))A7J*KDbD*Q*V*V*X*_*_`b`h`h*ij r   c                     | j                   S N)r-   r/   s    r   
step_indexzSCMScheduler.step_indexb   s    r   c                     | j                   S r2   r.   r3   s    r   begin_indexzSCMScheduler.begin_indexf   s       r   r7   c                     || _         y)z
        Sets the begin index for the scheduler. This function should be run from pipeline before the inference.

        Args:
            begin_index (`int`):
                The begin index for the scheduler.
        Nr6   )r/   r7   s     r   set_begin_indexzSCMScheduler.set_begin_indexk   s     (r   Nr%   r,   devicemax_timestepsintermediate_timestepsc           	      Z   || j                   j                  kD  r=t        d| d| j                   j                   d| j                   j                   d      |t        |      |dz   k7  rt        d      ||t        d      ||t        d	      ||d
k7  rt        d      || _        |t        |t              r+t        j                  ||      j                         | _
        nt        |t        j                        r%|j                  |      j                         | _
        nvt        dt        |             |.t        j                  ||dg|      j                         | _
        n/t        j                  |d|dz   |      j                         | _
        d| _        d| _        y)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.
            timesteps (`torch.Tensor`, *optional*):
                Custom timesteps to use for the denoising process.
            max_timesteps (`float`, defaults to 1.57080):
                The maximum timestep value used in the SCM scheduler.
            intermediate_timesteps (`float`, *optional*, defaults to 1.3):
                The intermediate timestep value used in SCM scheduler (only used when num_inference_steps=2).
        z`num_inference_steps`: z6 cannot be larger than `self.config.train_timesteps`: zG as the unet model trained with this scheduler can only handle maximal z timesteps.Nr   zWIf providing custom timesteps, `timesteps` must be of length `num_inference_steps + 1`.zFIf providing custom timesteps, `max_timesteps` should not be provided.z5Should provide either `timesteps` or `max_timesteps`.r   zNIntermediate timesteps for SCM is not supported when num_inference_steps != 2.)r:   zUnsupported timesteps type: r   )configr   
ValueErrorlenr%   
isinstancelistr   tensorfloatr,   r   totypelinspacer-   r.   )r/   r%   r,   r:   r;   r<   s         r   set_timestepszSCMScheduler.set_timestepsu   s   * !@!@@)*=)> ?KK334 5 KK;;<KI   S^7JQ7N%Nvww ]%>eff!6TUU!-2E2Jmnn#6  )T*!&i!G!M!M!OIu||4!*f!5!;!;!= #?Y?P!QRR#/"\\=:PRS*T]cdjjlDN #^^M1>QTU>U^dekkmDN r   c                     | j                   Vt        |t        j                        r%|j	                  | j
                  j                        }| j                  |      | _        y | j                  | _        y r2   )
r7   rA   r   r   rE   r,   r:   index_for_timestepr-   r.   )r/   timesteps     r   _init_step_indexzSCMScheduler._init_step_index   sU    #(ELL1#;;t~~'<'<=#66x@D#00Dr   c                     || j                   }||k(  j                         }t        |      dkD  rdnd}||   j                         S )Nr   r   )r,   nonzeror@   item)r/   rK   schedule_timestepsindicesposs        r   rJ   zSCMScheduler.index_for_timestep   sL    %!%%1::< w<!#as|  ""r   model_outputrK   sample	generatorreturn_dictreturnc                    | j                   t        d      | j                  | j                  |       | j                  | j                  dz      }| j                  | j                     }| j
                  j                  }|dk(  r2t        j                  |      |z  t        j                  |      |z  z
  }	nt        d|       t        | j                        dkD  rkt        |j                  |j                  |      | j
                  j                  z  }
t        j                  |      |	z  t        j                  |      |
z  z   }n|	}| xj                  dz  c_        |s||	fS t!        ||	      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`):
                The current discrete timestep in the diffusion chain.
            sample (`torch.FloatTensor`):
                A current instance of a sample created by the diffusion process.
            return_dict (`bool`, *optional*, defaults to `True`):
                Whether or not to return a [`~schedulers.scheduling_scm.SCMSchedulerOutput`] or `tuple`.
        Returns:
            [`~schedulers.scheduling_utils.SCMSchedulerOutput`] or `tuple`:
                If return_dict is `True`, [`~schedulers.scheduling_scm.SCMSchedulerOutput`] is returned, otherwise a
                tuple is returned where the first element is the sample tensor.
        zaNumber of inference steps is 'None', you need to run 'set_timesteps' after creating the schedulerr   trigflowzUnsupported parameterization: )r:   rU   )r   r   )r%   r?   r4   rL   r,   r>   r    r   cossinr@   r   shaper:   r!   r-   r   )r/   rS   rK   rT   rU   rV   tsparameterizationpred_x0noiser   s               r   stepzSCMScheduler.step   sS   4 ##+s  ??"!!(+ NN4??Q./NN4??+  ;;66z)iilV+eiil\.IIG=>N=OPQQ t~~"\//8K8KW`a++(()   ))A,0599Q<%3GGK!KA))!kPWXXr   c                 .    | j                   j                  S r2   )r>   r   r3   s    r   __len__zSCMScheduler.__len__  s    {{...r   )i  rY   g      ?)r   )NNgH.!?g?r2   )NT)r   r   r   r   orderr	   intstrrD   r0   propertyr4   r7   r9   r   r   r   r:   rH   rL   rJ   FloatTensor	Generatorboolr   r   rb   rd   r   r   r   r   r   4   sJ    E $()	! ! ! 	! !6     ! !(3 ( #'+/&(+8! 8! <<8! c5<<'(	8!
 8! !&8!v1#& &* >Y''>Y >Y !!	>Y
 ??>Y >Y 
!5(	)>Y@/r   r   )dataclassesr   typingr   r   r   numpyr'   r   configuration_utilsr   r	   schedulers.scheduling_utilsr
   utilsr   r   utils.torch_utilsr   
get_loggerr   loggerr   r   r   r   r   <module>ru      sa   $ " ) )   A 8 ' , 
		H	% 8 8 8"T/>; T/r   