Skip to content

devtools: print a stage_pipeline document as text - #1158

Closed
milindsrivastava1997 wants to merge 1 commit into
mainfrom
devtools/print-stages
Closed

milindsrivastava1997 wants to merge 1 commit into
mainfrom
devtools/print-stages

Conversation

@milindsrivastava1997

@milindsrivastava1997 milindsrivastava1997 commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Why. Reading the planner's data structures (memo groups, candidates, the plan each stage produces) currently requires the Stage Viewer or reading raw JSON. A text dump is easier to diff, grep and paste into issues; #1117, #1124 and #1126 were all written from it.

What. tools/dag-viewer/print_stages.py prints a stage_pipeline document as text:

  • Stage 0's DAG.
  • The memo after each step (stage0, pass1, pass2, concrete_states): each group with its children, parents, queries and roots, then its candidates with origin, reads, implements and accuracy budget parts.
  • Stage 1 and Stage 2 candidates, and Stage 2's pruned candidates counted by reason.
  • Stage 3's search status, selected DAG, per-node cost and per-query accuracy.

--enumerated prints every memo choice in memo.enumeration as a logical DAG.

How. It reads only the document. It sits next to the Stage Viewer, which reads the same format, so the viewer's CI step runs its test.

Key code interfaces added / modified: None; one new script.

Major algorithm changes: None.

Before this PR: the memo was visible only in the Stage Viewer or as raw JSON.

After this PR, for quantile_over_time(0.5, data[5m]) and quantile_over_time(0.9, data[5m]), both every 1m:

MEMO after pass2: Stage 1, Pass 2: local window composition
  G2 Aggregate quantile(q=0.5)  children=[1] parents=[] queries=[0] ROOT of q[0]
      cand 1 [pass1] Project ← SummaryEstimate Quantile(q=0.5) ← SummaryAgg Kll(failure_probability=1e-7 k=567)  reads=[1] implements=[2] budget_parts=1
      cand 3 [panes NEW] Project ← SummaryEstimate Quantile(q=0.5) ← SummaryMerge[newest all] ← PaneChain[5x60s] Kll(failure_probability=1e-7 k=567)  reads=[0] implements=[2] budget_parts=1
      cand 5 [panes NEW] Project ← SummaryEstimate Quantile(q=0.5) ← SummaryMerge[newest all] ← PaneChain[20x15s] Kll(failure_probability=1e-7 k=567)  reads=[0] implements=[2] budget_parts=1
...
STAGE 3: plan selection
  cost: 0.0213596 cost/s
    #2 SummaryAgg: 0.00335958  build Kll into 10000 states: 200000 rows x depth 1; x 0.0167/s; ...

Tests. test_print_stages.py plans that two-query workload with the built stage_pipeline and checks both modes. It is added to the viewer's CI step.

The committed examples/ documents predate #1108's format (the README calls them historical snapshots), so the script does not read them.

A follow-up PR renames stage_pipeline to explain_workload_plan.

🤖 Generated with Claude Code

