o
    ZiW                     @   sF   d dl Zd dlZddlmZ dd ZG dd deZG dd	 d	ZdS )
    N   )GaussianDiffusionc                 C   sL  t |trB|dr8t|tdd }td| D ]}ttd| ||kr/ttd| |  S qtd|  ddd |d	D }| t| }| t| }d}g }t	|D ]K\}}|||k radnd }	|	|k rrtd
|	 d| |dkryd}
n|	d |d  }
d}g }t|D ]}|
|t|  ||
7 }q||7 }||	7 }qVt|S )aQ  
    Create a list of timesteps to use from an original diffusion process,
    given the number of timesteps we want to take from equally-sized portions
    of the original process.
    For example, if there's 300 timesteps and the section counts are [10,15,20]
    then the first 100 timesteps are strided to be 10 timesteps, the second 100
    are strided to be 15 timesteps, and the final 100 are strided to be 20.
    If the stride is a string starting with "ddim", then the fixed striding
    from the DDIM paper is used, and only one section is allowed.
    :param num_timesteps: the number of diffusion steps in the original
                          process to divide up.
    :param section_counts: either a list of numbers, or a string containing
                           comma-separated numbers, indicating the step count
                           per section. As a special case, use "ddimN" where N
                           is a number of steps to use the striding from the
                           DDIM paper.
    :return: a set of diffusion steps from the original process to use.
    ZddimNr   r   zcannot create exactly z steps with an integer stridec                 S   s   g | ]}t |qS  )int).0xr   r   K/data/cameron/vidgen/unified_video_action/./simple_uva/diffusion/respace.py
<listcomp>(   s    z#space_timesteps.<locals>.<listcomp>,zcannot divide section of z steps into g        )
isinstancestr
startswithr   lenrangeset
ValueErrorsplit	enumerateappendround)num_timestepsZsection_countsZdesired_countiZsize_perextra	start_idxZ	all_stepsZsection_countsizeZfrac_strideZcur_idxZtaken_steps_r   r   r   space_timesteps   s@   




r   c                       s`   e Zd ZdZ fddZ fddZ fddZ fdd	Z fd
dZdd Z	dd Z
  ZS )SpacedDiffusiona"  
    A diffusion process which can skip steps in a base diffusion process.
    :param use_timesteps: a collection (sequence or set) of timesteps from the
                          original diffusion process to retain.
    :param kwargs: the kwargs to create the base diffusion process.
    c                    s   t || _g | _t|d | _tdi |}d}g }t|jD ]\}}|| jv r9|d||   |}| j| qt	
||d< t jdi | d S )Nbetasg      ?r   r   )r   use_timestepstimestep_mapr   original_num_stepsr   r   alphas_cumprodr   nparraysuper__init__)selfr   kwargsZbase_diffusionZlast_alpha_cumprodZ	new_betasr   Zalpha_cumprod	__class__r   r   r&   I   s   

zSpacedDiffusion.__init__c                        t  j| |g|R i |S N)r%   p_mean_variance_wrap_modelr'   modelargsr(   r)   r   r   r-   Y       zSpacedDiffusion.p_mean_variancec                    r+   r,   )r%   training_lossesr.   r/   r)   r   r   r3   ^   r2   zSpacedDiffusion.training_lossesc                    r+   r,   )r%   condition_meanr.   r'   cond_fnr1   r(   r)   r   r   r4   c       zSpacedDiffusion.condition_meanc                    r+   r,   )r%   condition_scorer.   r5   r)   r   r   r8   f   r7   zSpacedDiffusion.condition_scorec                 C   s   t |tr|S t|| j| jS r,   )r   _WrappedModelr    r!   )r'   r0   r   r   r   r.   i   s   
zSpacedDiffusion._wrap_modelc                 C   s   |S r,   r   )r'   tr   r   r   _scale_timestepsn   s   z SpacedDiffusion._scale_timesteps)__name__
__module____qualname____doc__r&   r-   r3   r4   r8   r.   r;   __classcell__r   r   r)   r   r   A   s    r   c                   @   s   e Zd Zdd Zdd ZdS )r9   c                 C   s   || _ || _|| _d S r,   )r0   r    r!   )r'   r0   r    r!   r   r   r   r&   t   s   
z_WrappedModel.__init__c                 K   s2   t j| j|j|jd}|| }| j||fi |S )N)devicedtype)thtensorr    rA   rB   r0   )r'   r   tsr(   Z
map_tensorZnew_tsr   r   r   __call__z   s   z_WrappedModel.__call__N)r<   r=   r>   r&   rF   r   r   r   r   r9   s   s    r9   )	numpyr#   torchrC   gaussian_diffusionr   r   r   r9   r   r   r   r   <module>   s   52