candle-graph
Independent project; not affiliated with candle-rs or Hugging Face.
candle-graph records one selected Candle training update or inference invocation and turns that
runtime trace into inspectable evidence. It can produce JSON for tools, a Markdown report, a
content-addressed bundle, and one offline HTML viewer.
The crate does not inspect Rust source or reconstruct execution statically. It can only report events that ran and that the application chose to record.
What it records
| Evidence | Meaning |
|---|---|
| Host spans | A semantic call hierarchy and one caller-owned measured region |
| Operations and tensors | Executed op metadata, backend tensor identities, shapes, dtypes, and dense footprints |
| Tensor statistics | Caller-labelled RMS, absolute maximum, mean, and non-finite counts |
| Gradients | Per-parameter state and norm, optionally checked against an exact manifest |
| Logical memory | Explicit storage allocation/free lifetimes keyed by device and storage identity |
| Physical memory | Independent device or allocator checkpoints such as used, free, and reserved bytes |
| Device timing | Explicit intervals that remain separate from host time |
| GPU evidence | Optional normalized NVIDIA Nsight Systems CSV reports bound to the trace by a manifest |
Absent evidence stays absent. Tensor size metadata does not become an allocation, host duration does not become GPU duration, and an observed event does not silently upgrade partial coverage to complete coverage.
Install
From a checkout:
The default visualizer feature includes the view command and adds viewer.html to published
bundles. Add --features all to install the optional Candle tensor helpers as well. See
Cargo features for the exact feature boundaries.
The package installs both candle-graph and the Cargo subcommand form used below:
Capture one invocation
Open a session only for the selected one-based invocation. Put exactly one measured region inside the session; that region supplies the outer-wall duration used by comparisons.
use Result;
use ;
For a CUDA comparison, synchronize immediately before and after the measured region and mark the
run with measured_region_device_synchronized(). Use device_synchronized() only if every nested
semantic span is individually synchronized; otherwise its duration is host launch time, not
completed GPU work.
The runtime evidence guide covers comparison identity, semantic labels, Candle helpers, tensor statistics, gradient contracts, memory, concurrent host spans, and failed captures.
Inspect the trace
# Bounded first look (recommended for agents; truncated lists say so explicitly).
# Semantic summary on stdout.
# Focused JSON queries.
# One offline HTML file (default feature).
# Atomic bundle containing trace, evidence, report, hashes, and viewer;
# emits a publication receipt.
overview, summary, import, and query accept either a raw trace or a finalized bundle.
Prefer a bundle when one exists: it is deeply verified and preserves its bound Nsight evidence.
overview is hard-bounded; some focused queries have fixed row caps, and unfiltered collection
queries such as memory, spans, tensors, tensor-stats, and gradients can grow with the
trace. The CLI reference lists every command, input type, query, and
size property.
Add Nsight Systems evidence
Export supported reports with nsys stats --format csv; do not depend on Nsight's internal SQLite
schema. Put the retained .nsys-rep, CSV files, and capture-manifest.json in one flat directory:
Supported reports are cuda_gpu_trace, cuda_gpu_kern_sum, cuda_api_sum,
cuda_gpu_mem_time_sum, and nvtx_gpu_proj_trace. The manifest binds artifact hashes, the trace
run ID, the correlation ID, and the semantic-label contract. Missing reports remain individually
unavailable; their row counts are not inferred as zero.
Compare implementations
Timing verdicts require at least five independent, complete, production-equivalent bundles in each cohort. Every bundle is verified, every run keeps its raw sample, and compatible runs receive a deterministic 95% bootstrap interval.
The capture contract, timing semantics, workload identity, model/config/data identity, batch and
precision settings, and device state must match. Each cohort has one stable implementation ID;
the baseline and candidate IDs may differ. Raw traces can be inspected with
--unverified-traces, but that result is always diagnostic and ineligible for a timing verdict.
Trust model
- A complete trace must have one root, one measured region, closed spans, a valid hierarchy, and a successful terminal event.
- Failed captures remain parseable only when the caller explicitly finishes them with
finish_failed(reason); they do not produce a derived execution graph or normal findings. - Coverage levels are producer declarations qualified by observed evidence. Exact gradient coverage additionally requires a digest-bound parameter manifest and family validation.
- Logical storage lifetime, physical memory, host time, device-event time, and Nsight time are separate evidence planes.
- A bundle manifest binds every published file.
verifyrejects missing, changed, undeclared files, symbolic links, and special files.
Documentation
- Documentation map
- Runtime evidence guide
- CLI reference
- Schema and compatibility reference
- Cargo features
- HTML visualizer
- Product context and glossary
Development