o
    ۷iS+                     @   s   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 dZ
G dd	 d	ZG d
d dZG dd dZG dd dZdS )    N)Any   )
get_logger)unwrap_modulec                   @      e Zd ZdddZdS )	BaseStatereturnNc                 O   s   t d)NzWBaseState::reset is not implemented. Please implement this method in the derived class.)NotImplementedError)selfargskwargs r   K/home/ubuntu/vllm_env/lib/python3.10/site-packages/diffusers/hooks/hooks.pyreset   s   zBaseState.resetr   N)__name__
__module____qualname__r   r   r   r   r   r          r   c                   @   s@   e Zd ZddefddZdd Zdeddfd	d
ZdddZdS )StateManagerN	state_clsc                 C   s:   || _ |d ur	|nd| _|d ur|ni | _i | _d | _d S )Nr   )
_state_cls
_init_args_init_kwargs_state_cache_current_context)r
   r   	init_argsinit_kwargsr   r   r   __init__#   s
   
zStateManager.__init__c                 C   sJ   | j d u r	td| 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
   r   r   r   	get_state*   s
   
zStateManager.get_statenamer   c                 C   s
   || _ d S N)r   r
   r#   r   r   r   set_context1      
zStateManager.set_contextc                 O   s>   t | j D ]\}}|j|i | | j| qd | _d S r$   )listr   itemsr   popr   )r
   r   r   r#   stater   r   r   r   4   s   
zStateManager.reset)NNr   )	r   r   r   r   r   r"   strr&   r   r   r   r   r   r   "   s
    r   c                   @   s   e Zd ZdZdZdd ZdejjdejjfddZ	dejjdejjfd	d
Z
dejjdeee eeef f fddZdejjdedefddZdejjdejjfddZdejjfddZdejjdeddfddZdS )	ModelHookzl
    A hook that contains callbacks to be executed just before and after the forward method of a model.
    Fc                 C   s
   d | _ d S r$   )fn_refr!   r   r   r   r   B   r'   zModelHook.__init__moduler   c                 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
   r/   r   r   r   initialize_hookE      zModelHook.initialize_hookc                 C   r0   )z
        Hook that is executed when a model is deinitialized.

        Args:
            module (`torch.nn.Module`):
                The module attached to this hook.
        r   r1   r   r   r   deinitalize_hookO   r3   zModelHook.deinitalize_hookc                 O   s   ||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
   r/   r   r   r   r   r   pre_forwardY   s   zModelHook.pre_forwardoutputc                 C   s   |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
   r/   r6   r   r   r   post_forwardj   s   zModelHook.post_forwardc                 C   r0   )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   r1   r   r   r   detach_hookx   r3   zModelHook.detach_hookc                 C   s   | j rtd|S )NzFThis hook is stateful and needs to implement the `reset_state` method.)_is_statefulr	   r1   r   r   r   reset_state   s   zModelHook.reset_stater#   Nc                 C   s0   t | D ]}t| |}t|tr|| q|S r$   )dirgetattr
isinstancer   r&   )r
   r/   r#   	attr_nameattrr   r   r   _set_context   s   


zModelHook._set_context)r   r   r   __doc__r9   r   torchnnModuler2   r4   tupler   dictr,   r5   r7   r8   r:   r@   r   r   r   r   r-   ;   s    
*

r-   c                   @   r   )HookFunctionReferencer   Nc                 C   s   d| _ d| _d| _d| _dS )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)r5   r7   forwardoriginal_forwardr!   r   r   r   r      s   
zHookFunctionReference.__init__r   )r   r   r   r   r   r   r   r   rG      r   rG   c                       s   e Zd Zdejjddf fddZdededdfdd	Z	dededB fd
dZ
ddededdfddZddeddfddZedejjdd fddZddedB ddfddZdefddZ  ZS )HookRegistry
module_refr   Nc                    s&   t    i | _|| _g | _g | _d S r$   )superr   hooks_module_ref_hook_order_fn_refs)r
   rK   	__class__r   r   r      s
   

zHookRegistry.__init__hookr#   c                 C   s   || j  v rtd| d|| j| _dtfdd}| jj}t }|j|_|j|_||_t	|drE||_
tt|j| j|j|_||}tt|| j|| j_||_|| j |< | j| | j| d S )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                    s    fdd}|S )Nc                    s8    j | g|R i |\}} j|i |} | |S r$   )r5   rH   r7   )r/   r   r   r6   rT   r   r   new_forward   s   zKHookRegistry.register_hook.<locals>.create_new_forward.<locals>.new_forwardr   )rT   rV   r   rU   r   create_new_forward   s   z6HookRegistry.register_hook.<locals>.create_new_forwardrV   )rM   r    r   r2   rN   rG   rH   r5   r7   hasattrrI   	functoolsupdate_wrapperpartialrV   r.   rO   appendrP   )r
   rS   r#   rW   rH   r.   rewritten_forwardr   r   r   register_hook   s0   


zHookRegistry.register_hookc                 C   s   | j |d S r$   )rM   getr%   r   r   r   get_hook   s   zHookRegistry.get_hookTrecursec           
      C   s   || j  v rQt| j}| j | }| j|}| j| }|j}|jd ur'|j}||d kr2|| j_n|| j|d  _|	| j| _| j |= | j
| | j
| |ro| j D ]\}}	|dkraqXt|	drn|	jj|dd qXd S d S )N    _diffusers_hookFra   )rM   r    lenrO   indexrP   rH   rI   rN   r4   r*   named_modulesrX   rd   remove_hook)
r
   r#   ra   	num_hooksrS   rg   r.   old_forwardmodule_namer/   r   r   r   ri      s0   





zHookRegistry.remove_hookc                 C   sz   t | jD ]}| j| }|jr|| j q|r9t| j D ]\}}|dkr(qt|}t|dr8|j	j
dd qd S d S )Nrc   rd   Fre   )reversedrO   rM   r9   r:   rN   r   rh   rX   rd   reset_stateful_hooks)r
   ra   	hook_namerS   rl   r/   r   r   r   rn      s   

z!HookRegistry.reset_stateful_hooksr/   c                 C   s   t |ds
| ||_|jS )Nrd   )rX   rd   )clsr/   r   r   r   check_if_exists_or_initialize  s   

z*HookRegistry.check_if_exists_or_initializec                 C   sr   t | jD ]}| j| }|jr|| j| qt| j D ]\}}|dkr'qt|}t|dr6|j	| qd S )Nrc   rd   )
rm   rO   rM   r9   r@   rN   r   rh   rX   rd   )r
   r#   ro   rS   rl   r/   r   r   r   r@     s   

zHookRegistry._set_contextc                 C   s   d}t | jD ]7\}}| j| jjtjur| j|  }n| j| jj}|d| d| d| 7 }|t| jd k r>|d7 }qd| dS )	Nrc   z  (z) z - rb   
zHookRegistry(
z
))	enumeraterO   rM   rR   __repr__objectr   rf   )r
   registry_repriro   	hook_reprr   r   r   rt     s   zHookRegistry.__repr__)Tr$   )r   r   r   rB   rC   rD   r   r-   r,   r^   r`   boolri   rn   classmethodrq   r@   rt   __classcell__r   r   rQ   r   rJ      s    	(rJ   )rY   typingr   rB   utils.loggingr   utils.torch_utilsr   r   loggerr   r   r-   rG   rJ   r   r   r   r   <module>   s   U