U
    ªÊ¹j¤  ã                   @   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f |Ž t ¡ stdƒ d S )Nz+torch.distributed package is not available!)ÚsuperÚ__init__r   Úis_availabler   )ÚselfÚkwargs©Ú	__class__© úb/var/www/html/bwave/python/venv/lib/python3.8/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k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 | ¡o4| |k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                       s>   e Zd Z‡ fdd„Zedd„ ƒZddddœ‡ fd	d
„Z‡  ZS )ÚPlacementClassVariablec                    s   t ƒ jf |Ž || _d S r   ©r   r   r!   ©r   r!   r   r   r   r   r   2   s    zPlacementClassVariable.__init__c                 C   s.   t  ¡ sdS ddlm} t| ƒtk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úList[VariableTracker]úDict[str, VariableTracker]r	   ©Úargsr   Úreturnc                    s~   t  | || ¡ ¡}t | jdd ¡tjfkrn| jrnt | j¡}t	|f|Ž}t | jdd ¡rn| 
| |d||¡¡S tƒ  |||¡S )NÚ__new__r   )r	   Ú	propagateÚvaluesr   Úgetattr_staticr!   Úobjectr5   ÚsourceÚPlacementVariableÚadd_optionsÚcall_methodr   Úcall_function)r   Útxr3   r   ÚoptionsZnew_objÚvarr   r   r   r>   @   s    ÿþz$PlacementClassVariable.call_function)r   r   r   r   r   r/   r>   r   r   r   r   r   r&   1   s   

 þr&   c                       sF   e Zd Z‡ fdd„Zedd„ ƒZdd„ Zddd	d
œ‡ fdd„Z‡  ZS )r;   c                    s   t ƒ jf |Ž || _d S r   r'   r(   r   r   r   r   S   s    zPlacementVariable.__init__c                 C   s"   t  ¡ sdS ddlm} t| |ƒS r)   )r   r   r+   r*   r   r.   r   r   r   Úis_placementW   s    zPlacementVariable.is_placementc                 C   s   | j S r   ©r!   ©r   r   r   r   Úas_python_constanta   s    z$PlacementVariable.as_python_constantr0   r1   r	   r2   c           
         sØ   ddl m} t | || ¡ ¡}ddg}||krÆz4t| jƒ}t |dd ¡d ksTt	dƒ‚t ||¡}	W n t
k
rz   d }	Y nX |	tjkr�|d|ŽS dd„ |D ƒ}d	d
„ | ¡ D ƒ}|	| jf|ž|Ž | S tƒ  ||||¡S )Nr   r
   r   Ú__setattr__Ú__getattr__zno custom getattr allowed!c                 S   s   g | ]}|  ¡ ‘qS r   ©rE   )Ú.0Úxr   r   r   Ú
<listcomp>}   s     z1PlacementVariable.call_method.<locals>.<listcomp>c                 S   s   i | ]\}}||  ¡ “qS r   rH   )rI   ÚkÚvr   r   r   Ú
<dictcomp>~   s      z1PlacementVariable.call_method.<locals>.<dictcomp>)N)Ú r   r	   r6   r7   r,   r!   r   r8   ÚAssertionErrorÚAttributeErrorr9   r   Úitemsr   r=   )
r   r?   Únamer3   r   r   r@   Úallowed_methodsZ
value_typeÚmethodr   r   r   r=   d   s(    
ÿþ


zPlacementVariable.call_method)	r   r   r   r   r   rB   rE   r=   r   r   r   r   r   r;   R   s   
	úr;   c                       sD   e Zd Z‡ fdd„Zedd„ ƒZdd„ Zeedœ‡ fdd	„Z	‡  Z
S )
ÚDeviceMeshVariablec                    s   t ƒ jf |Ž || _d S r   r'   r(   r   r   r   r   †   s    zDeviceMeshVariable.__init__c                 C   s"   t  ¡ sdS ddlm} t| |ƒS )NFr   )Ú
DeviceMesh)r   r   Z%torch.distributed._tensor.device_meshrW   r   )r!   rW   r   r   r   Úis_device_meshŠ   s    z!DeviceMeshVariable.is_device_meshc                 C   s   | j S r   rC   rD   r   r   r   rE   ”   s    z%DeviceMeshVariable.as_python_constant)rS   r4   c                    s"   |dkrt | jjƒS tƒ  ||¡S )NÚndim)r   r!   rY   r   Úvar_getattr©r   r?   rS   r   r   r   rZ   —   s    zDeviceMeshVariable.var_getattr)r   r   r   r   r   rX   rE   Ústrr	   rZ   r   r   r   r   r   rV   …   s
   
	rV   c                       s^   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	d
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                    s   t ƒ jf |Ž || _d S r   r'   r(   r   r   r   r   °   s    zProcessGroupVariable.__init__c                 C   s   | j S r   rC   rD   r   r   r   rE   ´   s    z'ProcessGroupVariable.as_python_constantc                 C   s
   t | jƒS r   )r,   r!   rD   r   r   r   Úpython_type·   s    z ProcessGroupVariable.python_typer0   r1   r	   r2   c                    sB   |dkrt  | j ¡ ¡S |dkr0t  | j ¡ ¡S tƒ  ||||¡S )NÚrankÚsize)r   r   r!   r_   r`   r   r=   )r   r?   rS   r3   r   r   r   r   r=   º   s
    z ProcessGroupVariable.call_methodc                    s2   ˆ dkr$t  ‡ ‡‡fdd„¡ ˆ¡S tƒ  ˆˆ ¡S )N)r_   r`   c                     s   ˆ  ˆˆ | |¡S r   )r=   )r3   r   ©rS   r   r?   r   r   Ú<lambda>Ë   ó    z2ProcessGroupVariable.var_getattr.<locals>.<lambda>)r   ZLambdaVariabler<   r   rZ   r[   r   ra   r   rZ   È   s    ÿþz ProcessGroupVariable.var_getattrc                 C   s"   t  ¡ sdS ddlm} t| |ƒS )NFr   )ÚProcessGroup)r   r   Ztorch._C._distributed_c10drd   r   )r!   rd   r   r   r   Úis_process_groupÐ   s    z%ProcessGroupVariable.is_process_group)r   r   r   Ú__doc__r   rE   r^   r=   rZ   r   re   r   r   r   r   r   r]   �   s   úr]   )r   Útypingr   r   r   rO   r   Úexcr   Úutilsr   Úbaser	   Zconstantr   r   r"   r%   r&   r;   rV   r]   r   r   r   r   Ú<module>   s   !3