
    (tiS+                         d dl Z d dlmZ d dlZddlmZ ddlmZ  ee      Z	 G d d      Z
 G d d	      Z G d
 d      Z G d d      Z G d d      Zy)    N)Any   )
get_logger)unwrap_modulec                       e Zd ZddZy)	BaseStateNc                     t        d      )NzWBaseState::reset is not implemented. Please implement this method in the derived class.)NotImplementedError)selfargskwargss      d/Volumes/fast/ai/experiments/MLX_z-image/.venv/lib/python3.12/site-packages/diffusers/hooks/hooks.pyresetzBaseState.reset   s    !e
 	
    returnN)__name__
__module____qualname__r    r   r   r   r      s    
r   r   c                   8    e Zd Zd	defdZd ZdeddfdZd
dZy)StateManagerN	state_clsc                 Z    || _         ||nd| _        ||ni | _        i | _        d | _        y )Nr   )
_state_cls
_init_args_init_kwargs_state_cache_current_context)r   r   	init_argsinit_kwargss       r   __init__zStateManager.__init__#   s6    #'0'<)"+6+BK $r   c                 (   | j                   t        d      | j                   | j                  j                         vr= | j                  | j
                  i | j                  | j                  | j                   <   | j                  | j                      S )NzDNo context is set. Please set a context before retrieving the state.)r   
ValueErrorr   keysr   r   r   r   s    r   	get_statezStateManager.get_state*   s      (cdd  (9(9(>(>(@@7Ft7m[_[l[l7mDd334  !6!677r   namer   c                     || _         y N)r   r   r(   s     r   set_contextzStateManager.set_context1   s
     $r   c                     t        | j                  j                               D ]2  \  }} |j                  |i | | j                  j	                  |       4 d | _        y r*   )listr   itemsr   popr   )r   r   r   r(   states        r   r   zStateManager.reset4   sU     1 1 7 7 9:KD%EKK((!!$' ; !%r   )NNr   )	r   r   r   r   r"   r'   strr,   r   r   r   r   r   r   "   s+    %) %8% % %%r   r   c                   8   e Zd ZdZdZd Zdej                  j                  dej                  j                  fdZ	dej                  j                  dej                  j                  fdZ
dej                  j                  deee   eeef   f   fdZdej                  j                  d	edefd
Zdej                  j                  dej                  j                  fdZdej                  j                  fdZdej                  j                  deddfdZy)	ModelHookzl
    A hook that contains callbacks to be executed just before and after the forward method of a model.
    Fc                     d | _         y r*   )fn_refr&   s    r   r"   zModelHook.__init__B   s	    /3r   moduler   c                     |S )z
        Hook that is executed when a model is initialized.

        Args:
            module (`torch.nn.Module`):
                The module attached to this hook.
        r   r   r7   s     r   initialize_hookzModelHook.initialize_hookE   	     r   c                     |S )z
        Hook that is executed when a model is deinitialized.

        Args:
            module (`torch.nn.Module`):
                The module attached to this hook.
        r   r9   s     r   deinitalize_hookzModelHook.deinitalize_hookO   r;   r   c                 
    ||fS )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   r7   r   r   s       r   pre_forwardzModelHook.pre_forwardY   s     V|r   outputc                     |S )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   r7   r@   s      r   post_forwardzModelHook.post_forwardj   s	     r   c                     |S )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   r9   s     r   detach_hookzModelHook.detach_hookx   r;   r   c                 4    | j                   rt        d      |S )NzFThis hook is stateful and needs to implement the `reset_state` method.)_is_statefulr
   r9   s     r   reset_statezModelHook.reset_state   s    %&noor   r(   Nc                     t        |       D ]0  }t        | |      }t        |t              s |j	                  |       2 |S r*   )dirgetattr
isinstancer   r,   )r   r7   r(   	attr_nameattrs        r   _set_contextzModelHook._set_context   s;    TI4+D$-  & # r   )r   r   r   __doc__rF   r"   torchnnModuler:   r=   tupler   dictr2   r?   rB   rD   rG   rN   r   r   r   r4   r4   ;   s    L4ehhoo %((// uxx 588?? %((// uUSVZY]^acf^fYgMgGh "588?? C C %((// ehhoo %((// 
588?? # $ r   r4   c                       e Zd ZddZy)HookFunctionReferenceNc                 <    d| _         d| _        d| _        d| _        y)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)r?   rB   forwardoriginal_forwardr&   s    r   r"   zHookFunctionReference.__init__   s#         $r   r   )r   r   r   r"   r   r   r   rV   rV      s    %r   rV   c                       e Zd Zdej                  j
                  ddf fdZdededdfdZ	dededz  fdZ
dded	eddfd
Zdd	eddfdZedej                  j
                  dd fd       Zddedz  ddfdZdefdZ xZS )HookRegistry
