Simulator Trace Cleaning¶
clean_sim_trace converts the MindStudio Insight binary dump
(visualize_data.bin) emitted by the operator simulator into a de-cluttered,
Perfetto-viewable AI-core pipeline trace (Chrome Trace Event JSON).
The simulator writes, per kernel run, an OPPROF_*/simulator/ directory with
two profiling artifacts:
trace.json— the official simulator-generated Perfetto/Chrome trace.visualize_data.bin— the binary container consumed by MindStudio Insight.
The official trace.json is lossy — it carries strictly less information
than visualize_data.bin. The binary container holds the full set of
MindStudio Insight blocks: the trace events plus per-instruction metrics
(API_INSTR), source mapping, and other detail blocks. trace.json exports
only the trace events. So clean_sim_trace reads the richer binary file
directly, recovering the per-instruction metrics — emitted as an
instr_metrics.json sidecar — that the official Perfetto export drops.
It also de-clutters the trace itself: opening trace.json in the Perfetto UI
is hard to read because SET_FLAG / WAIT_FLAG synchronization slices and
scalar address-arithmetic instructions bury the actual AI-core pipeline.
clean_sim_trace rebuilds it into a clean pipeline view (see Rebuild rules).
Producing the dump¶
The OPPROF_*/simulator/visualize_data.bin this tool consumes is generated by
the Ascend msprof op simulator (the cycle-accurate camodel), not by a normal
PyPTO run. The incore-profiling skill drives it per kernel — for each
PTOAS kernel in a build_output/<case>/ it generates a standalone testcase,
builds it with ccec/bisheng, and runs the op-simulator:
python .claude/skills/incore-profiling/incore_profile.py \
--build-dir build_output/<case> --func <kernel> --target a2a3
This writes .../kernel_insight_all_funcs_<ts>/funcs/<kernel>/collect/out/OPPROF_*/;
point clean_sim_trace at that OPPROF_* directory.
Data-dependent kernels — those whose loop trip-count or work-table size is read from an input tensor — profile as a near-empty trace under the skill's auto-generated zeroed inputs (
CUBE/VECTORbook ~0 cycles). That is a synthetic-input artifact, not a fast kernel; see the skill's Caveats for how to wire full-size real intermediates.
Usage¶
python -m pypto.tools.clean_sim_trace <path> [-o OUTPUT_DIR] [--keep-scalar] [--raw-metrics] [--no-copy-raw]
<path> is a visualize_data.bin file or an OPPROF_* directory (the tool
locates simulator/visualize_data.bin inside it). Two files are written next
to the input, or to -o if given. When -o points at a separate target
directory, the raw binary trace is also copied alongside so the folder is
self-contained:
| Output | Content |
|---|---|
trace.clean.json |
Rebuilt Chrome Trace Event JSON — opens in chrome://tracing and the Perfetto UI |
instr_metrics.json |
Per-core instruction metrics from the API_INSTR block |
raw_simulator/ |
Copy of the raw visualize_data.bin + per-core trace data (only with -o; the source OPPROF_* dir is left intact) |
| Flag | Effect |
|---|---|
--keep-scalar |
Keep the SCALAR setup lane (dropped by default) |
--raw-metrics |
Dump the API_INSTR block verbatim instead of reshaping it |
--no-copy-raw |
Skip copying the raw binary trace into <output-dir>/raw_simulator/ |
The visualize_data.bin format¶
The file is a flat sequence of length-prefixed blocks. Each block has a 12-byte, 4-byte-aligned header:
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | uint64 LE |
contentSize |
payload length, including trailing padding |
| 8 | uint8 |
type |
block type (2 = TRACE, 4 = API_INSTR, 1 = SOURCE, ...) |
| 9 | uint8 |
paddingLength |
trailing zero bytes for 4-byte alignment |
| 10 | uint8 |
instrVersion |
API_INSTR version marker |
| 11 | uint8 |
reserve |
always 0x5a (binary-format magic) |
Each block payload is plain JSON. SOURCE blocks prefix the payload with a
fixed 4096-byte file path. The tool consumes the TRACE and API_INSTR
blocks; other block types are skipped.
Rebuild rules¶
- Lane selection — keep the pipeline lanes (
MTE2,MTE1,CUBE,VECTOR,FIXPIPE,MTE3); dropCACHEMISS,FLOWCTRL,ALL. TheSCALARlane is dropped by default (--keep-scalarrestores it). - Event filtering — keep
X(complete) instruction events; dropSET_FLAG/WAIT_FLAG/BARslices. - Lane ordering — emit
process_*/thread_*metadata so cores and pipeline lanes render in dataflow order (load -> compute -> store). - Sub-lane packing — software-pipelined instructions on a pipe are often
several in flight at once and only partially overlap. Chrome-trace
Xevents on onetidmust be disjoint or strictly nested, so each pipe's overlapping instructions are greedily split into sub-lanes (MTE1,MTE1#1, ...) — one row per concurrently-live instruction — preserving the true pipeline depth in the viewer (otherwise the depth collapses to ~2). - Sync as arrows — each
SET_FLAG->WAIT_FLAGpair becomes one flow arrow, re-anchored from the producing instruction to the consuming one (on its actual sub-lane). - Coloring — slices are recolored per pipeline lane.
- Timestamps — kept verbatim, so the cleaned trace lines up with the raw
trace.json.
Metrics sidecar¶
instr_metrics.json reshapes the API_INSTR block: each metric, stored in the
raw block as an array indexed by core, is flattened into a per-core list of
instruction records (address, pipe, cycles, vector_utilization_percentage,
...). The original Instructions Dtype map is preserved under column_types.