
    /j;                        d Z ddlmZ ddlmZ ddlmZmZ erddlZe G d d                      Z	e G d d	                      Z
 G d
 d          ZdS )a  
Dynamo Profiler - tracks where Dynamo spends time during compilation.

This module provides profiling functionality for Dynamo tracing, showing per-function
cumtime (inclusive) and tottime (exclusive) in a cProfile-compatible format.
The output can be visualized with tools like snakeviz.

Usage:
    # Enable via config (prints pstats output):
    torch._dynamo.config.dynamo_profiler = True

    # Or save to file for snakeviz:
    torch._dynamo.config.dynamo_profiler = "/tmp/dynamo.prof"
    # Then: snakeviz /tmp/dynamo.prof
    )annotations)	dataclass)AnyTYPE_CHECKINGNc                  8   e Zd ZU dZded<   ded<   ded<   ded<   ded<   ded	<   ded
<   dZded<   dZded<   dZded<   dZded<   dZ	ded<   e
d"d            Ze
d#d            Ze
d#d            Ze
d#d            Ze
d$d            Ze
d%d             Zd&d!ZdS )'FunctionTraceTiminga+  
    Timing data for a single inlined function trace.

    Follows cProfile conventions:
    - cumtime: total time in function including all subcalls (inclusive)
    - tottime: time in function excluding subcalls (exclusive)
    - caller info: who called this function (for building call graph)
    str	func_namefilenameintfirstlineno
cumtime_ns
tottime_nsbytecode_countinline_depthN
str | Nonecaller_func_namecaller_filenamez
int | Nonecaller_firstlinenoTboolis_primitive_call  tuple[tuple[str, str, int], ...]
call_stackreturnc                    | j         S Nr   selfs    b/home/longshao/multi-rider-rag/.venv/lib/python3.11/site-packages/torch/_dynamo/dynamo_profiler.pytrace_time_nsz!FunctionTraceTiming.trace_time_ns=   s
        floatc                    | j         dz  S Ng    .Ar   r   s    r!   trace_time_msz!FunctionTraceTiming.trace_time_msA       $$r#   c                    | j         dz  S r&   r   r   s    r!   
cumtime_mszFunctionTraceTiming.cumtime_msE   r(   r#   c                    | j         dz  S r&   )r   r   s    r!   
tottime_mszFunctionTraceTiming.tottime_msI   r(   r#   tuple[str, int, str] | Nonec                D    | j         | j        pd| j        pd| j         fS dS )z/Return caller as a pstats-compatible key tuple.N r   )r   r   r   r   s    r!   
caller_keyzFunctionTraceTiming.caller_keyM   s:      ,$*',1% 
 tr#   tuple[str, int, str]c                *    | j         | j        | j        fS )z6Return this function as a pstats-compatible key tuple.)r   r   r
   r   s    r!   func_keyzFunctionTraceTiming.func_keyX   s     t/@@r#   c                |    d| j          d| j         d| j         d| j        dd| j        dd| j         d| j         d	S )
NzFunctionTraceTiming(z at :z
, cumtime=.2fzms, tottime=zms, bytecode=z, depth=))r
   r   r   r*   r,   r   r   r   s    r!   __repr__zFunctionTraceTiming.__repr__]   s    J4> J Jt} J JtGW J JQJ J8<QJ J+J J595FJ J J	
r#   )r   r   )r   r$   )r   r-   )r   r1   )r   r	   )__name__
__module____qualname____doc____annotations__r   r   r   r   r   propertyr"   r'   r*   r,   r0   r3   r8   r   r#   r!   r   r      s          NNNMMMOOOOOO#'''''"&O&&&&%))))) #"""" 46J5555    X % % % X% % % % X% % % % X%    X A A A XA
 
 
 
 
 
