
    sgF%                     r    d dl Z d dlZd dlmZmZmZ d dlZd dlmZ d dl	m
Z
mZ d dlmZ dgZ G d d      Zy)    N)CallableOptionalSet)register_multi_grad_hook)register_module_forward_hook register_module_forward_pre_hook)tree_flatten
ModTrackerc            
           e Zd ZU dZee   ed<   	 d Zd Ze	d        Z
d Z	 	 	 	 ddee   d	ee   d
ee   dee   fdZd Zd Zd Zd Zd Zd Zd Zd Zy)r
   a=  
    ``ModTracker`` is a context manager that tracks the nn.Module hierarchy during execution
    so that other system can query which Module is currently being executed (or its backward is being
    executed).

    You can access the ``parents`` attribute on this context manager to get the set of all the
    Modules currently being executed via their fqn (fully qualified name, also used as the key within
    the state_dict).
    You can access the ``is_bw`` attribute to know if you are currently running in backward or not.

    Note that ``parents`` is never empty and always contains the "Global" key. The ``is_bw`` flag
    will remain ``True`` after the forward until another Module is executed. If you need it to be
    more accurate, please submit an issue requesting this. Adding a map from fqn to the module instance
    is possible but not done yet, please submit an issue requesting this if you need it.

    Example usage

    .. code-block:: python

        mod = torch.nn.Linear(2, 2)

        with ModTracker() as tracker:
            # Access anything during the forward pass
            def my_linear(m1, m2, bias):
                print(f"Current modules: {tracker.parents}")
                return torch.mm(m1, m2.t()) + bias
            torch.nn.functional.linear = my_linear

            mod(torch.rand(2, 2))

    parentsc                     dh| _         i | _        t        j                         | _        t        j
                         | _        d| _        d | _        d | _	        d | _
        d | _        y NGlobalF)r   _active_module_cntweakrefWeakKeyDictionary_known_modulesWeakSet_seen_modules_has_callback_user_pre_fw_hook_user_post_fw_hook_user_pre_bw_hook_user_post_bw_hookselfs    W/var/www/html/venv/lib/python3.12/site-packages/torch/distributed/_tools/mod_tracker.py__init__zModTracker.__init__8   s[     z"$9@9R9R9T.5oo.?"!%"&!%"&    c                       j                   ry  fd}t        j                  j                  j                  j                  |       d _         y )Nc                  $    dh _         d _        y r   )r   r   r   s   r   callbackz7ModTracker._maybe_set_engine_callback.<locals>.callbackH   s    $:DL!&Dr   T)r   torchautogradVariable_execution_enginequeue_callback)r   r"   s   ` r   _maybe_set_engine_callbackz%ModTracker._maybe_set_engine_callbackC   s<    	' 	11@@J!r   c                 D    t         j                  j                         dk7  S )z`
        A boolean marking if this is currently running during the backward pass or not
        )r#   _C_current_graph_task_idr   s    r   is_bwzModTracker.is_bwO   s    
 xx..0B66r   c                 :    | j                   j                  |d      S )zo
        Return the fqn for the given module if it is known to the ``ModTracker``, otherwise ``None``.
        N)r   get)r   mods     r   get_known_fqnzModTracker.get_known_fqnV   s     ""&&sD11r   Npre_fw_hookpost_fw_hookpre_bw_hookpost_bw_hookc                     d } ||| j                   d      | _          ||| j                  d      | _         ||| j                  d      | _         ||| j                  d      | _        y)aB  
        Registers user-specified hooks to be called before/after the forward/backward pass for each
        module tracked by the ``ModTracker``. One or more can be ``None``.
        Args:
            pre_fw_hook (Callable, optional): A hook to be called before the forward pass for the
                module. It should have the following signature:
                pre_fw_hook (module, input) -> None
            post_fw_hook (Callable, optional): A hook to be called after the forward pass for the
                module. It should have the following signature:
                post_fw_hook (module, input, output) -> None
            pre_bw_hook (Callable, optional): A multi-grad hook to be called on all the outputs of
                the module that require gradients. It should have the following signature:
                pre_bw_hook (module, grad_output) -> None
            post_bw_hook (Callable, optional): A multi-grad hook to be called on all the inputs of
                the module that require gradients. It should have the following signature:
                post_bw_hook (module, grad_input) -> None
        Raises:
            AssertionError: If a new hook is provided when one is already registered.
        Note:
            If the module is not alive during the backward pass, the pre_bw_hook and post_bw_hook will
            will receive None as the module argument.
            The module fqn will be present in the ``parents`` attribute when each of the hooks is called.
            Hooks are intended to be used as markers only not to modify the inputs/outputs.
        c                 ,    | |t        d| d      | S )Nz	Only one zq can be registered at a time Clear the existing hook by calling ``clear_user_hooks`` before registering a new one)AssertionError)hook	user_hook	hook_names      r   set_hookz0ModTracker.register_user_hooks.<locals>.set_hook|   s4    I$9$	{ +l m  Kr   r2   r3   r4   r5   Nr   r   r   r   )r   r2   r3   r4   r5   r<   s         r   register_user_hookszModTracker.register_user_hooks\   sx    @	 "*//"
 #+$11>#
 "*//"
 #+$11>#
