Skip to content

Commit 4773afa

Browse files
committed
Move debug data from iterations to analysis
1 parent c0fe06a commit 4773afa

File tree

2 files changed

+68
-53
lines changed

2 files changed

+68
-53
lines changed

rust/cubesql/cubesql/src/compile/rewrite/analysis.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ use crate::{
22
compile::{
33
rewrite::{
44
converter::{is_expr_node, node_to_expr, LogicalPlanToLanguageConverter},
5-
expr_column_name, AggregateUDFExprFun, AliasExprAlias, AllMembersAlias, AllMembersCube,
6-
ChangeUserCube, ColumnExprColumn, DimensionName, FilterMemberMember, FilterMemberOp,
7-
LiteralExprValue, LiteralMemberRelation, LiteralMemberValue, LogicalPlanLanguage,
8-
MeasureName, ScalarFunctionExprFun, SegmentMemberMember, SegmentName,
9-
TableScanSourceTableName, TimeDimensionDateRange, TimeDimensionGranularity,
10-
TimeDimensionName, VirtualFieldCube, VirtualFieldName,
5+
expr_column_name,
6+
rewriter::{CubeEGraph, DebugData},
7+
AggregateUDFExprFun, AliasExprAlias, AllMembersAlias, AllMembersCube, ChangeUserCube,
8+
ColumnExprColumn, DimensionName, FilterMemberMember, FilterMemberOp, LiteralExprValue,
9+
LiteralMemberRelation, LiteralMemberValue, LogicalPlanLanguage, MeasureName,
10+
ScalarFunctionExprFun, SegmentMemberMember, SegmentName, TableScanSourceTableName,
11+
TimeDimensionDateRange, TimeDimensionGranularity, TimeDimensionName, VirtualFieldCube,
12+
VirtualFieldName,
1113
},
1214
CubeContext,
1315
},
@@ -233,11 +235,16 @@ impl Member {
233235
}
234236
}
235237

238+
type EgraphDebugState = DebugData;
239+
236240
#[derive(Clone)]
237241
pub struct LogicalPlanAnalysis {
238242
/* This is 0, when creating the EGraph. It's set to 1 before iteration 0,
239243
2 before the iteration 1, etc. */
240244
pub iteration_timestamp: usize,
245+
/// Debug info, used with egraph-debug
246+
/// Will be filled by special hook in Runner
247+
pub debug_states: Vec<EgraphDebugState>,
241248
cube_context: Arc<CubeContext>,
242249
planner: Arc<DefaultPhysicalPlanner>,
243250
}
@@ -270,11 +277,25 @@ impl LogicalPlanAnalysis {
270277
pub fn new(cube_context: Arc<CubeContext>, planner: Arc<DefaultPhysicalPlanner>) -> Self {
271278
Self {
272279
iteration_timestamp: 0,
280+
debug_states: vec![],
273281
cube_context,
274282
planner,
275283
}
276284
}
277285

286+
fn prepare_egraph_debug_state(egraph: &CubeEGraph) -> EgraphDebugState {
287+
DebugData::prepare(egraph)
288+
}
289+
290+
pub fn store_egraph_debug_state(egraph: &mut CubeEGraph) {
291+
debug_assert_eq!(
292+
egraph.analysis.iteration_timestamp,
293+
egraph.analysis.debug_states.len()
294+
);
295+
let state = Self::prepare_egraph_debug_state(egraph);
296+
egraph.analysis.debug_states.push(state);
297+
}
298+
278299
fn make_original_expr(
279300
egraph: &EGraph<LogicalPlanLanguage, Self>,
280301
enode: &LogicalPlanLanguage,

rust/cubesql/cubesql/src/compile/rewrite/rewriter.rs

Lines changed: 41 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
152141
pub struct IterInfo {
153-
debug_info: Option<IterDebugInfo>,
154142
debug_qtrace_eclasses: Option<Vec<QtraceEclass>>,
155143
}
156144

@@ -165,11 +153,6 @@ impl IterInfo {
165153
impl 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

Comments
 (0)