r#   r   c                  T    e Zd ZU dZded<   ded<   ded<   ded<   ded<   d	Zd
ed<   dS )ProfilerStackEntryz@Stack entry for tracking function timing in the Dynamo profiler.r	   r
   r   r   r   start_time_nschild_time_nsTr   r   N)r9   r:   r;   r<   r=   r   r   r#   r!   r@   r@   e   s`         JJNNNMMM"""""""r#   r@   c                  v    e Zd ZdZd'dZd(dZd)d	Zd*dZd+dZd,dZ	d-dZ
d.dZ	 d/d0d Z	 d1d2d#Z	 d3d4d&ZdS )5DynamoProfilerStatez:State for Dynamo profiler tracking function trace timings.r   Nonec                "    g | _         g | _        d S r   )timingsstackr   s    r!   __init__zDynamoProfilerState.__init__t   s    24/1


r#   timingr   c                :    | j                             |           dS )z)Record timing data for a traced function.N)rG   append)r    rJ   s     r!   record_timingz!DynamoProfilerState.record_timingx   s    F#####r#   list[FunctionTraceTiming]c                    | j         S )zGet all recorded timings.)rG   r   s    r!   get_timingszDynamoProfilerState.get_timings|   s
    |r#   r
   r	   r   r   r   rA   c           
         t          fd| j        D                        }| j                            t          |d|                     dS )z'Push a new entry onto the timing stack.c              3  Z   K   | ]%}|j         k    o|j        k    o
