
    i                        S r SSKJrJrJrJrJr  SSKrSSKJ	s  J
r  SSKJrJrJr  SSKJrJrJrJrJrJrJrJr  SSKJr  S\R6                  S\\R8                  R:                  \R6                  4   4S	 jr  SS
\S\\R6                  \\R6                     4   4   S\\\R6                        S\S\R@                  RB                  4S jjr"S\S\R6                  4   S\S\\R6                     4   S\RF                  S\\\R6                     \4   4S jr$S\\R6                  S4   S\S\S\\R6                  \\R6                     4   4   4   4S jr%g)a
  
This module contains tools for rewriting a dynamic PyTorch program such
that the dynamic part (e.g. control flow) can be properly captured by
DispatchTracer.
The core idea is annotating all branches in the graph with unique keys,
and using a dictionary of supplemental inputs as arguments to these
local branches so that every path gets a canonical input during tracing.

For example, consider the following usage of Python if statement:

.. code-block:: python

    if pred:
        ...
        ret = a
    else:
        ...
        ret = b

To rewrite the code to be tracable, users may use tracing_key decorator
and cond operator:

.. code-block:: python

    @control_flow.tracing_context(inputs)
    def branch_true(args):
        ...
        return a

    @control_flow.tracing_context(inputs)
    def branch_false(args):
        ...
        return b

    ret = control_flow.cond(pred, branch_true, branch_false, args)

and we can use the usual exir.capture() function.

.. code-block:: python

    exir.capture(module, args)

    )CallableListOptionalTupleUnionN)ExportErrorExportErrorTypeinternal_assert)DispatchTracerflattened_dispatch_tracePythonTensortree_returnunwrap_functionalunwrap_proxyusing_tracerValue)update_with_proxyxreturnc                 *   [         R                  " 5       nUc  U R                  $ [        U 5      n [	        U [
        5      (       d&  [        [        R                  S[        U 5       35      e[        R                  " [        U R                  5      [        R                  S9n[        U R                  5       H	  u  p4XBU'   M     [        R                  R                   R"                  R%                  U R&                  5      n[        [        U5      U5      $ )zL
A helper function for capturing the shape as a tensor from a tensor
value.
zEexir custom shape function only takes EXIR dispatch tensor, but got: )dtype)r   getshaper   
isinstancer   r   r	   INVALID_INPUT_TYPEtypetorchemptylenint64	enumerateopsaten_shape_as_tensordefaultproxy)r   tracertmpisr&   s         [/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/executorch/exir/control_flow.pyr   r   G   s    
 !F~ww!Aa&&..STXYZT[S\]
 	
 ++c!''l%++
6C!''"A #IINN++33AGG<E)#.66    fn.example_returnssingle_returnc                    [        U S5      (       d(  [        [        R                  SU R                   S35      eU R
                  n[        X[        5       SS9u  pE[        [        [        UR                  R                  5      5      5      nU(       aW  [        [        U5      [        UR                  S   5      :H  SU S[        U5       S	[        UR                  S   5       S
35        U(       an  [        [        UR                  S   5      S:H  SU S[        UR                  S   5       35        [!        UR                  S   5      Ul        UR#                  5         X4l        U$ )N__tracing_inputs__zExpect function 'z'' to be decorated with tracing_context.F)enable_functionalizationr   zEager mode of this z	 returns z" elements, but this graph returns z	 elements   zGraph z) should return just one element, but got )hasattrr   r	   MISSING_PROPERTY__name__r1   r   setnextiterreversedgraphnodesr
   r   argstuple	recompile)r-   r.   r/   r=   gm_outputs          r+   _make_submodulerC   _   s@   
 2+,,,,},ST
 	

   D$RsuuUEB$x/01F CA$77!"Ys?/C.DDfgjkqkvkvwxkygzf{  |E  F	

 A1$RDA#fkkRSnBUAVW	
 FKKN+
 Ir,   cond_fnbody_fninit_valc                    [         R                  " U5      u  p4[        S U 5       5      (       d  [        [        R
                  SU 35      e[        S5         UnU " U6 (       a  U" U6 nU " U6 (       a  M  SSS5        [         R                  " W5      u  pd[        S U 5       5      (       d  [        [        R                  SU 35      e[        R                  " 5       nUc  U$ [        U SS9n[        U5      n	[        U V
s/ s H  n
[        U
5      PM     sn
5      nUR                  S[        XU40 5      n[        X\[         5      $ ! , (       d  f       N= fs  sn
f )	zf
A higher order function returning the result based on executing body_fn
until cond_fn returns False.
c              3   V   #    U  H  n[        U[        R                  5      v   M!     g 7fNr   r   Tensor).0r)   s     r+   	<genexpr>while_loop.<locals>.<genexpr>   s      E4Dqz!U\\**4D   ')zRcontrol_flow.while_loop() expects all inputs values to be tensors, actual inputs: Nc              3   V   #    U  H  n[        U[        R                  5      v   M!     g 7frI   rJ   )rL   os     r+   rM   rN      s      F4Eqz!U\\**4ErO   zUcontrol_flow.while_loop() expects all returned values to be tensors, actual outputs: T)r/   call_function)pytreetree_flattenallr   r	   r   r   INVALID_OUTPUT_TYPEr   r   rC   r>   r   create_proxy
while_loopr   r   )rD   rE   rF   flattened_inputsrA   valflattened_outputsr'   gm_condgm_bodyvproxiesr&   s                r+   rX   rX      sT    !--h7E4DEEE..`ai`jk
 	

 
d	sm3-C smm 

 "..s3F4EFFF//cdgchi
 	

 !F~
gT:Gg&G.>?.>\!_.>?@G	7#
	E s#455; 
	( @s   EE
Einputsc           	         ^  S[         S[        [        R                     4   S[         S[        [        R                  [        [        R                     4   4   4U 4S jjnU$ )z
A decorator function to annotate code path that we conditionally
run during tracing. We need to annotate these paths for now because
during exir.capture(), the tracer does not know what's the proper
local inputs to be passed to the untaken path.
f.r   c                    >^  S[         R                  S[        [         R                     S[        [         R                     4U 4S jjnTUl        U$ )Nr=   kwargsr   c                  P   > U(       a  [        [        R                  S5      eT" U 6 $ )NzBkwargs are not supported for @tracing_context decorated functions.)r   r	   NOT_SUPPORTED)r=   rd   rb   s     r+   wrapper3tracing_context.<locals>.decorator.<locals>.wrapper   s,     !#11X 
 d8Or,   )r   rK   r   r1   )rb   rg   r`   s   ` r+   	decorator"tracing_context.<locals>.decorator   sE    		<<		+0+>		5<< 		 &,"r,   )r   r   r   rK   r   )r`   ri   s   ` r+   tracing_contextrk      sT    Cu||,,-	#uU\\5+>>??	@" r,   )NF)&__doc__typingr   r   r   r   r   r   torch.utils._pytreeutils_pytreerS   executorch.exir.errorr   r	   r
   executorch.exir.tracerr   r   r   r   r   r   r   r   executorch.exir.wrapr   rK   _CSizer   boolfxGraphModulerC   PyTreerX   rk    r,   r+   <module>r{      s~  *X : 9  $ $ O O	 	 	 37U\\ 7eEHHMM5<<$?@ 74 59eELL%*==>>?d5<<01  XX	D-6c5<<'(-6c5../-6 mm-6 5%&	-6`%,,#$c8Cu||U5<<5H'H!IIJJKr,   