Source-to-Kernel Provenance Audit
Phase 1 tooling for torch-spyre#2574.
It traces a SimpleMLP through the Spyre compilation pipeline and records, at
each stage, which provenance fields are present on the actual compile-path
objects — producing a measurement-only Markdown report.
What it measures
Six stages, mapped to issue #2574:
PyTorch model source
FX graph (pre-grad and post-grad)
Inductor passes
LoopLevelIR
OpSpec
SuperDSC JSON
For each stage it records which fields are present and their observed type:
FX node meta:
stack_trace,nn_module_stack,source_fn_stack,original_aten,from_nodeIR / LoopLevelIR attributes:
origins,origin_node,traceback,get_stack_traces()
The report is measurement-only — counts and presence computed from the run, no hand-written analysis. Interpretation is a separate deliverable.
How it works
Everything is observed in-process during one torch.compile, via read-only
monkey-patches installed for the duration of the call. No torch.export (a
separate front-end, not on the compile path), no iteration-space heuristics, no
/tmp globbing. Each stage reads the real object:
Stage |
Hook (class-level, in |
Reads |
|---|---|---|
2 pre-grad FX |
|
|
2 post-grad FX |
|
|
3 passes + 4 LoopLevelIR |
|
|
5 OpSpec |
|
input |
6 SuperDSC |
|
|
Stage 6’s JSON is then read by superdsc.py from the exact per-kernel
output directories captured at compile time (keyed by kernel_name) — not a
guessed location.
Caches are force-disabled (TORCHINDUCTOR_FORCE_DISABLE_CACHES=1 +
force_disable_caches + torch._dynamo.reset()) so scheduling and codegen
actually run; a cache hit would silently skip create_op_spec/define_kernel.
Layout
provenance/
├── audit.py # entry point: one compile → capture → bundle read → report
├── reference_mlp.py # the model under audit (the subject, not tooling)
├── README.md
└── pipeline/
├── captures.py # all six in-process stage hooks (one context manager)
├── superdsc.py # Stage 6: read sdsc_*.json from captured exact dirs
└── report.py # measurement-only Markdown renderer
Running
Requires a working Spyre device (first device access triggers init, ~60s).
cd docs/source/user_guide/examples/provenance
python audit.py # default outputs (below)
python audit.py --output /tmp/report.md --raw /tmp/raw.json
Outputs:
provenance_audit.md— the measurement-only report (for issue #2574).provenance_capture_raw.json— the full captured structure (every stage, every field, plus a_hooksblock recording whether each hook installed and fired). Useful for verifying a run and for the interpretation deliverable.
stdout prints a per-stage fired/count summary so a hook that fails to install on a given torch build is immediately visible rather than silently missing.
Reading the report
Counts table — node/op/kernel/file counts and
OpSpec’s declared fields.Stage × Field matrix — each column is measured on the object that stage produces (FX node → LoopLevelIR
ComputedBuffer→ theOpSpecdataclass → the emitted JSON). A leading Layer column groups fields by where they live:FX(FX-node meta) orIR(ComputedBufferattribute). The two IR columns are the same LoopLevelIR: LoopLevelIR (pre-pass) entering the Spyre pre-scheduling passes and LoopLevelIR (post-pass) after they mutate it in place (e.g. insertingrestickifybuffers — which can change the op count and nullorigin_nodeon synthesized buffers; issue #2574’s “Inductor passes” → “LoopLevelIR”). Every column tests population (the field exists and is non-empty;0counts,None/[]/{}/""do not). Symbols:✅present & non-empty on all ·◐ n/Non some ·❌reachable here but measured empty/absent (a genuine drop or an op with no source to carry, e.g. the unusedtracebackslot) ·➖not applicable (no such slot, or — for FX-meta downstream — carried only indirectly viaorigins). The drop reads as the✅/◐→❌atOpSpec(the dataclass has no provenance field). The capture recordshasattrper IR attribute, distinguishing an empty slot from a non-existent one.Per-stage detail — observed field
typeper node/op, source lines, the exactkernel → ops → originsmapping, and whether each emittedsdsc_*.jsoncarries any provenance field.
Verifying a run
In provenance_capture_raw.json, every entry under _hooks should read
installed, and each stage’s fired should be true. An install-failed or
error there means a class/signature drifted on the pinned torch build and that
stage’s row is missing data — fix the hook in captures.py before trusting the
report.