
    bi9*                         d dl mZ d dlmZmZmZ d dlZd dlmZ	 ddl
mZmZ ddlmZmZmZmZmZ ej&                  j                   G d d	             Ze G d
 de             Z G d dee      Zy)    )	dataclass)OptionalTupleUnionN   )ConfigMixinregister_to_config   )CommonSchedulerStateFlaxKarrasDiffusionSchedulersFlaxSchedulerMixinFlaxSchedulerOutputbroadcast_to_shape_from_leftc            	           e Zd ZU eed<   ej                  ed<   ej                  ed<   ej                  ed<   dZee	   ed<   e
dedej                  dej                  dej                  fd       Zy)EulerDiscreteSchedulerStatecommoninit_noise_sigma	timestepssigmasNnum_inference_stepsc                      | ||||      S )Nr   r   r   r    )clsr   r   r   r   s        n/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/diffusers/schedulers/scheduling_euler_discrete_flax.pycreatez"EulerDiscreteSchedulerState.create)   s     &3Cyaghh    )__name__
__module____qualname__r   __annotations__jnpndarrayr   r   intclassmethodr   r   r   r   r   r      s       kk!{{KK)-#-i)i=@[[iUXU`U`ijmjujui ir   r   c                       e Zd ZU eed<   y) FlaxEulerDiscreteSchedulerOutputstateN)r   r   r    r   r!   r   r   r   r'   r'   0   s    &&r   r'   c                   F   e Zd ZU dZeD  cg c]  }|j
                   c}} Zej                  e	d<   e
d        Zedddddd	d
ej                  fdededededeej$                     dededej                  fd       Zd%dee   defdZdedej$                  dedej$                  fdZ	 d&dedededefdZ	 d'dedej$                  dedej$                  dedeeef   fdZded ej$                  d!ej$                  d"ej$                  dej$                  f
d#Zd$ Zyc c}} w )(FlaxEulerDiscreteSchedulera  
    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                      y)NTr   selfs    r   	has_statez$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	                     || _         y Nr+   )	r.   r3   r4   r5   r6   r7   r8   r9   r+   s	            r   __init__z#FlaxEulerDiscreteScheduler.__init__Z   s     
r   r   returnc           	      v   |t        j                  |       }t        j                  d| j                  j
                        j                         d d d   }d|j                  z
  |j                  z  dz  }t        j                  |t        j                  dt        |            |      }t        j                  |t        j                  dg| j                        g      }| j                  j                  dv r|j                         }n|j                         dz  dz   dz  }t        j                  ||||	      S )
Nr   r
         ?        r<   r2   trailingr   r   )r   r   r"   arangeconfigr3   roundalphas_cumprodinterplenconcatenatearrayr+   r9   maxr   )r.   r   r   r   r   s        r   create_statez'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                     t        j                  |j                  |k(  d      \  }|d   }|j                  |   }||dz  dz   dz  z  }|S )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   rA   )r"   wherer   r   )r.   r(   rO   rP   
step_indexsigmas         r   scale_model_inputz,FlaxEulerDiscreteScheduler.scale_model_input~   sR     		%//X"=AF]
Z(E1HqLS01r   r   shapec           	         | j                   j                  dk(  r;t        j                  | j                   j                  dz
  d|| j
                        }n| j                   j                  dk(  rm| j                   j                  |z  }t        j                  d|      |z  j                         ddd   j                         j                  t              }|dz  }n"t        d| j                   j                         d|j                  j                  z
  |j                  j                  z  d	z  }t        j                  |t        j                  dt        |            |      }t        j                   |t        j"                  d
g| j
                        g      }| j                   j                  dv r|j%                         }n|j%                         dz  dz   d	z  }|j'                  ||||      S )a  
        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.
        r2   r
   r   r<   leadingNr@   z=timestep_spacing must be one of ['linspace', 'leading'], got rA   rB   rC   r   )r   r   r   r   )rF   r9   r"   r2   r3   r+   rE   rG   copyastypefloat
ValueErrorr   rH   rI   rJ   rK   rL   rM   replace)r.   r(   r   rX   r   
step_ratior   r   s           r   set_timestepsz(FlaxEulerDiscreteScheduler.set_timesteps   s    ;;'':5T[[%D%Dq%H!M`hlhrhr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                    |j                   t        d      t        j                  |j                  |k(  d      \  }|d   }|j
                  |   }| j                  j                  dk(  r	|||z  z
  }n[| j                  j                  dk(  r|| |dz  dz   dz  z  z  ||dz  dz   z  z   }n#t        d	| j                  j                   d
      ||z
  |z  }	|j
                  |dz      |z
  }
||	|
z  z   }|s||fS t        ||      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:
            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
   rR   r   r1   v_predictionr   rA   zprediction_type given as z, must be one of `epsilon`, or `v_prediction`)prev_sampler(   )	r   r^   r"   rT   r   r   rF   r8   r'   )r.   r(   rb   rP   rO   rc   rU   rV   pred_original_sample
derivativedtrf   s               r   stepzFlaxEulerDiscreteScheduler.step   s:   6 $$,s  		%//X"=AF]
Z( ;;&&)3#)EL,@#@ [[((N:#/E6UAX\c<Q3Q#RV\`egh`hkl`lVm#n +DKK,G,G+HHtu 
 33u<
 \\*q.)E1zB.''/KuUUr   original_samplesnoiser   c                 |    |j                   |   j                         }t        ||j                        }|||z  z   }|S r;   )r   flattenr   rX   )r.   r(   rk   rl   r   rV   noisy_sampless          r   	add_noisez$FlaxEulerDiscreteScheduler.add_noise   s?     Y'//1,UEKK@(55=8r   c                 .    | j                   j                  S r;   )rF   r3   r-   s    r   __len__z"FlaxEulerDiscreteScheduler.__len__  s    {{...r   r;   )r   )T) r   r   r    __doc__r   name_compatiblesr"   r+   r!   propertyr/   r	   float32r$   r]   strr   r#   r=   r   r   rN   rW   r   ra   boolr   r'   rj   rp   rr   ).0es   00r   r*   r*   5   s   8 %BBqAFF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   