
    sgJ%                         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
mZmZ d dlZd dlmZ d dlmZ d dlmZ ddZ e       Z e       Z G d d	      Zefd
ee   fdZdej2                  de	eeef      fdZy)    N)OrderedDictwraps)CallableDictListOptionalSequenceTypeUnion)_State)_get_root_modulesc                 F    |  dt        t        j                                S )N_)struuiduuid4)strings    Y/var/www/html/venv/lib/python3.12/site-packages/torch/distributed/_composable/contract.pygenerate_state_keyr      s    XQs4::<()**    c                       e Zd Zy)RegistryItemN)__name__
__module____qualname__ r   r   r   r      s    r   r   	state_clsc                 .     t                fd       }|S )a%  
    Decorate a function as a composable distributed API, where the first
    argument of the function must be an :class:`nn.Module` instance or sequence
    of :class:`nn.Module` instances.

    The decorator verifies that the decorated function does not modify
    fully-qualified names (FQNs) for parameters, buffers, or modules. The
    decorated function can return different module instances than the input
    modules; the FQN invariant will be enforced following the input order.

    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) -> None:
        >>>         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                     t               dt        t        j                  t        t        j                     f   dt
        t        j                     f fd       }dt        j                  dt
        t           f fd}||_        |S )Nmodulereturnc                    | }t        | t        j                        r| g}nt        t	        |             }        }t               }g }g }g }	|D ]f  } t               }
t               }| j                  j                  t        |
      }t        |t              st        d|       | j                  j                  t        |      }t        |t              st        d|       |v sj                  |v rt        dj                   d|        |j                  |       |j                  j                  |       |j                  t        | j                                      |j                  t        | j!                                      |	j                  t        | j#                                      i  |g|i |}||}t        |t        j                        r|g}nt        t	        |            }g }g }g }|D ]z  } |j                  t        | j                                      |j                  t        | j!                                      |j                  t        | j#                                      | t%        |	      }t%        |      }||k7  rt        j                   d| d| d      dt&        t(           d	t&        t(           d
t(        fd}t+        ||      D ]=  \  }} |t	        |j-                               t	        |j-                               d       ? t+        ||      D ]=  \  }} |t	        |j-                               t	        |j-                               d       ? t+        |	|      D ]=  \  }} |t	        |j-                               t	        |j-                               d       ? |S )Nz-Distributed composable API states corrupted: z/Distributed composable API registry corrupted: zOEach distinct composable distributed API can only be applied to a module once. z3 has already been applied to the following module:
zB should return the same number of modules as input modulesInputs: z modules
Outputs: z modules	orig_fqnsnew_fqns	check_keyc                     | |k(  ry t        |       t        |      }}||z
  }||z
  }t        |      st        |      rt        | d| d|       t        | d| d|       )NzVComposable distributed API implementations cannot modify FQNs.
FQNs only in original: z
FQNs only in new: 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_onlys          r   	check_fqnz;contract.<locals>.inner.<locals>.wrapper.<locals>.check_fqn   s    (,/	NCMk(;6	&5y>S]&$+22; =--5J8  '$+**3 5%%-J	0 r   zChecking parameters: zChecking buffers: zChecking modules: )
isinstancennModuler   listr   r   __dict__
setdefault	STATE_KEYdictAssertionErrorREGISTRY_KEYr   appendnamed_parametersnamed_buffersnamed_modulesr)   r   r   zipkeys)r!   argskwargs
inp_modulemodulesstateregistry_itemall_orig_named_paramsall_orig_named_buffersall_orig_named_modulesdefault_all_statedefault_registry	all_stateregistryupdatedupdated_modulesall_new_named_paramsall_new_named_buffersall_new_named_modulesnum_orig_modulesnum_new_modulesr/   orig_named_paramsnew_named_paramsorig_named_buffersnew_named_buffersorig_named_modulesnew_named_modulesfuncr   s                               r   wrapperz(contract.<locals>.inner.<locals>.wrapperI   s     J&")),!(
 ,DL9KE(NM
 DF!DF"AC"! S<GM!<GM 4:OO4N4N05	 ")T2(G	{S  5;OO4N4N "25 "(D1(I(T  9$(A(((, 7..4X7 
 $$T51##DMM=A%,,[9P9P9R-ST&--k&:N:N:P.QR&--k&:N:N:P.QR9S< :777G$'299-#*)"3D4D"EBD CE!@B!) R$++K8O8O8Q,RS%,,[9M9M9O-PQ%,,[9M9M9O-PQR
  ##9:!"78O?2$}}o &/0 1  /0: T#Y $s) PS . 8;%';8 3!#3 *//12)..01+ :=&(=: 5"$5 +0023*//12( :=&(=: 5"$5 +0023*//12( Nr   c                 b    | j                   j                  t        i       j                        S )N)r4   r5   r6   get)r!   rZ   s    r   	get_statez*contract.<locals>.inner.<locals>.get_state   s/    ??-- cr   )r   r   r1   r2   r
   r	   r   rD   )rZ   r[   r^   r   s   `  r   innerzcontract.<locals>.innerG   sx    	t	"))Xbii%889	bii 	 
	B	bii 	HV,< 	 "r   r   )r   r_   s   ` r   contractr`      s'    T 9M M^ Lr   r!   r"   c                 $    t        | t        d      S )z
    Get an ``OrderedDict`` of composable APIs that have been applied to the
    ``module``, indexed by the API name. If no API has been applied, then this
    returns ``None``.
    N)getattrr9   )r!   s    r   _get_registryrc      s     6<..r   )__composable_api_state_key)r   collectionsr   	functoolsr   typingr   r   r   r	   r
   r   r   torchtorch.nnr1   #torch.distributed._composable_stater   torch.distributed.utilsr   r   r6   r9   r   r`   r2   r   rc   r   r   r   <module>rl      s     #  H H H   6 5+  	!#	 	 (. zV zz/")) /c<6G1H(I /r   