a
    hJ                     @   s<  U d dl Z d dlmZ d dlmZ d dlmZmZmZ d dl	Z	d dl
Z	d dlmZ d dlmZ d dlmZmZ d dlmZ d d	lmZ erd dlZd
Zn8ee ed< zd dlZd
ZW n ey   dZdZY n0 dgZddddddZg dZddddZereddG dd dZnes8eddG dd dZdS )    N)chain)
ModuleType)AnyOptionalTYPE_CHECKING)compatibility)_parse_stack_trace)_format_arg_get_qualified_name)normalize_function)TensorMetadataTpydotFFxGraphDrawerz"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                
   @   sJ  e Zd ZdZd,ejje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_shapenormalize_argsc	              	   C   s   || _ |d ur|nd| _|| _| jtd< || ||||||i| _|jjD ]^}	|	jdkrZqJ| 	||	}
t
|
tjjsvqJ| |
| d|	j ||||| j| d|	j < qJd S )Nrecordshaper   _)_namer!   r"   _WEIGHT_TEMPLATE_to_dot_dot_graphsgraphnodesop_get_leaf_node
isinstancetorchfxGraphModuletarget)selfr   r   r   r   r   r    r!   r"   nodeZ	leaf_node r5   J/var/www/auris/lib/python3.9/site-packages/torch/fx/passes/graph_drawer.py__init__N   s8    

FxGraphDrawer.__init__)returnc                 C   s   |du r|   S | |S dS )aA  
            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) -> None:
                >>>         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r3   Zsubmod_namer5   r5   r6   get_dot_graph}   s    zFxGraphDrawer.get_dot_graphc                 C   s   | j | j S Nr)   r&   r3   r5   r5   r6   r:      s    z FxGraphDrawer.get_main_dot_graphc                 C   s   | j | j d|  S )Nr%   r?   r<   r5   r5   r6   r;      s    z"FxGraphDrawer.get_submod_dot_graphc                 C   s   | j S r>   )r)   r@   r5   r5   r6   get_all_dot_graphs   s    z FxGraphDrawer.get_all_dot_graphs)r4   r9   c                 C   sr   | j dddd}|jtv r*t|j |d< nD||j}ttj| dd	 d d d	}t
|tt
  |d< |S )
Nz#CAFFE3r   r   )r$   r   r   r   r   F)usedforsecurity      )r!   r,   
_COLOR_MAPZ_pretty_print_targetr2   inthashlibmd5encode	hexdigest_HASH_COLOR_MAPlen)r3   r4   templateZtarget_nameZtarget_hashr5   r5   r6   _get_node_style   s(    

zFxGraphDrawer._get_node_style)moduler4   r9   c                 C   sZ   |}t |jtsJ |jd}|D ]0}t||sJtt|d | d t||}q$|S )N.z does not have attribute !)r.   r2   strsplithasattrRuntimeErrorgetattr)r3   rO   r4   Zpy_objZatomsZatomr5   r5   r6   r-      s    
zFxGraphDrawer._get_leaf_node)r2   r9   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typenamerR   r
   replace)r3   r2   retr5   r5   r6   	_typename   s    
zFxGraphDrawer._typename   )full_file_nametruncate_to_last_nc                 C   s.   | d}t||kr*d|| d  S |S )N/)rS   rL   join)r3   rb   rc   splitsr5   r5   r6   _shorten_file_name   s    
z FxGraphDrawer._shorten_file_name)rO   r4   r   r    r9   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 }n|d| |j d 7 }| jrzt	|j|j
|jdd\}}	W q ty   |j
|j }}	Y q0 n|j
|j }}	t|dkr|||7 }t|	dkr,|||	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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 )rC   Zmax_list_lenr	   .0ar5   r5   r6   
<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 ): rC   rh   ri   )rk   kvr5   r5   r6   rm      s    c                 S   s   g | ]}d |vr|qS )%r5   rj   r5   r5   r6   rm      rn   r   z,\n   z\l\nrW   rX   rY   rZ   )r.   tupledictitemsrL   re   r^   )argprefixsuffixZarg_strs_listZarg_strs)r   r5   r6   _get_str_for_args_kwargs   s"    

