U
    yhZA                     @   s   d dl Z d dlZd dlZd dlmZ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 d dlmZ dg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#Zered
d$G d%d dZnesed
d$G d&d dZdS )'    N)AnyDictOptionalTYPE_CHECKING)_get_qualified_name_format_arg)_parse_stack_trace)TensorMetadata)compatibility)chainFxGraphDrawerTFz"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"filled,rounded"#000000)	fillcolorstyle	fontcolor)Zis_backward_compatiblec                	   @   sH  e Zd ZdZd,ejjeeee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d.eedddZejjejje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eejd)d*d+Z!dS )/r   z
        Visualize a torch.fx.Graph with graphviz
        Basic usage:
            g = FxGraphDrawer(symbolic_traced, "resnet18")
            g.get_dot_graph().write_svg("a.svg")
        FTNgraph_modulenameignore_getattrignore_parameters_and_buffersskip_node_names_in_argsparse_stack_tracedot_graph_shapec           
   	   C   s   || _ |d k	r|nd| _| jtd< || ||||||i| _|jjD ]^}|jdkrTqD| ||}	t	|	t
jjspqD| |	| d|j ||||| j| d|j < qDd S )Nrecordshaper   _)_namer   _WEIGHT_TEMPLATE_to_dot_dot_graphsgraphnodesop_get_leaf_node
isinstancetorchfxGraphModuletarget)
selfr   r   r   r   r   r   r   nodeZ	leaf_node r1   N/var/www/html/venv/lib/python3.8/site-packages/torch/fx/passes/graph_drawer.py__init__?   s8    

      
FxGraphDrawer.__init__)returnc                 C   s   |dkr|   S | |S dS )a9  
            Visualize a torch.fx.Graph with graphviz
            Example:
                >>> # xdoctest: +REQUIRES(module:pydot)
                >>> # xdoctest: +REQUIRES(module:ubelt)
                >>> # define module
                >>> class MyModule(torch.nn.Module):
                >>>     def __init__(self):
                >>>         super().__init__()
                >>>         self.linear = torch.nn.Linear(4, 5)
                >>>     def forward(self, x):
                >>>         return self.linear(x).clamp(min=0.0, max=1.0)
                >>> module = MyModule()
                >>> # trace the module
                >>> symbolic_traced = torch.fx.symbolic_trace(module)
                >>> # setup output file
                >>> import ubelt as ub
                >>> dpath = ub.Path.appdir('torch/tests/FxGraphDrawer').ensuredir()
                >>> fpath = dpath / 'linear.svg'
                >>> # draw the graph
                >>> g = FxGraphDrawer(symbolic_traced, "linear")
                >>> g.get_dot_graph().write_svg(fpath)
            N)get_main_dot_graphget_submod_dot_graphr/   Zsubmod_namer1   r1   r2   get_dot_graphh   s    zFxGraphDrawer.get_dot_graphc                 C   s   | j | j S Nr%   r"   r/   r1   r1   r2   r6      s    z FxGraphDrawer.get_main_dot_graphc                 C   s   | j | j d|  S )Nr!   r;   r8   r1   r1   r2   r7      s    z"FxGraphDrawer.get_submod_dot_graphc                 C   s   | j S r:   )r%   r<   r1   r1   r2   get_all_dot_graphs   s    z FxGraphDrawer.get_all_dot_graphs)r0   r5   c                 C   sn   | j dddd}|jtkr*t|j |d< n@||j}tt| 	 d d d}t
|tt
  |d< |S )Nz#CAFFE3r   r   )r    r   r   r   r         )r   r(   
_COLOR_MAPZ_pretty_print_targetr.   inthashlibmd5encode	hexdigest_HASH_COLOR_MAPlen)r/   r0   templateZtarget_nameZtarget_hashr1   r1   r2   _get_node_style   s    
 zFxGraphDrawer._get_node_style)moduler0   r5   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/   rJ   r0   Zpy_objZatomsZatomr1   r1   r2   r)      s    
zFxGraphDrawer._get_leaf_node)r.   r5   c                 C   sF   t |tjjrt|}nt |tr*|}nt|}|ddddS )N{\{}\})r*   r+   nnModuletypenamerM   r   replace)r/   r.   retr1   r1   r2   	_typename   s    
zFxGraphDrawer._typename   )full_file_nametruncate_to_last_nc                 C   s.   | d}t||kr*d|| d  S |S )N/)rO   rG   join)r/   r^   r_   Zsplitsr1   r1   r2   _shorten_file_name   s    
z FxGraphDrawer._shorten_file_name)rJ   r0   r   r   r5   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 }|jdd }	|	d k	rL|d|	j  d 7 }|d|	j d 7 }|r|jd k	rt|j}
| |
j}|d| d|
j d|
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	| | }t|d
kr|ddd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ar1   r1   r2   
<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>   rc   rd   )rf   kvr1   r1   r2   rh      s    c                 S   s   g | ]}d |kr|qS )%r1   re   r1   r1   r2   rh      s      r   z,\n   z\l\nrS   rT   rU   rV   )r*   tupledictitemsrG   ra   rZ   )argprefixsuffixZarg_strs_listZarg_strs)r   r1   r2   _get_str_for_args_kwargs   s"    

z?FxGraphDrawer._get_node_label.<locals>._get_str_for_args_kwargsrS   zname=%z	|op_code=
r   ro   z\n|rl   __constants__c                    s    g | ]}| d t  | qS )ri   )rR   )rf   c)leaf_moduler1   r2   rh      s     z1FxGraphDrawer._get_node_label.<locals>.<listcomp>z|target=r   z|num_users=tensor_metabuf_metaz|buf=z
|n_origin=z|file=: rU   )r   r(   r)   r\   rP   ra   rx   r.   rG   argskwargsusersmetaget_tensor_meta_to_labeln_originZstack_tracer   rb   filelinenocode)r/   rJ   r0   r   r   rv   labelextrar{   r|   Zparsed_stack_tracefnamer1   )rz   r   r2   _get_node_label   s8    



"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rxd}| D ]}|| |7 }q`|S t |trd}|D ]}|| |7 }q|S tdt	| d S )Nrl   zUnsupported tensor meta type )
r*   r	   _stringify_tensor_metalistr   rq   valuesrp   rQ   type)r/   tmresultitemrk   r1   r1   r2   r     s(    




z#FxGraphDrawer._tensor_meta_to_label)r   r5   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 )Nrl   dtyper   z|dtype=ro   z|shape=z|requires_grad=z|stride=qschemez	|q_scale=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=)rP   printrM   r   rp   r    Zrequires_gradZstrideZis_quantizedZqparamsrN   r+   Zper_tensor_affineZper_tensor_symmetricZper_channel_affineZper_channel_symmetricZ per_channel_affine_float_qparamsrQ   )r/   r   r   r   r1   r1   r2   r   %  s8    


z$FxGraphDrawer._stringify_tensor_meta)tr5   c                 C   s   t |jt t|j d S )Nro   )rM   r   r   r    )r/   r   r1   r1   r2   _get_tensor_labelD  s    zFxGraphDrawer._get_tensor_label)r   r   r   r   r   r   r5   c              
      st  t j|dd i }|jjD ]ډ|r.jdkr.q}t jjfd|||i|}	 }
j	
dd}|dk	r|jdkr|j}||krt j||d||< |
|}
|
|	  fd	d
}jdkr||sttjjs|  q| D ]&}|dd |dd  | q|jjD ]@|rHjdkrHq.jD ]} t j|j qNq. S )a  
            Actual interface to visualize a fx.Graph. Note that it takes in the GraphModule instead of the Graph.
            If ignore_parameters_and_buffers is True, the parameters and buffers
            created with the module will not be added as nodes and edges.
            TB)Zrankdirr   r   r|   Nrn   )r   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 )NrK   z|op_code=get_Z	parameterzbuffer\lr   rS   rU   )r   Znamed_parametersZnamed_buffersr   r*   r+   rW   	ParameterpydotNoder   r#   add_nodeadd_edgeEdge)ZpnameZptensorZpname1label1Z
dot_w_nodeZ	dot_graphrz   r0   r/   r1   r2   get_module_params_or_buffersr  s$     
z;FxGraphDrawer._to_dot.<locals>.get_module_params_or_buffersr   colorZ	royalblueZpenwidth2)r   Dotr&   r'   r(   rI   r   r   r   r   r   r   ZClusterr   r)   r*   r+   r,   r-   r   setZadd_subgraphr   r   r   )r/   r   r   r   r   r   r   Zbuf_name_to_subgraphr   Zdot_nodeZcurrent_graphr|   Zbuf_namer   Zsubgraphuserr1   r   r2   r$   I  sH    




zFxGraphDrawer._to_dot)FFTFN)N)r]   )"__name__
__module____qualname____doc__r+   r,   r-   rM   boolr   r3   r   r   r9   r6   r7   r   r=   r   rI   rW   rX   r)   r   r\   rA   rb   r   r   r	   r   ZTensorr   r$   r1   r1   r1   r2   r   6   s^        )  Fc                	   @   s0   e Zd Zdejjeeeeeee dddZ	dS )r   FTNr   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.)rQ   )r/   r   r   r   r   r   r   r   r1   r1   r2   r3     s    
r4   )FFTFN)
r   r   r   r+   r,   r-   rM   r   r   r3   r1   r1   r1   r2   r     s        )rB   r+   Ztorch.fxtypingr   r   r   r   Ztorch.fx.noder   r   Ztorch.fx.graphr   Ztorch.fx.passes.shape_propr	   Ztorch.fx._compatibilityr
   	itertoolsr   __all__r   Z	HAS_PYDOTImportErrorr@   rF   r#   r   r1   r1   r1   r2   <module>   sb   
	  d