o
    i9F                     @  s  U d dl mZ d dlZd dlmZmZ d dlmZmZ d dl	Z		dIdJddZ
dKddZeddG dd dZeddG dd dZeddG dd dZeegef Zeegeee ee	jdB  f f ZdLddZeZded< dMd"d#ZeZd$ed%< dNd(d)ZdNd*d+ZdOd.d/ZdPdQd1d2ZdPdQd3d4ZdRd6d7Z G d8d9 d9eZ!dSd=d>Z"dTdCdDZ#eddG dEdF dFZ$eddG dGdH dHZ%dS )U    )annotationsN)	dataclassreplace)Callable
NamedTupleFlengthint	ramp_left
ramp_rightleft_starts_from_0boolreturntorch.Tensorc                 C  s   | dkrt dtdt|| }tdt|| }t| }|dkrH|r'|d n|d }tdd|dd }|s>|dd }|d|  |9  < |dkretjdd|d d	dd }|| d  |9  < |ddS )
a  
    Generate a 1D trapezoidal blending mask with linear ramps.
    Args:
        length: Output length of the mask.
        ramp_left: Fade-in length on the left.
        ramp_right: Fade-out length on the right.
        left_starts_from_0: Whether the ramp starts from 0 or first non-zero value.
            Useful for temporal tiles where the first tile is causal.
    Returns:
        A 1D tensor of shape `(length,)` with values in [0, 1].
    r   Mask length must be positive.      g        g      ?N)steps)
ValueErrormaxmintorchoneslinspaceclamp_)r   r	   r
   r   maskinterval_lengthfade_infade_out r   ;/home/ubuntu/LTX-2/packages/ltx-core/src/ltx_core/tiling.pycompute_trapezoidal_mask_1d
   s   
r!   	left_ramp
right_rampc                 C  sH   | dkrt dt| }|dkrd|d|< |dkr"d|| d< |S )aG  
    Generate a 1D rectangular (pulse) mask.
    Args:
        length: Output length of the mask.
        left_ramp: Number of elements at the start of the mask to set to 0.
        right_ramp: Number of elements at the end of the mask to set to 0.
    Returns:
        A 1D tensor of shape `(length,)` with values 0 or 1.
    r   r   N)r   r   r   )r   r"   r#   r   r   r   r    compute_rectangular_mask_1d1   s   
r$   T)frozenc                   @  s.   e Zd ZU ded< ded< ded< ded< dS )DimensionIntervalr   startendr"   r#   N)__name__
__module____qualname____annotations__r   r   r   r    r&   J   s
   
 r&   c                   @  s   e Zd ZU dZded< dS )DimensionIntervalsa  Intervals which a single dimension of the latent space is split into.
    Each interval is defined by its start, end, left ramp, and right ramp.
    The start and end are the indices of the first and last element (exclusive) in the interval.
    Ramps are regions of the interval where the value of the mask tensor is
    interpolated between 0 and 1 for blending with neighboring intervals.
    The left ramp and right ramp values are the lengths of the left and right ramps.
    zlist[DimensionInterval]	intervalsNr)   r*   r+   __doc__r,   r   r   r   r    r-   R   s   
 r-   c                   @  s"   e Zd ZU dZded< ded< dS )LatentIntervalszIntervals which the latent tensor of given shape is split into.
    Each dimension of the latent space is split into intervals based on the length along said dimension.
    
torch.Sizeoriginal_shapeztuple[DimensionIntervals, ...]dimension_intervalsNr/   r   r   r   r    r1   _   s   
 r1   c                 C  s   t td| dddgdS )Nr   r'   r(   r"   r#   r.   )r-   r&   )r   r   r   r    default_split_operationo   s   r7   SplitOperationDEFAULT_SPLIT_OPERATION
