U
    ©Ê¹j®5  ã                   @   s  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 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"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 )'é    N)ÚDictÚAnyÚTYPE_CHECKING)Ú_get_qualified_nameÚ_format_arg)Ú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Ú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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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")
        FT)Úgraph_moduleÚnameÚignore_getattrÚignore_parameters_and_buffersÚskip_node_names_in_argsc                 C   sˆ   || _ ||  |||||¡i| _|jjD ]\}|jdkr6q&|  ||¡}t|tj	j
ƒsRq&|  ||› 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   r   ÚnodeZ	leaf_node© r+   ú[/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/fx/passes/graph_drawer.pyÚ__init__>   s.         ÿÿ
ûúFxGraphDrawer.__init__N)Úreturnc                 C   s   |dkr|   ¡ S |  |¡S d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_namer+   r+   r,   Úget_dot_graph^   s    zFxGraphDrawer.get_dot_graphc                 C   s   | j | j S ©N©r   r   ©r)   r+   r+   r,   r0   z   s    z FxGraphDrawer.get_main_dot_graphc                 C   s   | j | j› d|› � S )Nr   r5   r2   r+   r+   r,   r1   }   s    z"FxGraphDrawer.get_submod_dot_graphc                 C   s   | j S r4   )r   r6   r+   r+   r,   Úget_all_dot_graphs€   s    z FxGraphDrawer.get_all_dot_graphs)r*   r/   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_styleƒ   s    ü
 zFxGraphDrawer._get_node_style)Úmoduler*   r/   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)   rD   r*   Zpy_objZatomsZatomr+   r+   r,   r#   “   s    
ÿzFxGraphDrawer._get_leaf_node)r(   r/   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ÚtypenamerG   r   Úreplace)r)   r(   Úretr+   r+   r,   Ú	_typename¡   s    
zFxGraphDrawer._typename)rD   r*   r   r/   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 )r8   ©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 )ú: r8   rW   rX   )rZ   ÚkÚvr+   r+   r,   r\   º   s   ÿÚ c                 S   s   g | ]}d |kr|‘qS )ú%r+   rY   r+   r+   r,   r\   Ã   s      r   z,\nrM   rN   rO   rP   )r$   ÚtupleÚdictÚitemsrA   ÚjoinrT   )Ú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_kwargsrM   zname=%z	|op_code=Ú
r   ú\nz\n|r`   Ú__constants__c                    s    g | ]}|› d t ˆ |ƒ› �‘qS )r]   )rL   )rZ   Úc)Úleaf_moduler+   r,   r\   Ò   s     z1FxGraphDrawer._get_node_label.<locals>.<listcomp>z|target=r   z|num_users=Útensor_metarO   )r   r"   r#   rV   rJ   re   rl   r(   rA   ÚargsÚkwargsÚusersÚmetaÚgetÚ_tensor_meta_to_label)r)   rD   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ƒrxd}| ¡ D ]}||  |¡7 }q`|S t |tƒr¢d}|D ]}||  |¡7 }qŠ|S tdt	|ƒ› �ƒ‚d S )Nr`   zUnsupported tensor meta type )
r$   r   Ú_stringify_tensor_metaÚlistru   rc   Úvaluesrb   rK   Útype)r)   ÚtmÚresultÚitemr_   r+   r+   r,   ru   â   s(    




z#FxGraphDrawer._tensor_meta_to_label)r}   r/   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	sŠt
‚d	|j	ks˜t
‚|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=Ú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=)rJ   ÚprintrG   r€   rb   r   Zrequires_gradZstrideZis_quantizedZqparamsrH   r%   Zper_tensor_affineZper_tensor_symmetricZper_channel_affineZper_channel_symmetricZ per_channel_affine_float_qparamsrK   )r)   r}   r~   r�   r+   r+   r,   ry   ù   s8    


þýz$FxGraphDrawer._stringify_tensor_meta)Útr/   c                 C   s   t |jƒt t|jƒƒ d S )Nrk   )rG   r€   rz   r   )r)   r„   r+   r+   r,   Ú_get_tensor_label  s    zFxGraphDrawer._get_tensor_label)r   r   r   r   r   r/   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ˆ 
|ˆ¡‰|stˆtjjƒs|ƒ  q|jjD ]6‰|r¾ˆjdkr¾qªˆjD ]}	ˆ  t  ˆj|	j¡¡ qÄ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   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 )NrE   z|op_code=get_Z	parameterzbuffer\lrv   rM   rO   )r	   Znamed_parametersZnamed_buffersr   r$   r%   rQ   Ú	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_buffers4  s$     ÿÿýÿþý
z;FxGraphDrawer._to_dot.<locals>.get_module_params_or_buffersr   )rˆ   ÚDotr    r!   r"   rC   r‰   r   rx   r‹   r#   r$   r%   r&   r'   rr   rŒ   r�   )
r)   r   r   r   r   r   r   Zdot_noder�   Úuserr+   r�   r,   r     s0    
ÿÿÿ


zFxGraphDrawer._to_dot)FFT)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r%   r&   r'   rG   Úboolr-   rˆ   r‘   r3   r0   r1   r   r7   r‰   rC   rQ   rR   r#   r   rV   rx   ru   r   ry   ZTensorr…   r   r+   r+   r+   r,   r
   5   sH      úú  þû4ù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.)rK   )r)   r   r   r   r+   r+   r,   r-   Y  s    r.   N)F)	r“   r”   r•   r%   r&   r'   rG   r—   r-   r+   r+   r+   r,   r
   W  s   )r<   r%   Ztorch.fxÚtypingr   r   r   Ztorch.fx.noder   r   Ztorch.fx.passes.shape_propr   Ztorch.fx._compatibilityr   Ú	itertoolsr	   Ú__all__rˆ   Z	HAS_PYDOTÚImportErrorr:   r@   rŠ   r
   r+   r+   r+   r,   Ú<module>   sb   
û	ðü  "