o
    j9:jL                     @   s:  U d dl Z d dlmZ d dlmZ d dl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rJd dlZd
ZnedB ed< zd dlZd
ZW n eye   dZdZY nw dgZddddddZg dZddddZereddG dd dZdS eseddG dd dZdS dS )    N)chain)
ModuleType)AnyTYPE_CHECKING)compatibility)_parse_stack_trace)_format_arg_get_qualified_name)normalize_function)TensorMetadataTpydotFFxGraphDrawerz"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Wheat1r#   "filled,rounded"#000000)	fillcolorstyle	fontcolor)is_backward_compatiblec                   @   s  e Zd ZdZ						d2dejjdededed	ed
ededB defddZ	d3d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	!d4d"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d0d1Z dS )5r   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r-q%| 	||	}
t
|
tjjs;q%| |
| d|	j ||||| j| d|	j < q%d S )Nrecordshaper   _)_namer3   r4   _WEIGHT_TEMPLATE_to_dot_dot_graphsgraphnodesop_get_leaf_node
isinstancetorchfxGraphModuletarget)selfr-   r.   r/   r0   r1   r2   r3   r4   node	leaf_node rH   c/home/nk/hobo-godmode/plappi-mvp/.venv/lib/python3.10/site-packages/torch/fx/passes/graph_drawer.py__init__N   s:   

FxGraphDrawer.__init__returnc                 C   s   |du r|   S | |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rE   submod_namerH   rH   rI   get_dot_graph}   s   
zFxGraphDrawer.get_dot_graphc                 C   s   | j | j S Nr;   r8   rE   rH   rH   rI   rM      s   z FxGraphDrawer.get_main_dot_graphc                 C   s   | j | j d|  S )Nr7   rS   rO   rH   rH   rI   rN      s   z"FxGraphDrawer.get_submod_dot_graphc                 C   s   | j S rR   )r;   rT   rH   rH   rI   get_all_dot_graphs   s   z FxGraphDrawer.get_all_dot_graphsrF   c                 C   st   | j dddd}|jtv rt|j |d< |S ||j}ttj| dd	 d d d	}t
|tt
  |d< |S )
Nz#CAFFE3r'   r(   )r6   r)   r*   r+   r)   F)usedforsecurity      )r3   r>   
_COLOR_MAP_pretty_print_targetrD   inthashlibmd5encode	hexdigest_HASH_COLOR_MAPlen)rE   rF   templatetarget_nametarget_hashrH   rH   rI   _get_node_style   s*   


zFxGraphDrawer._get_node_stylemodulec                 C   sj   |}t |jtstdt|j |jd}|D ]}t||s-tt|d | d t||}q|S )NzExpected str target, got .z does not have attribute !)	r@   rD   strAssertionErrortypesplithasattrRuntimeErrorgetattr)rE   rf   rF   py_objatomsatomrH   rH   rI   r?      s   
zFxGraphDrawer._get_leaf_noderD   c                 C   sF   t |tjjrt|}nt |tr|}nt|}|ddddS )N{\{}\})r@   rA   nnModuletypenameri   r	   replace)rE   rD   retrH   rH   rI   	_typename   s   
zFxGraphDrawer._typename   full_file_nametruncate_to_last_nc                 C   s.   | d}t||krd|| d  S |S )N/)rl   ra   join)rE   r~   r   splitsrH   rH   rI   _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 }n[|d| |j d 7 }| jrtzt	|j|j
|jdd\}}	W n tys   |j
|j}}	Y nw |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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 )rW   max_list_lenr   .0arH   rH   rI   
<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 ): rW   r   r   )r   kvrH   rH   rI   r      s     c                 S   s   g | ]}d |vr|qS )%rH   r   rH   rH   rI   r      r   r   z,\n   z\l\nrs   rt   ru   rv   )r@   tupledictitemsra   r   rz   )argprefixsuffixarg_strs_listarg_strs)r1   rH   rI   _get_str_for_args_kwargs   s"   

z?FxGraphDrawer._get_node_label.<locals>._get_str_for_args_kwargsrs   zname=%z	|op_code=
r   r   z\n|r   __constants__c                    s    g | ]}| d t  | qS )r   )ro   )r   c)leaf_modulerH   rI   r     s    z1FxGraphDrawer._get_node_label.<locals>.<listcomp>z|target=T)normalize_to_only_use_kwargsr   z|num_users=tensor_metabuf_metaz|buf=z
|n_origin=z|file=: ru   )r.   r>   r?   r|   rm   r   r   rD   r4   r
   argskwargs	Exceptionra   usersmetaget_tensor_meta_to_labeln_originstack_tracer   r   filelinenocode)rE   rf   rF   r1   r2   r   labelextrar   r   r   r   parsed_stack_tracefnamerH   )r   r1   rI   _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   rn   rk   )rE   tmresultitemr   rH   rH   rI   r   :  s(   




z#FxGraphDrawer._tensor_meta_to_labelr   c                 C   s~  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 rFt
d	d
|j	vrOt
d|j	d
 }|tjtjhv rw|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=z$qparams is None for quantized tensorqschemezqscheme not in qparamsz	|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=)rm   printri   r   r   r6   requires_gradstrideis_quantizedqparamsrj   rA   per_tensor_affineper_tensor_symmetricper_channel_affineper_channel_symmetric per_channel_affine_float_qparamsrn   )rE   r   r   r   rH   rH   rI   r   Q  sl   




z$FxGraphDrawer._stringify_tensor_metatc                 C   s   t |jt t|j d S )Nr   )ri   r   r   r6   )rE   r   rH   rH   rI   _get_tensor_label  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)rankdirr   r   r   Nr   )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 )Nrg   z|op_code=get_	parameterzbuffer\lr   rs   ru   )r   named_parametersnamed_buffersr.   r@   rA   rw   	Parameterr   Noder   r9   add_nodeadd_edgeEdge)pnameptensorpname1label1
dot_w_node	dot_graphr   rF   rE   rH   rI   get_module_params_or_buffers  s&   
z;FxGraphDrawer._to_dot.<locals>.get_module_params_or_buffersr   color	royalbluepenwidth2)r   Dotr<   r=   r>   re   r   r.   r   r   r   r   Clusterr   r?   r@   rA   rB   rC   r   setadd_subgraphr   r   r   )rE   r-   r.   r/   r0   r1   r2   buf_name_to_subgraphr*   dot_nodecurrent_graphr   buf_namer   subgraphuserrH   r   rI   r:     sX   





zFxGraphDrawer._to_dotFFTFNFrR   )r}   )!__name__
__module____qualname____doc__rA   rB   rC   ri   boolrJ   r   r   rQ   rM   rN   r   rU   r   re   rw   rx   r?   r   r|   r[   r   r   r   r   r   Tensorr   r:   rH   rH   rH   rI   r   E   s    	
/



W9c                   @   sL   e Zd Z						ddejjdedededed	ed
edB defddZdS )r   FTNr-   r.   r/   r0   r1   r2   r3   r4   c	           	      C   s   t d)Nz|FXGraphDrawer requires the pydot package to be installed. Please install pydot through your favorite Python package manager.)rn   )	rE   r-   r.   r/   r0   r1   r2   r3   r4   rH   rH   rI   rJ     s   rK   r   )	r   r   r   rA   rB   rC   ri   r   rJ   rH   rH   rH   rI   r     s0    	)r\   	itertoolsr   typesr   typingr   r   rA   torch.fxtorch.fx._compatibilityr   torch.fx.graphr   torch.fx.noder   r	   torch.fx.operator_schemasr
   torch.fx.passes.shape_propr   r   	HAS_PYDOT__annotations__ModuleNotFoundError__all__rY   r`   r9   r   rH   rH   rH   rI   <module>   sX   
   &