
    [Th>                     p   S r SSKrSSKrSSKJr  SSKrSSKJr  SSKJ	r	J
r
  SSKJr  SSKJr  SS	KJr  SS
KJrJr  SSKJr  SSKJr  SSKJr  SSKJrJr  \(       a  SSKJr   " S S\5      rS r S r! " S S\5      r" " S S\5      r# " S S\5      r$ " S S\5      r% " S S\5      r& " S S \5      r'g)!a  
Distributed computing variable tracking classes for PyTorch Dynamo.

This module implements variable tracking for distributed computing components:
- Process Groups (for collective communication)
- Device Meshes (for distributed tensor sharding)
- Placement Types (for specifying distribution strategies)
- Distributed Tensors and their operations
- Backward hooks for distributed module operations

These classes are responsible for tracking distributed operations during graph
compilation while maintaining proper guards and handling distributed-specific
behaviors. They ensure correct handling of distributed components like process
groups, device meshes, and placement strategies while preserving proper semantics
for distributed tensor operations in the compiled code.

The implementation provides special handling for distributed package availability
checks and proper tracking of distributed state and operations across processes.
    N)TYPE_CHECKING)BackwardState   )compiled_autograd	variables)trace_wrapped)unimplemented_v2)%call_module_hooks_from_backward_state)GuardBuilderinstall_guard)
AttrSource)istype   )VariableTracker)ConstantVariableEnumVariable)InstructionTranslatorc                   F   ^  \ rS rSrSrSU 4S jjrS r\S 5       rSr	U =r
$ )DistributedVariable-   a_  
The base distributed variable that encapsulates common methods
for the distributed objects (i.e. ProcessGroup, DeviceMesh, etc.).
Concrete distributed objects could inherit this class and add object
specific logic.

i.e. It provides the check on the distributed package existance
and hold the tracking value for the corresponding distributed object.
c                 ~   > [         TU ]  " S0 UD6  [        R                  5       (       d  [	        SSSS/S9  Xl        g )Nz+torch.distributed package is not available! zOThe PyTorch package doesn't include torch.distributed when builing from source.zESet USE_DISTRIBUTED=1 to enable it when building PyTorch from source.gb_typecontextexplanationhints )super__init__r   is_availabler	   value)selfr"   kwargs	__class__s      [/var/www/auris/envauris/lib/python3.13/site-packages/torch/_dynamo/variables/distributed.pyr    DistributedVariable.__init__8   sB    "6""//11Em[	 
    c                 ,    [        U R                  5      $ N)typer"   r#   s    r&   python_typeDistributedVariable.python_typeE   s    DJJr(   c                  >    [         R                  R                  5       $ r*   )torchdistributedr!   r   r(   r&   r!    DistributedVariable.is_availableH   s       --//r(   r"   )returnN)__name__
