U
    d_/                     @   s&  d dl mZmZmZmZ d dlZd dlZd dlZd dlm	Z	m
Z
mZ d dlmZmZ d dlmZ d dlmZ d dlmZ zd dlZdZW n ek
r   d	ZY nX d
dddddZddddddddddddddddgZd dd!d"d#Zered	d$G d%d& d&Znes"ed	d$G d'd& d&ZdS )(    )absolute_importdivisionprint_functionunicode_literalsN)DictAnyTYPE_CHECKING)_get_qualified_name_format_arg)TensorMetadata)compatibility)chainTFz"AliceBlue"ZLemonChiffon1ZYellow2Z	LightGreyZ
PowderBlue)placeholdercall_module	get_paramget_attroutputZ
CadetBlue1ZCoralZDarkOliveGreen1ZDarkSeaGreen1Z
GhostWhiteZKhaki1ZLavenderBlush1ZLightSkyBlueZ
MistyRose1Z
MistyRose2ZPaleTurquoise2Z
PeachPuff1ZSalmonZThistle1ZThistle3ZWheat1record"filled,rounded"#000000shape	fillcolorstyleZ	fontcolor)Zis_backward_compatiblec                   @   s&  e Zd ZdZd(ejjeeedddZ	d)e
jdd	d
Ze
jdddZe
jdddZeee
jf dddZejjeeef dddZejjejjejjdddZeedddZejjejjeedddZedddZeedd d!Zejed"d#d$Zejjeeee
jd%d&d'ZdS )*FxGraphDrawerz
        Visualize a torch.fx.Graph with graphviz
        Basic usage:
            g = FxGraphDrawer(symbolic_traced, "resnet18")
            with open("a.svg", "w") as f:
                f.write(g.get_dot_graph().create_svg())
        FT)graph_modulenameignore_getattrskip_node_names_in_argsc                 C   s   || _ || ||||i| _|jjD ]Z}|jdkr4q$| ||}t|tj	j
sPq$| || d|j ||| j| d|j < q$d S )Nr   _)_name_to_dot_dot_graphsgraphnodesop_get_leaf_node
isinstancetorchfxGraphModuletarget)selfr   r   r   r   nodeZ	leaf_node r.   @/tmp/pip-unpacked-wheel-ua33x9lu/torch/fx/passes/graph_drawer.py__init__?   s*        
FxGraphDrawer.__init__N)returnc                 C   s   |d kr|   S | |S d S N)get_main_dot_graphget_submod_dot_graphr,   Zsubmod_namer.   r.   r/   get_dot_graph]   s    zFxGraphDrawer.get_dot_graphc                 C   s   | j | j S r3   r"   r    r,   r.   r.   r/   r4   c   s    z FxGraphDrawer.get_main_dot_graphc                 C   s   | j | j d|  S )Nr   r8   r6   r.   r.   r/   r5   f   s    z"FxGraphDrawer.get_submod_dot_graphc                 C   s   | j S r3   )r"   r9   r.   r.   r/   get_all_dot_graphsi   s    z FxGraphDrawer.get_all_dot_graphs)r-   r2   c                 C   sl   ddddd}|j tkr(t|j  |d< n@||j}tt|  d d d}t	|t
t	  |d< |S )	Nr   z#CAFFE3r   r   r   r         )r%   
_COLOR_MAPZ_pretty_print_targetr+   inthashlibmd5encode	hexdigest_HASH_COLOR_MAPlen)r,   r-   templateZtarget_nameZtarget_hashr.   r.   r/   _get_node_stylel   s    
 zFxGraphDrawer._get_node_style)moduler-   r2   c                 C   sZ   |}t |jtst|jd}|D ]0}t||sJtt|d | d t||}q$|S )N.z does not have attribute !)r'   r+   strAssertionErrorsplithasattrRuntimeErrorgetattr)r,   rG   r-   Zpy_objZatomsZatomr.   r.   r/   r&   |   s    
zFxGraphDrawer._get_leaf_node)r+   r2   c                 C   s.   t |tjjrt|S t |tr&|S t|S r3   )r'   r(   nnModuletypenamerJ   r	   )r,   r+   r.   r.   r/   	_typename   s
    

zFxGraphDrawer._typename)rG   r-   r   r2   c                    s  fdd}dd|j  d|j d }|jdkr| || |d|   d	 7 }d
}t drzd fdd jD }||d 7 }nj|d| |j d 7 }t|j	dkr|||j	7 }t|j
dkr|||j
7 }|dt|j d 7 }|jd}|| |7 }|d S )Nc                    s   t | tr"d\}}dd | D }n*t | trHd\}}dd |  D }ndS  r^dd |D }t|dkrndS |d	| | }|d
dddS )N)z	|args=(\lz,\n)\lc                 S   s   g | ]}t |d dqS )r;   Zmax_list_lenr
   .0ar.   r.   r/   
<listcomp>   s     zSFxGraphDrawer._get_node_label.<locals>._get_str_for_args_kwargs.<locals>.<listcomp>)z|kwargs={\lz,\n}\lc                 S   s&   g | ]\}}| d t |dd qS ): r;   rT   rU   )rW   kvr.   r.   r/   rY      s    c                 S   s   g | ]}d |kr|qS )%r.   rV   r.   r.   r/   rY      s      r   z,\n{z\{}z\})r'   tupledictitemsrD   joinreplace)argprefixsuffixZarg_strs_listZarg_strs)r   r.   r/   _get_str_for_args_kwargs   s    

