o
    H&iA                     @   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yN   d
ZY nw ddddddZg dZddddZerqed
dG dd dZdS esed
dG dd dZdS 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output)Z
CadetBlue1ZCoralZDarkOliveGreen1ZDarkSeaGreen1Z
GhostWhiteZKhaki1ZLavenderBlush1ZLightSkyBlueZ
MistyRose1Z
MistyRose2ZPaleTurquoise2Z
PeachPuff1SalmonZThistle1ZThistle3ZWheat1r   "filled,rounded"#000000)	fillcolorstyle	fontcolor)Zis_backward_compatiblec                   @   s  e Zd ZdZ					d1dejjdededed	ed
ede	e fddZ
d2dejfddZdejfddZdejfddZdeeejf fddZdejjdeeef fddZdejjdejjdejjfddZdedefddZ	 d3d!ed"efd#d$Zdejjdejjd	ed
edef
d%d&Zdefd'd(Zd)edefd*d+Zd,ejdefd-d.Z dejjdededed	ed
edejfd/d0Z!dS )4r   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 ur	|nd| _| jtd< || ||||||i| _|jjD ]/}|jdkr*q"| ||}	t	|	t
jjs8q"| |	| d|j ||||| j| d|j < q"d 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   GC:\wamp64\www\opt\env\Lib\site-packages\torch/fx/passes/graph_drawer.py__init__>   s.   


FxGraphDrawer.__init__returnc                 C   s   |du r|   S | |S )a  
            Visualize a torch.fx.Graph with graphviz
            Example:
                >>> # xdoctest: +REQUIRES(module:pydot)
                >>> # 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_graphg   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_graphsr0   c                 C   sp   | j dddd}|jtv rt|j |d< |S ||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   templatetarget_nameZtarget_hashr1   r1   r2   _get_node_style   s   
 zFxGraphDrawer._get_node_stylemodulec                 C   sZ   |}t |jts
J |jd}|D ]}t||s%tt|d | d t||}q|S )N.z does not have attribute !)r*   r.   strsplithasattrRuntimeErrorgetattr)r/   rK   r0   Zpy_objZatomsZatomr1   r1   r2   r)      s   
zFxGraphDrawer._get_leaf_noder.   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typenamerN   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_namec                    s  fdd}dd|j  d|j d }|jdkrD| || |d|   d	 7 }d
}t dr=d fdd jD }||d 7 }n5|d| |j d 7 }t|j	dkr_|||j	7 }t|j
dkrm|||j
7 }|dt|j d 7 }|jd}|| |7 }|jdd }	|	d ur|d|	j  d 7 }|d|	j d 7 }|r|jd urt|j}
| |
j}|d| d|
j d|
j d 7 }|d S )Nc                    s   t | trd\}}dd | D }nt | tr$d\}}dd |  D }ndS  r/dd |D }t|dkr7dS |d	| | }t|d
krP|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>       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 |vr|qS )%r1   re   r1   r1   r2   rh      ri   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   rp   z\n|rm   __constants__c                    s    g | ]}| d t  | qS )rj   )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   ry   r.   rG   argskwargsusersmetaget_tensor_meta_to_labeln_originZstack_tracer   rb   filelinenocode)r/   rK   r0   r   r   rw   labelextrar|   r}   Zparsed_stack_tracefnamer1   )r{   r   r2   _get_node_label   s8   


"zFxGraphDrawer._get_node_labelc                 C   s   |d u rdS t |tr| |S t |tr%d}|D ]	}|| |7 }q|S t |tr<d}| D ]	}|| |7 }q0|S t |trQd}|D ]	}|| |7 }qE|S tdt	| )Nrm   zUnsupported tensor meta type )
r*   r	   _stringify_tensor_metalistr   rr   valuesrq   rQ   type)r/   tmresultitemrl   r1   r1   r2   r     s(   




z#FxGraphDrawer._tensor_meta_to_labelr   c                 C   sv  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r|j	d usDJ d	|j	v sKJ |j	d	 }|t
jt
jhv rs|d
t|j	d  d 7 }|dt|j	d  d 7 }n9|t
jt
jt
jhv r|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 )Nrm   dtyper   z|dtype=rp   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   printrN   r   rq   r    Zrequires_gradZstrideZis_quantizedZqparamsr+   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tc                 C   s   t |jt t|j d S )Nrp   )rN   r   r   r    )r/   r   r1   r1   r2   _get_tensor_labelB  s   zFxGraphDrawer._get_tensor_labelc              
      sj  t j|dd i }|jjD ]m|rjdkrq}t jjfd|||i|}	 }
j	
dd}|durU|jdkrU|j}||vrPt j||d||< |
|}
|
|	  fd	d
}jdkrz||szttjjsz|  q| D ]}|dd |dd  | q|jjD ]|rjdkrqjD ]} t j|j qq 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}   Nro   )r   c                     s   t   D ]=\} }jd |  }t|tjjr!|d d nd}tj	|fdd| 
| d it} |  t|j q	d S )NrL   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_graphr{   r0   r/   r1   r2   get_module_params_or_buffersp  s$   
z;FxGraphDrawer._to_dot.<locals>.get_module_params_or_buffersr   colorZ	royalblueZpenwidth2)r   Dotr&   r'   r(   rJ   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$   G  sL   




zFxGraphDrawer._to_dot)FFTFNr:   )r]   )"__name__
__module____qualname____doc__r+   r,   r-   rN   boolr   r3   r   r   r9   r6   r7   r   r=   r   rJ   rW   rX   r)   r   r\   rA   rb   r   r   r	   r   ZTensorr   r$   r1   r1   r1   r2   r   5   s    
)


Fc                	   @   s0   e Zd Z		d	dejjdededefddZdS )
r   Fr   r   r   r   c                 C   s   t d)Nz|FXGraphDrawer requires the pydot package to be installed. Please install pydot through your favorite Python package manager.)rQ   )r/   r   r   r   r   r1   r1   r2   r3     s   r4   N)FF)	r   r   r   r+   r,   r-   rN   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>   sH     c