module_refr   Nc                 Z    t         |           i | _        || _        g | _        g | _        y r*   )superr"   hooks_module_ref_hook_order_fn_refs)r   r\   	__class__s     r   r"   zHookRegistry.__init__   s,    +-
%r   hookr(   c                 .   || j                   j                         v rt        d| d      |j                  | j                        | _        dt
        fd}| j                  j                  }t               }|j                  |_        |j                  |_        ||_        t        |d      rT||_
        t        j                  t        j                  |j                  | j                        |j                        |_         ||      }t        j                  t        j                  || j                        |      | j                  _        ||_        || j                   |<   | j                   j#                  |       | j$                  j#                  |       y )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                       fd}|S )Nc                 ~     j                   | g|i |\  }} j                  |i |}j                  | |      S r*   )r?   rX   rB   )r7   r   r   r@   rf   s       r   new_forwardzKHookRegistry.register_hook.<locals>.create_new_forward.<locals>.new_forward   sO    =1==fVtVvVf3+33TDVD)66vvFFr   r   )rf   ri   s   ` r   create_new_forwardz6HookRegistry.register_hook.<locals>.create_new_forward   s    G
 r   ri   )r_   r%   r$   r:   r`   rV   rX   r?   rB   hasattrrY   	functoolsupdate_wrapperpartialri   r6   ra   appendrb   )r   rd   r(   rj   rX   r6   rewritten_forwards          r   register_hookzHookRegistry.register_hook   s`   4::??$$!$ (I J 
  //0@0@A	3H 	 ""**&(!--"// 4'&-F#&55!!$"2"2D4D4DEtGWGWFN /v6#,#;#;/1A1ABDU$
  

4%V$r   c                 :    | j                   j                  |d       S r*   )r_   getr+   s     r   get_hookzHookRegistry.get_hook   s    zz~~dD))r   recursec                    || j                   j                         v rt        | j                        }| j                   |   }| j                  j	                  |      }| j
                  |   }|j                  }|j                  |j                  }||dz
  k(  r|| j                  _        n|| j
                  |dz      _        |j                  | j                        | _        | j                   |= | j                  j                  |       | j
                  j                  |       |rS| j                  j                         D ]5  \  }}	|dk(  rt        |	d      s|	j                  j                  |d       7 y y )N    _diffusers_hookFru   )r_   r%   lenra   indexrb   rX   rY   r`   r=   r0   named_modulesrk   ry   remove_hook)
r   r(   ru   	num_hooksrd   r|   r6   old_forwardmodule_namer7   s
             r   r~   zHookRegistry.remove_hook   sG   4::??$$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#V"$6#45**66tU6K	 (H r   c                 v   t        | j                        D ]9  }| j                  |   }|j                  s|j	                  | j
                         ; |rft        | j
                        j                         D ]?  \  }}|dk(  rt        |      }t        |d      s$|j                  j                  d       A y y )Nrx   ry   Frz   )reversedra   r_   rF   rG   r`   r   r}   rk   ry   reset_stateful_hooks)r   ru   	hook_namerd   r   r7   s         r   r   z!HookRegistry.reset_stateful_hooks   s    !$"2"23I::i(D    !1!12 4
 '4T5E5E'F'T'T'V#V"$&v.6#45**???N (W r   r7   c                 L    t        |d      s | |      |_        |j                  S )Nry   )rk   ry   )clsr7   s     r   check_if_exists_or_initializez*HookRegistry.check_if_exists_or_initialize  s%    v01%([F"%%%r   c                 p   t        | j                        D ]:  }| j                  |   }|j                  s|j	                  | j
                  |       < t        | j
                        j                         D ]>  \  }}|dk(  rt        |      }t        |d      s$|j                  j	                  |       @ y )Nrx   ry   )
r   ra   r_   rF   rN   r`   r   r}   rk   ry   )r   r(   r   rd   r   r7   s         r   rN   zHookRegistry._set_context  s    !$"2"23I::i(D  !!$"2"2D9 4
 $11A1A#B#P#P#RKb "6*Fv01&&33D9 $Sr   c                    d}t        | j                        D ]  \  }}| j                  |   j                  j                  t
        j                  ur| j                  |   j	                         }n#| j                  |   j                  j                  }|d| d| d| z  }|t        | j                        dz
  k  s|dz  } d| dS )	Nrx   z  (z) z - rw   
zHookRegistry(
z
))	enumeratera   r_   rc   __repr__objectr   r{   )r   registry_reprir   	hook_reprs        r   r   zHookRegistry.__repr__  s    %d&6&67LAyzz)$..77vN JJy1::<	 JJy1;;DD	s1#R	{#i[AAM3t''(1,,% 8 !s33r   )Tr*   )r   r   r   rP   rQ   rR   r"   r4   r2   rq   rt   boolr~   r   classmethodr   rN   r   __classcell__)rc   s   @r   r[   r[      s    588?? t &%) &%3 &%4 &%P*S *Y%5 *L Ld Ld L8OD OD O &588?? &~ & &
:t :t :
4# 
4r   r[   )rl   typingr   rP   utils.loggingr   utils.torch_utilsr   r   loggerr   r   r4   rV   r[   r   r   r   <module>r      sY       & - 
H	
 
% %2R Rj% %.|4 |4r   