U
    9%e                     @   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 ddd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)_State__composable_api_state_keyc                 C   s   |  dt t  S )N_)struuiduuid4)string r   e/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/torch/distributed/_composable/contract.pygenerate_state_key
   s    r   c                   @   s   e Zd ZdS )RegistryItemN)__name__
__module____qualname__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&tdt  }| jt|}t|tsLtd |kr^ j|ksttd j d|  |   | jt	  t | 
 }t | jdd}t | jdd}	 | f||}
|
d kr| }
t |

 }t |
jdd}t |
jdd}t|
tjs&tdt|
 tt tt tdd	d
}|t| t| d |t| t| d |t|	 t| d |
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_fqns	check_keyc                 S   st   | |krd S t | t | }}|| }|| }t|s>t|rXt| 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   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_fqnzCheck parameters, zCheck buffer, zCheck modules, )r   __dict__
setdefault	STATE_KEY
isinstancedictAssertionError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   wrapperB   s        









z(contract.<locals>.inner.<locals>.wrapperc                    s   | j ti  S )N)r$   r%   r&   get)r   r5   r   r   	get_state   s    z*contract.<locals>.inner.<locals>.get_state)r   r+   r,   r   r
   state)r5   r6   r9   r   r8   r   inner@   s
     jzcontract.<locals>.innerr   )r   r;   r   r   r   contract   s    &xr<   r   c                 C   s2   t | td}|dkr*t }t| t| |S |S dS )zz
    Get an ``OrderedDict`` of composable APIs that have been applied to the
    ``module``, indexed by the API name.
    N)getattrr*   r   setattr)r   r3   r2   r   r   r   _get_registry   s    r?   )r   )r   collectionsr   	functoolsr   typingr   r   r   r   r	   Ztorch.nnr+   Z#torch.distributed._composable_stater
   r   r&   r*   r   r<   r,   r   r?   r   r   r   r   <module>   s   
 #