U
    yh?                     @   sp  U d dl Z d dlZd dlZd dlmZ d dlmZmZmZm	Z	m
Z
mZ d dlmZ d dlmZ d dlmZ d dlmZmZ e dZe jed< G d	d
 d
eeZG dd deeZd%ejeedddZej ejdddZ!d&ej eee
ej dddZ"ej e
ej edddZ#ej e
ej eje
ej dddZ$d'ej%edddd Z&d(eeej%f eed"d#d$Z'dS ))    N)Enum)CallablecastDictIterableListSet)TensorMetadata)_pytree)tree_flattentree_unflattenZgraph_utilsloggerc                   @   s$   e Zd ZdZdZdZdZdZdZdS )OPcall_functionZcall_moduleZcall_methodZget_attroutputplaceholderN)	__name__
__module____qualname__CALL_FUNCTIONZCALL_MODULECALL_METHODZGET_ATTROUTPUTZPLACEHOLDER r   r   U/var/www/html/venv/lib/python3.8/site-packages/torch/distributed/_spmd/graph_utils.pyr      s   r   c                   @   s    e Zd ZdZdZdZdZdZdS )CommTypeZ
allreduce_Z
allgather_Z
broadcast_Zreduce_scatter_Zscatter_N)r   r   r   Z	ALLREDUCEZ	ALLGATHERZ	BROADCASTZREDUCESCATTERZSCATTERr   r   r   r   r      s
   r   T)nodeis_requiredreturnc              	   C   sF   | j dd }|rB|d krBtd| j d| j d| j d| j |S )NZtensor_metaz2Callsite expects that ``tensor_meta`` exists in ``z ``, but got None instead. Node:  )metagetRuntimeErrornameoptarget)r   r   metadatar   r   r   get_node_tensor_metadata!   s    "r&   )graphr   c                 C   s6   t | jD ]}|jtjkr
|  S q
td|  dS )zTake a graphmodule and return the graph output node.

    We traverse in reverse to expedite it, with the idea that last node should be output
    zCannot find the output node in N)reversednodesr#   r   r   r!   )r'   r   r   r   r   
get_output+   s    
r*   F)r'   	predicatereverse_orderr   c                    s@   t ttj | j}|r.t ttj tt|} fdd|D S )zSTake a predicate and return all the nodes in the `graph` where the predicate holds.c                    s   g | ]} |r|qS r   r   ).0r   r+   r   r   
<listcomp>=   s      zfind_node.<locals>.<listcomp>)r   r   fxNoder)   iterr(   )r'   r+   r,   r)   r   r.   r   	find_node6   s    r3   )r'   subgraphr   c                 C   sP   t |}t| }|D ]6}|jD ]*}t|tjs0q||kr||kr  dS qqdS )zEnsure nodes in ``subgraph`` satisfy one of the following rules.

    1. The user of the node is in ``subgraph``.
    2. The user of the node is output.
    3. There are no users -- the node is a side-effect node.
    FT)setr*   Zusers
isinstancer0   r1   )r'   r4   	all_nodesr   r   userr   r   r   is_leaf_subgraph@   s    
r9   )r'   r4   r$   r   c              	   C   s   t |}t }g }| | |D ]}| |j|j|j|j}tj	|j|j}t
|j|jf\}	}
g }t||	D ]B\}}t|tjr||kr||kst|||  qp|| qpt||
\|_|_|||< || q"W 5 Q R X |S )zClone the given subgraph and insert it before ``target``.

    This API currently does not support inserting after ``target``.
    )r5   dictZinserting_beforer   r$   argskwargstypepytreeZarg_tree_leavesr   zipr6   r0   r1   AssertionErrorappendr   )r'   r4   r$   r7   mappingZcloned_subgraphr   Zcloned_nodeZoriginal_inputZcloned_inputspecZmapped_cloned_inputZoriginal_input_nodeZcloned_input_noder   r   r   clone_subgraphR   s@        
 rD   )gmremove_dead_coder   c                 C   s$   | j   |r| j   |   dS )zRun the required steps to ensure production-ready graph.

    Note - per the fx docs, elimination of dead code is not very precise.
    Hence, the flag to make this step optional.
    N)r'   ZlintZeliminate_dead_codeZ	recompile)rE   rF   r   r   r   rebuild_graph{   s    

rG    )graphsfolderr   c              
   C   sb   |st  }|  D ]<\}}ttj|| dd}|t| W 5 Q R X qt	
d| |S )Nz.graphwzDump graphs to %s)tempfilemkdtempitemsopenospathjoinwritestrr   warning)rI   rJ   prefixrE   fpr   r   r   dump_graphs_to_files   s    rX   )T)F)T)rH   )(loggingrP   rL   enumr   typingr   r   r   r   r   r   Ztorch.fxr0   Ztorch.fx.passes.shape_propr	   Ztorch.utilsr
   r>   Ztorch.utils._pytreer   r   	getLoggerr   Logger__annotations__rT   r   r   r1   boolr&   ZGraphr*   r3   r9   rD   ZGraphModulerG   rX   r   r   r   r   <module>   s:     	
   
  )