print_stages.py prints each stage's DAG and the memo after each step
(groups with children, parents and queries; candidates with origin,
reads and pane-window parameters). --enumerated prints every memo choice
as a logical DAG. The Stage Viewer shows the same document graphically.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
zzylol added a commit that referenced this pull request Nov 2, 2026
One binary plans the workload; --text writes the run as text instead of the
viewer document, so both outputs come from the same inputs and flags.
The text output, now in the aligned format (G1:  TimeRange 60s  <- G0), also
covers what tools/dag-viewer/print_stages.py (#1158) prints: candidates new
at each memo step, the selected memo choice, Stage 3's search outcome, cost
per plan node and accepted accuracy per query, and with --enumerated the
memo choices with their DAGs. --out - writes to standard output.
node_label prints a time range as 60s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zzylol

zzylol commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

#1159 now prints the same content in Rust, as stage_pipeline --text (--out - for stdout), so the text and the viewer document come from one binary and one planning run. It covers this script's sections:

  • the memo after each step, with new candidates;
  • the selected choice;
  • Stage 3's search status, cost per node and accepted accuracy per query;
  • --enumerated with --max-enumerated.

It also prints Stage 2's whole PhysicalASAPMemoCandidates, which the JSON document does not hold. If that works for you, this PR could close in favor of #1159; the explain_workload_plan rename stays as its own PR.

@milindsrivastava1997

Copy link
Copy Markdown
Collaborator Author

Closing in favor of #1159, which prints the same stages as text from the planner's own data structures (stage_pipeline --text) instead of re-reading the JSON document.

milindsrivastava1997 pushed a commit that referenced this pull request Nov 3, 2026
One binary plans the workload; --text writes the run as text instead of the
viewer document, so both outputs come from the same inputs and flags.
The text output, now in the aligned format (G1:  TimeRange 60s  <- G0), also
covers what tools/dag-viewer/print_stages.py (#1158) prints: candidates new
at each memo step, the selected memo choice, Stage 3's search outcome, cost
per plan node and accepted accuracy per query, and with --enumerated the
memo choices with their DAGs. --out - writes to standard output.
node_label prints a time range as 60s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milindsrivastava1997 added a commit that referenced this pull request Nov 4, 2026
…p to --run-until (#1161) (#1190)

* feat(devtools): print_planning_stages prints every planner stage's output as text

Adds asap_devtools::planning_stages_text and the print_planning_stages
bin: the frontends' roots, the memo groups, Pass 1's
PerComputationLogicalMemoCandidates, the memo after Pass 2's local window
composition, LogicalASAPMemoCandidates, PhysicalASAPMemoCandidates and
Stage 3's Selection for one PromQL workload. node_label moves from
stage_pipeline to candidate_labels so both share it, and now names a
pane chain's layout (pane_width_ms, pane_count).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(devtools): stage_pipeline --text replaces the separate print bin

One binary plans the workload; --text writes the run as text instead of the
viewer document, so both outputs come from the same inputs and flags.
The text output, now in the aligned format (G1:  TimeRange 60s  <- G0), also
covers what tools/dag-viewer/print_stages.py (#1158) prints: candidates new
at each memo step, the selected memo choice, Stage 3's search outcome, cost
per plan node and accepted accuracy per query, and with --enumerated the
memo choices with their DAGs. --out - writes to standard output.
node_label prints a time range as 60s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(devtools): asap_planner runs the stages up to --run-until and prints them (#1161)

One planner CLI replaces stage_pipeline and show_logical_dag:
asap_planner --workload <file>... --run-until stage0|pass1|pass2|stage2|stage3
[--format text|json]. Each stage runs once, with no deadline, over every
legal tumbling-window width; Pass 2 prints the memo after local window
composition and after the sharing rules. Accuracy guarantees are enforced
by default; removed flags are usage errors.

Tests move to tests/asap_planner.rs (plus acceptance tests); snapshots,
memo_pricing and planner_fuzz go through asap_planner. Five snapshots are
now proven optimal (plans unchanged) and q18/q21 are no longer skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(dag-viewer): plan through asap_planner; drop committed documents and the planner box (#1161)

The server plans with asap_planner --run-until stage3 --format json and
writes the three small examples into out/. The committed example
documents, editor.js and /api/plan are removed; workload files stay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: asap_planner user guide; rename stage_pipeline across the docs (#1161)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(devtools): asap_planner review fixes (#1190)

- Exit 1 without the usage line for non-argument failures; 2 stays for
  bad arguments.
- Report a Pass 1 rejection before contradictory deployment capabilities,
  as run_planning does.
- Report a Stage 2 failure under Stage 2, not Stage 1.
- Attach warnings only to a Stage 3 section that exists.
- Number accepted accuracy q1..qN in text, like the warnings.
- Build the Stage 0 memo once.
- Viewer server and validate_joint_workloads accept a null Stage 3.
- Test that the viewer's cost-input files match the presets.
- Drop stale --exhaustive/--table references.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: asap_planner exit status 1 for planning failures (#1190)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(devtools): failed runs exit 1; viewer shows partial runs (#1190)

- asap_planner exits 1 when a stage failed, in text and JSON, after
  writing its output; the viewer server reads the document whenever
  one was written.
- The viewer shows a null (not run) stage section as empty, so
  --run-until before stage3 and Pass 1 failures open again.
- sql_catalog returns the table names; catalog_table_names is gone.
- stage0_memo_groups is built only by run_stages_until.
- planner_fuzz repro commands say when the exhaustive search may not
  reproduce.
- Docs: exit status; joint-workload reproduction uses asap_planner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(devtools): --run-until stage1_pass1 / stage1_pass2 (#1190)

Every --run-until value now names its stage: stage0, stage1_pass1,
stage1_pass2, stage2, stage3. The old pass1 and pass2 are usage errors.
The JSON run_until uses the same names; the memo step ids (pass1, pass2)
are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: zzylol <50204836+zzylol@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@milindsrivastava1997
milindsrivastava1997 deleted the devtools/print-stages branch November 4, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants