
    
3j.                         S SK r S SKJr  S SKrSSKJr  SSKJr  \" \5      r	 " S S5      r
 " S S	5      r " S
 S5      r " S S5      r " S S5      rg)    N)Any   )
get_logger)unwrap_modulec                       \ rS rSrSS jrSrg)	BaseState   Nc                     [        S5      e)NzWBaseState::reset is not implemented. Please implement this method in the derived class.)NotImplementedError)selfargskwargss      O/home/wildlama/miniconda3/lib/python3.13/site-packages/diffusers/hooks/hooks.pyresetBaseState.reset   s    !e
 	
     returnN)__name__
__module____qualname____firstlineno__r   __static_attributes__r   r   r   r   r      s    
r   r   c                   H    \ rS rSrSS\4S jjrS rS\SS4S jrSS	 jr	S
r
g)StateManager"   N	state_clsc                 \    Xl         Ub  UOSU l        Ub  UO0 U l        0 U l        S U l        g )Nr   )
_state_cls
_init_args_init_kwargs_state_cache_current_context)r   r   	init_argsinit_kwargss       r   __init__StateManager.__init__#   s4    #'0'<)"+6+BK $r   c                 .   U R                   c  [        S5      eU R                   U R                  R                  5       ;  a=  U R                  " U R
                  0 U R                  D6U R                  U R                   '   U R                  U R                      $ )NzDNo context is set. Please set a context before retrieving the state.)r$   
ValueErrorr#   keysr    r!   r"   r   s    r   	get_stateStateManager.get_state*   s}      (cdd  (9(9(>(>(@@7;7m[_[l[l7mDd334  !6!677r   namer   c                     Xl         g N)r$   r   r/   s     r   set_contextStateManager.set_context1   s     $r   c                     [        U R                  R                  5       5       H2  u  p4UR                  " U0 UD6  U R                  R	                  U5        M4     S U l        g r1   )listr#   itemsr   popr$   )r   r   r   r/   states        r   r   StateManager.reset4   sQ     1 1 7 7 9:KDKK((!!$' ; !%r   )r$   r!   r"   r#   r    )NNr   )r   r   r   r   r   r'   r-   strr3   r   r   r   r   r   r   r   "   s+    %) %8% % %%r   r   c                   N   \ rS rSrSrSrS rS\R                  R                  S\R                  R                  4S jr
S\R                  R                  S\R                  R                  4S jrS\R                  R                  S\\\   \\\4   4   4S	 jrS\R                  R                  S
\S\4S jrS\R                  R                  S\R                  R                  4S jrS\R                  R                  4S jrS\R                  R                  S\SS4S jrSrg)	ModelHook;   zd
A hook that contains callbacks to be executed just before and after the forward method of a model.
Fc                     S U l         g r1   fn_refr,   s    r   r'   ModelHook.__init__B   s	    /3r   moduler   c                     U$ )z
Hook that is executed when a model is initialized.

Args:
    module (`torch.nn.Module`):
        The module attached to this hook.
r   r   rC   s     r   initialize_hookModelHook.initialize_hookE   	     r   c                     U$ )z
Hook that is executed when a model is deinitialized.

Args:
    module (`torch.nn.Module`):
        The module attached to this hook.
r   rE   s     r   deinitalize_hookModelHook.deinitalize_hookO   rH   r   c                     X#4$ )a  
Hook that is executed just before the forward method of the model.

Args:
    module (`torch.nn.Module`):
        The module whose forward pass will be executed just after this event.
    args (`tuple[Any]`):
        The positional arguments passed to the module.
    kwargs (`dict[Str, Any]`):
        The keyword arguments passed to the module.
Returns:
    `tuple[tuple[Any], dict[Str, Any]]`:
        A tuple with the treated `args` and `kwargs`.
r   )r   rC   r   r   s       r   pre_forwardModelHook.pre_forwardY   s     |r   outputc                     U$ )a  
Hook that is executed just after the forward method of the model.

Args:
    module (`torch.nn.Module`):
        The module whose forward pass been executed just before this event.
    output (`Any`):
        The output of the module.
Returns:
    `Any`: The processed `output`.
r   )r   rC   rO   s      r   post_forwardModelHook.post_forwardj   s	     r   c                     U$ )z
Hook that is executed when the hook is detached from a module.

Args:
    module (`torch.nn.Module`):
        The module detached from this hook.
