U
    ©Ê¹jÔ0  ã                   @   s  d dl mZ d dlmZmZmZmZ d dlmZm	Z	 G d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G dd„ deƒZeee edœdd„Ze
eeef edœdd„Zee
 eeef ee
ef dœdd„Ze
e
edœdd„Zee
 ee
ef edœdd„ZdS ) é    )ÚEnum)Ú
NamedTupleÚDictÚListÚSet)ÚNodeÚmap_argc                   @   s@   e Zd ZdZeddœdd„Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )Ú	Partitionz—Partition class contains all the information about an individual partition.
    It also provides necessary methods for manipulation the partition.
    N)Úpartition_idÚreturnc                 C   s4   t ƒ | _|| _t ƒ | _t ƒ | _d| _d| _g | _d S )Néÿÿÿÿr   )ÚsetÚnodesr
   ÚparentsÚchildrenZ	bfs_levelÚused_mem_bytesÚlogical_device_ids)Úselfr
   © r   úf/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/fx/experimental/partitioner_utils.pyÚ__init__   s    zPartition.__init__c                 C   s
   t | jƒS ©N)Ústrr
   ©r   r   r   r   Ú__str__   s    zPartition.__str__c                 C   s,   d| _ | jD ]}|  j t|| jƒ7  _ qd S )Nr   )r   r   Úget_extra_size_of)r   Únoder   r   r   Úrecalculate_mem_size   s    
zPartition.recalculate_mem_sizec                    sd   i ‰ t |j‡ fdd„ƒ t |j‡ fdd„ƒ ˆ D ]}|jdkr0| j |¡ q0| j |¡ |  ¡  d S )Nc                    s
   ˆ   | ¡S r   ©Ú
setdefault©Ún©Úinput_nodesr   r   Ú<lambda>   ó    z$Partition.add_node.<locals>.<lambda>c                    s
   ˆ   | ¡S r   r   r    r"   r   r   r$       r%   >   ÚplaceholderÚget_attr)r   ÚargsÚkwargsÚopr   Úaddr   )r   r   r!   r   r"   r   Úadd_node   s    
zPartition.add_nodec                    s†   |ˆj kr‚ˆj  |¡ i ‰ t|j‡ fdd„ƒ t|j‡ fdd„ƒ ˆ D ]2}t‡fdd„|jD ƒƒrF|jdkrFˆj  |¡ qFˆ ¡  d S )Nc                    s
   ˆ   | ¡S r   r   r    r"   r   r   r$   .   r%   z'Partition.remove_node.<locals>.<lambda>c                    s
   ˆ   | ¡S r   r   r    r"   r   r   r$   /   r%   c                 3   s   | ]}|ˆ j kV  qd S r   )r   ©Ú.0r!   r   r   r   Ú	<genexpr>4   s    z(Partition.remove_node.<locals>.<genexpr>>   r&   r'   )	r   Úremover   r(   r)   ÚallÚusersr*   r   )r   r   Z
input_noder   )r#   r   r   Úremove_node(   s    
ÿþzPartition.remove_node)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úintr   r   r   r,   r3   r   r   r   r   r	      s   	r	   c                   @   s&   e Zd ZU eed< eed< eed< dS )ÚDeviceÚnameZavailable_mem_bytesZ
logical_idN)r4   r5   r6   r   Ú__annotations__r8   r   r   r   r   r9   ;   s   
r9   c                   @   s   e Zd ZU eed< eed< dS )ÚNodeLatencyÚmem_latency_secÚcomputer_latency_secN©r4   r5   r6   Úfloatr;   r   r   r   r   r<   A   s   
r<   c                   @   s&   e Zd ZU eed< eed< eed< dS )ÚPartitionLatencyr=   r>   Úoverall_latency_secNr?   r   r   r   r   rA   H   s   
rA   c                   @   s    e Zd ZdZdZdZdZdZdS )ÚPartitionModer   é   é   é   é   N)r4   r5   r6   Ú
size_basedZ	sparse_nnZ
cost_awareZkl_basedZ	aot_basedr   r   r   r   rC   Q   s
   rC   c                   @   s€   e Zd ZU ee ed< ejZeed< dZ	e
ed< i Zeeef ed< i Zeeef ed< i Zeeee f ed< dZeed	< d
S )ÚPartitionerConfigZdevicesÚmodeç        Útransfer_rate_bytes_per_secÚnode_to_latency_mappingÚnode_to_partition_mappingÚ#partition_to_logical_device_mappingFÚsaturate_hostN)r4   r5   r6   r   r9   r;   rC   rH   rJ   rL   r@   rM   r   r   r<   rN   r8   rO   rP   Úboolr   r   r   r   rI   Y   s   
rI   )r   r   r   c                    sŽ   i ‰ t | j‡ fdd„ƒ t | j‡ fdd„ƒ d}ˆ D ]0}||kr4t|ddƒ}|r\||j7 }q4tdƒ‚q4t| ddƒ}|r‚||j7 }ntdƒ‚|S )zƒGiven a node and a set of nodes,
    this function return the extra size that needed
    if this node is included in this set.
    c                    s
   ˆ   | ¡S r   r   r    r"   r   r   r$   k   r%   z#get_extra_size_of.<locals>.<lambda>c                    s
   ˆ   | ¡S r   r   r    r"   r   r   r$   l   r%   r   Ú
