
    JTh	                         S SK r S SKrS SKJr  S SKrS SKJr  S SKJrJ	r	  S SK
Jr  \(       a  S SKJr  \ R                  " \5      rS/r " S S5      rg)	    N)TYPE_CHECKING)register_multi_grad_hook)register_module_forward_hook register_module_forward_pre_hook)tree_flatten)RemovableHandleModuleTrackerc                   v    \ rS rSr% Sr\\   \S'    SS jrS r	\
S 5       rS rS	 rS
 rS rS rS rS rSrg)r	      a  
``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                     S1U l         [        R                  " 5       U l        [        R                  " 5       U l        SU l        / U l        g NGlobalF)r   weakrefWeakKeyDictionary_known_modulesWeakSet_seen_modules_has_callback_hooksselfs    R/var/www/auris/envauris/lib/python3.13/site-packages/torch/utils/module_tracker.py__init__ModuleTracker.__init__?   s:     z9@9R9R9T.5oo.?"-/    c                    ^  T R                   (       a  g U 4S jn[        R                  R                  R                  R                  U5        ST l         g )Nc                  $   > S1T l         ST l        g r   )r   r   r   s   r   callback:ModuleTracker._maybe_set_engine_callback.<locals>.callbackK   s    $:DL!&Dr   T)r   torchautogradVariable_execution_enginequeue_callback)r   r   s   ` r   _maybe_set_engine_callback(ModuleTracker._maybe_set_engine_callbackF   s<    	' 	11@@J!r   c                 D    [         R                  R                  5       S:g  $ )zP
A boolean marking if this is currently running during the backward pass or not
)r!   _C_current_graph_task_idr   s    r   is_bwModuleTracker.is_bwR   s    
 xx..0B66r   c                 V   XR                   ;  a"  [        U5      R                  U R                   U'   U R                   U   nXR                  ;  aY  UR	                  5        H*  u  p4U SU 3U R                   U'   U R                  U5        M,     U R                  R                  U5        U$ )N.)r   type__name__r   named_children_get_mod_nameadd)r   modmod_namenamesubmods        r   r3   ModuleTracker._get_mod_nameY   s    )))'+Cy'9'9D$&&s+((( # 2 2 419
!D6.B##F+""6* !5 ""3'r   c                    ^ ^^ UUU 4S jnU$ )Nc                     > T(       a  TR                  5         TTR                  ;   a   [        R                  STT(       a  SOS5        TR                  R	                  T5        g )NzaThe module hierarchy tracking seems to be broken as this Module was already entered. %s during %sbackwardforward)r&   r   loggerinfor4   argsr,   r7   r   s    r   fn(ModuleTracker._get_append_fn.<locals>.fne   sK    //1t||#w"'JY
 LLT"r    r   r7   r,   rB   s   ``` r   _get_append_fnModuleTracker._get_append_fnd   s    		# 	r   c                    ^ ^^ UUU 4S jnU$ )Nc                     > TTR                   ;   a  TR                   R                  T5        g [        R                  STT(       a  SOS5        g )NzhThe Module hierarchy tracking is confused as we're exiting a Module that was never entered. %s during %sr<   r=   )r   remover>   r?   r@   s    r   rB   %ModuleTracker._get_pop_fn.<locals>.fns   s:    t||###D)~"'JYr   rD   rE   s   ``` r   _get_pop_fnModuleTracker._get_pop_fnr   s    	 	r   c           	      |   U R                  U5      nU R                  US5      " 5         [        U5      u  pEU Vs/ s H9  n[        U[        R
                  5      (       d  M$  UR                  (       d  M7  UPM;     nnU(       a5  U R                  R                  [        XpR                  US5      5      5        g g s  snf NFT)r3   rF   r   
isinstancer!   Tensorrequires_gradr   appendr   rL   )r   r5   inputr7   rA   _atensorss           r   _fw_pre_hookModuleTracker._fw_pre_hook   s    !!#&D%(*u%"VdjELL&A1aoo1dVKK(2B2B42NO  W   #B9!B94B9c           	      |   U R                  U5      nU R                  US5      " 5         [        U5      u  pVU Vs/ s H9  n[        U[        R
                  5      (       d  M$  UR                  (       d  M7  UPM;     nnU(       a5  U R                  R                  [        XR                  US5      5      5        g g s  snf rO   )r3   rL   r   rP   r!   rQ   rR   r   rS   r   rF   )	r   r5   rT   outputr7   rA   rU   rV   rW   s	            r   _fw_post_hookModuleTracker._fw_post_hook   s    !!#&u%'v&"VdjELL&A1aoo1dVKK(2E2EdD2QR  WrZ   c                 n    [        U R                  5      U l        [        U R                  5      U l        U $ N)r   rX   _fw_pre_handler   r]   _fw_post_handler   s    r   	__enter__ModuleTracker.__enter__   s-    >t?P?PQ;D<N<NOr   c                     U R                   R                  5         U R                  R                  5         U R                   H  nUR                  5         M     U R                  R	                  5         g r`   )ra   rJ   rb   r   clear)r   rA   hooks      r   __exit__ModuleTracker.__exit__   sM    ""$##%KKDKKM  r   )rb   ra   r   r   r   r   r   )returnN)r1   
__module____qualname____firstlineno____doc__setstr__annotations__r   r&   propertyr,   r3   rF   rL   rX   r]   rc   rh   __static_attributes__rD   r   r   r	   r	      sZ    @ X0
" 7 7			
r   )loggingr   typingr   r!   torch.autograd.graphr   torch.nn.modules.moduler   r   torch.utils._pytreer   torch.utils.hooksr   	getLoggerr1   r>   __all__r	   rD   r   r   <module>r|      sN         9 - 1 
		8	$ 
F Fr   