@@ -77,13 +77,8 @@ pub struct DebugData {
7777 applied_rules : Option < Vec < String > > ,
7878}
7979
80- #[ derive( Debug ) ]
81- pub struct IterDebugInfo {
82- debug_data : DebugData ,
83- }
84-
85- impl IterDebugInfo {
86- pub fn prepare_debug_data ( graph : & CubeEGraph ) -> DebugData {
80+ impl DebugData {
81+ pub fn prepare ( graph : & CubeEGraph ) -> DebugData {
8782 DebugData {
8883 applied_rules : None ,
8984 nodes : graph
@@ -140,17 +135,10 @@ impl IterDebugInfo {
140135 removed_combos : Vec :: new ( ) ,
141136 }
142137 }
143-
144- fn make ( runner : & CubeRunner ) -> Self {
145- IterDebugInfo {
146- debug_data : Self :: prepare_debug_data ( & runner. egraph ) ,
147- }
148- }
149138}
150139
151140#[ derive( Debug ) ]
152141pub struct IterInfo {
153- debug_info : Option < IterDebugInfo > ,
154142 debug_qtrace_eclasses : Option < Vec < QtraceEclass > > ,
155143}
156144
@@ -165,11 +153,6 @@ impl IterInfo {
165153impl IterationData < LogicalPlanLanguage , LogicalPlanAnalysis > for IterInfo {
166154 fn make ( runner : & CubeRunner ) -> Self {
167155 IterInfo {
168- debug_info : if Self :: egraph_debug_enabled ( ) {
169- Some ( IterDebugInfo :: make ( runner) )
170- } else {
171- None
172- } ,
173156 debug_qtrace_eclasses : if Qtrace :: is_enabled ( ) {
174157 Some (
175158 runner
@@ -185,11 +168,7 @@ impl IterationData<LogicalPlanLanguage, LogicalPlanAnalysis> for IterInfo {
185168 }
186169}
187170
188- fn write_debug_states (
189- init_debug_data : & DebugData ,
190- runner : & CubeRunner ,
191- stage : & str ,
192- ) -> Result < ( ) , CubeError > {
171+ fn write_debug_states ( runner : & CubeRunner , stage : & str ) -> Result < ( ) , CubeError > {
193172 let dir = format ! ( "egraph-debug-{}" , stage) ;
194173 let _ = fs:: create_dir_all ( dir. clone ( ) ) ;
195174 let _ = fs:: create_dir_all ( format ! ( "{}/public" , dir) ) ;
@@ -210,13 +189,16 @@ fn write_debug_states(
210189 let mut states = Vec :: new ( ) ;
211190 let mut last_debug_data: Option < DebugData > = None ;
212191
213- let states_data =
214- std:: iter:: once ( ( init_debug_data, None ) ) . chain ( runner. iterations . iter ( ) . map ( |i| {
215- (
216- & i. data . debug_info . as_ref ( ) . unwrap ( ) . debug_data ,
217- Some ( & i. applied ) ,
218- )
219- } ) ) ;
192+ let debug_data = runner. egraph . analysis . debug_states . as_slice ( ) ;
193+ debug_assert_eq ! ( debug_data. len( ) , runner. iterations. len( ) + 1 ) ;
194+
195+ // debug_data[0] is initial state
196+ // runner.iterations[0] is result of first iteration
197+ let states_data = debug_data
198+ . iter ( )
199+ . skip ( 1 )
200+ . zip ( runner. iterations . iter ( ) . map ( |i| Some ( & i. applied ) ) ) ;
201+ let states_data = std:: iter:: once ( ( & debug_data[ 0 ] , None ) ) . chain ( states_data) ;
220202
221203 for ( debug_data, applied) in states_data {
222204 let mut debug_data = debug_data. clone ( ) ;
@@ -277,7 +259,7 @@ impl Rewriter {
277259 }
278260
279261 pub fn rewrite_runner ( cube_context : Arc < CubeContext > , egraph : CubeEGraph ) -> CubeRunner {
280- CubeRunner :: new ( LogicalPlanAnalysis :: new (
262+ let runner = CubeRunner :: new ( LogicalPlanAnalysis :: new (
281263 cube_context,
282264 Arc :: new ( DefaultPhysicalPlanner :: default ( ) ) ,
283265 ) )
@@ -297,12 +279,29 @@ impl Rewriter {
297279 . map ( |v| v. parse :: < u64 > ( ) . unwrap ( ) )
298280 . unwrap_or ( 30 ) ,
299281 ) )
300- . with_scheduler ( IncrementalScheduler :: default ( ) )
301- . with_hook ( |runner| {
302- runner. egraph . analysis . iteration_timestamp = runner. iterations . len ( ) + 1 ;
303- Ok ( ( ) )
304- } )
305- . with_egraph ( egraph)
282+ . with_scheduler ( IncrementalScheduler :: default ( ) ) ;
283+
284+ let runner = if IterInfo :: egraph_debug_enabled ( ) {
285+ // We want more access than Iterations gives us
286+ // Specifically, there's no way to store and access egraph state before first iteration
287+ // This hook is not really order-dependent with iteration timestamp bump
288+ // But just for clarity it should run before, so first captured state would be when iteration is zero, before first iteration started
289+ runner. with_hook ( |runner| {
290+ LogicalPlanAnalysis :: store_egraph_debug_state ( & mut runner. egraph ) ;
291+ Ok ( ( ) )
292+ } )
293+ } else {
294+ runner
295+ } ;
296+
297+ let runner = runner
298+ . with_hook ( |runner| {
299+ runner. egraph . analysis . iteration_timestamp = runner. iterations . len ( ) + 1 ;
300+ Ok ( ( ) )
301+ } )
302+ . with_egraph ( egraph) ;
303+
304+ runner
306305 }
307306
308307 pub async fn run_rewrite_to_completion (
@@ -478,12 +477,8 @@ impl Rewriter {
478477 rules : Arc < Vec < CubeRewrite > > ,
479478 stage : & str ,
480479 ) -> Result < ( CubeRunner , Vec < QtraceEgraphIteration > ) , CubeError > {
481- // Capture initial egraph state, before rewrites
482- let init_debug_data =
483- IterInfo :: egraph_debug_enabled ( ) . then ( || IterDebugInfo :: prepare_debug_data ( & egraph) ) ;
484-
485480 let runner = Self :: rewrite_runner ( cube_context. clone ( ) , egraph) ;
486- let runner = runner. run ( rules. iter ( ) ) ;
481+ let mut runner = runner. run ( rules. iter ( ) ) ;
487482 if !IterInfo :: egraph_debug_enabled ( ) {
488483 log:: debug!( "Iterations: {:?}" , runner. iterations) ;
489484 }
@@ -501,10 +496,9 @@ impl Rewriter {
501496 }
502497 } ;
503498 if IterInfo :: egraph_debug_enabled ( ) {
504- // `unwrap()` should be ok here
505- // When IterInfo::egraph_debug_enabled() init_debug_data should be filled
506- let init_debug_data = init_debug_data. unwrap ( ) ;
507- write_debug_states ( & init_debug_data, & runner, stage) ?;
499+ // Store final state after all rewrites
500+ LogicalPlanAnalysis :: store_egraph_debug_state ( & mut runner. egraph ) ;
501+ write_debug_states ( & runner, stage) ?;
508502 }
509503 if let Some ( stop_reason) = stop_reason {
510504 return Err ( CubeError :: user ( format ! (
0 commit comments