o
    IÆ&iA  ã                   @   sÀ   d dl Z d dl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lmZ dd	lmZ G d
d„ deƒZdd„ Zdd„ ZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZdS )é    N)ÚDictÚListé   )Ú	variables)Úunimplemented)Úistypeé   )ÚVariableTracker©ÚConstantVariablec                       s(   e Zd Z‡ fdd„Zedd„ ƒZ‡  ZS )ÚDistributedVariablec                    s*   t ƒ jdi |¤Ž t ¡ stdƒ d S d S )Nz+torch.distributed package is not available!© )ÚsuperÚ__init__r   Úis_availabler   )ÚselfÚkwargs©Ú	__class__r   úNC:\wamp64\www\opt\env\Lib\site-packages\torch/_dynamo/variables/distributed.pyr      s   ÿzDistributedVariable.__init__c                   C   s
   t j ¡ S ©N)ÚtorchÚdistributedr   r   r   r   r   r      s   
z DistributedVariable.is_available)Ú__name__Ú
__module__Ú__qualname__r   Ústaticmethodr   Ú__classcell__r   r   r   r   r      s    r   c                 C   s,   t  ¡ sdS ddlm} t | ¡o| |ju S )NFr   )ÚDTensor)r   r   Ztorch.distributed._tensorr   ÚinspectÚ
isfunctionZ
from_local)Úvaluer   r   r   r   Úis_from_local   s   r"   c                 C   s6   t  ¡ sdS ddlm}m} ||g}t | ¡o| |v S )NFr   )Ú_get_group_tagÚget_process_group_ranks)r   r   Z"torch.distributed.distributed_c10dr#   r$   r   r    )r!   r#   r$   Zconstant_processgroup_functionsr   r   r   Úis_constant_pg_functions    s   þr%   c                       sB   e Zd Z‡ fdd„Zedd„ ƒZ							
d‡ fdd„Z‡  ZS )ÚPlacementClassVariablec                    ó   t ƒ jdi |¤Ž || _d S ©Nr   ©r   r   r!   ©r   r!   r   r   r   r   r   2   ó   
zPlacementClassVariable.__init__c                 C   s.   t  ¡ sdS ddlm} t| ƒtu ot| |ƒS ©NFr   )Ú	Placement)r   r   Ú)torch.distributed._tensor.placement_typesr-   ÚtypeÚ
issubclass©r!   r-   r   r   r   Úis_placement_type6   s   z(PlacementClassVariable.is_placement_typeÚargsúList[VariableTracker]r   úDict[str, VariableTracker]Úreturnr	   c                    sf   t  | jdd ¡tjfv r+| jr+t | j¡}t|ƒ}t  | jdd ¡r+| |d||¡ |S tƒ  	|||¡S )NÚ__new__r   )
r   Úgetattr_staticr!   Úobjectr7   ÚsourceÚPlacementVariableÚcall_methodr   Úcall_function)r   Útxr3   r   Znew_objÚvarr   r   r   r=   @   s   ÿz$PlacementClassVariable.call_function©r3   r4   r   r5   r6   r	   )r   r   r   r   r   r2   r=   r   r   r   r   r   r&   1   s    
	ÿÿþr&   c                       sJ   e Zd Z‡ fdd„Zedd„ ƒZdd„ Z					
		d‡ fdd„Z‡  ZS )r;   c                    r'   r(   r)   r*   r   r   r   r   S   r+   zPlacementVariable.__init__c                 C   ó"   t  ¡ sdS ddlm} t| |ƒS r,   )r   r   r.   r-   Ú
isinstancer1   r   r   r   Úis_placementW   ó   
zPlacementVariable.is_placementc                 C   ó   | j S r   ©r!   ©r   r   r   r   Úas_python_constanta   ó   z$PlacementVariable.as_python_constantr3   r4   r   r5   r6   r	   c           	         sÊ   ddl m} ddg}||v r\zt| jƒ}t |dd ¡d u s!J dƒ‚t ||¡}W n ty3   d }Y nw |tju r>| 	d ¡S dd„ |D ƒ}d	d
„ | 
¡ D ƒ}|| jg|¢R i |¤Ž | S tƒ  ||||¡S )Nr   r
   r   Ú__setattr__Ú__getattr__zno custom getattr allowed!c                 S   s   g | ]}|  ¡ ‘qS r   ©rH   )Ú.0Úxr   r   r   Ú
