Ë
    ÄÓ^jÊ,  ã                   ó  — d dl Z d dlmZ d dlZd dlmZ d dlmZmZm	Z	m
Z
 d dlmZ d„ Zdd„Zd„ Zdd	„Zd
„ Ze j$                  ded   fd„«       Ze j$                  ded   fd„«       Ze j$                  ded   fd„«       Zy)é    N)Ú	Generator)Úglobal_decomposition_table)Ú_rnn_helperÚgather_paramsÚgru_cellÚ	lstm_cell)Ú
while_loopc                 óÆ   ‡— g }g }| D ]M  Š‰�$t        ˆfd„|D «       «      r‰j                  «       Š|j                  ‰«       ‰€Œ=|j                  ‰«       ŒO t        |«      S )Nc              3   ó^   •K  — | ]$  }t         j                  j                  ‰|«      –— Œ& y ­w)N)ÚtorchÚ_CÚ	_overlaps)Ú.0Úseen_tensorÚtensors     €ú`/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/torch/export/_patches.pyú	<genexpr>z,_clone_tensors_that_alias.<locals>.<genexpr>   s'   øè ø€ ò &
Ø8CŒE�H‰H×Ñ˜v {×3ñ&
ùs   ƒ*-)ÚanyÚcloneÚappendÚtuple)ÚtensorsÚcloned_tensorsÚseen_tensorsr   s      @r   Ú_clone_tensors_that_aliasr   
   st   ø€ ð €NØ€LØò (ˆØÐ¤#ó &
ØGSô&
ô #
ð —\‘\“^ˆFØ×Ñ˜fÔ%ØÑØ×Ñ Õ'ð(ô �Ó Ð ó    c                 ó*  ‡‡‡‡— |d   }|d   Š|r|d   nd}|r|d   ndŠt        |«      dk(  r|d   nt        |«      dk(  r|d   ndŠ|d   j                  d«      }|d   j                  d«      }t        j                  j                  j                  | ||«      Š|r‰j                  d«      n‰Št        ‰‰‰f«      \  ŠŠŠt        j                  ‰j                  d«      gt        |j                  dd «      ¢­|j                  |j                  dœŽ}	ˆfd	„}
ˆˆˆˆfd
„}t        j                  dt        j                  ¬«      }t!        |
|||	||g«      \  }}}}|r|j                  d«      }||j#                  d«      |j#                  d«      ffS )ay  
    1 layer fn for while loop LSTM

    Args:
        inp: Input tensor of shape (seq_len, batch, input_size)
        hidden: Tuple of (hx, cx) hidden states
        params: List of weight and bias tensors
        has_biases: Whether biases are included
        reverse: Whether to process sequence in reverse

    Returns:
        Tuple of (output, (final_hx, final_cx))
    r   é   é   Né   é   é   ©ÚdtypeÚdevicec                 ó,   •— | ‰j                  d«      k  S ©Nr   ©Úsize)ÚiÚoutÚhxÚcxÚprecomputed_inputs       €r   Úcond_fnz*one_layer_while_loop_lstm.<locals>.cond_fnA   ó   ø€ ØÐ$×)Ñ)¨!Ó,Ñ,Ð,r   c           	      ó*  •— | j                  «       }t        j                  |«       t        j                  |‰j                  d«      dz
  ¬«       t	        ‰|   ||‰‰‰d¬«      \  }}|j                  «       }|j                  d«      ||<   | dz   |||fS )Nr   r   ©Úmaxr   )Ú	chunk_dim)Úitemr   Ú_check_is_sizer)   r   r   Úsqueeze)	Úidxr+   r,   r-   r*   Úhh_biasÚ	hh_weightÚ	hr_weightr.   s	        €€€€r   Úbody_fnz*one_layer_while_loop_lstm.<locals>.body_fnD   s‘   ø€ à�H‰H‹JˆÜ×Ñ˜QÔÜ×Ñ˜QÐ$5×$:Ñ$:¸1Ó$=ÀÑ$AÕBÜØ˜aÑ  " b¨)°W¸iÐSTô
‰ˆˆBð �i‰i‹kˆà—‘˜A“ˆˆA‰Ø�Q‰w˜˜R Ð#Ð#r   ©r$   )ÚlenÚ	unsqueezer   ÚnnÚ
functionalÚlinearÚflipr   Úemptyr)   r   Úshaper$   r%   r   Úint64r	   r7   )ÚinpÚhiddenÚparamsÚ
has_biasesÚreverseÚ	ih_weightÚih_biasr,   r-   Ústep_outputr/   r<   ÚcntÚ_r+   Úfinal_hxÚfinal_cxr9   r:   r;   r.   s                    @@@@r   Úone_layer_while_loop_lstmrS      s›  û€ ð �q‘	€IØ�q‘	€IÙ%ˆf�QŠi¨4€GÙ%ˆf�QŠi¨4€Gä˜“[ AÒ%ˆˆqŠ	¼¸F»ÀqÒ8H¨6°!ª9Èdð ð 
�‰×	Ñ	˜QÓ	€BØ	�‰×	Ñ	˜QÓ	€BäŸ™×+Ñ+×2Ñ2°3¸	À7ÓKÐÙ5<Ð)×.Ñ.¨qÔ1ÐBSÐÜ$=Ø	�G˜YÐ'ó%Ñ!€Iˆw˜	ô
 —+‘+Ø×Ñ˜qÓ!ðä	ˆr�x‰x˜˜ˆ|Ó	ñð �h‰hØ�y‰yò	€Kô-÷$ô �,‰,�q¤§¡Ô
,€CÜ!+Ø�˜3 ¨R°Ð4ó"Ñ€A€sˆH�hñ Ø�h‰h�q‹kˆà�×!Ñ! !Ó$ h×&6Ñ&6°qÓ&9Ð:Ð:Ð:r   c	                 ó”  — t        |«      dk7  rt        d«      ‚t        |||d   j                  d«      |d   j                  d«      k7  «      }t	        t        |d   |d   «      «      }	t        }
t        | |	||||||||
«
      \  }}t	        t        |Ž «      }|t        j                  |d   d«      t        j                  |d   d«      fS )aª  
    LSTM implementation using while_loop for export compatibility.

    This is a drop-in replacement for the default LSTM decomposition that uses
    while_loop instead of Python loops, making it more suitable for torch.export.

    Args:
        input: Input tensor
        hx: Tuple of (h0, c0) hidden states
        params: List of weight and bias tensors
        has_biases: Whether biases are included
        num_layers: Number of LSTM layers
        dropout: Dropout probability
        train: Training mode
        bidirectional: Whether to use bidirectional LSTM
        batch_first: Whether batch dimension is first

    Returns:
        Tuple of (output, h_n, c_n)
    r   zlstm expects two hidden statesr   r   )
r>   ÚAssertionErrorr   r)   ÚlistÚziprS   r   r   Ústack©Úinputr,   rI   rJ   Ú
num_layersÚdropoutÚtrainÚbidirectionalÚbatch_firstrH   Úlayer_fnr+   Úfinal_hiddenss                r   Úlstm_while_loop_implrb   [   sÐ   € ô> ˆ2ƒw�!‚|ÜÐ=Ó>Ð>Ü˜6 :¨r°!©u¯z©z¸!«}ÀÀ1ÁÇ
Á
È1ÃÑ/MÓN€FÜ”#�b˜‘e˜R ™UÓ#Ó$€FÜ(€HÜ$ØØØØØØØØØØóÑ€Cˆô œ˜mÐ,Ó-€MØ”—‘˜M¨!Ñ,¨aÓ0´%·+±+¸mÈAÑ>NÐPQÓ2RÐRÐRr   c                 ó~  ‡‡‡— |d   }|d   Š|r|d   nd}|r|d   ndŠt         j                  j                  j                  | ||«      Š|r‰j	                  d«      n‰Št        ‰‰f«      \  ŠŠ|j                  d«      }t        j                  ‰j                  d«      gt        |j                  dd «      ¢­|j                  |j                  dœŽ}ˆfd„}	ˆˆˆfd„}
t        j                  dt         j                  ¬	«      }t        |	|
|||g«      \  }}}|r|j	                  d«      }||j!                  d«      fS )
ad  
    1 layer fn for while loop GRU

    Args:
        inp: Input tensor of shape (seq_len, batch, input_size)
        hidden: Hidden state tensor
        params: List of weight and bias tensors
        has_biases: Whether biases are included
        reverse: Whether to process sequence in reverse

    Returns:
        Tuple of (output, final_hidden)
    r   r   r   Nr    r#   c                 ó,   •— | ‰j                  d«      k  S r'   r(   )r*   r+   Ú
cur_hiddenr.   s      €r   r/   z)one_layer_while_loop_gru.<locals>.cond_fn¯   r0   r   c                 ó  •— | j                  «       }t        j                  |«       t        j                  |‰j                  d«      dz
  ¬«       t	        ‰|   |d d ‰‰«      }|j                  «       }|j                  d«      ||<   | dz   ||fS )Nr   r   r2   )r5   r   r6   r)   r   r   r7   )r8   r+   re   r*   r9   r:   r.   s       €€€r   r<   z)one_layer_while_loop_gru.<locals>.body_fn²   s‹   ø€ à�H‰H‹JˆÜ×Ñ˜QÔÜ×Ñ˜QÐ$5×$:Ñ$:¸1Ó$=ÀÑ$AÕBÜØ˜aÑ  *¨d°D¸)ÀWó
ˆ
ð �i‰i‹kˆØ×#Ñ# AÓ&ˆˆA‰Ø�Q‰w˜˜ZÐ'Ð'r   r=   )r   r@   rA   rB   rC   r   r?   rD   r)   r   rE   r$   r%   r   rF   r	   r7   )rG   rH   rI   rJ   rK   rL   rM   re   rN   r/   r<   rO   rP   r+   Úfinal_hiddenr9   r:   r.   s                  @@@r   Úone_layer_while_loop_grurh   �   s>  ú€ ð �q‘	€IØ�q‘	€IÙ%ˆf�QŠi¨4€GÙ%ˆf�QŠi¨4€GäŸ™×+Ñ+×2Ñ2°3¸	À7ÓKÐÙ5<Ð)×.Ñ.¨qÔ1ÐBSÐÜ2°I¸wÐ3GÓHÑ€IˆwØ×!Ñ! !Ó$€Jô —+‘+Ø×Ñ˜qÓ!ðä	ˆz×Ñ  Ð#Ó	$ñð ×ÑØ× Ñ ò	€Kô-ö
(ô �,‰,�q¤§¡Ô
,€CÜ% g¨w¸¸kÈ:Ð8VÓWÑ€A€sˆLÙØ�h‰h�q‹kˆà�×$Ñ$ QÓ'Ð'Ð'r   c	                 óº   — t        ||d«      }t        |j                  d«      «      }	t        }
t	        | |	||||||||
«
      \  }}|t        j                  |d«      fS )a•  
    GRU implementation using while_loop for export compatibility.

    This is a drop-in replacement for the default GRU decomposition that uses
    while_loop instead of Python loops, making it more suitable for torch.export.

    Args:
        input: Input tensor
        hx: Hidden state tensor
        params: List of weight and bias tensors
        has_biases: Whether biases are included
        num_layers: Number of GRU layers
        dropout: Dropout probability
        train: Training mode
        bidirectional: Whether to use bidirectional GRU
        batch_first: Whether batch dimension is first

    Returns:
        Tuple of (output, h_n)
    Fr   )r   rV   Úunbindrh   r   r   rX   rY   s                r   Úgru_while_loop_implrk   Æ   sn   € ô> ˜6 :¨uÓ5€FÜ�"—)‘)˜A“,Ó€FÜ'€HÜ$ØØØØØØØØØØóÑ€Cˆð ”—‘˜M¨1Ó-Ð-Ð-r   Úreturn)NNNc              #   ón  K  — t         d   }|j                  | d«      }| j                  j                  t        j                  j
                  j                  d«      }	 ||| <   || j                  t        j                  j
                  j                  <   d–— |�||| <   n|j                  | d«       |�2|| j                  t        j                  j
                  j                  <   y| j                  j                  t        j                  j
                  j                  d«       y# |�||| <   n|j                  | d«       |�2|| j                  t        j                  j
                  j                  <   w | j                  j                  t        j                  j
                  j                  d«       w xY w­w)a†  
    Generic context manager for registering while_loop-based RNN decompositions.

    Args:
        rnn_op: The aten operation to patch (e.g., torch.ops.aten.lstm.input)
        rnn_impl: The while_loop-based implementation function

    Note:
        This is an internal helper. Use register_lstm_while_loop_decomposition()
        or register_gru_while_loop_decomposition() instead.
    Úpost_autogradN)r   ÚgetÚ
py_kernelsr   r   ÚDispatchKeyÚCompositeImplicitAutogradÚpop)Úrnn_opÚrnn_implÚregistryÚoriginal_decompÚoriginal_py_kernels        r   Ú&_register_rnn_while_loop_decompositionry   ÷   sr  è ø€ ô *¨/Ñ:€Hð —l‘l 6¨4Ó0€Oð  ×*Ñ*×.Ñ.Ü�‰×Ñ×6Ñ6¸óÐðXà#ˆ�ÑØLTˆ×Ñœ%Ÿ(™(×.Ñ.×HÑHÑIÛð Ð&Ø.ˆH�VÒð �L‰L˜ Ô&ð Ð)à"ð ×ÑœeŸh™h×2Ñ2×LÑLÒMð
 ×Ñ×!Ñ!¤%§(¡(×"6Ñ"6×"PÑ"PÐRVÕWøð Ð&Ø.ˆH�VÒð �L‰L˜ Ô&ð Ð)à"ð ×ÑœeŸh™h×2Ñ2×LÑLÒMð
 ×Ñ×!Ñ!¤%§(¡(×"6Ñ"6×"PÑ"PÐRVÕWüs    ‚AF5Á:D$ ÂBF5Ä$BF2Æ2F5c               #   ó¶   K  — t        t        j                  j                  j                  j
                  t        «      5  d–— ddd«       y# 1 sw Y   yxY w­w)aŽ  
    Context manager that temporarily registers the while_loop-based LSTM decomposition.

    The while_loop-based decomposition is more suitable for export and graph-based
    execution, as it avoids Python control flow that cannot be captured in the graph.
    This should support dynamic sequence lengths, however as while_loop does not
    support Autograd yet, an ExportedProgram created with this will not be trainable.

    Usage::

        from torch.export._patches import register_lstm_while_loop_decomposition
        from torch.export import export

        with register_lstm_while_loop_decomposition():
            # Export your model with LSTM
            ep = export(model, (x, h0, c0))

    Note:
        This context manager temporarily modifies the global decomposition table
        and py_kernels registration. The original registrations are restored when
        exiting the context.
    N)ry   r   ÚopsÚatenÚlstmrZ   rb   © r   r   Ú&register_lstm_while_loop_decompositionr   '  sC   è ø€ ô0 
0Ü�	‰	�‰×Ñ×!Ñ!Ô#7ó
ñ ó 	÷÷ ñ üó   ‚=A¿AÁ	AÁAÁAc               #   ó¶   K  — t        t        j                  j                  j                  j
                  t        «      5  d–— ddd«       y# 1 sw Y   yxY w­w)a†  
    Context manager that temporarily registers the while_loop-based GRU decomposition.

    The while_loop-based decomposition is more suitable for export and graph-based
    execution, as it avoids Python control flow that cannot be captured in the graph.
    This should support dynamic sequence lengths, however as while_loop does not
    support Autograd yet, an ExportedProgram created with this will not be trainable.

    Usage::

        from torch.export._patches import register_gru_while_loop_decomposition
        from torch.export import export

        with register_gru_while_loop_decomposition():
            # Export your model with GRU
            ep = export(model, (x, h0))

    Note:
        This context manager temporarily modifies the global decomposition table
        and py_kernels registration. The original registrations are restored when
        exiting the context.
    N)ry   r   r{   r|   ÚgrurZ   rk   r~   r   r   Ú%register_gru_while_loop_decompositionrƒ   E  sC   è ø€ ô0 
0Ü�	‰	�‰×Ñ× Ñ Ô"5ó
ñ ó 	÷÷ ñ ür€   )F)Ú
contextlibÚcollections.abcr   r   Útorch._decompr   Útorch._decomp.decompositionsr   r   r   r   Ú"torch._higher_order_ops.while_loopr	   r   rS   rb   rh   rk   Úcontextmanagerry   r   rƒ   r~   r   r   ú<module>rŠ      s²   ðÛ Ý %ã Ý 4ß XÓ XÝ 9ò!ó >;òB1Sóh4(òn..ðb ×Ñð,XàÐÑ ò,Xó ð,Xð^ ×Ñð°	Ð:JÑ0Kò ó ðð: ×Ñð¨yÐ9IÑ/Jò ó ñr   