r   rE   s     r   detach_hookModelHook.detach_hookx   rH   r   c                 >    U R                   (       a  [        S5      eU$ )NzFThis hook is stateful and needs to implement the `reset_state` method.)_is_statefulr   rE   s     r   reset_stateModelHook.reset_state   s    %&noor   r/   Nc                     [        U 5       H6  n[        X5      n[        U[        5      (       d  M%  UR	                  U5        M8     U$ r1   )dirgetattr
isinstancer   r3   )r   rC   r/   	attr_nameattrs        r   _set_contextModelHook._set_context   s<    TI4+D$--  & # r   r@   )r   r   r   r   __doc__rW   r'   torchnnModulerF   rJ   tupler   dictr;   rM   rQ   rT   rX   r`   r   r   r   r   r=   r=   ;   s    L4ehhoo %((// uxx 588?? %((// uUSVZY]^acf^fYgMgGh "588?? C C %((// ehhoo %((// 
588?? # $ r   r=   c                       \ rS rSrSS jrSrg)HookFunctionReference   Nc                 <    SU l         SU l        SU l        SU l        g)a^  A container class that maintains mutable references to forward pass functions in a hook chain.

Its mutable nature allows the hook system to modify the execution chain dynamically without rebuilding the
entire forward pass structure.

Attributes:
    pre_forward: A callable that processes inputs before the main forward pass.
    post_forward: A callable that processes outputs after the main forward pass.
    forward: The current forward function in the hook chain.
    original_forward: The original forward function, stored when a hook provides a custom new_forward.

The class enables hook removal by allowing updates to the forward chain through reference modification rather
than requiring reconstruction of the entire chain. When a hook is removed, only the relevant references need to
be updated, preserving the execution order of the remaining hooks.
N)rM   rQ   forwardoriginal_forwardr,   s    r   r'   HookFunctionReference.__init__   s#         $r   )rl   rm   rQ   rM   r   )r   r   r   r   r'   r   r   r   r   ri   ri      s    %r   ri   c                   <  ^  \ rS rSrS\R
                  R                  SS4U 4S jjrS\S\	SS4S jr
S\	S\S-  4S	 jrSS\	S
\SS4S jjrSS
\SS4S jjr\S\R
                  R                  SS 4S j5       rSS\	S-  SS4S jjrS\S    4S jrS\	4S jrSrU =r$ )HookRegistry   
module_refr   Nc                 X   > [         TU ]  5         0 U l        Xl        / U l        / U l        g r1   )superr'   hooks_module_ref_hook_order_fn_refs)r   rr   	__class__s     r   r'   HookRegistry.__init__   s*    +-
%r   hookr/   c                 :   X R                   R                  5       ;   a  [        SU S35      eUR                  U R                  5      U l        S[
        4S jnU R                  R                  n[        5       nUR                  Ul        UR                  Ul        XEl        [        US5      (       aU  XEl
        [        R                  " [        R                  " UR                  U R                  5      UR                  5      Ul        U" U5      n[        R                  " [        R                  " X`R                  5      U5      U R                  l        XQl        XR                   U'   U R                   R#                  U5        U R$                  R#                  U5        g )NzHook with name zv already exists in the registry. Please use a different name or first remove the existing hook and then add a new one.function_referencec                    ^  U 4S jnU$ )Nc                 z   > TR                   " U /UQ70 UD6u  pTR                  " U0 UD6nTR                  X5      $ r1   )rM   rl   rQ   )rC   r   r   rO   r}   s       r   new_forwardKHookRegistry.register_hook.<locals>.create_new_forward.<locals>.new_forward   sE    1==fVtVvV+33TDVD)66vFFr   r   )r}   r   s   ` r   create_new_forward6HookRegistry.register_hook.<locals>.create_new_forward   s    G
 r   r   )ru   r+   r*   rF   rv   ri   rl   rM   rQ   hasattrrm   	functoolsupdate_wrapperpartialr   rA   rw   appendrx   )r   r{   r/   r   rl   rA   rewritten_forwards          r   register_hookHookRegistry.register_hook   sW   ::??$$!$ (I J 
  //0@0@A	3H 	 ""**&(!--"// 4''&-#&55!!$"2"2D4D4DEtGWGWFN /v6#,#;#;/1A1ABDU$
  

4%V$r   c                 :    U R                   R                  US 5      $ r1   )ru   getr2   s     r   get_hookHookRegistry.get_hook   s    zz~~dD))r   recursec                 
   XR                   R                  5       ;   Ga  [        U R                  5      nU R                   U   nU R                  R	                  U5      nU R
                  U   nUR                  nUR                  b  UR                  nXSS-
  :X  a  XpR                  l        OXpR
                  US-      l        UR                  U R                  5      U l        U R                   U	 U R                  R                  U5        U R
                  R                  U5        U(       aY  U R                  R                  5        H:  u  pUS:X  a  M  [        U	S5      (       d  M   U	R                  R                  USS9  M<     g g )N    _diffusers_hookFr   )ru   r+   lenrw   indexrx   rl   rm   rv   rJ   r8   named_modulesr   r   remove_hook)
r   r/   r   	num_hooksr{   r   rA   old_forwardmodule_namerC   s
             r   r   HookRegistry.remove_hook   s@   ::??$$D,,-I::d#D$$**40E]]5)F ..K&&2$55A%+6  (3>eai(0#44T5E5EFD

4   'MMe$'+'7'7'E'E'G#"$6#455**66tU6K	 (H r   c                    [        U R                  5       H@  nU R                  U   nUR                  (       d  M%  UR	                  U R
                  5        MB     U(       al  [        U R
                  5      R                  5        HD  u  pEUS:X  a  M  [        U5      n[        US5      (       d  M+  UR                  R                  SS9  MF     g g )Nr   r   Fr   )reversedrw   ru   rW   rX   rv   r   r   r   r   reset_stateful_hooks)r   r   	hook_namer{   r   rC   s         r   r   !HookRegistry.reset_stateful_hooks   s    !$"2"23I::i(D     !1!12 4
 '4T5E5E'F'T'T'V#"$&v.6#455**???N (W r   rC   c                 V    [        US5      (       d  U " U5      Ul        UR                  $ )Nr   )r   r   )clsrC   s     r   check_if_exists_or_initialize*HookRegistry.check_if_exists_or_initialize  s(    v011%([F"%%%r   c                    [        U R                  5       HA  nU R                  U   nUR                  (       d  M%  UR	                  U R
                  U5        MC     U R                  5        H  nUR	                  U5        M     g r1   )r   rw   ru   rW   r`   rv   _get_child_registries)r   r/   r   r{   registrys        r   r`   HookRegistry._set_context  sj    !$"2"23I::i(D   !!$"2"2D9 4
 224H!!$' 5r   c                 R   [        U S5      (       d  SU l        U R                  b  U R                  $ / n[        U R                  5      R	                  5        HF  u  p#US:X  a  M  [        U5      n[        US5      (       d  M+  UR                  UR                  5        MH     Xl        U$ )a7  Return registries of child modules, using a cached list when available.

The cache is built on first call and reused for subsequent calls. This avoids the cost of walking the full
module tree via named_modules() on every _set_context call, which is significant for large models (e.g. ~2.7ms
per call on Flux2).
_child_registries_cacheNr   r   )r   r   r   rv   r   r   r   )r   
registriesr   rC   s       r   r   "HookRegistry._get_child_registries  s     t677+/D(''3///
#01A1A#B#P#P#RKb "6*Fv011!!&"8"89 $S (2$r   c                    Sn[        U R                  5       H  u  p#U R                  U   R                  R                  [
        R                  La  U R                  U   R	                  5       nO#U R                  U   R                  R                  nUSU SU SU 3-  nU[        U R                  5      S-
  :  d  M  US-  nM     SU S3$ )	Nr   z  (z) z - r   
zHookRegistry(
z
))	enumeraterw   ru   ry   __repr__objectr   r   )r   registry_reprir   	hook_reprs        r   r   HookRegistry.__repr__,  s    %d&6&67LAzz)$..77vN JJy1::<	 JJy1;;DD	s1#R	{#i[AAM3t''(1,,% 8 !s33r   )r   rx   rw   rv   ru   )Tr1   )r   r   r   r   rc   rd   re   r'   r=   r;   r   r   boolr   r   classmethodr   r`   r6   r   r   r   __classcell__)ry   s   @r   rp   rp      s    588?? t &%) &%3 &%4 &%P*S *Y%5 *L Ld Ld L8OD OD O &588?? &~ & &
(t (t (tN'; .
4# 
4 
4r   rp   )r   typingr   rc   utils.loggingr   utils.torch_utilsr   r   loggerr   r   r=   ri   rp   r   r   r   <module>r      sY       & - 
H	
 
% %2R Rj% %.O4 O4r   