o
    vi                     @   sN   d dl mZ d dlZd dlmZ G dd dZG dd dZG dd	 d	ZdS )
    )CallableN)FlowMatchEulerDiscreteSchedulerc                   @   s.   e Zd Z	d	defddZdejfddZdS )
TrainTimeWeightuniformweightc                 C   s.   |dkrd}|| _ || _| j dksJ dd S )NZreweightingr   z+Only uniform loss weight is supported in RF)r   noise_scheduler)selfr   r    r	   [/data/cameron/vidgen/cosmos-policy/cosmos_policy/_src/predict2/schedulers/rectified_flow.py__init__   s
   zTrainTimeWeight.__init__returnc                 C   s*   | j dkrt|}|S td| j  d)Nr   zTime weight '' is not implemented.)r   torch	ones_likeNotImplementedError)r   ttensor_kwargsZwtsr	   r	   r
   __call__%   s   

zTrainTimeWeight.__call__Nr   )__name__
__module____qualname__strr   r   Tensorr   r	   r	   r	   r
   r      s    
r   c                
   @   sT   e Zd Z	ddefddZe edejfde	dejdej
d	ejfd
dZdS )TrainTimeSamplerr   distributionc                 C   s
   || _ d S )N)r   )r   r   r	   r	   r
   r   /   s   
zTrainTimeSampler.__init__cpu
batch_sizedevicedtyper   c                 C   s`   | j dkrt|fj||d}|S | j dkr'tt|fj||d}|S td| j d)z~
        Sample time tensor for training

        Returns:
            torch.Tensor: Time tensor, shape (batch_size,)
        r   r   r   logitnormalzTime distribution 'r   )r   r   randtosigmoidrandnr   dist)r   r   r   r   r   r	   r	   r
   r   5   s   

zTrainTimeSampler.__call__Nr   )r   r   r   r   r   r   no_gradr   float32intr   r   r   r	   r	   r	   r
   r   .   s"    
r   c                   @   s   e Zd ZddddedejfdedeeB dede	d	e
d
ejdejfddZde
fddZdd Zdd ZdejdejdejfddZdS )RectifiedFlowr   F   r   velocity_fieldtrain_time_distributiontrain_time_weight_methoduse_dynamic_shiftshiftr   r   c                 C   s   || _ t|tr
|nt|| _|rt|d| _nt|d| _t| j|| _t|tr/t	
|n|| _
t|tr?t	|| _dS || _dS )a  Initialize the RectifiedFlow class.

        Args:
            velocity_field (`Callable`):
                A function that predicts the velocity given the current state and time.
            train_time_distribution (`TrainTimeSampler` or `str`, *optional*, defaults to `"uniform"`):
                Distribution for sampling training times.
                Can be an instance of `TrainTimeSampler` or a string specifying the distribution type.
            train_time_weight (`TrainTimeWeight` or `str`, *optional*, defaults to `"uniform"`):
                Weight applied to training times.
                Can be an instance of `TrainTimeWeight` or a string specifying the weight type.
        )use_dynamic_shifting)r0   N)r,   
isinstancer   train_time_samplerr   r   r   train_time_weightr   r   r   r   )r   r,   r-   r.   r/   r0   r   r   r	   r	   r
   r   M   s   $zRectifiedFlow.__init__r   c                 C   s   | j || j| jd}|S )a  This method calls the `TrainTimeSampler` to sample training times.

        Returns:
            t (`torch.Tensor`):
                A tensor of sampled training times with shape `(batch_size,)`,
                matching the class specified `device` and `dtype`.
        r    )r3   r   r   )r   r   timer	   r	   r
   sample_train_times   s   zRectifiedFlow.sample_train_timec                 C   sF   |  | jjj  }| jjjdi || }|jdkr!|dS |S )z/This method map time from 0,1 to discrete stepsr   Nr	   )	squeezer   confignum_train_timestepslong	timestepsr#   ndim	unsqueeze)r   ur   indicesr;   r	   r	   r
   get_discrete_timestamp~   s   z$RectifiedFlow.get_discrete_timestampc                    sd   | j jjdi |}| j jjdi |  fdd|D }t||jd ks*J d||  }|S )Nc                    s    g | ]} |k    qS r	   )nonzeror7   tolist).0r   schedule_timestepsr	   r
   
<listcomp>   s     z,RectifiedFlow.get_sigmas.<locals>.<listcomp>r   z3Number of indices do not match the given timesteps.r	   )r   sigmasr#   r;   lenshapeflatten)r   r;   r   rG   step_indicessigmar	   rD   r
   
get_sigmas   s   zRectifiedFlow.get_sigmasx_0x_1r   c                 C   s   |j |j ks
J d|j d |j d ksJ d|j d |j d ks&J d|j|j d gdgt|j d  R  }|| |d|   }|| }||fS )a   
        This method computes interpolation `X_t` and their time derivatives `dotX_t` at the specified time points `t`.
        Note that `x_0` is the noise, and `x_1` is the clean data. This is aligned with the notation in the recified flow community,
        but different from the notation in the diffusion community.

        Args:
            x_0 (`torch.Tensor`):
                noise, shape `(B, D1, D2, ..., Dn)`, where `B` is the batch size, and `D1, D2, ..., Dn` are the data dimensions.
            x_1 (`torch.Tensor`):
                clean data, with the same shape as `x_0`
            t (`torch.Tensor`):
                A tensor of time steps, with shape `(B,)`, where each value is in `[0, 1]`.

        Returns:
            (x_t, dot_x_t) (`Tuple[torch.Tensor, torch.Tensor]`):
                - x_t (`torch.Tensor`): The interpolated state, with shape `(B, D1, D2, ..., Dn)`.
                - dot_x_t (torch.Tensor): The time derivative of the interpolated state, with the same shape as `x_t`.
        z%x_0 and x_1 must have the same shape.r   z%Batch size of x_0 and x_1 must match.zBatch size of t must match x_1.   )rI   viewrH   )r   rN   rO   r   x_tZdot_x_tr	   r	   r
   get_interpolation   s   (zRectifiedFlow.get_interpolationN)r   r   r   r   r   r(   r   r   r   boolr)   r   r   r6   r@   rM   r   rS   r	   r	   r	   r
   r*   L   s@    
&	r*   )typingr   r   	diffusersr   r   r   r*   r	   r	   r	   r
   <module>   s   