a
    d                     @   s   d dl Z d dlmZ d dlmZ d dlmZmZmZm	Z	m
Z
 d dlmZ d dlmZ G dd deZe Ze ZG dd	 d	Zefe
e d
ddZejeeef dddZdS )    N)OrderedDictwraps)CallableDictListOptionalType)_Statec                       s   e Zd Zd fdd	Z  ZS )	_StateKey__composable_api_state_keyc                    s    t  | | dtt  S )N_)super__new__struuiduuid4)clsstring	__class__ o/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torch/distributed/_composable/contract.pyr      s    z_StateKey.__new__)r   )__name__
__module____qualname__r   __classcell__r   r   r   r   r      s   r   c                   @   s   e Zd ZdS )RegistryItemN)r   r   r   r   r   r   r   r      s   r   	state_clsc                    s   t   fdd}|S )aJ  
    Decorate a function as a composable distributed API, where the first
    argument of the function must be an :class:`nn.Module` instance. The
    decorator verifies that the wrapped function does not modify parameter,
    buffer or sub-module fully-qualified names (FQN).

    When a function ``func`` is decorated by ``@contract()``, a
    ``.state(module: nn.Module)`` method will be installed to the decorated
    function. Then you can retrieve and modify the state on a module by calling
    ``func.state(module)``.

    Example::
        >>> # xdoctest: +SKIP
        >>> import torch.nn as nn
        >>>
        >>> class MyModel(nn.Module):
        >>>     def __init__(self):
        >>>         super().__init__()
        >>>         self.l1 = nn.Linear(10, 10)
        >>>         self.l2 = nn.Linear(10, 10)
        >>>
        >>>     def forward(self, x):
        >>>         return self.l2(self.l1(x))
        >>>
        >>> @contract()
        >>> def my_feature(module: nn.Module) -> nn.Module:
        >>>     my_feature.state(module).some_state = "any value"
        >>>     return module
        >>>
        >>> model = MyModel()
        >>> my_feature(model.l1)
        >>> assert my_feature.state(model.l1).some_state == "any value"
        >>> my_feature(model.l2)
        >>> model(torch.randn(2, 10)).sum().backward()
    c                    sJ   t  tjttj d fdd}tjtt d fdd}||_|S )Nmodulereturnc                    s  t  }| jt|}t|ts&J dt  }| jt|}t|tsLJ d |vr^ j|vstJ d j d|  |   | jt  t | 	 }t | j
dd}t | jdd}	 | g|R i |}
|
d u r| }
t |
	 }t |
j
dd}t |
jdd}t|
tjs,J dt|
 tt tt dd	d
}|t| t|  |t| t|  |t|	 t|  |
S )Nz+Distributed composable API states corruptedz-Distributed composable API registry corruptedzOEach distinct composable distributed API can only be applied to a module once. z3 has already been applied to the following module.
F)Zremove_duplicatezPOutput of composable distributed APIs must be either None or nn.Module, but got )	orig_fqnsnew_fqnsc                 S   sl   | |krd S t | t | }}|| }|| }t|s>t|rTtd| d| ntd| d| d S )NzVComposable distributed API implementations cannot modify FQNs.
Only in original FQNs: z,
Only in new FQNs: z[Composable distributed API implementations cannot modify the order of FQNs.
Original FQNs: z
New FQNs: )setlenRuntimeError)r#   r$   Zorig_fqn_setZnew_fqn_setZ	orig_onlyZnew_onlyr   r   r   	check_fqn   s(    z;contract.<locals>.inner.<locals>.wrapper.<locals>.check_fqn)r   __dict__
setdefault	STATE_KEY
isinstancedictREGISTRY_KEYr   r   Znamed_parametersZnamed_buffersZnamed_modulesnnModuletyper   r   listkeys)r!   argskwargsZdefault_all_stateZ	all_statedefault_registryregistryZorig_named_paramsZorig_named_buffersZorig_named_modulesupdatedZnew_named_paramsZnew_named_buffersZnew_named_modulesr(   )funcr   r   r   wrapperH   sl    



z(contract.<locals>.inner.<locals>.wrapperc                    s   | j ti  S )N)r)   r*   r+   get)r!   r9   r   r   	get_state   s    z*contract.<locals>.inner.<locals>.get_state)r   r/   r0   r   r
   state)r9   r:   r=   r   r<   r   innerF   s
     \zcontract.<locals>.innerr   )r   r?   r   r   r   contract    s    &jr@   r    c                 C   s   t  }| jt|S )zz
    Get an ``OrderedDict`` of composable APIs that have been applied to the
    ``module``, indexed by the API name.
    )r   r)   r*   r.   )r!   r6   r   r   r   _get_registry   s    rA   )r   collectionsr   	functoolsr   typingr   r   r   r   r	   Ztorch.nnr/   Z#torch.distributed._composable_stater
   r   r   r+   r.   r   r@   r0   rA   r   r   r   r   <module>   s    