o
    ?߱i)                     @   s  d Z ddlZddlmZmZmZmZmZmZm	Z	 ddl
Z
ddlZddlmZ ddlmZmZ ddlmZmZ ddlmZ ed Zee
jd	d
G dd dZee
jd	d
G dd dZee
jd	d
G dd dZ		d'dededede	eef dedejfddZG dd dej j!Z"dededeeegef dedef
dd Z#	d(d!eejejgejf d"ejd#ed$eee  deejgejf f
d%d&Z$dS ))a  
A general framework for various sampling algorithm from a diffusion model.
Impl based on
* Refined Exponential Solver (RES) in https://arxiv.org/pdf/2308.02157
* also clude other impl, DDIM, DEIS, DPM-Solver, EDM sampler.
Most of sampling algorihtm, Runge-Kutta, Multi-step, etc, can be impl in this framework by     adding new step function in get_runge_kutta_fn or get_multi_step_fn.
    N)AnyCallableListLiteralOptionalTupleUnion)make_freezable)get_multi_step_fnis_multi_step_fn_supported)get_runge_kutta_fnis_runge_kutta_fn_supported)log)2ab2midZ1eulerF)slotsc                   @   sf   e Zd ZU dZeed< dZeed< dZeed< dZ	e
ed< e
d	Ze
ed
< dZe
ed< dZe
ed< dS )SolverConfigFis_multir   rkr   	multistepg        s_churninfs_t_maxg?s_t_ming      ?s_noiseN)__name__
__module____qualname__r   bool__annotations__r   strr   r   floatr   r   r    r"   r"   ]/data/cameron/vidgen/cosmos-predict2.5/cosmos_predict2/_src/imaginaire/modules/res_sampler.pyr   '   s   
 r   c                   @   sJ   e Zd ZU dZeed< dZeed< dZeed< dZ	eed< d	Z
eed
< dS )SolverTimestampConfig2   nfeMb`?t_ming      T@t_maxg      @orderF
is_forwardN)r   r   r   r&   intr   r(   r!   r)   r*   r+   r   r"   r"   r"   r#   r$   5   s   
 r$   c                   @   sB   e Zd ZU ejedZeed< ejedZ	eed< dZ
eed< dS )SamplerConfig)factorysolver
timestampsTsample_cleanN)r   r   r   attrsfieldr   r/   r   r$   r0   r1   r   r"   r"   r"   r#   r-   ?   s   
 r-   r(   r)   	num_stepsts_orderr+   returnc                 C   s~   | |krt dt|ttfstdtj|d tjd}|d|  || | d|  |d|     | }|r=|jddS |S )a  
    Generate a sequence of reverse time steps.

    Args:
        t_min (float): The minimum time value.
        t_max (float): The maximum time value.
        num_steps (int): The number of time steps to generate.
        ts_order (Union[int, float]): The order of the time step progression.
        is_forward (bool, optional): If True, returns the sequence in forward order. Defaults to False.

    Returns:
        torch.Tensor: A tensor containing the generated time steps in reverse or forward order.

    Raises:
        ValueError: If `t_min` is not less than `t_max`.
        TypeError: If `ts_order` is not an integer or float.
    zt_min must be less than t_maxz$ts_order must be an integer or float   )dtype)r   )dims)	
ValueError
isinstancer,   r!   	TypeErrortorcharangefloat64flip)r(   r)   r4   r5   r+   Zstep_indicesZ
time_stepsr"   r"   r#   
get_rev_tsG   s   *rA   c                       s   e Zd Zd!dee f fddZe ddddd	d	ed
ddf	de	dej
dedededededededededej
fddZe 		d"de	ej
ej
gej
f dej
dee deee	  dej
f
dd Z  ZS )#SamplerNcfgc                    s"   t    |d u rt }|| _d S N)super__init__r-   rC   )selfrC   	__class__r"   r#   rF   m   s   

zSampler.__init__#   r'   P      r   r   r7   r   x0_fnx_sigma_maxr4   	sigma_min	sigma_maxrhoS_churnS_minS_maxS_noisesolver_optionr6   c              	      s   |j  dtjdtjdtjf fdd}t|}t|}|s'|s'J d| t||	||
|||d}t||||d}t||d	d
}| |||	 S )Nx_B_StateShapet_Br6   c                    s   |   |   tjS rD   )tor=   r?   )rW   rX   in_dtyperM   r"   r#   float64_x0_fn   s   z&Sampler.forward.<locals>.float64_x0_fnz2Only support multistep or Runge-Kutta method, got )r   r   r   r   r   r   r   )r&   r(   r)   r*   T)r/   r0   r1   )
r8   r=   Tensorr   r   r   r$   r-   _forward_implrY   )rG   rM   rN   r4   rO   rP   rQ   rR   rS   rT   rU   rV   r\   Zis_multistepZis_rk
solver_cfgZtimestamps_cfgsampler_cfgr"   rZ   r#   forwards   s"   "	zSampler.forwarddenoiser_fnnoisy_input_B_StateShaper`   callback_fnsc           
      C   s   |du r| j n|}|jjrdnt|jjd }|jj| }t|jj|jj	||jj
