§
    ÎÐjý  ã                  óˆ   — d Z ddlmZ ddlmZ ddlZdZdZdZdZ	efdd„Z
dd„Zd d„Zd!d„Ze G d„ d¦  «        ¦   «         ZdS )"ad  Per-step tiled latent fusion geometry.

One latent canvas is denoised through overlapping spatial tiles and temporal windows. At every
step each tile is evaluated separately and the tile predictions are merged back with Gaussian
weights, so all tiles follow one coupled trajectory and no seams form. Blending clean-latent (x0)
predictions and then taking one Euler step on the canvas is identical to blending the stepped
tiles, because every tile starts from the same canvas crop and the weights are normalized per cell.

Canvas tensors use the channels-last layout ``(B, F, H, W, C)`` in latent units.

Grid planning, grid cycling, temporal windows, Gaussian weights and first-latent skipping are
ported from ComfyUI-LTXVideo (``tiled_fusion_plan.py`` / ``tiled_fusion_sampler.py``,
https://github.com/Lightricks/ComfyUI-LTXVideo, LTX-2 Community License Agreement).
é    )Úannotations)Ú	dataclassNé   g      à?gš™™™™™©?é   ÚnÚintÚstepÚreturnc                ó‚   — t          dt          | ¦  «        ¦  «        } | dz
  |z  |z  dz   }||z   }|| z
  | |z
  k     r|n|S )z<Nearest ``step * k + 1`` length. Ties keep the shorter clip.é   )Úmaxr   )r   r	   ÚbelowÚaboves       úAC:\Users\johnn\OneDrive\Documents\AI\shared\utils\tiled_fusion.pyÚsnap_framesr      sQ   € åˆA�s�1‰vŒv‰Œ€AØ�!‰e˜‰_ Ñ$ qÑ(€EØ�D‰L€EØ˜A‘I  E¡	Ò)Ð)ˆ5ˆ5¨uÐ4ó    ÚcanvasÚtileÚmin_overlapú	list[int]c                ó  ‡— | |k    rdgS t          t          d|¦  «        |dz
  ¦  «        }d}|| k     r/||z  | z
  |dz
  z  |k     r|dz  }|| k     r||z  | z
  |dz
  z  |k     °| |z
  |dz
  z  Šˆfd„t          |¦  «        D ¦   «         S )zYTile origins covering ``[0, canvas)`` with pinned endpoints and at least ``min_overlap``.r   r   é   c                ó4   •— g | ]}t          |‰z  ¦  «        ‘ŒS © )Úround)Ú.0Úir	   s     €r   ú