size_bytesNznode has no size_bytes attr)r   r(   r)   ÚgetattrÚoutput_sizeÚRuntimeErrorZ
total_size)r   r   Ztotal_size_of_input_nodesr!   rR   r   r"   r   r   d   s    
r   )Ú	partitionrM   r   c                    st   t tt dœdd„}ttdœ‡ ‡‡fdd„‰ |ˆƒ}tdddd�}|D ](}ˆ |tdddd�ƒ}|j|jkrF|}qF|S )	zVGiven a partition and its nodes' latency, return a PartitionLatency for this partition)rV   r   c                    sl   g }ˆj D ]\}|jdkrq
i ‰ t|j‡ fdd„ƒ t|j‡ fdd„ƒ t‡fdd„ˆ D ƒƒs
| |¡ q
|S )z>Given a partition, return a list of nodes on the top bfs level>   r&   r'   c                    s
   ˆ   | ¡S r   r   r    r"   r   r   r$   �   r%   zEget_latency_of_one_partition.<locals>.get_top_nodes.<locals>.<lambda>c                    s
   ˆ   | ¡S r   r   r    r"   r   r   r$   Ž   r%   c                 3   s"   | ]}|ˆ j ko|jd kV  qdS )>   r&   r'   N)r   r*   r-   )rV   r   r   r/   ’   s   ÿzFget_latency_of_one_partition.<locals>.get_top_nodes.<locals>.<genexpr>)r   r*   r   r(   r)   ÚanyÚappend)rV   Ú	top_nodesr   r   )r#   rV   r   Úget_top_nodes…   s    

þz3get_latency_of_one_partition.<locals>.get_top_nodes)r   r   c           
         s”   ˆ|  }|j t|j|jƒ }|j|j }|j|j }t| jƒ ˆj¡}|rˆtdddd�}|D ]&}ˆ |t|||ƒƒ}	|	j |j kr\|	}q\|S t|||ƒS )zyGiven a top node of a partition, this function returns
        the latency of the critical path in the partition
        rK   ©r=   r>   rB   )	rB   Úmaxr>   r=   r   r2   Úintersectionr   rA   )
r   Úpartition_latencyZnode_latencyrB   r=   r>   r2   Zmax_latencyr!   Znew_partition_latency©Ú
dfs_helperrM   rV   r   r   r`   ™   sH     ÿ
ÿ
ÿ  ÿ  ÿþÿÿ  ÿz0get_latency_of_one_partition.<locals>.dfs_helperrK   r[   )r	   r   r   rA   rB   )rV   rM   rZ   rY   Zcritical_path_latencyr   r^   r   r_   r   Úget_latency_of_one_partition€   s.    ,  ÿ  ÿþÿÿra   )Ú
partitionsrM   r   c                 C   s$   i }| D ]}t ||ƒ}|||< q|S )zŽGiven all the partitions and node_to_latency_mapping dictionary,
    return a mapping dictionary of each partition to its overall latency
    )ra   )rb   rM   Úpartition_to_latency_mappingrV   r^   r   r   r   Ú get_partition_to_latency_mappingÙ   s     ÿ
rd   )Úparent_partitionÚchild_partitionrL   c                    s²   | j g kr$|j g kr$| j |j kr$dS d}tƒ }|jD ]t}i ‰ t|j‡ fdd„ƒ t|j‡ fdd„ƒ ˆ D ]>}|| jkrh||krht|ddƒ}|dk	rœ||j7 }| |¡ qhq4|| S )zfGiven two partitions (parent and child),
    calculate the communication latency between the two.
    rK   r   c                    s
   ˆ   | ¡S r   r   r    r"   r   r   r$     r%   z*get_comm_latency_between.<locals>.<lambda>c                    s
   ˆ   | ¡S r   r   r    r"   r   r   r$     r%   rR   N)	r   r   r   r   r(   r)   rS   rT   r+   )re   rf   rL   Z	comm_sizeZvisited_nodesr   r!   rR   r   r"   r   Úget_comm_latency_betweené   s(    
ÿþ
ý

rg   )rb   rc   rL   c                    sb   t ttdœ‡ ‡‡fdd„‰ tt  tt  dœdd„}|| ƒ}d}|D ]}ˆ |dƒ}||krB|}qB|S )zŽGiven all partitions in a graph, find the critical path among all partitions
    and return its latency as the latency of the whole graph
    )rV   Úlatency_so_far_secr   c                    sX   |ˆ|  j 7 }| j}| jrTd}| jD ]*}t| |ˆƒ}ˆ ||| ƒ}||kr$|}q$|S |S )zJThis function helps to recursively get the latency of a path of partitionsrK   )rB   r   rg   )rV   rh   r   Zmax_latency_secÚchildZcomm_latency_secZnew_latency_sec©r`   rc   rL   r   r   r`     s(    ÿ
  ÿ ÿz4get_latency_of_partitioned_graph.<locals>.dfs_helper)rb   r   c                 S   s*   g }| D ]}t |jƒdkr| |¡ q|S )zvThis function is to return all the partitions without parents
        as the starting points of all the paths
        r   )Úlenr   rX   )rb   Útop_partitionsrV   r   r   r   Úget_top_partitions,  s
    z<get_latency_of_partitioned_graph.<locals>.get_top_partitionsrK   )r	   r@   r   )rb   rc   rL   rm   rl   Zcritical_path_latency_secrV   Zlatency_secr   rj   r   Ú get_latency_of_partitioned_graph  s    	
rn   N)Úenumr   Útypingr   r   r   r   Ztorch.fx.noder   r   r	   r9   r<   rA   rC   rI   r8   r   ra   rd   r@   rg   rn   r   r   r   r   Ú<module>   s2   4	 
þZ 

þý%
ý