o
    h                     @   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de
e fddZdejdeeef f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   \/var/www/html/ai/venv/lib/python3.10/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                    sN   t  dtjdttj f fdd}dtjdtt f fdd}||_|S )Nmodulereturnc                    s  t  }| jt|}t|tsJ dt  }| jt|}t|ts&J d |vr/ j|vs:J d j d|  |   | jt  t | 	 }t | j
dd}t | jdd}	 | g|R i |}
|
d u rp| }
t |
	 }t |
j
dd}t |
jdd}t|
tjsJ dt|
 dtt d	tt d
tf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)remove_duplicatezPOutput of composable distributed APIs must be either None or nn.Module, but got 	orig_fqnsnew_fqns	check_keyc                 S   sn   | |krd S t | t |}}|| }|| }t|st|r+t| d| d| t| d| d| )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   orig_fqn_setnew_fqn_set	orig_only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REGISTRY_KEYr   r   named_parametersnamed_buffersnamed_modulesnnModuletyper   r   listkeys)r   argskwargsdefault_all_state	all_statedefault_registryregistryorig_named_paramsorig_named_buffersorig_named_modulesupdatednew_named_paramsnew_named_buffers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   rB   r   r   	get_state   s   z*contract.<locals>.inner.<locals>.get_state)r   r0   r1   r   r
   state)rB   rC   rF   r   rE   r   inner@   s
   "jzcontract.<locals>.innerr   )r   rI   r   rH   r   contract   s   &xrJ   r   r   c                 C   s.   t | td}|du rt }t| t| |S |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   r:   r9   r   r   r   _get_registry   s   rM   )r   )r   collectionsr   	functoolsr   typingr   r   r   r   r	   torch.nnr0   #torch.distributed._composable_stater
   r   r)   r,   r   rJ   r1   r   rM   r   r   r   r   <module>   s    
  #