<listcomp>|   s    z1PlacementVariable.call_method.<locals>.<listcomp>c                 S   s   i | ]	\}}||  ¡ “qS r   rL   )rM   ÚkÚvr   r   r   Ú
<dictcomp>}   s    z1PlacementVariable.call_method.<locals>.<dictcomp>)Ú r   r/   r!   r   r8   ÚAttributeErrorr9   r   ÚcreateÚitemsr   r<   )	r   r>   Únamer3   r   r   Úallowed_methodsZ
value_typeÚmethodr   r   r   r<   d   s&   
ÿÿ

zPlacementVariable.call_methodr@   )	r   r   r   r   r   rC   rH   r<   r   r   r   r   r   r;   R   s    
	üûúr;   c                       sF   e Zd Z‡ fdd„Zedd„ ƒZdd„ Zdedef‡ fd	d
„Z	‡  Z
S )ÚDeviceMeshVariablec                    r'   r(   r)   r*   r   r   r   r   …   r+   zDeviceMeshVariable.__init__c                 C   rA   )NFr   )Ú
DeviceMesh)r   r   Ztorch.distributed.device_meshr[   r   )r!   r[   r   r   r   Úis_device_mesh‰   rD   z!DeviceMeshVariable.is_device_meshc                 C   rE   r   rF   rG   r   r   r   rH   “   rI   z%DeviceMeshVariable.as_python_constantrW   r6   c                    s$   |dkrt  | jj¡S tƒ  ||¡S )NÚndim)r   rU   r!   r]   r   Úvar_getattr©r   r>   rW   r   r   r   r^   –   s   zDeviceMeshVariable.var_getattr)r   r   r   r   r   r\   rH   Ústrr	   r^   r   r   r   r   r   rZ   „   s    
	rZ   c                       sb   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z				
			d‡ fdd„Z‡ fdd„Ze	dd„ ƒZ
‡  ZS )ÚProcessGroupVariablea£  
    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                    r'   r(   r)   r*   r   r   r   r   ¯   r+   zProcessGroupVariable.__init__c                 C   rE   r   rF   rG   r   r   r   rH   ³   rI   z'ProcessGroupVariable.as_python_constantc                 C   s
   t | jƒS r   )r/   r!   rG   r   r   r   Úpython_type¶   s   
z ProcessGroupVariable.python_typer3   r4   r   r5   r6   r	   c                    sF   |dkrt j | j ¡ ¡S |dkrt j | j ¡ ¡S tƒ  ||||¡S )NÚrankÚsize)r   r   rU   r!   rc   rd   r   r<   )r   r>   rW   r3   r   r   r   r   r<   ¹   s
   z ProcessGroupVariable.call_methodc                    s,   ˆ dv rt  ‡ ‡‡fdd„¡S tƒ  ˆˆ ¡S )N)rc   rd   c                     s   ˆ  ˆˆ | |¡S r   )r<   )r3   r   ©rW   r   r>   r   r   Ú<lambda>Ê   s    z2ProcessGroupVariable.var_getattr.<locals>.<lambda>)r   ZLambdaVariabler   r^   r_   r   re   r   r^   Ç   s
   ÿz ProcessGroupVariable.var_getattrc                 C   s2   t  ¡ sdS ddlm} ddlm} t| ||fƒS )NFr   )ÚProcessGroup)ÚFakeProcessGroup)r   r   Ztorch._C._distributed_c10drg   Z+torch.testing._internal.distributed.fake_pgrh   r   )r!   rg   rh   r   r   r   Úis_process_groupÏ   s
   z%ProcessGroupVariable.is_process_groupr@   )r   r   r   Ú__doc__r   rH   rb   r<   r^   r   ri   r   r   r   r   r   ra   œ   s    üûúra   )r   Útypingr   r   r   rS   r   Úexcr   Úutilsr   Úbaser	   Zconstantr   r   r"   r%   r&   r;   rZ   ra   r   r   r   r   Ú<module>   s    !2