
    9j;                        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y)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                     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y)#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_stackc                    | j                   S Nr   selfs    ]/media/conek/DATA/Code/OCR/venv/lib/python3.12/site-packages/torch/_dynamo/dynamo_profiler.pytrace_time_nsz!FunctionTraceTiming.trace_time_ns=   s        c                     | 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"   c                r    | j                   +| j                  xs d| j                  xs d| j                   fS y)z/Return caller as a pstats-compatible key tuple.N r   )r   r   r   r   s    r    
caller_keyzFunctionTraceTiming.caller_keyM   sD       ,$$*'',1%% 
 r"   c                H    | 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__]   sp    "4>>"2$t}}oQtGWGWFX Ys+<7L M++,HT5F5F4GqJ	
r"   )returnr   )r5   float)r5   ztuple[str, int, str] | None)r5   ztuple[str, int, str])r5   r	   )__name__
__module____qualname____doc____annotations__r   r   r   r   r   propertyr!   r%   r(   r*   r-   r/   r4   r   r"   r    r   r      s     NMOO#'j'"&OZ&%)
) #t" 46J05   % % % % % %   A A
r"   r   c                  R    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<   y)ProfilerStackEntryz@Stack entry for tracking function timing in the Dynamo profiler.r	   r
   r   r   r   start_time_nschild_time_nsTr   r   N)r7   r8   r9   r:   r;   r   r   r"   r    r>   r>   e   s,    JNM"t"r"   r>   c                      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	 	 	 	 	 ddZ	 d	 	 	 	 	 ddZ	 d	 	 	 	 	 ddZy
)DynamoProfilerStatez:State for Dynamo profiler tracking function trace timings.c                     g | _         g | _        y r   )timingsstackr   s    r    __init__zDynamoProfilerState.__init__t   s    24/1
r"   c                :    | j                   j                  |       y)z)Record timing data for a traced function.N)rD   append)r   timings     r    record_timingz!DynamoProfilerState.record_timingx   s    F#r"   c                    | j                   S )zGet all recorded timings.)rD   r   s    r    get_timingszDynamoProfilerState.get_timings|   s    ||r"   c           
         t        fd| j                  D               }| j                  j                  t        |d|             y)z'Push a new entry onto the timing stack.c              3     K   | ]5  }|j                   k(  xr  |j                  k(  xr |j                  k(   7 y wr   r
   r   r   ).0entryr   r   r
   s     r    	<genexpr>z+DynamoProfilerState.push.<locals>.<genexpr>   sM      
  OOy( 1(*1!![01
s   ;>r   )r
   r   r   r?   r@   r   N)anyrE   rH   r>   )r   r
   r   r   r?   is_primitives    ```  r    pushzDynamoProfilerState.push   sU    
  
 	
 
 
 	

#!'+".		
r"   c                P    | j                   r| j                   j                         S y)z(Pop the top entry from the timing stack.N)rE   popr   s    r    rW   zDynamoProfilerState.pop   s    ::::>>##r"   c                b    | j                   r#| j                   d   xj                  |z  c_        yy)zGAdd the child's cumulative time to the parent's child_time accumulator.N)rE   r@   )r   child_cumtime_nss     r    add_child_timez"DynamoProfilerState.add_child_time   s(    ::JJrN((,<<( r"   c                    | j                   r2| j                   d   }|j                  |j                  |j                  fS y)zLGet the current caller (top of stack) as (func_name, filename, firstlineno).rY   N)rE   r
   r   r   )r   rQ   s     r    get_current_callerz&DynamoProfilerState.get_current_caller   s4    ::JJrNEOOU^^U5F5FGGr"   c                :    t        d | j                  D              S )zOGet the full current call stack as tuple of (func_name, filename, firstlineno).c              3  b   K   | ]'  }|j                   |j                  |j                  f ) y wr   rO   )rP   rQ   s     r    rR   z5DynamoProfilerState.get_call_stack.<locals>.<genexpr>   s*      
EJU__enne.?.?@
s   -/)tuplerE   r   s    r    get_call_stackz"DynamoProfilerState.get_call_stack   s      
NRjj
 
 	
r"   Nc                B   ddl }ddl}ddl}ddl}|j	                  t
              }i }i }	| j                  D ]H  }
|
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                  xs d|
j                  xs 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                  s<|d	xx   dz  cc<   K |rt!        |j#                         d d      }t%        d       t%        dddd	dddddd
dd       t%        d       d}d}|D ]k  \  \  }}}}|d   }|d	   }|d   dz  }|d
   dz  }||z  }||z  }d|v r|j'                  d      d   n|}t%        |dd|dd|dd|dd| d| d| d       m t%        d       t%        dt)        | j                         dt)        |              t%        d |d!d"|d!d#       t+        |	j-                               D ]   }|	|   D ]  }||vsddddd||<   i |	|<    " i }|j#                         D ]M  \  }}i }|	|   j#                         D ]  \  }}|d   |d	   |d   |d
   f||<    |d	   |d   |d   |d
   |f||<   O |j/                         }|j1                          |j3                           |j4                  ||j7                         $      }||_        t;        d% |j=                         D              |_        t;        d& |j=                         D              |_         t;        d' |j=                         D              |_!        |r$|jE                  |       |jG                  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cumtimerc      re   g    eArd   rf   r,   c                    | d   d   S )Nrg   rf   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  /rY   z>10.2fzms zms  z (r1   r3   zTotal timings: z, unique functions: zSum tottime: r2   zms, Sum cumtime: ms)streamc              3  &   K   | ]	  }|d      yw)rg   Nr   rP   ss     r    rR   z6DynamoProfilerState.generate_pstats.<locals>.<genexpr>;  s     B!B   c              3  &   K   | ]	  }|d      yw)r   Nr   rr   s     r    rR   z6DynamoProfilerState.generate_pstats.<locals>.<genexpr><  s     AqtArt   c              3  &   K   | ]	  }|d      yw)   Nr   rr   s     r    rR   z6DynamoProfilerState.generate_pstats.<locals>.<genexpr>=  s     ?aQqT?rt   z/Saved pstats to %s. Visualize with: snakeviz %s)$cProfileiologgingpstats	getLoggerr7   rD   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   output_file	print_rawrx   ry   rz   r{   log
aggregatedcaller_edgestrk   aggr-   edgesorted_itemstotal_cumtimetotal_tottimer   linenor
   rc   rd   re   rf   
short_file
stats_dictcallersdummy_profiler   s                                 r    generate_pstatsz#DynamoProfilerState.generate_pstats   s    	) BD
  	  )	(A::q}}akk:C*$""	#
3 %'S!S/CMQM	NallS00N""H"I!,,"44   ,%%((-A&&,"

 \#%66"#"##&#&	5L%j1 $C(4X!#Y1<<##55 Y1<<##55&&Na'NS)	(V !  "(A4L 56B-q"QyoQyoZX (OMM6B 2-69sXXi.4/i.4/((8;xX^^C04X
bk6"+Qwv.>c'&AQQU kJ<q; (O!#dll"3!44HZHYZ c22CMRUCVVXY ))+, 		2C*3/ 2
Z/"#"##&#&	.Jz* 02L,2		2  	 #((* 	HCQSG$0$5$;$;$=  
DNNOO	'
# HHIIJsO	& !((*]2;;=A Bj.?.?.ABBAZ->->-@AA?:+<+<+>??[)HHA r"   c           	     |   ddl }ddl}ddl}|j                  d      st	        d       y|j                  d      st	        d       y||j                  dd      d   d	z   }	 |j                  dd
dddd|g|j                  |j                        }|j                  ddd|g|j                  |j                  |j                        }|j                  j                          |j                         \  }}	|j                         \  }}
|j                  dk7  rt	        d|
j                                 y|j                  dk7  rt	        d|	j                                 y|j                  j                  |      st	        d|        yt	        d|        |S # t        $ r}t	        d|        Y d}~y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..rg   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   profile_filesvg_filer   r   r   r   r   _dot_errgprof2dot_erres               r    generate_svgz DynamoProfilerState.generate_svgI  s    	||K(LM||E"GH#**3215>H,	"((87-  "! ) I ""x0&&!!	 # C ""$*JAw(446A}##q(()=)=)?(@A ~~"-gnn.>-?@A77>>(+28*=>-hZ89O 	,QC01	s+   "CF 4+F  )F 
F 	F;#F66F;c                (   ddl }| j                  sy| j                  |d      }t        d       |j                  |_        |j                  d      j                          |r1t        d|        t        d|        |r| j                  |       yyy)	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)r   z!
=== Dynamo Profiler (pstats) ===
cumulativez
Profile saved to: zVisualize with: snakeviz )	sysrD   r   r   r   rp   
sort_statsprint_statsr   )r   r   r   r   r   s        r    r   zDynamoProfilerState.dump_stats  s     	||$$[D$A23zz&224(67-k];<!!+. 	 r"   )r5   None)rI   r   r5   r   )r5   zlist[FunctionTraceTiming])
r
   r	   r   r	   r   r   r?   r   r5   r   )r5   zProfilerStackEntry | None)rZ   r   r5   r   )r5   ztuple[str, str, int] | None)r5   r   )NF)r   r   r   r   r5   zpstats.Statsr   )r   r	   r   r   r5   r   )NT)r   r   r   r   r5   r   )r7   r8   r9   r:   rF   rJ   rL   rU   rW   r[   r]   ra   r   r   r   r   r"   r    rB   rB   q   s    D2$

(+
:=
NQ
	
,=

 AFY%Y9=Y	Yx 9=HH+5H	HV DH/%/<@/	/r"   rB   )r:   
__future__r   dataclassesr   typingr   r   r{   r   r>   rB   r   r"   r    <module>r      s_     # ! %  F
 F
 F
R # # #{/ {/r"   