Skip to content

Aie dtrace compute io bound - #101

Open
jyothees99 wants to merge 6 commits into
Xilinx:masterfrom
jyothees99:aie-dtrace-compute-io-bound
Open

Aie dtrace compute io bound#101
jyothees99 wants to merge 6 commits into
Xilinx:masterfrom
jyothees99:aie-dtrace-compute-io-bound

Conversation

@jyothees99

Copy link
Copy Markdown
Collaborator

Add a compute_io_bound core-tile metric set to aie_dtrace (VE2)

Adds a metric set that answers whether a layer is compute-bound or IO-bound, by
measuring how much of each record-timer interval the core spends inside the
kernel dispatch window versus executing at all.

How it works

Two core-module performance counters are programmed on a single core tile
(first column, first core row):

Counter Label Programming Meaning
2 compute Start = PC_0 @ start_pc, Stop = PC_1 @ stop_pc kernel dispatch window
3 io_compute PC_RANGE_2_3 over [0, PROG_MEM_END] total execution

Counter 2 is a start/stop pair rather than a PC range, so it accumulates the
whole dispatch window including the called kernel. The ratio of the two deltas
over an interval is the compute percentage; the analysis side turns that into
the Compute/IO verdict.

The two PCs are not derived on the board. They are computed on the host from the
design's aiecompiler listings and read at run time from aie_pc_metadata.json
in the run directory. An earlier revision parsed the .lst files in the plugin,
which cost 16-26s per run walking the design tree over NFS; reading the
generated JSON is a single file open.

Enabling

xrt.ini:

[AIE_dtrace_settings]
tile_based_aie_metrics = compute_io_bound

Accepts all:compute_io_bound, <col>:compute_io_bound, or the bare metric
name; the tile is fixed regardless, so the column is only positional. Also
honours aie_tile from Debug.profiling_runtime_config when a blob is in use,
replacing the "will be supported in a follow-up" notice.

Changes

  • aie_dtrace_metadata: parse and validate the core metric set, register
    tile_based_aie_metrics as a valid setting, and make isConfigured() true
    when either the shim or the core module is configured.
  • aie_dtrace_ct_writer: new generateCT() that emits bandwidth and/or
    compute_io_bound counters into one CT file, so a single run can carry both.
    The bandwidth path is factored into appendBandwidthConfig() and
    writeBandwidthCTFile() is renamed writeCounterCTFile(); behaviour for
    bandwidth-only runs is unchanged.
  • aie_dtrace_ve2: read and cache the PCs from the JSON. A missing or
    malformed file logs a warning naming the file and the command that generates
    it, and compute_io_bound is skipped rather than failing the run.

Listings and metadata use relative core rows, so the config map is keyed on the
relative row and the CT writer resolves the absolute row from
driver_config.aie_tile_row_start.

Dependencies

  • Requires an XRT change adding
    xrt_core::config::get_aie_dtrace_settings_tile_based_aie_metrics() and the
    matching AIE_dtrace_settings.tile_based_aie_metrics ini key. That accessor is
    not in XRT master today, so this branch will not compile until it lands.
  • Pairs with the vaianalyze PR that generates aie_pc_metadata.json and reports
    the results. Neither is useful without the other.

jyothees99 and others added 6 commits July 31, 2026 01:55
Adds a core-tile PC-range metric that measures Compute vs IO+Compute
cycles via the two AIE core PC-range events (PC_Range_0-1 / PC_Range_2-3)
on a single core tile (col 0, row 3). The wrapper PC is read from the
col0/row0 elfs_metadata reloadable_elfs entry (all values must match).

Configurable through profiling_runtime_config aie_tile and the new
AIE_dtrace_settings.tile_based_aie_metrics option, and emitted alongside
interface-tile bandwidth metrics in the same per-run CT file.

Co-authored-by: Cursor <cursoragent@cursor.com>
Program Performance_Control1 (0x37504) and read Performance_Counter2/3 (0x37528/0x3752C) instead of counters 0/1, leaving counters 0/1 free. Counter 2 counts PC_Range_0-1 (Compute), counter 3 counts PC_Range_2-3 (IO + Compute).
When elfs_metadata.reloadable_elfs is empty (static/inlined designs), the
kernelWrapper PC is unavailable so the metric was skipped. Add a robust
fallback that derives the kernelWrapper loop start/stop PCs from the core
tile's .lst listing (isolate main, find the single indirect 'jl pN'
dispatch, then the first backward branch after it) and counts kernelWrapper
cycles via performance-counter Start/Stop on PC breakpoint events
(PC_0=start_pc, PC_1=stop_pc), so the dispatched kernel is included.

The flow is gated on kernelWrapper being inline (checked from the tile
source .cc); reloadable designs keep using the metadata wpc PC-range path.
Listing/source lookup uses relative rows; register addressing uses the
absolute core row from aie_tile_row_start (getAIETileRowOffset) instead of
a hardcoded value.

Co-authored-by: Cursor <cursoragent@cursor.com>
Both static and reloadable designs now measure the compute window with the
same rule instead of two different derivations: start_pc is the single
indirect kernel dispatch ("jl pN") found in the core tile's .lst, and
stop_pc is the 10th listed instruction from it (the dispatch counted as
Xilinx#1, "..." elision lines skipped), clamped at the end of the enclosing
label. Performance counter 2 is always driven by PC breakpoint events
(Start=PC_0, Stop=PC_1), so the called kernel is included in the count;
counter 3 (total) is unchanged.

Reloadable designs read every <tile>_reloadable*.lst and require them to
agree on the PCs; static designs read <tile>.lst. Listing lookup searches
only for those filenames, pruning the walk so it never descends into the
other per-tile directories, and the result is cached so the search runs
once per process rather than once per run. XRT_AIE_DTRACE_DESIGN_DIR can
override the search root.

Also shrinks the change relative to upstream: base_filetype_impl.h is back
to master (the reloadable-ELF PC and static-ELF tile-name helpers are no
longer needed), the unused metadata accessors are gone, and the absolute
core row now comes from the existing driver_config.aie_tile_row_start.

Co-authored-by: Cursor <cursoragent@cursor.com>
Stop deriving the compute start/stop PCs at run time. The listing parsing
and directory search are replaced by a single read of aie_pc_metadata.json
from the run directory, generated on the host by
"vaiprofile --gen-pc-metadata <design>".

This removes the per-run filesystem walk that stalled generateCTForRun (it
descended into the design's per-tile directories over NFS), deletes
lst_helper.{h,cpp} entirely, and keeps the derivation rule in exactly one
place so the C++ side cannot drift from it. The PCs are cached after the
first read; when the JSON is missing or malformed a warning names the file
and the generating command, and compute_io_bound is skipped.

The counter configuration is unchanged: PC_Event0/1 hold start/stop and
counter 2 uses Start=PC_0 / Stop=PC_1, counter 3 remains the total.

Co-authored-by: Cursor <cursoragent@cursor.com>
The generator now writes start_pc/stop_pc as "0x"-prefixed hex strings, so
read them as strings and convert with base 16 instead of asking ptree for a
uint32_t. Reject a value with trailing junk rather than silently using the
truncated prefix, and name the expected spelling in the warning.

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

1 participant