
    ¯wg                         d dl Z 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	 d dl
mZ  e j                  e      ZdgZ G d d      Zy)    N)Set)register_multi_grad_hook)register_module_forward_hook register_module_forward_pre_hook)tree_flattenModuleTrackerc                   l    e Zd ZU dZee   ed<   	 ddZd Ze	d        Z
d Zd Zd	 Zd
 Zd Zd Zd Zy)r   aC  
    ``ModuleTracker`` 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 ModuleTracker() 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))

    parentsNc                     dh| _         t        j                         | _        t        j                         | _        d| _        y NGlobalF)r
   weakrefWeakKeyDictionary_known_modulesWeakSet_seen_modules_has_callbackselfs    _/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/torch/utils/module_tracker.py__init__zModuleTracker.__init__;   s3     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   callbackz:ModuleTracker._maybe_set_engine_callback.<locals>.callbackF   s    $:DL!&Dr   T)r   torchautogradVariable_execution_enginequeue_callback)r   r   s   ` r   _maybe_set_engine_callbackz(ModuleTracker._maybe_set_engine_callbackA   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ModuleTracker.is_bwM   s    
 xx..0B66r   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   modmod_namenamesubmods        r   r,   zModuleTracker._get_mod_nameT   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 rt        j                  drdnd       j                  j	                         y )NzaThe module hierarchy tracking seems to be broken as this Module was already entered. %s during %sbackwardforward)r!   r
   loggerinfor-   argsr&   r0   r   s    r   fnz(ModuleTracker._get_append_fn.<locals>.fn`   sK    //1t||#w"'JY
 LLT"r    r   r0   r&   r:   s   ``` r   _get_append_fnzModuleTracker._get_append_fn_   s    		# 	r   c                       fd}|S )Nc                      j                   v rj                   j                         y t        j                  drdnd       y )NzhThe Module hierarchy tracking is confused as we're exiting a Module that was never entered. %s during %sr4   r5   )r
   remover6   r7   r8   s    r   r:   z%ModuleTracker._get_pop_fn.<locals>.fnn   s:    t||###D)~"'JYr   r;   r<   s   ``` r   _get_pop_fnzModuleTracker._get_pop_fnm   s    	 	r   c                 &   | j                  |      } | j                  |d              t        |      \  }}|D cg c],  }t        |t        j
                        s|j                  s+|. }}|rt        || j                  |d             y y c c}w NFT)	r,   r=   r   
isinstancer   Tensorrequires_gradr   rA   )r   r.   inputr0   r9   _atensorss           r   _fw_pre_hookzModuleTracker._fw_pre_hookz   s    !!#&(D%(*u%a"VjELL&Aaoo1VV$Wd.>.>tT.JK  W   BB(Bc                 &   | j                  |      } | j                  |d              t        |      \  }}|D cg c],  }t        |t        j
                        s|j                  s+|. }}|rt        || j                  |d             y y c c}w rC   )	r,   rA   r   rD   r   rE   rF   r   r=   )	r   r.   rG   outputr0   r9   rH   rI   rJ   s	            r   _fw_post_hookzModuleTracker._fw_post_hook   s    !!#&%u%'v&a"VjELL&Aaoo1VV$Wd.A.A$.MN  WrL   c                 n    t        | j                        | _        t        | j                        | _        | S N)r   rK   _fw_pre_handler   rO   _fw_post_handler   s    r   	__enter__zModuleTracker.__enter__   s-    >t?P?PQ;D<N<NOr   c                 l    | j                   j                          | j                  j                          y rQ   )rR   r@   rS   )r   r9   s     r   __exit__zModuleTracker.__exit__   s&    ""$##%r   )returnN)r*   
__module____qualname____doc__r   str__annotations__r   r!   propertyr&   r,   r=   rA   rK   rO   rT   rV   r;   r   r   r   r      s\    @ X#
" 7 7	LO
&r   )loggingr   typingr   r   torch.autograd.graphr   torch.nn.modules.moduler   r   torch.utils._pytreer   	getLoggerr*   r6   __all__r   r;   r   r   <module>re      sH        9 - 
		8	$ 
~& ~&r   