<listcomp>zplan_grid.<locals>.<listcomp>0   s#   ø€ Ð.Ð.Ð. �E�!�d‘(‰OŒOÐ.Ð.Ð.r   )Úminr   Úrange)r   r   r   r   r	   s       @r   Ú	plan_gridr!   '   s¼   ø€ à�‚~€~Øˆsˆ
Ý•c˜!˜[Ñ)Ô)¨4°!©8Ñ4Ô4€KØ	€AØ
ˆfŠ*ˆ*˜!˜d™( VÑ+°°A±Ñ6¸ÒDÐDØ	ˆQ‰ˆð ˆfŠ*ˆ*˜!˜d™( VÑ+°°A±Ñ6¸ÒDÐDà�T‰M˜a !™eÑ$€DØ.Ð.Ð.Ð.¥U¨1¡X¤XÐ.Ñ.Ô.Ð.r   ÚbaseÚoffsetc                ó`   ‡ ‡‡‡— t          ˆ ˆˆˆfd„t          ‰ ¦  «        D ¦   «         ¦  «        S )zNShift interior origins by ``offset``; endpoints stay pinned so coverage holds.c           
     ó”   •— h | ]D\  }}|d t          ‰¦  «        dz
  fv r|n&t          dt          ‰‰z
  dz
  |‰z   ¦  «        ¦  «        ’ŒES ©r   r   )Úlenr   r   )r   r   Úvr"   r   r#   r   s      €€€€r   ú	<setcomp>zshifted.<locals>.<setcomp>5   sb   ø€ Ð|Ð|Ð|ÑdhÐdeÐgh˜˜a¥ T¡¤¨Q¡Ð/Ð/Ð/�1�1µS¸½CÀÈÁÐPQÑ@QÐSTÐW]ÑS]Ñ<^Ô<^Ñ5_Ô5_Ð|Ð|Ð|r   )ÚsortedÚ	enumerate)r"   r   r   r#   s   ````r   Úshiftedr,   3   s<   øøøø€ åÐ|Ð|Ð|Ð|Ð|Ð|Ð|ÕluÐvzÑl{Ôl{Ð|Ñ|Ô|Ñ}Ô}Ð}r   ÚvarÚfloatÚdeviceútorch.deviceútorch.Tensorc                óž   — t          j        | t           j        |¬¦  «        }t          j        || dz
  dz  z
  dz   | | z  dz  |z  z  ¦  «        S )N©Údtyper/   r   r   )ÚtorchÚarangeÚfloat32Úexp)r   r-   r/   Úxs       r   Úgaussian_weightr:   8   sO   € ÝŒ�Q�eœm°FÐ;Ñ;Ô;€AÝŒ9˜˜Q ™U a™K™¨AÑ-Ð.°!°a±%¸!±)¸c±/ÑBÑCÔCÐCr   c                  óê   — e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   ded	<   ded
<   ded<   ded<   ded<   ded<   eeeddœd/d„¦   «         Zed0d„¦   «         Z	d1d „Z
d2d%„Zd3d*„Zd4d+„Zd5d-„Zd.S )6ÚTiledFusionPlanr   ÚframesÚheightÚwidthÚtile_framesÚtile_heightÚ
tile_widthr   ÚwindowsÚskipszlist[list[tuple[int, int]]]Úgridsr1   Útime_weightÚweightsúlist[torch.Tensor]Úweight_sumsr   )ÚoverlapÚ	blend_varÚ
grid_cycler/   r0   rJ   r.   rK   rL   r
   ú'TiledFusionPlan'c               ó(  ‡‡‡‡‡‡‡‡— t          ‰‰¦  «        t          ‰‰¦  «        cŠŠt          dt          ‰|z  ¦  «        ¦  «        t          dt          ‰|z  ¦  «        ¦  «        }}t          ‰‰|¦  «        t          ‰‰|¦  «        cŠŠt	          ‰¦  «        dk    r‰‰d         ‰d         z
  z
  n‰}t	          ‰¦  «        dk    r‰‰d         ‰d         z
  z
  n‰}t          t
          t          dt          ||z
  ||z
  ¦  «        ¦  «        ¦  «        }|
dk    r	|dk     rdgn!d||f|dfd|fgdt          d|
¦  «        …         }ˆˆˆˆˆˆfd„|D ¦   «         }d‰cxk     o|k     nc }|rYt          |‰t          dt          ‰|z  ¦  «        ¦  «        ¦  «        Šˆˆfd„t          t	          ‰¦  «        ¦  «        D ¦   «         }n	|dgdgcŠŠ}t	          ‰¦  «        dk    rt          ‰|	|¦  «        nt          j	        ‰|¬¦  «        }|dd…ddf         t          ‰|	|¦  «        dd…df         z  t          ‰|	|¦  «        ddd…f         z  }g }|D ]¬}t          j
        |‰‰ft          j        |¬	¦  «        }t          ‰|¦  «        D ]:\  }}|D ]2\  }}|||z   |‰z   …||‰z   …||‰z   …fxx         ||d…         z  cc<   Œ3Œ;|                     |                     d
¦  «                             d¦  «        ¦  «         Œ­ | |‰‰‰‰‰‰|||||¦  «        S )z\All sizes are latent units. ``tile_frames <= 0`` or ``>= frames`` keeps one temporal extent.r   r   r   )r   r   Nc           	     óZ   •‡— g | ]&\  Š}ˆˆˆˆfd „t          ‰‰‰|¦  «        D ¦   «         ‘Œ'S )c                óB   •— g | ]}t          ‰‰‰‰¦  «        D ]}||f‘ŒŒS r   ©r,   )r   Úyr9   ÚoxrB   r?   Úxss      €€€€r   r   z4TiledFusionPlan.build.<locals>.<listcomp>.<listcomp>V   s=   ø€ ÐsÐsÐs˜QÕPWÐXZÐ\aÐcmÐoqÑPrÔPrÐsÐsÈ1�1�a�&ÐsÐsÐsÐsr   rQ   )	r   ÚoyrS   r>   rA   rB   r?   rT   Úyss	     @€€€€€€r   r   z)TiledFusionPlan.build.<locals>.<listcomp>V   s_   øø€ ð  Kð  Kð  KÑx~ÐxzÐ|~ÐsÐsÐsÐsÐsÐsÐs¥'¨"¨f°kÀ2Ñ"FÔ"FÐsÑsÔsð  Kð  Kð  Kr   c                óf   •— g | ]-}t          |d k    o‰|         ‰|dz
           ‰z   k     ¦  «        ‘Œ.S r&   )r   )r   Úwr@   rC   s     €€r   r   z)TiledFusionPlan.build.<locals>.<listcomp>[   sA   ø€ ÐkÐkÐkÐRS•S˜˜QšÐL 7¨1¤:°¸¸A¹´ÀÑ0LÒ#LÑMÔMÐkÐkÐkr   )r/   r3   gê-�™—q=éÿÿÿÿ)r   r   r   r!   r'   ÚMAX_GRID_SHIFTr    r:   r5   ÚonesÚzerosr7   ÚzipÚappendÚ
clamp_min_Ú	unsqueeze) Úclsr=   r>   r?   rA   rB   r@   r/   rJ   rK   rL   Úmin_overlap_yÚmin_overlap_xÚ	overlap_yÚ	overlap_xr#   ÚoffsetsrE   ÚtemporalrD   rF   rG   rI   ÚgridÚ
weight_sumÚt0ÚskipÚy0Úx0rC   rT   rV   s      `````                      @@@r   ÚbuildzTiledFusionPlan.buildL   sf  øøøøøøøø€ õ #& k°6Ñ":Ô":½CÀ
ÈEÑ<RÔ<RÐˆ�ZÝ'*¨1­c°+ÀÑ2GÑ.HÔ.HÑ'IÔ'IÍ3ÈqÕRUÐV`ÐcjÑVjÑRkÔRkÑKlÔKl�}ˆÝ˜6 ;°Ñ>Ô>Å	È%ÐQ[Ð]jÑ@kÔ@kˆˆˆBÝ58¸±W´W¸q²[°[�K 2 a¤5¨2¨a¬5¡=Ñ1Ð1Àkˆ	Ý47¸±G´G¸a²K°K�J " Q¤%¨"¨Q¬%¡-Ñ0Ð0ÀZˆ	Ý•^¥S¨­C°	¸MÑ0IÈ9ÐWdÑKdÑ,eÔ,eÑ%fÔ%fÑgÔgˆØ(¨1šn˜n°¸!²°�6�(�(À&È6ÐSYÐJZÐ]cÐefÐ\gÐjkÐmsÐitÐAuð  wKÕx{Ð|}ð  @Jñ  yKô  yKð  wKô  BLˆð Kð  Kð  Kð  Kð  Kð  Kð  Kð  Kð  Kð  CJð  Kñ  Kô  Kˆà�{Ð+Ð+Ò+Ð+ VÒ+Ð+Ð+Ð+ˆØð 	;Ý ¨µS¸½CÀÈgÑ@UÑ<VÔ<VÑ5WÔ5WÑXÔXˆGØkÐkÐkÐkÐkÕW\Õ]`ÐahÑ]iÔ]iÑWjÔWjÐkÑkÔkˆEˆEà*0°1°#¸°sÐ'ˆK˜ %ÝILÈWÉÌÐXYÒIYÐIY•o k°9¸fÑEÔEÐEÕ_dÔ_iÐjuð  Eð  `Fñ  `Fô  `FˆØ˜a˜a˜a  t˜mÔ,­¸{ÈIÐW]Ñ/^Ô/^Ð_`Ð_`Ð_`ÐbfÐ_fÔ/gÑgÕjyð  {Eð  GPð  RXñ  kYô  kYð  Z^ð  `að  `að  `að  Zaô  kbñ  bˆàˆØð 	Kð 	KˆDÝœ f¨f°eÐ%<ÅEÄMÐZ`ÐaÑaÔaˆJÝ ¨Ñ/Ô/ð |ð |‘��DØ"ð |ð |‘F�B˜Ø˜r D™y¨2°Ñ+;Ð;¸RÀ"À{ÑBRÐ=RÐTVÐY[Ð^hÑYhÐThÐhÐiÐiÔiÐmtÐuyÐuzÐuzÔm{Ñ{ÐiÐiÑiÐið|à×Ò˜z×4Ò4°UÑ;Ô;×EÒEÀbÑIÔIÑJÔJÐJÐJØˆs�6˜6 5¨+°{ÀJÐPWÐY^Ð`eÐgrÐt{ð  ~Iñ  Jô  Jð  	Jr   c                ó`   — t          | j        ¦  «        t          | j        d         ¦  «        z  S )Nr   )r'   rC   rE   )Úselfs    r   Útiles_per_stepzTiledFusionPlan.tiles_per_stepj   s%   € å�4”<Ñ Ô ¥3 t¤z°!¤}Ñ#5Ô#5Ñ5Ð5r   r	   úlist[tuple[int, int, int, int]]c                óH   ‡ ‡— ˆ ˆfd„t          ‰ j        ¦  «        D ¦   «         S )zD``(window_index, t0, y0, x0)`` for every tile evaluated at ``step``.c                ór   •— g | ]3\  }}‰j         ‰t          ‰j         ¦  «        z           D ]\  }}||||f‘ŒŒ4S r   )rE   r'   )r   Úwindowrj   rl   rm   rp   r	   s        €€r   r   z)TiledFusionPlan.tiles.<locals>.<listcomp>p   sq   ø€ ð  Að  Að  A©¨°Ð]aÔ]gÐhlÕorÐswÔs}Ño~Ôo~Ñh~Ô]ð  Að  AÑSYÐSUÐWY�˜˜R Ð$ð  Að  Að  Að  Ar   )r+   rC   )rp   r	   s   ``r   ÚtileszTiledFusionPlan.tilesn   sF   øø€ ð Að  Að  Að  Að  AµyÀÄÑ7NÔ7Nð  Añ  Aô  Að  	Ar   r   rj   rl   rm   c                óZ   — |d d …||| j         z   …||| j        z   …||| j        z   …f         S ©N)r@   rA   rB   )rp   r   rj   rl   rm   s        r   ÚcropzTiledFusionPlan.cropr   sD   € Ø�a�a�a˜˜b 4Ô#3Ñ3Ð3°R¸"¸tÔ?OÑ:OÐ5OÐQSÐVXÐ[_Ô[jÑVjÐQjÐjÔkÐkr   Úaccumulatorr   ru   ÚNonec           	     ó  — | j         |         | j        |         }}|dd…||z   || j        z   …||| j        z   …||| j        z   …fxx         |dd…|d…f                              ¦   «         | j        |d…dd…dd…df         z  z  cc<   dS )zPAdd a weighted ``(B, tile_frames, tile_height, tile_width, C)`` tile prediction.N)rC   rD   r@   rA   rB   r.   rG   )rp   rz   r   ru   rl   rm   rj   rk   s           r   Ú
accumulatezTiledFusionPlan.accumulateu   s+  € à”< Ô'¨¬°FÔ);ˆDˆØ�A�A�A�r˜D‘y 2¨Ô(8Ñ#8Ð8¸"¸rÀDÔDTÑ?TÐ:TÐVXÐ[]Ð`dÔ`oÑ[oÐVoÐoÐpÐpÔpÐtxÐyzÐyzÐyzð  }Að  }Bð  }Bð  zBô  uC÷  uIò  uIñ  uKô  uKð  NRô  NZð  [_ð  [`ð  [`ð  bcð  bcð  bcð  efð  efð  efð  hlð  [lô  Nmñ  umñ  	mÐpÐpÑpÐpÐpr   c                ól   — |                      | j        |t          | j        ¦  «        z           ¦  «        S rx   )Údiv_rI   r'   rE   )rp   rz   r	   s      r   Ú	normalizezTiledFusionPlan.normalizez   s+   € Ø×Ò Ô 0°½¸D¼J¹¼Ñ1GÔ HÑIÔIÐIr   Úwindow_latentsc           
     ót  — | j         |d         }}t          j        |j        d         | j        g|j        dd…         ¢R t          j        |j        ¬¦  «        }t          j        | j        t          j        |j        ¬¦  «        }t          || j        | j	        ¦  «        D ]y\  }}}|dd…||z   || j
        z   …fxx         |dd…|d…f                              ¦   «         ||d…dddf         z  z  cc<   |||z   || j
        z   …xx         ||d…         z  cc<   Œz|                     |ddd…dddf         ¦  «        S )zhMerge full-width ``(B, tile_frames, H, W, C)`` window latents into one canvas with the temporal weights.r   r   Nr3   )rF   r5   r\   Úshaper=   r7   r/   r]   rC   rD   r@   r.   r   )	rp   r�   rF   Úfirstr   ri   Úlatentrj   rk   s	            r   Úblend_windowszTiledFusionPlan.blend_windows}   sd  € à!Ô-¨~¸aÔ/@�UˆÝ”˜eœk¨!œn¨d¬kÐL¸E¼KÈÈÈ¼OÐLÐLÕTYÔTaÐjoÔjvÐwÑwÔwˆÝ”[ ¤µE´MÈ%Ì,ÐWÑWÔWˆ
Ý # N°D´LÀ$Ä*Ñ MÔ Mð 	Pð 	PÑˆF�B˜Ø�1�1�1�b˜4‘i " tÔ'7Ñ"7Ð7Ð7Ð8Ð8Ô8¸FÀ1À1À1ÀdÀeÀeÀ8Ô<L×<RÒ<RÑ<TÔ<TÐWbÐcgÐchÐchÐjnÐptÐvzÐczÔW{Ñ<{Ñ{Ð8Ð8Ñ8Ø�r˜D‘y 2¨Ô(8Ñ#8Ð8Ð9Ð9Ô9¸[ÈÈÈÔ=OÑOÐ9Ð9Ñ9Ð9Ø�{Š{˜: d¨A¨A¨A¨t°T¸4Ð&?Ô@ÑAÔAÐAr   N)r=   r   r>   r   r?   r   rA   r   rB   r   r@   r   r/   r0   rJ   r.   rK   r.   rL   r   r
   rM   )r
   r   )r	   r   r
   rr   )
