
    +h9*                         S SK Jr  S SKJrJrJr  S SKrS SKJr	  SSK
JrJr  SSKJrJrJrJrJr  \R&                  R                   " S S	5      5       r\ " S
 S\5      5       r " S S\\5      rg)    )	dataclass)OptionalTupleUnionN   )ConfigMixinregister_to_config   )CommonSchedulerStateFlaxKarrasDiffusionSchedulersFlaxSchedulerMixinFlaxSchedulerOutputbroadcast_to_shape_from_leftc            	           \ rS rSr% \\S'   \R                  \S'   \R                  \S'   \R                  \S'   Sr\	\
   \S'   \S\S\R                  S\R                  S\R                  4S j5       rS	rg)
EulerDiscreteSchedulerState   commoninit_noise_sigma	timestepssigmasNnum_inference_stepsc                     U " XX4S9$ )Nr   r   r   r    )clsr   r   r   r   s        m/home/james-whalen/.local/lib/python3.13/site-packages/diffusers/schedulers/scheduling_euler_discrete_flax.pycreate"EulerDiscreteSchedulerState.create)   s     &yhh    r   )__name__
__module____qualname____firstlineno__r   __annotations__jnpndarrayr   r   intclassmethodr   __static_attributes__r   r   r   r   r      s       kk!{{KK)-#-i)i=@[[iUXU`U`ijmjujui ir   r   c                        \ rS rSr% \\S'   Srg) FlaxEulerDiscreteSchedulerOutput0   stater   N)r    r!   r"   r#   r   r$   r)   r   r   r   r+   r+   0   s    &&r   r+   c                   f   \ rS rSr% Sr\ V Vs/ s H  oR                  PM     snn r\R                  \
S'   \S 5       r\SSSSS	S
S\R                  4S\S\S\S\S\\R&                     S\S\S\R                  4S jj5       rS'S\\   S\4S jjrS\S\R&                  S\S\R&                  4S jr S(S\S\S\S\4S jjr S)S\S\R&                  S\S\R&                  S\S\\\4   4S  jjrS\S!\R&                  S"\R&                  S#\R&                  S\R&                  4
S$ jrS% r S&r!g	s  snn f )*FlaxEulerDiscreteScheduler5   aj  
Euler scheduler (Algorithm 2) from Karras et al. (2022) https://huggingface.co/papers/2206.00364. . Based on the
original k-diffusion implementation by Katherine Crowson:
https://github.com/crowsonkb/k-diffusion/blob/481677d114f6ea445aa009cf5bd7a9cdee909e47/k_diffusion/sampling.py#L51