_intervals-tuple[list[slice], list[torch.Tensor | None]]c                 C  s   t dd gd gfS )Nr   )slice)r:   r   r   r    default_mapping_operationv   s   r=   MappingOperationDEFAULT_MAPPING_OPERATIONsizeoverlapc                   sN   dkrt d  dk s krt d  d d fd	d
}|S )a  Split a dimension into overlapping tiles of a given size.
    Tiles are sized ``size`` with ``overlap`` shared elements between
    consecutive tiles.  The last tile may be shorter if the dimension
    doesn't divide evenly.
    Args:
        size: Target tile size (in axis units).
        overlap: Overlap between consecutive tiles.
    Returns:
        A split operation that divides a dimension into tiles.
    r   zsize must be > 0, got z6overlap must satisfy 0 <= overlap < size, got overlap=z, size=dimension_sizer   r   r-   c                   s   | krt | S |  d   d    }tdd dg fddtd|d D t|d    |  dd}t|dS )Nr   r   r   r5   c                 3  s4    | ]}t |   |      d V  qdS )r5   N)r&   ).0irA   r@   r   r    	<genexpr>   s    

z/split_by_size.<locals>.split.<locals>.<genexpr>r6   )r9   r&   ranger-   )rB   amountr.   rE   r   r    split   s   
zsplit_by_size.<locals>.splitNrB   r   r   r-   r   r@   rA   rI   r   rE   r    split_by_size   s   rM   c                      t | d fdd}|S )	a  Split a temporal axis into overlapping tiles with causal handling.
    Each tile after the first is shifted back by 1 and its left ramp is
    increased by 1, ensuring causal continuity through the blend ramps.
    Args:
        size: Tile size in axis units.
        overlap: Overlap between tiles in the same units.
    Returns:
        Split operation that divides temporal dimension with causal handling.
    rB   r   r   r-   c                   sF   | krt | S  | }|jd gdd |jdd  D  }t|dS )Nr   c                 S  &   g | ]}t ||jd  |jd  dqS r   )r'   r"   r   r'   r"   rC   intervalr   r   r    
<listcomp>       z8split_temporal_causal.<locals>.split.<locals>.<listcomp>r   r6   )r9   r.   r-   rB   dim_intervalsmodified_intervalsnon_causal_splitr@   r   r    rI      s   
z$split_temporal_causal.<locals>.splitNrJ   rM   rL   r   rY   r    split_temporal_causal   s   