r   c                 <    d| _         d| _        d| _        d| _        y)zY
        Clears the user specified hooks registered with ``register_user_hooks``
        Nr=   r   s    r   clear_user_hookszModTracker.clear_user_hooks   s$     "&"&!%"&r   c                 P   || j                   vr"t        |      j                  | j                   |<   | j                   |   }|| j                  vrX|j	                         D ]*  \  }}| d| | j                   |<   | j                  |       , | j                  j                  |       |S )N.)r   type__name__r   named_children_get_mod_nameadd)r   r0   mod_namenamesubmods        r   rF   zModTracker._get_mod_name   s    d)))'+Cy'9'9D$&&s+d((( # 2 2 4 +f19
!D6.B##F+""6*+ ""3'r   c                       fd}|S )Nc                     rj                          j                  v r0j                  s$dd}|t        _        t        j
                  d       j                  vr+dj                  <   j                  j                         nj                  xx   dz  cc<   j                  rj                          |        y y y )Nc                 2    | d| d|j                    d|  dS )N:z: z 
)rD   )msgcategoryfilenamelinenolines        r   custom_formatwarningzCModTracker._get_append_fn.<locals>.fn.<locals>.custom_formatwarning   s(    &Zq83D3D2ERuCPPr   zbThe module hierarchy tracking maybe be messed up. Please file a bug to PyTorch, if it is the case.   N)	r(   r   r-   warningsformatwarningwarnr   rG   r   )argsrT   r-   rI   r   w_mods     r   fnz%ModTracker._get_append_fn.<locals>.fn   s    //1t||#DJJQ *>&H 4<<'01''-  &''-2-%%1e&&uw5 7<1r    r   r[   rI   r-   r\   s   ```` r   _get_append_fnzModTracker._get_append_fn   s    	6, 	r   c                       fd}|S )Nc                  &   j                   rj                          |        j                  v rFj                  xx   dz  cc<   j                     dk(  rj                  j                         y y j                  st        d      y )NrU   r   z?The Module hierarchy tracking is wrong. Report a bug to PyTorch)r   r   r   remover-   RuntimeError)rZ   r-   rI   r   r[   s    r   r\   z"ModTracker._get_pop_fn.<locals>.fn   s    &&2u''6t||#''-2-**40A5LL''- 6ZZ #U   r   r]   r^   s   ```` r   _get_pop_fnzModTracker._get_pop_fn   s    	 	r   c                    | j                  |      }t        j                  |      } | j                  ||d              | j                  | j	                  ||       t        |      \  }}|D cg c],  }t        |t        j                        s|j                  s+|. }}| j                  s!|rt        || j                  ||d             y y y c c}w NFT)rF   r   refr_   r   r	   
isinstancer#   Tensorrequires_gradr-   r   rd   )	r   r0   inputrI   r[   rZ   _atensorss	            r   _fw_pre_hookzModTracker._fw_pre_hook   s    !!#&C /E4/1!!-""3.u%a"VjELL&Aaoo1VVzzg$Wd.>.>udD.QR &z Ws   /CCCc                    | j                  |      }t        j                  |      }| j                  | j                  |||        | j	                  ||d              t        |      \  }}|D cg c],  }t        |t        j                        s|j                  s+|. }	}| j                  s!|	rt        |	| j                  ||d             y y y c c}w rf   )rF   r   rg   r   rd   r	   rh   r#   ri   rj   r-   r   r_   )
r   r0   rk   outputrI   r[   rZ   rl   rm   rn   s
             r   _fw_post_hookzModTracker._fw_post_hook   s    !!#&C "".##C7,e,.v&a"VjELL&Aaoo1VVzzg$Wd.A.A%t.TU &z Ws   0CCCc                 r    t        | j                        | _        t        | j                  d      | _        | S )NT)always_call)r   ro   _fw_pre_handler   rr   _fw_post_handler   s    r   	__enter__zModTracker.__enter__   s4    >t?P?PQ;D 
 r   c                 l    | j                   j                          | j                  j                          y rV   )ru   rb   rv   )r   rZ   s     r   __exit__zModTracker.__exit__   s&    ""$##%r   )NNNN)rD   
__module____qualname____doc__r   str__annotations__r   r(   propertyr-   r1   r   r   r>   r@   rF   r_   rd   ro   rr   rw   ry   r]   r   r   r
   r
      s    @ X	'
" 7 72 +/+/*.+/3
h'3
 x(3
 h'	3

 x(3
j'	2"	S	V&r   )rW   r   typingr   r   r   r#   torch.autograd.graphr   torch.nn.modules.moduler   r   torch.utils._pytreer	   __all__r
   r]   r   r   <module>r      s6      * *  9 - .\& \&r   