Skip to content

IR Lowering Trace

pypto-ir-trace turns a PyPTO passes_dump/ directory into a deterministic, self-contained HTML report. The report compares each pass output with its input so that lowering changes can be inspected without a web server or network access.

Generate pass dumps

Enable per-pass dumps when compiling a program. dump_passes=True emits concise canonical IR, which is usually the clearest input for textual comparison:

from pypto import ir

ir.compile(MyProgram, output_dir="build/my_program", dump_passes=True)

Use PassDumpLevel.EXPLICIT when the trace must include fully resolved tile layouts and distributed window-buffer references:

from pypto import ir
from pypto.ir import PassDumpLevel

ir.compile(
    MyProgram,
    output_dir="build/my_program",
    dump_passes=PassDumpLevel.EXPLICIT,
)

Both forms create build/my_program/passes_dump/, containing 00_frontend.py and consecutively numbered NN_after_PassName.py snapshots. See the pass manager documentation for dump levels and pass-pipeline behavior.

Dump ptoas pass IR

PyPTO can also expose ptoas's MLIR pass dumps. This is a separate switch from dump_passes because it observes the backend pipeline after PTO codegen:

ir.compile(
    MyProgram,
    output_dir="build/my_program",
    dump_ptoas_passes=True,
)

The same option is available to JIT and runtime callers through RunConfig(dump_ptoas_passes=True). PyPTO invokes ptoas with full-module IR printing after every pass and writes each codegen unit to its own directory:

build/my_program/ptoas_passes/<kernel-or-group>/

Per-unit directories keep parallel ptoas invocations from colliding. The files inside are named and organized by ptoas/MLIR. This option has no effect with skip_ptoas=True, because no ptoas pass pipeline runs in that mode.

Generate a report

Run the installed command with the dump directory:

pypto-ir-trace build/my_program/passes_dump

The pypto-ir-trace command is generated by pip install. A source checkout that only sets PYTHONPATH runs the module entry point instead, which takes the same arguments and returns the same exit codes:

python -m pypto.tools.ir_trace build/my_program/passes_dump

The default output is ir_trace.html in the current directory. Output is written to a temporary file in the destination directory and atomically replaces the requested path, so a failed write does not leave a partial report.

CLI options

Argument Description
passes_dump Input directory containing the ordered pass snapshots.
-o PATH, --output PATH Output report path; defaults to ir_trace.html.
--context N Unchanged lines shown around each change; defaults to 3 and must be non-negative.

For example, keep one unchanged line around changes and choose an explicit destination:

pypto-ir-trace build/my_program/passes_dump --context 1 -o build/ir-trace.html

Use the viewer

Open the generated HTML file in a browser. All styles, scripts, and trace data are embedded in the file; it does not load external resources.

The sidebar lists passes in execution order with inserted/deleted line counts, change status, and warning badges. Changed and No-op filters independently show or hide passes that changed the printed IR or left it unchanged. The first changed pass is selected initially, falling back to the first pass when every pass is a no-op. The sidebar scrolls independently from the comparison panel, while its title and filters remain visible at the top.

Select a pass in the sidebar to compare its input and output. Press j or Down Arrow to move to the next visible pass, and k or Up Arrow to move to the previous visible pass. Keyboard navigation is ignored while an input or selection control has focus.

Use Side by side to place Before and After in columns, or Stacked to place Before above After. Side by side is the default. The selected layout is retained while navigating passes and functions in the open report, and resets when the page is reloaded. The toolbar remains visible while the comparison panes use the remaining viewport height. Each pane is independently scrollable, and scrolling either pane keeps the Before and After vertical and horizontal positions synchronized in both layouts.

Compare by function

Use the Function selector to focus the diff on one top-level function or a direct method of a top-level class. Whole file is the first option and the default. Functions are matched by exact qualified key; class methods use keys such as Program.run. Unambiguous entries display only their short name, while duplicate short names display the qualified key. A function that exists only in After is shown as added, and one that exists only in Before is shown as deleted.

The selected function is retained when changing passes if it exists on either side of the new comparison. Otherwise the viewer falls back to Whole file. Nested functions are kept inside their containing function rather than listed separately. If either snapshot cannot be parsed safely, function selection is disabled for that pass and the existing Whole file diff is used.

Within replacement blocks, the viewer first aligns lines whose content matches after removing leading whitespace. Indentation-only differences remain replacement rows so structural changes stay visible. Remaining changed ranges align single-line Python calls by qualified operation name. This keeps control-flow headers and related operations paired while preserving one-sided rows for actual insertions and deletions. Replacement rows use light delete/insert backgrounds, with the exact changed characters emphasized in stronger red and green. Both panes use the same scrollable canvas width so row backgrounds cover the complete code line.

Copy snapshots

Use Copy full source above either pane to copy the complete before or after snapshot, including unchanged lines hidden by context folding. This remains a full-snapshot action when one function is selected. Copying uses the browser clipboard API when available and a local fallback otherwise.

Warnings

If a snapshot has a matching .log file, its text appears in the warning panel and the pass receives a warning badge. The warning is diagnostic context from the pass run; it does not change the textual diff.

Theme and collapsed context

Use Theme to switch between light and dark colors. The initial theme follows the browser's preferred color scheme. Long unchanged regions are collapsed according to --context; click an individual collapsed region, or use Expand all and Collapse all, to change its visibility.

Error handling

Argument syntax and invalid --context values use argparse diagnostics and exit with status 2. Invalid dump contents and input/output I/O failures print one concise diagnostic to standard error and exit with status 1. A report written successfully exits with status 0.

$ pypto-ir-trace missing/passes_dump
pypto-ir-trace: error: input directory does not exist: missing/passes_dump

$ pypto-ir-trace passes_dump --context -1
pypto-ir-trace: error: argument --context: must be non-negative, got -1

The input directory must contain valid UTF-8 snapshots named 00_frontend.py, 01_after_*.py, 02_after_*.py, and so on without index gaps. The output directory must already exist.

Interpretation and limitations

The viewer computes a line-oriented textual diff of printed IR. A changed report means the serialized text changed; it does not prove that program semantics changed. Conversely, textual similarity is not a proof of semantic equivalence. Use the trace to locate lowering steps, then use IR verification and behavioral tests to decide semantic correctness.