
    sgI(                        d dl Z d dlZd dlmZ d dlmZ d dlmZmZm	Z	 d dl
mZ d dlmZ d dlmZ d dlmZ  ej$                  e      Zej+                  ej,                         g dZ ed	
      dedefd       Zdeeegef   de	e   ddfdZde	e   de	e   de	e   fdZ ed	
      dededefd       Z ed	
       G d d             Zy)    N)Queue)wraps)CallableDictList)GraphModule)compatibility)
PassResult)pass_result_wrapper this_before_that_pass_constraintPassManagerF)is_backward_compatiblefnreturnc                       yt                fd       }t        j                         st               j                  |_        |S )a+  
    Wrapper for passes which currently do not return a PassResult.
    This wrapper makes them return a PassResult containing the modified object
    and True for the "modified" flag.

    Args:
        fn (Callable[Module, Any])

    Returns:
        wrapped_fn (Callable[Module, PassResult])
    Nc                      |       }|t        | d      S t        |t               r|S t        |t        j                        rt        |d      S y )NT)r
   
isinstancennModule)gmresr   s     U/var/www/html/venv/lib/python3.12/site-packages/torch/fx/passes/infra/pass_manager.py
wrapped_fnz'pass_result_wrapper.<locals>.wrapped_fn"   sM    f;b$''c:&JRYY'c4(( (    )r   inspect
isfunctiontype__name__)r   r   s   ` r   r   r      sK     
z
2Y) ) b!"2h//
r   
constraintpassesc                     t        |      D ]E  \  }}t        ||dz   d        D ],  \  }} | ||      rt        d| d| d| d| d| d| d       G y )	N   z,pass schedule constraint violated. Expected z before z but found z
 at index z and z	 at indexz in pass list.)	enumerateRuntimeError)r   r    iajbs         r   "_validate_pass_schedule_constraintr)   1   s     &! 1fQUWo. 	DAq!Q>qc!aS
1#U1#Yqc B 	r   constraintsc                    t        |      dk(  r| S | D ci c]  }|g  }}t        j                  | d      t               }| D ][  }| D ]:  }||k(  r	|D ]-  } |||      r||   j	                  |       |xx   dz  cc<   / < |   dk(  sK|j                  |       ] t        j                  | d      }g }	|j                         sn|j                         }|	j	                  |       d||<   ||   D ]/  }
||
   r	|
xx   dz  cc<   |
   dk(  s|j                  |
       1 |j                         snt        t        fdj                                     }t        |      dk7  rd| }t        |      |	S c c}w )z
    Args
        passes: Passes that we are ordering
        constraints: Constraints applied on these passes

    Returns
        A sorted list of callables and a boolean of if a circular dependency
        existed
    r   r"   FTc                     |    dk7  S )Nr    )pindegree_maps    r   <lambda>z*_topological_sort_passes.<locals>.<lambda>m   s    aA)= r   z:Circular dependency detected within the following passes: )lendictfromkeysr   appendputemptygetlistfilterkeysr$   )r    r*   r.   graph
candidatesr&   r(   r   visitedsorted_passesncycle_passeserrorr/   s                @r   _topological_sort_passesrB   >   s    ;1 >D,DQV,DE,D(,fa(@LJ  	)AAv) )
!!Q'!HOOA& Oq(O)		) ?aNN1 %)MM&%$@G$&M NNQ
q 	&A1:Q1$?a'NN1%		&   =|?P?P?RSTL
<AL\N[5!!I -Es   
E>thisthatc                 0     dt         dt         f fd}|S )a  
    Defines a partial order ('depends on' function) where `this` must occur
    before `that`.

    For example, the following pass list and constraint list would be invalid.
    ```
    passes = [pass_b, pass_a]

    constraints = [
        this_before_that_pass_constraint(pass_a, pass_b)
    ]
    ```

    Args:
        this (Callable): pass which should occur first
        that (Callable): pass which should occur later

    Returns:
        depends_on (Callable[[Object, Object], bool]
    r&   r(   c                     | k7  xs |k7  S Nr-   )r&   r(   rD   rC   s     r   
depends_onz4this_before_that_pass_constraint.<locals>.depends_on   s    Dy%AI%r   )r   )rC   rD   rH   s   `` r   r   r   t   s    .&h &8 & r   c                      e Zd ZU dZeeej                  gef      e	d<   eeeege
f      e	d<   dZe
e	d<   dZee	d<   	 	 	 	 	 dd	e
d
e
fdZdefdZdefdZd Zd ZdeddfdZdej                  ddfdZdej                  defdZy)r   ad  
    Construct a PassManager.

    Collects passes and constraints. This defines the pass schedule, manages
    pass constraints and pass execution.

    Args:
        passes (Optional[List[Callable]]): List of passes. A pass is a
            callable which modifies an object and returns a PassResult
        constraint (Optional[List[Callable]]): List of constraints. A
            constraint is a callable which takes two passes (A, B) and returns
            True if A depends on B and False otherwise. See implementation of
            `this_before_that_pass_constraint` for example.
        steps (int): Max number of times we run the passes (default = 1).
        run_checks_after_each_pass (bool): Whether to run checks and linting
            after each pass
        suppress_check_failures (bool): Whether to raise errors when running
            checks
    r    r*   F
_validatedr"   stepsNrun_checks_after_each_passsuppress_check_failuresc                 ^    |xs g | _         |xs g | _        |r|| _        || _        || _        y rG   )r    r*   rK   rL   rM   )selfr    r*   rK   rL   rM   s         r   __init__zPassManager.__init__   s6     l&,"DJ*D''>$r   _passc                 H    | j                   j                  |       d| _        y)z>
        Adds a pass into the current list of passes.
        FN)r    r4   rJ   )rO   rQ   s     r   add_passzPassManager.add_pass   s     	5!r   r   c                 H    | j                   j                  |       d| _        y)zI
        Adds a constraint into the current list of constraints.
        FN)r*   r4   rJ   rO   r   s     r   add_constraintzPassManager.add_constraint   s     	
+r   c                 z    | j                   ry| j                  D ]  }t        || j                          d| _         y)z
        Validates that current pass schedule defined by `self.passes` is valid
        according to all constraints in `self.constraints`
        NT)rJ   r*   r)   r    rU   s     r   validate_constraintsz PassManager.validate_constraints   s:    
 ??** 	HJ.z4;;G	Hr   c                 \    t        | j                  | j                        | _        d| _        y)ab  
        Finds a valid traversal order based on the given constraints and orders
        the passes based on this order.

        If a circular dependency exists between the constraints and steps = 1,
        then we will raise an error because if steps != 1 this means that we
        will re-run the passes, allowing for circular dependencies.
        TN)rB   r    r*   rJ   )rO   s    r   solve_constraintszPassManager.solve_constraints   s#     /t{{D<L<LMr   checkr   c                     t        j                  |      }t        t        |j                  j                                     dk7  rt        d      t        | d|       y)z
        Adds a function which takes runs various checks on a given graph module.
        This function is run before and after each pass if the
        `run_checks_after_each_pass` flag is enabled.
        r"   zEPassManager check function should only take in one variable, a moduler[   N)r   	signaturer1   r8   
parametersvalues	TypeErrorsetattr)rO   r[   sigs      r   
add_checkszPassManager.add_checks   sK     &tCNN))+,-2cddgu%r   modulec                      y rG   r-   )rO   rd   s     r   r[   zPassManager.check   s    r   c           	         | j                   s| j                          | j                  |       d}t        | j                        D ]+  }d}t        | j                        D ]  \  }}t        j                  |      r|j                  nt        |      j                  }t        j                  d|       	  ||      }t        |t              st        |d      st!        d| ddz         |j"                  }|xs |j$                  }t        |t&              r1t        j                  d||j(                         |j+                          | j,                  r| j                  |        |xs |}|r, n t        ||      S # t.        $ ro}	| j                  d| D 
cg c]8  }
t        j                  |
      r|
j                  nt        |
      j                  : nc c}
w }}
d	| d
| }t/        |      |	d}	~	ww xY w)a}  
        Runs a list of passes in the order based on `self.passes` on the given
        graph module. Each time a pass is run, checks and linting will be run on
        the graph module if `run_checks_after_each_pass` is set.

        If the module is a graph module, we will run the list of passes until
        the graph stops changing, or until `steps` number of times.
        FzRunning pass '%s'graph_modulezThe result of the pass z should be type PassResult.z)Please wrap it with pass_result_wrapper()zGraph after pass '%s': %sNz$An error occurred when running the 'z#' pass after the following passes: )rJ   rZ   r[   rangerK   r#   r    r   r   r   r   loggerdebugr   r
   hasattrr`   rg   modifiedr   r;   	recompilerL   	Exception)rO   rd   overall_modified_rl   r%   r   fn_namer   er.   prev_pass_namesmsgs                r   __call__zPassManager.__call__   s    ""$ 	