[`~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.

Args:
    num_train_timesteps (`int`): number of diffusion steps used to train the model.
    beta_start (`float`): the starting `beta` value of inference.
    beta_end (`float`): the final `beta` value.
    beta_schedule (`str`):
        the beta schedule, a mapping from a beta range to a sequence of betas for stepping the model. Choose from
        `linear` or `scaled_linear`.
    trained_betas (`jnp.ndarray`, optional):
        option to pass an array of betas directly to the constructor to bypass `beta_start`, `beta_end` etc.
    prediction_type (`str`, default `epsilon`, optional):
        prediction type of the scheduler function, one of `epsilon` (predicting the noise of the diffusion
        process), `sample` (directly predicting the noisy sample`) or `v_prediction` (see section 2.4
        https://imagen.research.google/video/paper.pdf)
    dtype (`jnp.dtype`, *optional*, defaults to `jnp.float32`):
        the `dtype` used for params and computation.
dtypec                     g)NTr   selfs    r   	has_state$FlaxEulerDiscreteScheduler.has_stateV   s    r   i  g-C6?g{Gz?linearNepsilonlinspacenum_train_timesteps
beta_startbeta_endbeta_scheduletrained_betasprediction_typetimestep_spacingc	                     Xl         g Nr1   )	r4   r:   r;   r<   r=   r>   r?   r@   r1   s	            r   __init__#FlaxEulerDiscreteScheduler.__init__Z   s	     
r   r   returnc           	      |   Uc  [         R                  " U 5      n[        R                  " SU R                  R
                  5      R                  5       S S S2   nSUR                  -
  UR                  -  S-  n[        R                  " U[        R                  " S[        U5      5      U5      n[        R                  " U[        R                  " S/U R                  S9/5      nU R                  R                  S;   a  UR                  5       nOUR                  5       S-  S-   S-  n[        R                  UUUUS	9$ )
Nr   r
         ?        rC   r9   trailingr   r   )r   r   r%   arangeconfigr:   roundalphas_cumprodinterplenconcatenatearrayr1   r@   maxr   )r4   r   r   r   r   s        r   create_state'FlaxEulerDiscreteScheduler.create_stateh   s   >)006FJJq$++"A"ABHHJ4R4P	v,,,0E0EE#MIszz!S['A6J&#))SE*L!MN ;;''+CC%zz| &

 1A 5#=*11-	 2 
 	
r   r-   sampletimestepc                     [         R                  " UR                  U:H  SS9u  nUS   nUR                  U   nX%S-  S-   S-  -  nU$ )a  
Scales the denoising model input by `(sigma**2 + 1) ** 0.5` to match the Euler algorithm.

Args:
    state (`EulerDiscreteSchedulerState`):
        the `FlaxEulerDiscreteScheduler` state data class instance.
    sample (`jnp.ndarray`):
        current instance of sample being created by diffusion process.
    timestep (`int`):
        current discrete timestep in the diffusion chain.

Returns:
    `jnp.ndarray`: scaled input sample
r
   sizer   r   rI   )r%   wherer   r   )r4   r-   rX   rY   
step_indexsigmas         r   scale_model_input,FlaxEulerDiscreteScheduler.scale_model_input~   sP     		%//X"=AF]
Z(1HqLS01r   r   shapec           	         U R                   R                  S:X  a8  [        R                  " U R                   R                  S-
  SX R
                  S9nOU R                   R                  S:X  an  U R                   R                  U-  n[        R                  " SU5      U-  R                  5       SSS2   R                  5       R                  [        5      nUS-  nO"[        SU R                   R                   35      eSUR                  R                  -
  UR                  R                  -  S	-  n[        R                  " U[        R                  " S[        U5      5      U5      n[        R                   " U[        R"                  " S
/U R
                  S9/5      nU R                   R                  S;   a  UR%                  5       nOUR%                  5       S-  S-   S	-  nUR'                  UUUUS9$ )aV  
Sets the timesteps used for the diffusion chain. Supporting function to be run before inference.

Args:
    state (`EulerDiscreteSchedulerState`):
        the `FlaxEulerDiscreteScheduler` state data class instance.
    num_inference_steps (`int`):
        the number of diffusion steps used when generating samples with a pre-trained model.
r9   r
   r   rC   leadingNrH   z=timestep_spacing must be one of ['linspace', 'leading'], got rI   rJ   rK   r   )r   r   r   r   )rN   r@   r%   r9   r:   r1   rM   rO   copyastypefloat
ValueErrorr   rP   rQ   rR   rS   rT   rU   replace)r4   r-   r   rb   r   
step_ratior   r   s           r   set_timesteps(FlaxEulerDiscreteScheduler.set_timesteps   s    ;;'':5T[[%D%Dq%H!M`hrhrsI[[))Y688<OOJA':;jHOOQRVTVRVW\\^eefklINIOPTP[P[PlPlOmn  u||222ell6Q6QQVYYIszz!S['A6J&#))SE*L!MN ;;''+CC%zz| &

 1A 5#=}} 3-	  
 	
r   model_outputreturn_dictc                    UR                   c  [        S5      e[        R                  " UR                  U:H  SS9u  nUS   nUR
                  U   nU R                  R                  S:X  a  XGU-  -
  nOZU R                  R                  S:X  a  X'* US-  S-   S-  -  -  XGS-  S-   -  -   nO#[        S	U R                  R                   S
35      eXH-
  U-  n	UR
                  US-      U-
  n
XIU
-  -   nU(       d  X4$ [        XS9$ )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:
    state (`EulerDiscreteSchedulerState`):
        the `FlaxEulerDiscreteScheduler` state data class instance.
    model_output (`jnp.ndarray`): direct output from learned diffusion model.
    timestep (`int`): current discrete timestep in the diffusion chain.
    sample (`jnp.ndarray`):
        current instance of sample being created by diffusion process.
    order: coefficient for multi-step inference.
    return_dict (`bool`): option for returning tuple rather than FlaxEulerDiscreteScheduler class

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

zaNumber of inference steps is 'None', you need to run 'set_timesteps' after creating the schedulerr
   r[   r   r8   v_predictionr   rI   zprediction_type given as z, must be one of `epsilon`, or `v_prediction`)prev_sampler-   )	r   rh   r%   r]   r   r   rN   r?   r+   )r4   r-   rm   rY   rX   rn   r^   r_   pred_original_sample
derivativedtrq   s               r   stepFlaxEulerDiscreteScheduler.step   s*   6 $$,s  		%//X"=AF]
Z( ;;&&)3#)L,@#@ [[((N:#/6UAX\c<Q3Q#RV\gh`hkl`lVm#n +DKK,G,G+HHtu 
 3u<
 \\*q.)E1B.''/KUUr   original_samplesnoiser   c                 x    UR                   U   R                  5       n[        XSR                  5      nX#U-  -   nU$ rB   )r   flattenr   rb   )r4   r-   rw   rx   r   r_   noisy_sampless          r   	add_noise$FlaxEulerDiscreteScheduler.add_noise   s;     Y'//1,UKK@(5=8r   c                 .    U R                   R                  $ rB   )rN   r:   r3   s    r   __len__"FlaxEulerDiscreteScheduler.__len__  s    {{...r   rC   rB   )r   )T)"r    r!   r"   r#   __doc__r   name_compatiblesr%   r1   r$   propertyr5   r	   float32r'   rg   strr   r&   rD   r   r   rV   r`   r   rk   boolr   r+   ru   r|   r   r)   ).0es   00r   r/   r/   5   s   8 %BB$AqFF$ABL99   $("%/3( *;;   	
   ,   yy 
8,@#A 
Mh 
,'B CKK cf knkvkv . \^'
0'
GJ'
SX'
	$'
^ !;V*;V kk;V 	;V
 ;V ;V 
/6	7;Vz* ++ {{	
 ;; 
/m Cs   D-r/   )dataclassesr   typingr   r   r   flax	jax.numpynumpyr%   configuration_utilsr   r	   scheduling_utils_flaxr   r   r   r   r   structr   r+   r/   r   r   r   <module>r      sv    " ) )   A  i i i  '': ' 'T/!3[ T/r   