1+ use std:: collections:: BTreeMap ;
2+
13/// Stats for a nested span in the execution segment that is tracked by the [`CycleTracker`].
24#[ derive( Clone , Debug , Default ) ]
35pub struct SpanInfo {
46 /// The name of the span.
57 pub tag : String ,
68 /// The cycle count at which the span starts.
79 pub start : usize ,
10+ /// Maps (dsl_ir, opcode) to number of times opcode was executed
11+ pub counts : BTreeMap < ( Option < String > , String ) , usize > ,
812}
913
10- #[ derive( Clone , Debug , Default ) ]
14+ #[ derive( Clone , Debug ) ]
1115pub struct CycleTracker {
1216 /// Stack of span names, with most recent at the end
1317 stack : Vec < SpanInfo > ,
1418 /// Depth of the stack.
1519 depth : usize ,
20+ max_depth : usize ,
21+ }
22+
23+ impl Default for CycleTracker {
24+ fn default ( ) -> Self {
25+ Self {
26+ stack : Vec :: new ( ) ,
27+ depth : 0 ,
28+ max_depth : std:: env:: var ( "CYCLE_TRACKER_MAX_DEPTH" )
29+ . ok ( )
30+ . and_then ( |s| s. parse ( ) . ok ( ) )
31+ . unwrap_or ( 2 ) ,
32+ }
33+ }
1634}
1735
1836impl CycleTracker {
19- pub fn new ( ) -> Self {
20- Self :: default ( )
37+ pub fn new ( max_depth : usize ) -> Self {
38+ Self {
39+ max_depth,
40+ ..Default :: default ( )
41+ }
2142 }
2243
2344 pub fn top ( & self ) -> Option < & String > {
@@ -30,33 +51,48 @@ impl CycleTracker {
3051 /// Starts a new cycle tracker span for the given name.
3152 /// If a span already exists for the given name, it ends the existing span and pushes a new one
3253 /// to the vec.
33- pub fn start ( & mut self , mut name : String , cycles_count : usize ) {
54+ pub fn start ( & mut self , mut name : String , cycles_count : usize , num_insns_by_dsl : & BTreeMap < ( Option < String > , String ) , usize > ) {
3455 // hack to remove "CT-" prefix
3556 if name. starts_with ( "CT-" ) {
3657 name = name. split_off ( 3 ) ;
3758 }
59+ self . depth += 1 ;
60+ if self . depth > self . max_depth {
61+ return ;
62+ }
3863 self . stack . push ( SpanInfo {
3964 tag : name. clone ( ) ,
4065 start : cycles_count,
66+ counts : num_insns_by_dsl. clone ( ) ,
4167 } ) ;
4268 let padding = "│ " . repeat ( self . depth ) ;
4369 tracing:: info!( "{}┌╴{}" , padding, name) ;
44- self . depth += 1 ;
4570 }
4671
4772 /// Ends the cycle tracker span for the given name.
4873 /// If no span exists for the given name, it panics.
49- pub fn end ( & mut self , mut name : String , cycles_count : usize ) {
74+ pub fn end ( & mut self , mut name : String , cycles_count : usize , num_insns_by_dsl : & BTreeMap < ( Option < String > , String ) , usize > ) {
5075 // hack to remove "CT-" prefix
5176 if name. starts_with ( "CT-" ) {
5277 name = name. split_off ( 3 ) ;
5378 }
54- let SpanInfo { tag, start } = self . stack . pop ( ) . unwrap ( ) ;
55- assert_eq ! ( tag, name, "Stack top does not match name" ) ;
5679 self . depth -= 1 ;
80+ if self . depth >= self . max_depth {
81+ return ;
82+ }
83+ let SpanInfo { tag, start, counts : num_insns_start } = self . stack . pop ( ) . unwrap ( ) ;
84+ assert_eq ! ( tag, name, "Stack top does not match name" ) ;
5785 let padding = "│ " . repeat ( self . depth ) ;
5886 let span_cycles = cycles_count - start;
59- tracing:: info!( "{}└╴{} cycles" , padding, span_cycles) ;
87+ for ( dsl_opcode, num_insns) in num_insns_by_dsl {
88+ let start_count = num_insns_start. get ( dsl_opcode) . cloned ( ) . unwrap_or ( 0 ) ;
89+ let span_count = num_insns - start_count;
90+ if span_count > 0 {
91+ tracing:: info!( "{}│ ({:?},{}): {} instructions" , padding, dsl_opcode. 0 , dsl_opcode. 1 , span_count) ;
92+
93+ }
94+ }
95+ tracing:: info!( "{}└╴({}) {} cycles" , padding, name, span_cycles) ;
6096 }
6197
6298 /// Ends the current cycle tracker span.
0 commit comments