r\   tile_size_framesoverlap_framesc                   rN   )	a4  Split a temporal axis in video frame space into overlapping tiles.
    Args:
        tile_size_frames: Tile length in frames.
        overlap_frames: Overlap between consecutive tiles in frames.
    Returns:
        Split operation that takes frame count and returns DimensionIntervals in frame indices.
    rB   r   r   r-   c                   sN   | krt | S  | }dd |jd d D t|jd ddg }t|dS )Nc                 S  s    g | ]}t ||jd  ddqS )r   r   )r(   r#   )r   r(   rR   r   r   r    rT      s    z1split_temporal.<locals>.split.<locals>.<listcomp>r   r   )r#   r6   )r9   r.   r   r-   rV   rZ   r]   r   r    rI      s   
zsplit_temporal.<locals>.splitNrJ   r[   )r]   r^   rI   r   r_   r    split_temporal   s   
	r`   	num_tilesc                   s   t | | d fdd}|S )	a  Split a temporal dimension by count with causal handling.
    Wraps :func:`split_by_count` with the same causal adjustment as
    :func:`split_temporal_causal`: each tile after the first is shifted
    back by 1 and its left ramp is increased by 1.
    Args:
        num_tiles: Number of tiles. Must be >= 1.
        overlap: Overlap between adjacent tiles (default 0).
    Returns:
        A split operation that divides a temporal dimension into tiles.
    rB   r   r   r-   c                   sH    | }t |jdkr|S |jd gdd |jdd  D  }t|dS )Nr   r   c                 S  rO   rP   rQ   rR   r   r   r    rT      rU   zAsplit_by_count_temporal_causal.<locals>.split.<locals>.<listcomp>r6   )lenr.   r-   rV   rZ   r   r    rI      s   
z-split_by_count_temporal_causal.<locals>.splitNrJ   )split_by_countra   rA   rI   r   rc   r    split_by_count_temporal_causal   s   

rf   c                   s@    dk rt d  dk rt d d fd	d
}|S )a  Split a dimension into a given number of tiles with overlap.
    Computes the tile size as
    ``(dim_size + overlap * (num_tiles - 1)) // num_tiles`` so that
    ``num_tiles`` tiles of that size with ``overlap`` shared elements
    cover the dimension evenly.  Delegates to :func:`split_by_size` for
    the actual interval construction.
    When the total ``dim_size + overlap * (num_tiles - 1)`` is not evenly
    divisible by ``num_tiles``, the first ``remainder`` tiles each absorb
    one extra unit.
    Args:
        num_tiles: Number of tiles. Must be >= 1.
        overlap: Overlap between adjacent tiles (default 0). Must be >= 0
            and less than the computed tile size.
    Returns:
        A split operation that divides a dimension into tiles.
    r   num_tiles must be >= 1, got r   overlap must be >= 0, got dim_sizer   r   r-   c           
        s    | krt d  d|  d dkrt| S |  d   }|  }|  }t|| | j}g }t|D ]#\}}t||}||k rFdnd}	|t||j| |j	| |	 d q7t
|dS )Nznum_tiles (z) exceeds dim_size (z*). Cannot assign at least 1 unit per tile.r   r   )r'   r(   r6   )r   r9   rM   r.   	enumerater   appendr   r'   r(   r-   )
ri   total	tile_size	remainderbase_intervalsr.   rD   ivshiftgrowra   rA   r   r    rI     s    
&
zsplit_by_count.<locals>.splitN)ri   r   r   r-   rK   re   r   rs   r    rd      s   rd   r.   c                 C  sN   g }g }| j D ]}|t|j|j |t|j|j |j|j q||fS )a  Map each DimensionInterval to an output region at the same position, with trapezoidal blend masks.
    For every interval the output start/end matches the input start/end and a
    1-D blending mask is built from the interval's left_ramp and right_ramp.
    )r.   rk   r<   r'   r(   r!   r"   r#   )r.   
out_slicesmasksrp   r   r   r    identity_mapping_operation*  s   
 rv   c                   @  s8   e Zd ZU dZded< ded< ded< edd	d
ZdS )Tilea  
    Represents a single tile.
    Attributes:
        in_coords:
            Tuple of slices specifying where to cut the tile from the INPUT tensor.
        out_coords:
            Tuple of slices specifying where this tile's OUTPUT should be placed in the reconstructed OUTPUT tensor.
        masks_1d:
            Per-dimension masks in OUTPUT units.
            These are used to create all-dimensional blending mask.
    Methods:
        blend_mask:
            Create a single N-D mask from the per-dimension masks.
    ztuple[slice, ...]	in_coords
out_coordsztuple[torch.Tensor | None, ...]masks_1dr   r   c           	      C  s   t | j}g }t|D ]1}| j| }dg| }|d u r-td}d||< ||j|  q|jd ||< ||j|  q|d }|dd  D ]}|| }qG|S )Nr   r   )	rb   ry   rG   rz   r   r   rk   viewshape)	selfnum_dimsper_dimension_masksdim_idxmask_1d
view_shapeonecombined_maskr   r   r   r    
blend_maskK  s    




zTile.blend_maskN)r   r   )r)   r*   r+   r0   r,   propertyr   r   r   r   r    rw   7  s   
 rw   mapperslist[MappingOperation]
list[Tile]c                 C  s   g }g }g }t t| jD ]K}| j| }dd |jD }|| |\}}	t|}
t||
ks4t|	|
krItd| dt| dt|	 d|
 d	|| || ||	 qdd ttj	| tj	| tj	| d	d
D S )Nc                 S  s   g | ]	}t |j|jqS r   )r<   r'   r(   rR   r   r   r    rT   p  s    z;create_tiles_from_intervals_and_mappers.<locals>.<listcomp>zAxis z: mapper produced z output slices and z masks for z input intervalsc                 S  s    g | ]\}}}t |||d qS ))rx   ry   rz   )rw   )rC   in_coord	out_coordr   r   r   r    rT   |  s    Tstrict)
rG   rb   r3   r4   r.   r   rk   zip	itertoolsproduct)r.   r   full_dim_input_slicesfull_dim_output_slicesfull_dim_masks_1d
axis_indexr4   input_slicesoutput_slicesrz   n_intervalsr   r   r    'create_tiles_from_intervals_and_mappersg  s6   


r   latent_shaper2   	splitterslist[SplitOperation]c                 C  s   t |t | krtdt | dt |  t |t | kr,tdt | dt |  dd t|| ddD }t| t|d}t||S )	NzONumber of splitters must be equal to number of dimensions in latent shape, got z and zMNumber of mappers must be equal to number of dimensions in latent shape, got c                 S  s   g | ]\}}||qS r   r   )rC   splitterr   r   r   r    rT     s    z create_tiles.<locals>.<listcomp>Tr   )r3   r4   )rb   r   r   r1   tupler   )r   r   r   r.   latent_intervalsr   r   r    create_tiles  s&   
r   c                   @  s@   e Zd ZU dZded< dZded< ddd	ZeddddZdS )DimensionTilingConfigar  Tiling parameters for a single dimension of the patchified grid.
    Attributes:
        num_tiles: Number of tiles along this dimension.
        overlap: Overlap between adjacent tiles, in latent grid units.
            Adjacent tiles share ``overlap`` grid cells at their
            boundary, producing an overlap zone blended with
            trapezoidal masks.
    r   ra   r   rA   r   Nonec                 C  s8   | j dk rtd| j  | jdk rtd| j d S )Nr   rg   r   rh   )ra   r   rA   )r}   r   r   r    __post_init__  s
   

z#DimensionTilingConfig.__post_init__ri   rm   c                 C  s$   t ||}||}| t|j|dS )aS  Create config by computing ``num_tiles`` from dimension size and tile size.
        Args:
            dim_size: Total length of the dimension.
            tile_size: Desired tile size.
            overlap: Overlap between consecutive tiles.
        Returns:
            A ``DimensionTilingConfig`` with the computed ``num_tiles``.
        rs   )rM   rb   r.   )clsri   rm   rA   split_opr.   r   r   r    from_tile_size  s   

z$DimensionTilingConfig.from_tile_sizeN)r   r   r   )ri   r   rm   r   rA   r   r   r   )	r)   r*   r+   r0   r,   rA   r   classmethodr   r   r   r   r    r     s   
 	
r   c                   @  sN   e Zd ZU dZedddZded< edddZded< edddZded< d	S )
TileCountConfigan  Tiling layout for a ``(F, H, W)`` grid.
    Specifies tile *counts* per dimension (as opposed to tile *sizes*
    which are used by the single-GPU VAE ``TilingConfig``).
    Attributes:
        frames: Tiling along the temporal (frames) dimension.
        height: Tiling along the latent height dimension.
        width: Tiling along the latent width dimension.
    r   r   rs   r   framesheightwidthN)	r)   r*   r+   r0   r   r   r,   r   r   r   r   r   r    r     s
   
 	r   )F)
r   r   r	   r   r
   r   r   r   r   r   )r   r   r"   r   r#   r   r   r   )r   r   r   r-   )r:   r-   r   r;   )r@   r   rA   r   r   r8   )r]   r   r^   r   r   r8   r   )ra   r   rA   r   r   r8   )r.   r-   r   r;   )r.   r1   r   r   r   r   )r   r2   r   r   r   r   r   r   )&
__future__r   r   dataclassesr   r   typingr   r   r   r!   r$   r&   r-   r1   r   r8   r   listr<   Tensorr>   r7   r9   r,   r=   r?   rM   r\   r`   rf   rd   rv   rw   r   r   r   r   r   r   r   r    <module>   sB    
'
$



(

5
0
 "