ó
    KëgjÄ  ã                   ó  • S r SSKrSSKJr  SSKJrJr  SSKJ	r	J
r
Jr   " S S\R                  R                  5      r\R                  R                     SS\R"                  S\	S	\R"                  S-  S
\R"                  S-  4S jj5       rg)av  
Context Parallel support for Token Shift.

Token shift has a 1-token dependency on previous tokens:
    y[t] = x[t-1] - x[t]  (for t > 0)
    y[0] = cache - x[0]   (cache is the last token from previous rank)

In CP mode, non-first ranks need the last token from the previous rank as cache.
Backward: non-last ranks need to send the last token's gradient to previous rank.
é    N)Útoken_shift_bwdÚtoken_shift_fwd)ÚFLACPContextÚconv_cp_send_recv_bwdÚconv_cp_send_recv_fwdc                   óÄ  • \ rS rSrSr\S\R                  S\R                  S-  S\S\	R                  S-  S\\R                  S-  \4   4
S	 j5       r\ SS
\R                  S\R                  S-  S\	R                  S-  S\S\SS4S jj5       r\S\R                  S\R                  S-  S\R                  S-  S\S-  4S j5       r\S\R                  4S j5       rSrg)ÚTokenShiftCPFunctioné   a$  
Context Parallel version of TokenShift.

Forward:
    1. Get last token from previous rank to construct cache
    2. Call token_shift_fwd with cache

Backward:
    1. Call token_shift_bwd to get dx
    2. Sync communication: add next rank's first token gradient to current rank's last token
ÚxÚ
cu_seqlensNÚcontextÚgroupÚreturnc                 ó@  • Uc  gU R                   S   nSnSnUR                  (       dÅ  U R                  5       S:X  a  U R                   S   S:X  d   SU R                    35       eU R                  S5      nUSS R	                  5       n[        Xƒ5      n	Ub  [        U5      S-
  OSn
[        R                  " X¤U R                  U R                  S9n[        US	S5      nUS:”  a  U	S   US'   XV4$ U R                  S5      nUSS R	                  5       n[        Xƒ5      nXV4$ )
am  Prepare cache for CP forward pass by communicating with previous rank.

Args:
    x: Input tensor of shape [1, T, D]
    cu_seqlens: Cumulative sequence lengths
    context: CP context
    group: Process group for communication

Returns:
    cache: Cache tensor of shape [N, D] or None
    pre_num_tokens: Number of tokens from previous rank for the first sequence
N)Nr   éÿÿÿÿr   é   é   zCP requires [1, T, D], got ©ÚdeviceÚdtypeÚpre_num_conv_tokens)ÚshapeÚis_first_rankÚdimÚsqueezeÚ
contiguousr   ÚlenÚtorchÚzerosr   r   Úgetattr)r   r   r   r   ÚDÚcacheÚpre_num_tokensÚx_2dÚ
last_tokenÚprev_last_tokenÚNÚ_s               Ú¨C:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\fla/modules/token_shift_cp.pyÚ_prepare_cache_for_cpÚ*TokenShiftCPFunction._prepare_cache_for_cp'   s&  € ð& ‰=Øà�G‰G�B‰KˆØˆØˆà×$×$à—5‘5“7˜a“< A§G¡G¨A¡J°!£OÐ\Ð7RÐST×SZÑSZÐR[Ð5\Ó\Ð3Ø—9‘9˜Q“<ˆDØ˜b˜c˜×-Ñ-Ó/ˆJÜ3°JÓFˆOð (2Ñ'=”�J“ !Ò#À1ˆAÜ—K’K ¨Q¯X©X¸Q¿W¹WÑEˆEô % WÐ.CÀQÓGˆNØ Ó!à*¨1Ñ-��a‘ð Ð$Ð$ð	 —9‘9˜Q“<ˆDØ˜b˜c˜×-Ñ-Ó/ˆJÜ% jÓ8ˆAàÐ$Ð$ó    ÚdxÚ
grad_cacher   r#   c                 óê   • Uc  gU R                   S   nUb  US:”  a  USS nO*[        R                  " SXPR                  U R                  S9n[        Xb5      nU SSSS24   R                  US   5        g)a=  Correct dx gradients for CP backward pass.

Args:
    dx: Gradient tensor to be corrected, shape [1, T, D]
    grad_cache: Gradient w.r.t. cache, shape [N, D] or None
    group: Process group
    is_first_rank: Whether this is the first rank
    pre_num_tokens: Number of tokens from previous rank for first sequence
Nr   r   r   r   )r   r   r   r   r   r   Úadd_)r-   r.   r   r   r#   r!   Úd_cacheÚ	recv_grads           r)   Ú_correct_dx_for_cpÚ'TokenShiftCPFunction._correct_dx_for_cpZ   sw   € ð" ‰=Øà�H‰H�R‰Lˆð Ñ! n°qÓ&8à   1�o‰Gä—k’k ! Q¯y©yÀÇÁÑIˆGô *¨'Ó9ˆ	ð 	ˆ1ˆb’!ˆ8‰×Ñ˜) A™,Õ'r,   Úchunk_indicesÚ
cp_contextc                 ó,  • Uc  [        S5      eUR                  nUR                  n[        R	                  UUUUS9u  pgX l        X0l        XPl        US LU l        UR                  U l        Xpl        [        UUUSUS9u  p‰p«nX�l
        X l        X°l        U$ )Nz4cp_context must be provided for TokenShiftCPFunction)r   r   r   r   T)r   r   r"   Úoutput_cacher5   )Ú
