o
    h0                     @   s0  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dedee defddZde
deeef defddZdee
 deeef dee
ef fddZde
de
defdd Zdee
 d!ee
ef defd"d#Zd$S )%    )Enum)
NamedTupleDictListSet)Nodemap_argc                   @   sB   e Zd ZdZdeddfddZdd Zd	d
 Zdd Zdd Z	dS )	PartitionzPartition class contains all the information about an individual partition.
    It also provides necessary methods for manipulation the partition.
    partition_idreturnNc                 C   s4   t  | _|| _t  | _t  | _d| _d| _g | _d S )Nr   )setnodesr
   parentschildren	bfs_levelused_mem_byteslogical_device_ids)selfr
    r   ]/var/www/html/ai/venv/lib/python3.10/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v r%| j| q| j| |   d S )Nc                    
     | S r   
setdefaultninput_nodesr   r   <lambda>      
 z$Partition.add_node.<locals>.<lambda>c                    r   r   r    r"   r$   r   r   r&       r'   >   get_attrplaceholder)r   argskwargsopr   addr   )r   r   r#   r   r$   r   add_node   s   
zPartition.add_nodec                    s   |j v rCj | i  t|j fdd t|j fdd  D ]}tfdd|jD r<|jdv r<j | q#  d S d S )Nc                    r   r   r    r"   r$   r   r   r&   .   r'   z'Partition.remove_node.<locals>.<lambda>c                    r   r   r    r"   r$   r   r   r&   /   r'   c                 3   s    | ]}| j v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   
input_noder   )r%   r   r   remove_node(   s   

zPartition.remove_node)
__name__
__module____qualname____doc__intr   r   r   r.   r6   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nameavailable_mem_bytes
logical_idN)r7   r8   r9   r   __annotations__r;   r   r   r   r   r<   ;   s   
 r<   c                   @   s   e Zd ZU eed< eed< dS )NodeLatencymem_latency_seccomputer_latency_secNr7   r8   r9   floatr@   r   r   r   r   rA   A   s   
 rA   c                   @   s&   e Zd ZU eed< eed< eed< dS )PartitionLatencyrB   rC   overall_latency_secNrD   r   r   r   r   rF   H   s   
 rF   c                   @   s    e Zd ZdZdZdZdZdZdS )PartitionModer               N)r7   r8   r9   
size_based	sparse_nn
cost_awarekl_based	aot_basedr   r   r   r   rH   Q   s    rH   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 )PartitionerConfigdevicesmode        transfer_rate_bytes_per_secnode_to_latency_mappingnode_to_partition_mapping#partition_to_logical_device_mappingFsaturate_hostN)r7   r8   r9   r   r<   r@   rH   rM   rT   rV   rE   rW   r   r   rA   rX   r;   rY   rZ   boolr   r   r   r   rR   Y   s   
 rR   r   r   r   c                    s   i  t | j fdd t | j fdd d} D ]}||vr2t|dd}|r.||j7 }qtdqt| dd}|rB||j7 }|S td)zGiven a node and a set of nodes,
    this function return the extra size that needed
    if this node is included in this set.
    c                    r   r   r    r"   r$   r   r   r&   k   r'   z#get_extra_size_of.<locals>.<lambda>c                    r   r   r    r"   r$   r   r   r&   l   r'   r   
size_bytesNznode has no size_bytes attr)r   r*   r+   getattroutput_sizeRuntimeError
total_size)r   r   total_size_of_input_nodesr#   r\   r   r$   r   r   d   s    
r   	partitionrW   c                    sx   dt dtt fdd}dtdtf fdd |}tdddd	}|D ]} |tdddd	}|j|jkr9|}q%|S )
zVGiven a partition and its nodes' latency, return a PartitionLatency for this partitionrb   r   c                    sl   g }j D ].}|jdv rqi  t|j fdd t|j fdd tfdd D s3|| q|S )z>Given a partition, return a list of nodes on the top bfs level>   r(   r)   c                    r   r   r    r"   r$   r   r   r&      r'   zEget_latency_of_one_partition.<locals>.get_top_nodes.<locals>.<lambda>c                    r   r   r    r"   r$   r   r   r&      r'   c                 3   s$    | ]}| j v o|jd vV  qdS )>   r(   r)   N)r   r,   r/   )rb   r   r   r1      s
    
zFget_latency_of_one_partition.<locals>.get_top_nodes.<locals>.<genexpr>)r   r,   r   r*   r+   anyappend)rb   	top_nodesr   r   )r%   rb   r   get_top_nodes   s   


z3get_latency_of_one_partition.<locals>.get_top_nodesr   c           
         s   |  }|j t|j|j }|j|j }|j|j }t| jj}|rDtdddd}|D ]} |t|||}	|	j |j krA|	}q.|S t|||S )zyGiven a top node of a partition, this function returns
        the latency of the critical path in the partition
        rU   rB   rC   rG   )	rG   maxrC   rB   r   r4   intersectionr   rF   )
r   partition_latencynode_latencyrG   rB   rC   r4   max_latencyr#   new_partition_latency
dfs_helperrW   rb   r   r   ro      s:   

z0get_latency_of_one_partition.<locals>.dfs_helperrU   rg   )r	   r   r   rF   rG   )rb   rW   rf   re   critical_path_latencyr   rj   r   rn   r   get_latency_of_one_partition   s&   ,rq   
partitionsc                 C   s$   i }| D ]}t ||}|||< q|S )zGiven all the partitions and node_to_latency_mapping dictionary,
    return a mapping dictionary of each partition to its overall latency
    )rq   )rr   rW   partition_to_latency_mappingrb   rj   r   r   r    get_partition_to_latency_mapping   s   
rt   parent_partitionchild_partitionrV   c                    s   | j g kr|j g kr| j |j krdS d}t }|jD ]:}i  t|j fdd t|j fdd  D ]}|| jv rS||vrSt|dd}|durN||j7 }|| q4q|| S )zfGiven two partitions (parent and child),
    calculate the communication latency between the two.
    rU   r   c                    r   r   r    r"   r$   r   r   r&     r'   z*get_comm_latency_between.<locals>.<lambda>c                    r   r   r    r"   r$   r   r   r&     r'   r\   N)	r   r   r   r   r*   r+   r]   r^   r-   )ru   rv   rV   	comm_sizevisited_nodesr   r#   r\   r   r$   r   get_comm_latency_between   s&   





ry   rs   c                    sh   dt dtdtf fdd dtt  dtt  fdd}|| }d	}|D ]} |d	}||kr1|}q$|S )
zGiven all partitions in a graph, find the critical path among all partitions
    and return its latency as the latency of the whole graph
    rb   latency_so_far_secr   c                    sX   ||  j 7 }| j}| jr*d}| jD ]}t| |} ||| }||kr'|}q|S |S )zJThis function helps to recursively get the latency of a path of partitionsrU   )rG   r   ry   )rb   rz   r   max_latency_secchildcomm_latency_secnew_latency_secro   rs   rV   r   r   ro     s(   
z4get_latency_of_partitioned_graph.<locals>.dfs_helperrr   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   rd   )rr   top_partitionsrb   r   r   r   get_top_partitions,  s   
z<get_latency_of_partitioned_graph.<locals>.get_top_partitionsrU   )r	   rE   r   )rr   rs   rV   r   r   critical_path_latency_secrb   latency_secr   r   r    get_latency_of_partitioned_graph  s   	
r   N)enumr   typingr   r   r   r   torch.fx.noder   r   r	   r<   rA   rF   rH   rR   r;   r   rq   rt   rE   ry   r   r   r   r   r   <module>   sL    4	

Y



$