__module____qualname____firstlineno____doc__r    r-   staticmethodr!   __static_attributes____classcell__r%   s   @r&   r   r   -   s&      0 0r(   r   c                     [         R                  5       (       d  gSSKJn  [        R
                  " U 5      =(       a    XR                  L $ )NFr   )DTensor)r   r!   torch.distributed.tensorr?   inspect
isfunction
from_local)r"   r?   s     r&   is_from_localrD   N   s6    ++--0e$D2D2D)DDr(   c                     [         R                  5       (       d  gSSKJnJnJnJnJn  UUUUU/n[        R                  " U 5      =(       a    X;   $ )NFr   )_get_group_size_by_name_get_group_tag_rank_not_in_group$_resolve_group_name_by_ranks_and_tagget_process_group_ranks)
r   r!   "torch.distributed.distributed_c10drF   rG   rH   rI   rJ   rA   rB   )r"   rF   rG   rH   rI   rJ   constant_processgroup_functionss          r&   is_constant_pg_functionsrM   V   sR    ++--  	 ,'# e$Q)QQr(   c                   L   ^  \ rS rSrSr\S 5       rSSS\S\4U 4S jjr	S	r
U =r$ )
WorldMetaClassVariablem   zt
Tracks torch.distributed.GroupMember and torch.distributed.group, which are
instances of the metaclass _WorldMeta.
c                 T    U R                  5       (       d  gSSKJn  [        U5      UL $ )NFr   )
_WorldMeta)r!   rK   rR   r+   )clsr"   rR   s      r&   is_group_member_type+WorldMetaClassVariable.is_group_member_types   s&    !!AE{j((r(   txr   namer4   c                   > US:X  a[  [        U R                  SS9n[        UR                  [        R
                  5      5        [        U R                  R                  5      $ US:X  a[  [        U R                  SS9n[        UR                  [        R
                  5      5        [        U R                  R                  5      $ [        TU ]1  X5      $ )NWORLD)basememberNON_GROUP_MEMBER)r   sourcer   
make_guardr   ID_MATCHProcessGroupVariabler"   rY   r   r\   r   var_getattr)r#   rV   rW   r]   r%   s       r&   ra   "WorldMetaClassVariable.var_getattr|   s    7?T[[AF&++L,A,ABC'

(8(899''T[[9KLF&++L,A,ABC

 ; ;<<w"2,,r(   r   )r5   r6   r7   r8   r9   classmethodrT   strr   ra   r;   r<   r=   s   @r&   rO   rO   m   s<    
 ) )	-5 	-S 	-_ 	- 	-r(   rO   c                   R   ^  \ rS rSr\S 5       rS r        SU 4S jjrSrU =r	$ )PlacementClassVariable   c                     [         R                  5       (       d  gSSKJn  [	        U 5      [        L =(       a    [        X5      $ NFr   )	Placement)r   r!   (torch.distributed.tensor.placement_typesrj   r+   
issubclassr"   rj   s     r&   is_placement_type(PlacementClassVariable.is_placement_type   s2     #//11FE{d"Cz%'CCr(   c                     U R                   $ r*   r3   r,   s    r&   as_python_constant)PlacementClassVariable.as_python_constant       zzr(   c                 |  > [         R                  " U R                  SS 5      [        R                  4;   aw  U R
                  (       af  [        R	                  U R                  5      n[        U5      n[         R                  " U R                  SS 5      (       a  UR                  USX#5        U$ [        TU ]%  XU5      $ )N__new__r    )
rA   getattr_staticr"   objectru   r]   PlacementVariablecall_methodr   call_function)r#   rV   argsr$   new_objvarr%   s         r&   rz   $PlacementClassVariable.call_function   s     ""4::y$?FNNCTT nnTZZ0G#G,C%%djj*dCCJ=
w$Rv66r(   r   )rV   r   r{   list[VariableTracker]r$   dict[str, VariableTracker]r4   r   )
r5   r6   r7   r8   r:   rn   rq   rz   r;   r<   r=   s   @r&   rf   rf      sL    D D7#7 &7 -	7
 
7 7r(   rf   c                   j   ^  \ rS rSr\S 5       rS rSSS\S\4U 4S jjr	      SU 4S	 jjr
S
rU =r$ )rx      c                 X    [         R                  5       (       d  gSSKJn  [	        X5      $ ri   )r   r!   rk   rj   
isinstancerm   s     r&   is_placementPlacementVariable.is_placement   s$     #//11F%++r(   c                     U R                   $ r*   r3   r,   s    r&   rq   $PlacementVariable.as_python_constant   rs   r(   rV   r   rW   r4   c                    > US:X  a*  [         R                  " U R                  R                  5      $ [        TU ]  X5      $ )Ndim)r   creater"   r   r   ra   r#   rV   rW   r%   s      r&   ra   PlacementVariable.var_getattr   s3    5=#**4::>>::w"2,,r(   c                   > SSK Jn  / SQnX&;   Ga   [        U R                  5      n[        R
                  " USS 5      b   S5       e[        R
                  " Xr5      nU[        R                  L a  UR                  " S 5      $ U V	s/ s H  oR                  5       PM     nn	UR                  5        V
Vs0 s H  u  pXR                  5       _M     nn
nUS:X  a  U" U R                  /UQ70 UD6  U $ U" U R                  /UQ70 UD6nUR                  " U5      $ [        TU ]5  XX45      $ ! [         a    S n Nf = fs  sn	f s  snn
f )Nr   )r   )r    __setattr__is_shard
is_partialis_replicate__getattr__zno custom getattr allowed!r   )r   r   r+   r"   rA   rv   AttributeErrorrw   r    r   rq   itemsr   ry   )r#   rV   rW   r{   r$   r   constant_fold_functions
value_typemethodxkvconstant_valr%   s                r&   ry   PlacementVariable.call_method   s=    	'#
 *!$**-
**:}dKS0/0S //
A ('..t44489Dq((*DD9<BLLNKNDAa--//NFK}$tzz3D3F3!$**>t>v>L#**<88w"2T:: " 
 :Ks   AD* D<5E*D98D9r   r{   r   r$   r   r4   r   )r5   r6   r7   r8   r:   r   rq   rd   r   ra   ry   r;   r<   r=   s   @r&   rx   rx      s]    , ,-5 -S -_ -
*; &	*;
 -*; 
*; *;r(   rx   c                   j   ^  \ rS rSr\S 5       rS rSSS\S\4U 4S jjr	      SU 4S	 jjr
S
rU =r$ )DeviceMeshVariable   c                 X    [         R                  5       (       d  gSSKJn  [	        X5      $ )NFr   )
DeviceMesh)r   r!   torch.distributed.device_meshr   r   )r"   r   s     r&   is_device_mesh!DeviceMeshVariable.is_device_mesh   s$     #//11<e((r(   c                     U R                   $ r*   r3   r,   s    r&   rq   %DeviceMeshVariable.as_python_constant   rs   r(   rV   r   rW   r4   c                    > US:X  a*  [         R                  " U R                  R                  5      $ US:X  a*  [         R                  " U R                  R                  5      $ [
        TU ]  X5      $ )Nndimdevice_type)r   r   r"   r   r   r   ra   r   s      r&   ra   DeviceMeshVariable.var_getattr   sV    6>#**4::??;;= #**4::+A+ABBw"2,,r(   c                   > US:X  a  U Vs/ s H  oUR                  5       PM     nnUR                  5        VVs0 s H  u  pxXxR                  5       _M     n	nn[        R                  " U R                  R
                  " U0 U	D65      $ US:X  a.  [        R                  " U R                  R                  5       5      $ US:X  av  U Vs/ s H  oUR                  5       PM     nnUR                  5        VVs0 s H  u  pxXxR                  5       _M     n	nn[        U R                  R                  " U0 U	D65      $ US:X  a#  [        U R                  R                  5       5      $ [        T
U ]-  XX45      $ s  snf s  snnf s  snf s  snnf )Nsizeget_coordinate	get_group_get_or_create_default_group)rq   r   r   r   r"   r   r   r`   r   r   r   ry   )r#   rV   rW   r{   r$   r   
const_argsr   r   const_kwargsr%   s             r&   ry   DeviceMeshVariable.call_method   sO    6>:>?$Q..0$J?BH,,.Q.$!A3355.LQ#**4::??J+W,+WXX###**4::+D+D+FGG;:>?$Q..0$J?BH,,.Q.$!A3355.LQ'

$$jALA  11'

(O(O(QRRw"2T:: @Q
 @Qs   E2E7E=5Fr   r   )r5   r6   r7   r8   r:   r   rq   rd   r   ra   ry   r;   r<   r=   s   @r&   r   r      s]    ) )-5 -S -_ -; &	;
 -; 
; ;r(   r   c                   b   ^  \ rS rSrSrS r      SU 4S jjrS	U 4S jjr\S 5       r	Sr
U =r$ )
r`   i  ao  
We don't want a ProcessGroup object to end up in our output graph.

But it's common for dynamo to intercept a PG that is then used to get info like
rank() or world_size(), as well as passed to utility functions in distributed_c10d
which desugar it into plain types like a ranklist and tag.

For convenience and proper guarding, we construct a variable type.

TODO: make it possible to use ProcessGroupVariable as input to simple functions
      like _expand_group without dynamo complaining about making a proxy for it.
      It is not a tensor-like type, and we don't want a proxy- but dynamo assumes
      torch library functions are dealing with tensor-like types and would have proxies
      for their args.
TODO: should we make this inherit VT instead of UDOV? Do we want any of the default behaviors
      or just graph-break whenever one of our special cases is not hit?
c                     U R                   $ r*   r3   r,   s    r&   rq   'ProcessGroupVariable.as_python_constant+  rs   r(   c                   > US:X  a7  [         R                  R                  U R                  R	                  5       5      $ US:X  a7  [         R                  R                  U R                  R                  5       5      $ US:X  a7  [         R                  R                  U R                  R                  5       5      $ [        TU ]!  XX45      $ )Nrankr   _get_backend_name)	r   r   r   r"   r   r   r   r   ry   r#   rV   rW   r{   r$   r%   s        r&   ry    ProcessGroupVariable.call_method.  s     6>--44TZZ__5FGG6>--44TZZ__5FGG&&--44TZZ5Q5Q5STTw"2T::r(   c                    >^ ^^ TS:X  a3  [         R                  R                  T R                  R                  5      $ TS;   a  [         R
                  " UU U4S j5      $ [        TT ]  TT5      $ )N
group_name)r   r   c                  *   > TR                  TTX5      $ r*   )ry   )r{   r$   rW   r#   rV   s     r&   <lambda>2ProcessGroupVariable.var_getattr.<locals>.<lambda>C  s    (8(8T4(Pr(   )r   r   r   r"   r   LambdaVariabler   ra   r   s   ```r&   ra    ProcessGroupVariable.var_getattr>  s_    <--44TZZ5J5JKK##++P  w"2t,,r(   c                 h    [         R                  5       (       d  gSSKJn  SSKJn  [        XU45      $ )NFr   )ProcessGroup)FakeProcessGroup)r   r!   torch._C._distributed_c10dr   +torch.testing._internal.distributed.fake_pgr   r   )r"   r   r   s      r&   is_process_group%ProcessGroupVariable.is_process_groupH  s-     #//11;Pe,<=>>r(   r   r   rV   r   )r5   r6   r7   r8   r9   rq   ry   ra   r:   r   r;   r<   r=   s   @r&   r`   r`     sI    $; &	;
 -; 
; - ? ?r(   r`   c            
          ^  \ rS rSrSr\S\S\S\4S j5       rS\R                  R                  S\S\S\SS	4
U 4S
 jjrS rS\\   S\\\4   S\4U 4S jjrSS jrSrU =r$ )BackwardHookVariableiS  zI
Handles torch.utils.hooks.BackwardHook for module-level backward
hooks.
module
user_hooksuser_pre_hooksc                   ^^	^
 [         R                  (       d  [        SSSS/S9  S[        4UU	U
4S jjnU R                  R                  US5      u  mnU R                  R                  U5      u  m
nU R                  R                  U5      u  m	nU R                  R                  SUU40 5      n[        R                  R                  R                  S S	S	5      UR                  R                  S
'   [        XqX#5      $ )Nz7Module-level backwards hooks require compiled autograd.r   zREnable compiled autograd by setting torch._dynamo.config.compiled_autograd = True.r   bw_statec                    > [         R                  R                  R                  S[        R
                  " [        [        U TTS94[        R
                  " [        [        U TTS945      $ )z
Rather than installing the user hooks in the graph (which
don't survive AotAutograd), we install hooks that will call
trace_wrapped in the backward pass that CompiledAutograd
can turn into actual hook calls.
N)fnr   
hooks_namemodule_name)r0   utilshooksBackwardHook	functoolspartialr   r
   )r   r   user_hooks_nameuser_pre_hooks_names    r&   _in_graph_bw_hooks7BackwardHookVariable.create.<locals>._in_graph_bw_hooksj  sk     ;;$$11%%%@!)#2$/ %%%@!)#6$/ r(   modrz   r   example_value)r   compiled_autograd_enabledr	   r   outputadd_backward_state_hookcreate_proxyr0   r   r   r   nodemetar   )rV   r   r   r   r   bw_state_proxy_proxyr   r   r   s           @@@r&   r   BackwardHookVariable.createY  s     !::Qh		 	 	: ')ii&G&GPU&V#^!#!B!B>!RQYY>>zJ		&&	
 ,1;;+<+<+I+I$PRTV+W

(#E:NNr(   r   r4   Nc                 V   > [         TU ]  " S0 UD6  Xl        X l        X0l        X@l        g )Nr   )r   r    r   r   r   r   )r#   r   r   r   r   optionsr%   s         r&   r    BackwardHookVariable.__init__  s*     	#7#
$,r(   c                     U R                   $ r*   )r   r,   s    r&   as_proxyBackwardHookVariable.as_proxy  rs   r(   r{   r$   c                 \   > US;   a  U R                   " X/UQ70 UD6$ [        TU ]	  XX45      $ )N)setup_input_hooksetup_output_hook)_setup_hookr   ry   r   s        r&   ry    BackwardHookVariable.call_method  s;     <<##B>t>v>>w"2T::r(   c           
          SSK Jn  U" UUR                  R                  SUU R	                  5       UR	                  5       40 5      5      $ )Nr   )wrap_fx_proxyry   )builderr   r   r   r   )r#   rV   hook_method_namer{   r   s        r&   r    BackwardHookVariable._setup_hook  sD    *II"" $--/2	
 	
r(   )r   r   r   r   r   )r5   r6   r7   r8   r9   r:   r   r   r0   fxProxyr    r   listdictrd   ry   r   r;   r<   r=   s   @r&   r   r   S  s    
 7O7O $7O (	7O 7Or-xx~~-  - $	-
 (- 
-	; ?#		;
 S/)*	; 
	;
 
r(   r   )(r9   r   rA   typingr   r0   %torch.fx.experimental._backward_stater   r   r   r   _trace_wrapped_higher_order_opr   excr	   external_utilsr
   guardsr   r   r]   r   r   r   rZ   r   constantr   r   torch._dynamo.symbolic_convertr   r   rD   rM   rO   rf   rx   r   r`   r   r   r(   r&   <module>r     s   (      ? + : " B 0   ! 4 D0/ 0BER.-0 -6 70  7F=;+ =;@*;, *;Z8?. 8?vg
? g
r(   