ValueErrorr   r   r	   r*   r5   Ú	has_cacher   r#   r   r'   ÚTÚuse_short_kernel)Úctxr   r   r5   r6   r   r"   r#   Úyr'   r;   r<   Ú	cache_outs                r)   ÚforwardÚTokenShiftCPFunction.forward}   s¾   € ð ÑÜÐSÓTÐTà×*Ñ*ˆ
Ø× Ñ ˆô !5× JÑ JØØ!ØØð	 !Kð !
Ñˆð $ŒØ)ÔØŒ	Ø TÐ)ˆŒØ&×4Ñ4ˆÔØ+Ôô 0?ØØ!ØØØ'ñ0
Ñ,ˆˆa 9ð ŒØŒØ/Ôàˆr,   Údyc                 ó  • U R                   nS n[        UU R                  U R                  UU R                  U R
                  U R                  U R                  S9u  pE[        R                  UUUU R                  U R                  S9  US S S 4$ )N)rB   r'   r;   Údcacher   r<   Úhas_init_cacher5   )r-   r.   r   r   r#   )r   r   r'   r;   r   r<   r:   r5   r	   r3   r   r#   )r=   rB   r   rD   r-   r.   s         r)   ÚbackwardÚTokenShiftCPFunction.backwardª   s•   € à—	‘	ˆð
 ˆô )ØØ�e‰eØ�e‰eØØ—~‘~Ø ×1Ñ1ØŸ=™=Ø×+Ñ+ñ	
‰ˆô 	×/Ñ/ØØ!ØØ×+Ñ+Ø×-Ñ-ð 	0ñ 	
ð �4˜˜tÐ#Ð#r,   © )r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ústaticmethodr   ÚTensorr   ÚdistÚProcessGroupÚtupleÚintr*   Úboolr3   r@   rF   Ú__static_attributes__rH   r,   r)   r	   r	      sT  † ñ
ð ð0%Ø�<‰<ð0%à—L‘L 4Ñ'ð0%ð ð0%ð × Ñ  4Ñ'ð	0%ð
 
ˆu�|‰|˜dÑ" CÐ'Ñ	(ó0%ó ð0%ðd ð  ñ (Ø�L‰Lð (à—L‘L 4Ñ'ð (ð × Ñ  4Ñ'ð (ð ð	 (ð
 ð (ð 
ô (ó ð (ðD ð*à�<‰<ð*ð —L‘L 4Ñ'ð*ð —|‘| dÑ*ð	*ð
 ! 4Ñ'ó*ó ð*ðX ð$˜%Ÿ,™,ó $ó ó$r,   r	   r   r6   r   r5   c                 ór   • Uc  [        S5      eUR                  c   S5       e[        R                  XX15      $ )a@  
Context Parallel version of token_shift.

Args:
    x: Input tensor of shape [1, T, D]
    cp_context: CP context (required for CP mode)
    cu_seqlens: Cumulative sequence lengths
    chunk_indices: Chunk indices for variable-length sequences

Returns:
    output: Tensor of shape [1, T, D] after applying token-shift
z.cp_context must be provided for token_shift_cpz.cu_seqlens must be provided for token_shift_cp)r9   r   r	   Úapply)r   r6   r   r5   s       r)   Útoken_shift_cprX   Ë   sF   € ð& ÑÜÐIÓJÐJà× Ñ Ñ,Ð^Ð.^Ó^Ð,ä×%Ñ%Ø	�}óð r,   )NN)rM   r   Útorch.distributedÚdistributedrP   Úfla.modules.token_shiftr   r   Ú
fla.ops.cpr   r   r   ÚautogradÚFunctionr	   ÚcompilerÚdisablerO   rX   rH   r,   r)   Ú<module>ra      s”   ðñ	ó Ý  ç Dß QÑ Qôn$˜5Ÿ>™>×2Ñ2ô n$ðb ‡�×Ñð '+Ø)-ñ	Ø‡|�|ðàðð —‘˜tÑ#ðð —<‘< $Ñ&ô	ó ñr,   