|j        k    V  &d S r   r
   r   r   ).0entryr   r   r
   s     r!   	<genexpr>z+DynamoProfilerState.push.<locals>.<genexpr>   s_       
 
  Oy( 1(*1![0
 
 
 
 
 
r#   r   )r
   r   r   rA   rB   r   N)anyrH   rL   r@   )r    r
   r   r   rA   is_primitives    ```  r!   pushzDynamoProfilerState.push   s    
  
 
 
 
 
 
 	
 
 
 
 
 
 	
#!'+".  		
 		
 		
 		
 		
r#   ProfilerStackEntry | Nonec                F    | j         r| j                                         S dS )z(Pop the top entry from the timing stack.N)rH   popr   s    r!   r\   zDynamoProfilerState.pop   s#    : 	$:>>###tr#   child_cumtime_nsc                N    | j         r| j         d         xj        |z  c_        dS dS )zGAdd the child's cumulative time to the parent's child_time accumulator.N)rH   rB   )r    r]   s     r!   add_child_timez"DynamoProfilerState.add_child_time   s7    : 	=JrN((,<<((((	= 	=r#   tuple[str, str, int] | Nonec                V    | j         r!| j         d         }|j        |j        |j        fS dS )zLGet the current caller (top of stack) as (func_name, filename, firstlineno).r_   N)rH   r
   r   r   )r    rU   s     r!   get_current_callerz&DynamoProfilerState.get_current_caller   s1    : 	HJrNEOU^U5FGGtr#   r   c                >    t          d | j        D                       S )zOGet the full current call stack as tuple of (func_name, filename, firstlineno).c              3  >   K   | ]}|j         |j        |j        fV  d S r   rS   )rT   rU   s     r!   rV   z5DynamoProfilerState.get_call_stack.<locals>.<genexpr>   sA       
 
EJU_ene.?@
 
 
 
 
 
r#   )tuplerH   r   s    r!   get_call_stackz"DynamoProfilerState.get_call_stack   s2     
 
NRj
 
 
 
 
 	
r#   NFoutput_filer   	print_rawr   pstats.Statsc                $	   ddl }ddl}ddl}ddl}|                    t
                    }i }i }	| j        D ]'}
|
j        |
j        |
j	        f}||vrddddd||<   i |	|<   ||         }|dxx         dz  cc<   |dxx         |
j
        dz  z  cc<   |
j        r(|d	xx         dz  cc<   |d
xx         |
j        dz  z  cc<   |
j        |
j        |
j        pd|
j        pdf}||	|         vrddddd|	|         |<   |	|         |         }|dxx         dz  cc<   |dxx         |
j
        dz  z  cc<   |d
xx         |
j        dz  z  cc<   |
j        r|d	xx         dz  cc<   )|rFt!          |                                d d          }t%          d           t%          dddd	dddddd
dd           t%          d           d}d}|D ]\  \  }}}}|d         }|d	         }|d         dz  }|d
         dz  }||z  }||z  }d|v r|                    d          d         n|}t%          |dd|dd|dd|dd| d| d| d           t%          d           t%          dt)          | j                   dt)          |                      t%          d |d!d"|d!d#           t+          |	                                          D ] }|	|         D ]}||vrddddd||<   i |	|<   !i }|                                D ]j\  }}i }|	|                                         D ]&\  }}|d         |d	         |d         |d
         f||<   '|d	         |d         |d         |d
         |f||<   k|                                }|                                 |                                  |j        ||                                $          }||_        t;          d% |                                D                       |_        t;          d& |                                D                       |_         t;          d' |                                D                       |_!        |r,|"                    |           |#                    d(||           |S ))zGenerate pstats.Stats object from recorded timings.

        Args:
            output_file: Optional file path to save the stats.
            print_raw: If True, print raw aggregate timings before returning.
        r   Ng        )ncallspcallstottimecumtimerl      rn   g    eArm   ro   r/   c                    | d         d         S )Nrp   ro   r   )xs    r!   <lambda>z5DynamoProfilerState.generate_pstats.<locals>.<lambda>   s    !A$y/ r#   T)keyreversez 
=== Aggregate Timings (raw) ===z>8 z>12z
  functionzP--------------------------------------------------------------------------------i  /r_   z>10.2fzms zms  z (r5   r7   zTotal timings: z, unique functions: zSum tottime: r6   zms, Sum cumtime: ms)streamc              3  &   K   | ]}|d          V  dS )rp   Nr   rT   ss     r!   rV   z6DynamoProfilerState.generate_pstats.<locals>.<genexpr>;  s&      BB!BBBBBBr#   c              3  &   K   | ]}|d          V  dS )r   Nr   r{   s     r!   rV   z6DynamoProfilerState.generate_pstats.<locals>.<genexpr><  s&      AAqtAAAAAAr#   c              3  &   K   | ]}|d          V  dS )   Nr   r{   s     r!   rV   z6DynamoProfilerState.generate_pstats.<locals>.<genexpr>=  s&      ??aQqT??????r#   z/Saved pstats to %s. Visualize with: snakeviz %s)$cProfileiologgingpstats	getLoggerr9   rG   r   r   r
   r   r   r   r   r   r   sorteditemsprintsplitlenlistkeysProfileenabledisableStatsStringIOstatssumvaluestotal_calls
prim_callstotal_tt
dump_statsinfo)r    rh   ri   r   r   r   r   log
aggregatedcaller_edgestrt   aggr0   edgesorted_itemstotal_cumtimetotal_tottimer   linenor
   rl   rm   rn   ro   
short_file
stats_dictcallersdummy_profiler   s                                 r!   generate_pstatsz#DynamoProfilerState.generate_pstats   sU    				)) BD
  	  )	( )	(A:q}ak:C*$$""	# #
3 %'S!S/CMMMQMMM	NNNalS00NNN" 5H"I!,"44  ,%(-A&,"

 \#%666"#"##&#&	5 5L%j1 $C(4X!#Y1<##55 Y1<##55& (NNNa'NNN 	!  ""(A(A4  L 5666XXXXXXyXXXyXXXX   (OOOMM6B  2-69sXXi.4/i.4/((8;xX^^C0044X
V ; ;6V ; ;wV ; ;'V ; ; ; ;$.; ;17; ; ;    (OOOZ#dl"3"3ZZZZZ   YYYYMYYYY   ))++,, 		2 		2C*3/ 2 2
Z//"#"##&#&	. .Jz* 02L,2  	 #((** 	 	HCQSG$0$5$;$;$=$=   
DNNOO	'
## HHIIJsOO !((**]2;;==AAA BBj.?.?.A.ABBBBBAAZ->->-@-@AAAAA??:+<+<+>+>????? 	[)))HHA   r#   profile_filesvg_filec           	        ddl }ddl}ddl}|                    d          st	          d           dS |                    d          st	          d           dS ||                    dd          d         d	z   }	 |                    dd
dddd|g|j        |j                  }|                    ddd|g|j        |j        |j                  }|j        	                                 |
                                \  }}	|
                                \  }}
|j        dk    r&t	          d|
                                            dS |j        dk    r&t	          d|	                                            dS |j                            |          st	          d|            dS t	          d|            |S # t          $ r}t	          d|            Y d}~dS d}~ww xY w)a{  Generate an SVG call graph from a profile file using gprof2dot and graphviz.

        Args:
            profile_file: Path to the pstats profile file.
            svg_file: Optional path for the output SVG. If not provided, uses
                profile_file with .svg extension.

        Returns:
            Path to the generated SVG file, or None if generation failed.
        r   N	gprof2dotz8gprof2dot not found. Install with: pip install gprof2dotdotz3graphviz 'dot' not found. Install graphviz package..rp   z.svgz-fr   z"--node-label=total-time-percentagez!--node-label=self-time-percentagez--node-label=total-time)stdoutstderrz-Tsvgz-o)stdinr   r   zgprof2dot failed: zgraphviz dot failed: zSVG file was not created: zSVG call graph saved to: zFailed to generate SVG: )osshutil
subprocesswhichr   rsplitPopenPIPEr   closecommunicate
returncodedecodepathisfile	Exception)r    r   r   r   r   r   r   r   _dot_errgprof2dot_erres               r!   generate_svgz DynamoProfilerState.generate_svgI  sV    				||K(( 	LMMM4||E"" 	GHHH4#**32215>H,	"((87-  "! )  I ""x0&!!	 #  C ""$$$**JAw(4466A}#q((A)=)=)?)?AA   t~""@gnn.>.>@@AAAt7>>(++ =8==>>>t8h88999O 	 	 	0Q0011144444	s+   ;CF; /F; 9,F; 'F; ;
G"GG"Tr   c                T   ddl }| j        sdS |                     |d          }t          d           |j        |_        |                    d                                           |r=t          d|            t          d|            |r|                     |           dS dS dS )	a#  Print profiler stats to stdout and optionally save to file.

        Args:
            output_file: Optional path to save the pstats profile.
            generate_svg: If True and output_file is provided, also generate an SVG
                call graph using gprof2dot and graphviz.
        r   NT)ri   z!
=== Dynamo Profiler (pstats) ===
cumulativez
Profile saved to: zVisualize with: snakeviz )	sysrG   r   r   r   ry   
sort_statsprint_statsr   )r    rh   r   r   r   s        r!   r   zDynamoProfilerState.dump_stats  s     	


| 	F$$[D$AA2333z&&22444 	/666777;k;;<<< /!!+.....	/ 	// /r#   )r   rE   )rJ   r   r   rE   )r   rN   )
r
   r	   r   r	   r   r   rA   r   r   rE   )r   rZ   )r]   r   r   rE   )r   ra   )r   r   )NF)rh   r   ri   r   r   rj   r   )r   r	   r   r   r   r   )NT)rh   r   r   r   r   rE   )r9   r:   r;   r<   rI   rM   rP   rY   r\   r`   rc   rg   r   r   r   r   r#   r!   rD   rD   q   s$       DD2 2 2 2$ $ $ $   
 
 
 
,   = = = =
   
 
 
 
 AFY Y Y Y Yx 9=H H H H HV DH/ / / / / / /r#   rD   )r<   
__future__r   dataclassesr   typingr   r   r   r   r@   rD   r   r#   r!   <module>r      s     # " " " " " ! ! ! ! ! ! % % % % % % % %  MMM F
 F
 F
 F
 F
 F
 F
 F
R # # # # # # # #{/ {/ {/ {/ {/ {/ {/ {/ {/ {/r#   