r   r1   rj   r   rl   r   rm   r   r
   r1   )rz   r1   r   r1   ru   r   rl   r   rm   r   r
   r{   )rz   r1   r	   r   r
   r1   )r�   rH   r
   r1   )Ú__name__Ú
__module__Ú__qualname__Ú__annotations__ÚclassmethodÚDEFAULT_OVERLAPÚDEFAULT_BLEND_VARrn   Úpropertyrq   rv   ry   r}   r€   r†   r   r   r   r<   r<   =   sw  € € € € € € à€K€K�KØ€K€K�KØ€J€J�JØÐÐÑØÐÐÑØ€O€O�OØÐÐÑØÐÐÑØ&Ð&Ð&Ñ&ØÐÐÑØÐÐÑØ#Ð#Ð#Ñ#àð Yhð  }Nð  bcð Jð Jð Jð Jð Jñ „[ðJð: ð6ð 6ð 6ñ „Xð6ðAð Að Að Aðlð lð lð lðmð mð mð mð
Jð Jð Jð JðBð Bð Bð Bð Bð B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   r-   r.   r/   r0   r
   r1   )Ú__doc__Ú
__future__r   Údataclassesr   r5   Ú
FRAME_STEPrŒ   r�   rZ   r   r!   r,   r:   r<   r   r   r   ú<module>r“      s  ððð ð #Ð "Ð "Ð "Ð "Ð "à !Ð !Ð !Ð !Ð !Ð !à €€€à€
Ø€ØÐ Ø€ð %/ð 5ð 5ð 5ð 5ð 5ð	/ð 	/ð 	/ð 	/ð~ð ~ð ~ð ~ð
Dð Dð Dð Dð
 ðGBð GBð GBð GBð GBñ GBô GBñ „ðGBð GBð GBr   