z?FxGraphDrawer._get_node_label.<locals>._get_str_for_args_kwargsrW   zname=%z	|op_code=
r   ru   z\n|rr   __constants__c                    s    g | ]}| d t  | qS )ro   )rV   )rk   c)leaf_moduler5   r6   rm     s   z1FxGraphDrawer._get_node_label.<locals>.<listcomp>z|target=T)Znormalize_to_only_use_kwargsr   z|num_users=tensor_metabuf_metaz|buf=z
|n_origin=z|file=: rY   )r   r,   r-   r`   rT   re   r~   r2   r"   r   argskwargs	ExceptionrL   usersmetaget_tensor_meta_to_labeln_originZstack_tracer   rg   filelinenocode)r3   rO   r4   r   r    r|   labelextrar   r   r   r   Zparsed_stack_tracefnamer5   )r   r   r6   _get_node_label   sZ    




zFxGraphDrawer._get_node_labelc                 C   s   |d u 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 )Nrr   zUnsupported tensor meta type )
r.   r   _stringify_tensor_metalistr   rw   valuesrv   rU   type)r3   tmresultitemrq   r5   r5   r6   r   9  s(    




z#FxGraphDrawer._tensor_meta_to_label)r   r9   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 usJ d	|j	v sJ |j	d	 }|t
jt
jhv r|d
t|j	d  d 7 }|dt|j	d  d 7 }nt|t
jt
jt
jhv 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 )Nrr   dtyper   z|dtype=ru   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=)rT   printrR   r   rv   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_qparamsrU   )r3   r   r   r   r5   r5   r6   r   P  sh    


z$FxGraphDrawer._stringify_tensor_meta)tr9   c                 C   s   t |jt t|j d S )Nru   )rR   r   r   r$   )r3   r   r5   r5   r6   _get_tensor_label  s    zFxGraphDrawer._get_tensor_label)r   r   r   r   r   r    r9   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ur|jdkr|j}||v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.
            ZTB)Zrankdirr   r   r   Nrt   )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 )NrP   z|op_code=get_Z	parameterzbuffer\lr   rW   rY   )r   Znamed_parametersZnamed_buffersr   r.   r/   r[   	Parameterr   Noder   r'   add_nodeadd_edgeEdge)ZpnameZptensorZpname1label1Z
dot_w_nodeZ	dot_graphr   r4   r3   r5   r6   get_module_params_or_buffers  s"    
z;FxGraphDrawer._to_dot.<locals>.get_module_params_or_buffersr   colorZ	royalblueZpenwidth2)r   Dotr*   r+   r,   rN   r   r   r   r   r   r   ZClusterr   r-   r.   r/   r0   r1   r   setZadd_subgraphr   r   r   )r3   r   r   r   r   r   r    Zbuf_name_to_subgraphr   Zdot_nodeZcurrent_graphr   Zbuf_namer   Zsubgraphuserr5   r   r6   r(     sT    





zFxGraphDrawer._to_dot)FFTFNF)N)ra   )"__name__
__module____qualname____doc__r/   r0   r1   rR   boolr   r7   r   r   r=   r:   r;   rw   rA   r   rN   r[   r\   r-   r   r`   rF   rg   r   r   r   r   ZTensorr   r(   r5   r5   r5   r6   r   E   s`         / W7c                
   @   s2   e Zd Zdejje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.)rU   )	r3   r   r   r   r   r   r    r!   r"   r5   r5   r6   r7     s    r8   )FFTFNF)
r   r   r   r/   r0   r1   rR   r   r   r7   r5   r5   r5   r6   r     s          )rG   	itertoolsr   typesr   typingr   r   r   r/   Ztorch.fxZtorch.fx._compatibilityr   Ztorch.fx.graphr   Ztorch.fx.noder	   r
   Ztorch.fx.operator_schemasr   Ztorch.fx.passes.shape_propr   r   Z	HAS_PYDOT__annotations__ModuleNotFoundError__all__rE   rK   r'   r   r5   r5   r5   r6   <module>   sR   

    