z?FxGraphDrawer._get_node_label.<locals>._get_str_for_args_kwargsr_   zname=%z	|op_code=
r   \nz\n|r]   __constants__c                    s    g | ]}| d t  | qS )rZ   )rO   )rW   c)leaf_moduler.   r/   rY      s     z1FxGraphDrawer._get_node_label.<locals>.<listcomp>z|target=r   z|num_users=tensor_metar`   )r   r%   r&   rS   rM   rd   rl   r+   rD   argskwargsusersmetaget_tensor_meta_to_label)r,   rG   r-   r   ri   labelextraro   r.   )rn   r   r/   _get_node_label   s(    

zFxGraphDrawer._get_node_labelc                 C   s   |d krdS t |tr | |S t |trJd}|D ]}|| |7 }q2|S t |tr|d}| D ]\}}|| |7 }q`|S t |trd}|D ]}|| |7 }q|S tdt	| d S )Nr]   zUnsupported tensor meta type )
r'   r   _stringify_tensor_metalistru   rb   rc   ra   rN   type)r,   tmresultitemr[   r\   r.   r.   r/   ru      s(    




z#FxGraphDrawer._tensor_meta_to_label)r|   r2   c                 C   sz  d}t |dstd| |dt|j d 7 }|dtt|j d 7 }|dt|j d 7 }|dt|j d 7 }|jrv|j	d k	st
d	|j	kst
|j	d	 }|tjtjhkr|d
t|j	d  d 7 }|dt|j	d  d 7 }nt|tjtjtjhkrN|dt|j	d  d 7 }|dt|j	d  d 7 }|dt|j	d  d 7 }ntd| |dt|j	d	  d 7 }|S )Nr]   dtyper|   z|dtype=rk   z|shape=z|requires_grad=z|stride=qschemez	|q_scale=Zscalez|q_zero_point=Z
zero_pointz|q_per_channel_scale=z|q_per_channel_zero_point=z|q_per_channel_axis=ZaxiszUnsupported qscheme: z	|qscheme=)rM   printrJ   r   ra   r   Zrequires_gradZstrideZis_quantizedZqparamsrK   r(   Zper_tensor_affineZper_tensor_symmetricZper_channel_affineZper_channel_symmetricZ per_channel_affine_float_qparamsrN   )r,   r|   r}   r   r.   r.   r/   ry      s8    


z$FxGraphDrawer._stringify_tensor_meta)tr2   c                 C   s   t |jt t|j d S )Nrk   )rJ   r   rz   r   )r,   r   r.   r.   r/   _get_tensor_label   s    zFxGraphDrawer._get_tensor_label)r   r   r   r   r2   c           	   	      s   t j|dd |jjD ]|r*jdkr*q}t jjfd||i|} 	|  fdd}jdkr
|ttjjs|  q|jjD ]6|rjdkrqjD ]} t j|j qq S )z~
            Actual interface to visualize a fx.Graph. Note that it takes in the GraphModule instead of the Graph
            ZTB)Zrankdirr   rv   c                     s   t   D ]z\} }jd |  }t|tjjrB|d d nd}tj	|fdd| 
| d it} |  t|j qd S )NrH   z|op_code=get_Z	parameterzbuffer\lrv   r_   r`   )r   Znamed_parametersZnamed_buffersr   r'   r(   rP   	ParameterpydotNoder   _WEIGHT_TEMPLATEadd_nodeadd_edgeEdge)ZpnameZptensorZpname1label1Z
dot_w_nodeZ	dot_graphrn   r-   r,   r.   r/   get_module_params_or_buffers  s$     
z;FxGraphDrawer._to_dot.<locals>.get_module_params_or_buffersr   )r   Dotr#   r$   r%   rF   r   r   rx   r   r&   r'   r(   r)   r*   rr   r   r   )	r,   r   r   r   r   r   Zdot_noder   userr.   r   r/   r!      s0    




zFxGraphDrawer._to_dot)FT)N)__name__
__module____qualname____doc__r(   r)   r*   rJ   boolr0   r   r   r7   r4   r5   r   r:   r   rF   rP   rQ   r&   r   rS   rx   ru   r   ry   ZTensorr   r!   r.   r.   r.   r/   r   5   sB      4r   c                   @   s$   e Zd ZdejjeedddZdS )r   F)r   r   r   c                 C   s   t dd S )Nz|FXGraphDrawer requires the pydot package to be installed. Please install pydot through your favorite Python package manager.)rN   )r,   r   r   r   r.   r.   r/   r0   ;  s    r1   N)F)	r   r   r   r(   r)   r*   rJ   r   r0   r.   r.   r.   r/   r   9  s   )
__future__r   r   r   r   r?   r(   Ztorch.fxtypingr   r   r   Ztorch.fx.noder	   r
   Ztorch.fx.passes.shape_propr   Ztorch.fx._compatibilityr   	itertoolsr   r   Z	HAS_PYDOTImportErrorr=   rC   r   r   r.   r.   r.   r/   <module>   sb   
	  