6 !tzz" (	AH #4;;/ 02)0););B)?"++T"XEVEV0':0V*C%c:6w^@ (5gY>YZIJ  !--F'73<<H!&+6%@'6<<X((* 66

6*/0D  0;8Q(	T &"233 ! 0 "&Ra' '.&8&8&;

aAQAQQ' 'O ' A	Ilm|l}~C#C.a/0s%   4B0F  	G8	G3=G
G33G8)NNNFF)r   
__module____qualname____doc__r   r   r   r   r
   __annotations__boolrJ   rK   intrP   rS   rV   rX   rZ   rc   r[   ru   r-   r   r   r   r      s    ( 299+z1233h(3T9:;;JE3N +0(-?
 %)? "&?  h     	
& &T &BII $ =4ryy =4Z =4r   r   )r   loggingqueuer   	functoolsr   typingr   r   r   torch.nnr   torch.fx.graph_moduler   torch.fx._compatibilityr	   torch.fx.passes.infra.pass_baser
   	getLoggerr   ri   setLevelWARNING__all__r   rz   r)   rB   r   r   r-   r   r   <module>r      s       ' '  - 1 6			8	$   
Te,H   -<(H-t34>B8n	4N4)-h4	(^4l e,8 8   -8 e,\4 \4 -\4r   