o
    h5                     @   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yF   d	ZY nw d
dddddZg dZdddddZerjed	dG dd dZdS eszed	dG dd dZdS dS )    N)DictAnyTYPE_CHECKING)_get_qualified_name_format_arg)TensorMetadata)compatibility)chainFxGraphDrawerTFz"AliceBlue"LemonChiffon1Yellow2	LightGrey
PowderBlue)placeholdercall_module	get_paramget_attroutput)
CadetBlue1CoralDarkOliveGreen1DarkSeaGreen1
GhostWhiteKhaki1LavenderBlush1LightSkyBlue
MistyRose1
MistyRose2PaleTurquoise2
PeachPuff1SalmonThistle1Thistle3Wheat1recordr    "filled,rounded"#000000shape	fillcolorstyle	fontcolor)is_backward_compatiblec                   @   sT  e Zd ZdZ			d*dejjdedededef
d	d
Z	d+d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dejjdejj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
jf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rq| ||}t|tj	j
s)q| || 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/   r0   r1   node	leaf_node rB   R/var/www/html/ai/venv/lib/python3.10/site-packages/torch/fx/passes/graph_drawer.py__init__>   s&   

FxGraphDrawer.__init__N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?   submod_namerB   rB   rC   get_dot_graph^   s   
zFxGraphDrawer.get_dot_graphc                 C   s   | j | j S Nr5   r3   r?   rB   rB   rC   rG   z   s   z FxGraphDrawer.get_main_dot_graphc                 C   s   | j | j d|  S )Nr2   rM   rI   rB   rB   rC   rH   }   s   z"FxGraphDrawer.get_submod_dot_graphc                 C   s   | j S rL   )r5   rN   rB   rB   rC   get_all_dot_graphs   s   z FxGraphDrawer.get_all_dot_graphsr@   c                 C   sn   ddddd}|j tv rt|j  |d< |S ||j}tt|  d d d}t	|t
t	  |d< |S )	Nr$   z#CAFFE3r%   r&   r'   r)         )r8   
_COLOR_MAP_pretty_print_targetr>   inthashlibmd5encode	hexdigest_HASH_COLOR_MAPlen)r?   r@   templatetarget_nametarget_hashrB   rB   rC   _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?   r_   r@   py_objatomsatomrB   rB   rC   r9      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typenamerb   r   replace)r?   r>   retrB   rB   rC   	_typename   s   
zFxGraphDrawer._typenamec                    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 }|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	| | }|d
dddS )N)z	|args=(\lz,\n)\lc                 S   s   g | ]}t |d dqS )rP   max_list_lenr   .0arB   rB   rC   
<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 ): rP   rt   rv   )rx   kvrB   rB   rC   rz      s     c                 S   s   g | ]}d |vr|qS )%rB   rw   rB   rB   rC   rz      r{   r   z,\nrj   rk   rl   rm   )r:   tupledictitemsrZ   joinrq   )argprefixsuffixarg_strs_listarg_strs)r1   rB   rC   _get_str_for_args_kwargs   s   

z?FxGraphDrawer._get_node_label.<locals>._get_str_for_args_kwargsrj   zname=%z	|op_code=
r   \nz\n|r   __constants__c                    s    g | ]}| d t  | qS )r|   )rf   )rx   c)leaf_modulerB   rC   rz      s     z1FxGraphDrawer._get_node_label.<locals>.<listcomp>z|target=r   z|num_users=tensor_metarl   )r.   r8   r9   rs   rd   r   r   r>   rZ   argskwargsusersmetaget_tensor_meta_to_label)r?   r_   r@   r1   r   labelextrar   rB   )r   r1   rC   _get_node_label   s(   

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	| )Nr   zUnsupported tensor meta type )
r:   r   _stringify_tensor_metalistr   r   valuesr   re   type)r?   tmresultitemr~   rB   rB   rC   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 )Nr   dtyper   z|dtype=r   z|shape=z|requires_grad=z|stride=qschemez	|q_scale=scalez|q_zero_point=
zero_pointz|q_per_channel_scale=z|q_per_channel_zero_point=z|q_per_channel_axis=axiszUnsupported qscheme: z	|qscheme=)rd   printrb   r   r   r(   requires_gradstrideis_quantizedqparamsr;   per_tensor_affineper_tensor_symmetricper_channel_affineper_channel_symmetric per_channel_affine_float_qparamsre   )r?   r   r   r   rB   rB   rC   r      s8   


z$FxGraphDrawer._stringify_tensor_metatc                 C   s   t |jt t|j d S )Nr   )rb   r   r   r(   )r?   r   rB   rB   rC   _get_tensor_label  s   zFxGraphDrawer._get_tensor_labelc           
   	      s   t j|dd |jjD ]E|rjdkrq}t jjfd||i|} 	|  fdd}jdkrP
||sPttjjsP|  q|jjD ]|r_jdkr_qUjD ]}	 t j|	j qbqU 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)rankdirr   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 )Nr`   z|op_code=get_	parameterzbuffer\lr   rj   rl   )r	   named_parametersnamed_buffersr.   r:   r;   rn   	ParameterpydotNoder   _WEIGHT_TEMPLATEadd_nodeadd_edgeEdge)pnameptensorpname1label1
dot_w_node	dot_graphr   r@   r?   rB   rC   get_module_params_or_buffers4  s$   
z;FxGraphDrawer._to_dot.<locals>.get_module_params_or_buffersr   )r   Dotr6   r7   r8   r^   r   r.   r   r   r9   r:   r;   r<   r=   r   r   r   )
r?   r-   r.   r/   r0   r1   r*   dot_noder   userrB   r   rC   r4     s4   



zFxGraphDrawer._to_dot)FFTrL   )__name__
__module____qualname____doc__r;   r<   r=   rb   boolrD   r   r   rK   rG   rH   r   rO   r   r^   rn   ro   r9   r   rs   r   r   r   r   Tensorr   r4   rB   rB   rB   rC   r
   5   sl    
 

4c                   @   s(   e Zd ZddejjdedefddZdS )	r
   Fr-   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.)re   )r?   r-   r.   r/   rB   rB   rC   rD   Y  s   rE   N)F)	r   r   r   r;   r<   r=   rb   r   rD   rB   rB   rB   rC   r
   W  s     )rU   r;   torch.fxtypingr   r   r   torch.fx.noder   r   torch.fx.passes.shape_propr   torch.fx._compatibilityr   	itertoolsr	   __all__r   	HAS_PYDOTImportErrorrR   rY   r   r
   rB   rB   rB   rC   <module>   sH     "