|j}t|||j|d|}|jrRtj|d|j|jd}	|||d |	 }|S )a  
        Internal implementation of the forward pass.

        Args:
            denoiser_fn: Function to denoise the input.
            noisy_input_B_StateShape: Input tensor with noise.
            sampler_cfg: Configuration for the sampler.
            callback_fns: List of callback functions to be called during sampling.

        Returns:
            torch.Tensor: Denoised output tensor.
        Nr7   r   )rd   devicer8   )rC   r/   r   r,   r   r0   r&   rA   r(   r)   r*   rY   rf   differential_equation_solverr1   r=   onessizer8   )
rG   rb   rc   r`   rd   Zsolver_orderZnum_timestampssigmas_LZdenoised_outputri   r"   r"   r#   r^      s"   
zSampler._forward_implrD   )NN)r   r   r   r   r-   rF   r=   no_gradr!   r   r]   r,   r    ra   r   r^   __classcell__r"   r"   rH   r#   rB   l   sf    	
%
rB   lowerupperbody_funinit_valc                 C   s>   |}t | |D ]}|d dkrtd|  |||}q|S )aJ  
    Implements a for loop with a function.

    Args:
        lower: Lower bound of the loop (inclusive).
        upper: Upper bound of the loop (exclusive).
        body_fun: Function to be applied in each iteration.
        init_val: Initial value for the loop.

    Returns:
        The final result after all iterations.
    
   r   zfori_loop: )ranger   info)rn   ro   rp   rq   valir"   r"   r#   	fori_loop   s   rw   rM   rk   r_   rd   c                    sp   t d jrtjntjtjd  t	dd dt
jdt
jf fdd}|S )af  
    Creates a differential equation solver function.

    Args:
        x0_fn: Function to compute x0 prediction.
        sigmas_L: Tensor of sigma values with shape [L,].
        solver_cfg: Configuration for the solver.
        callback_fns: Optional list of callback functions.

    Returns:
        A function that solves the differential equation.
    r7   g333333?input_xT_B_StateShaper6   c              
      s   t j| d| jt jd dtdtt jtt	t j  f dtt jtt	t j  f f fdd}t
d|| dg\}}|S )	z
        Samples from the differential equation.

        Args:
            input_xT_B_StateShape: Input tensor with shape [B, StateShape].

        Returns:
            Output tensor with shape [B, StateShape].
        r   re   i_thstater6   c           
         s   |\}}|  | d  }}j |  k rjk r9n n||  }||d |d   j t|  }|}jrR|| }|| | ||\}}n|| | \}} rn D ]
}	|	di t  qc||fS )Nr7      r"   )r   r   sqrtr   r=   
randn_liker   locals)
ry   rz   Zinput_x_B_StateShapeZx0_predsZsigma_cur_0Zsigma_next_0Zhat_sigma_cur_0Zx0_pred_B_StateShapeZoutput_x_B_StateShapecallback_fn)rd   etaones_Brk   r_   update_step_fnrM   r"   r#   step_fn   s.   
z@differential_equation_solver.<locals>.sample_fn.<locals>.step_fnN)r=   ri   rj   rf   r?   r,   r   r]   r   r   rw   )rx   r   Zx_at_eps_rd   r   Znum_steprk   r_   r   rM   )r   r#   	sample_fn   s   
z/differential_equation_solver.<locals>.sample_fn)lenr   r
   r   r   r   minr   mathr|   r=   r]   )rM   rk   r_   rd   r   r"   r   r#   rh      s   
&-rh   )FrD   )%__doc__r   typingr   r   r   r   r   r   r   r2   r=   &cosmos_predict2._src.imaginaire.configr	   Z5cosmos_predict2._src.imaginaire.functional.multi_stepr
   r   Z6cosmos_predict2._src.imaginaire.functional.runge_kuttar   r   %cosmos_predict2._src.imaginaire.utilsr   COMMON_SOLVER_OPTIONSdefiner   r$   r-   r!   r,   r   r]   rA   nnModulerB   rw   rh   r"   r"   r"   r#   <module>   s^   	$




%*U
