Skip to content

Render Memory Chart from JSON description document - #962

Merged
tomk-amd merged 19 commits into
mainfrom
dhingora/memory-chart-json
Sep 17, 2026
Merged

tomk-amd merged 19 commits into
mainfrom
dhingora/memory-chart-json

Conversation

@dhingora-amd

Copy link
Copy Markdown
Contributor

Motivation

The compute kernel-details Memory Chart was a static, hardcoded diagram that couldn't adapt to different GPU architectures or traces. This makes it data-driven: the memory hierarchy is described as JSON stored per-workload in the trace database, so the chart reflects each workload and can evolve without code changes.

Technical Details

  • Relational layout model (rocprofvis_memory_chart_model.{h,cpp}): a set of blocks (nodes) and arrows (edges) parsed from JSON. Blocks nest via children (container boxes); metrics are referenced by their full dotted id category.table.entry; a semantic category drives accent colors. No coordinates in JSON — columns, block sizing, and arrow routing are computed at runtime.
  • Layout from the database: new optional compute_workload.memory_chart_extdata column, detected via PRAGMA and plumbed model → controller C ABI (kRPVControllerWorkloadMemoryChartLayout) → data provider → view, with an embedded default (rocprofvis_memory_chart_default_layout.h) as fallback.
  • Renderer (rocprofvis_compute_memory_chart.{cpp,h}): resolves the selected kernel's metric values and draws the chart. Skip-arrow routing packs "highway" lanes (horizontally disjoint arrows share a lane; shorter spans nest inside longer ones), spreads each block's bottom connectors symmetrically about its centre, and draws all lines before labels so no line is painted over a label.
  • Docs updated (.agents/AGENTS.md)

dhingora-amd and others added 4 commits July 16, 2026 15:07
…ps, categories)

Renders the compute memory chart from a relational JSON layout (blocks/arrows/metric refs) instead of hardcoded C++. Layout is read from the compute_workload.memory_chart_extdata DB blob with an embedded default fallback. Supports nested container blocks, per-item color categories, and metric refs by dotted id or name. Excludes local CMakePresets and sample .db changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
Extract the embedded default layout into rocprofvis_memory_chart_default_layout.h (kDefaultMemoryChartLayout) instead of a ~90-line inline blob in the renderer.

Drop the display-name fallback: metrics now resolve only by their full dotted id 'category.table.entry'. Removes the m_ptr_by_name map and its population/lookups, and the schema's metricRef now regex-enforces the three-part id (no abbreviated ids or name aliases).

Tighten comments in the renderer/header. No behavior change beyond the stricter metric-id rule.

Co-authored-by: Cursor <cursoragent@cursor.com>
The schema, default layout, and example JSON are kept out of the PR (retained locally). The runtime default lives in rocprofvis_memory_chart_default_layout.h and real layouts come from the compute_workload.memory_chart_extdata blob.

Co-authored-by: Cursor <cursoragent@cursor.com>
Pack skip-arrow highway lanes: horizontally disjoint arrows share a lane and shorter spans nest nearer the blocks than the spans enclosing them - fewer lanes, no crossings.

Spread each block's bottom connectors symmetrically about its centre (longest spans centre-most) so vertical drops no longer stack.

Draw all arrow lines first, then labels, with an opaque label background, so a later arrow's line is never painted over a label; widen lane pitch so labels clear the line above.

Co-authored-by: Cursor <cursoragent@cursor.com>
@dhingora-amd

dhingora-amd commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

memory_chart.schema.json
Above is the proposed schema.

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	.agents/UI.md
Comment thread src/view/src/compute/rocprofvis_compute_memory_chart.cpp Dismissed
Comment thread src/view/src/compute/rocprofvis_memory_chart_default_layout.h Outdated
Comment thread src/view/src/compute/rocprofvis_memory_chart_model.h Outdated
- Remove the metric_source field: metric refs are full dotted ids (category.table.entry) that already encode their source, and a layout may span multiple categories/tables. FetchMemChartMetrics now fetches every category the layout references and UpdateMetrics indexes all of them (no single-category filter).

- Start the layout version at 1 instead of 2 (default JSON, model default, and parser fallback).

- Drop the unused id/by_id from MemChartMetricRef; refs are dotted-id strings only, so ParseMetricRef and MetricLabel are simplified.

Co-authored-by: Cursor <cursoragent@cursor.com>
@dhingora-amd

Copy link
Copy Markdown
Contributor Author

memory_chart.schema.json
Updated Schema.

@tomk-amd tomk-amd changed the title Dhingora/memory chart json Render Memory Chart from JSON description document Jul 29, 2026
dhingora-amd and others added 3 commits July 31, 2026 11:20
- Move the layout out of the hardcoded header into per-arch JSON files
  (resources/memory_chart/{gfx950,gfx94x,default}.json + schema), embedded
  at build time via cmake/embed_memory_chart_layouts.cmake.
- Select layout by workload gpu_arch: dev override -> DB memory_chart_extdata
  blob -> arch-specific embedded -> default (legacy chart kept as default).
- Size each block from max(content, connectors, labels) and let the chart
  grow vertically (uncapped) so fanned arrow labels no longer overlap.
Comment thread src/controller/src/compute/rocprofvis_controller_workload.cpp Fixed
Replace hardcoded pixel offsets, sizes, alphas, and gaps in the compute memory chart with named static constexpr constants at the top of the file, per CODING.md. No behavior change.
Comment thread src/model/src/database/rocprofvis_db_compute.cpp

@drchen-amd drchen-amd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you merge in latest main? Metrics for newer db versions are mapped incorrectly and there is a change that should address it.

A couple of issues from testing:

  • Metric tooltips get cut off a few ticks above minimum font size.
  • % metrics like hit rate and utilization now display without units where old version had them.
image

- Add an optional per-item `unit` to the layout (takes priority over the
  metric entry's unit) so the curated Memory Chart metrics (hit rate,
  utilization) show "%" again - those metrics carry no unit in the DB.
  Populated gfx950/gfx94x/default layouts + schema.
- Fix description tooltips clipping near small font sizes: drop the window
  max-width constraint that fought the text-wrap position and let the
  tooltip auto-size to the wrapped text.
Remap all gfx950 metric ids to the current Memory Chart table (schema 2.2.0);
Flat/Buffer/LDS read-write-atomic and xGMI BW now resolve instead of N/A.

@drchen-amd drchen-amd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to lack a "render friendly" memory chart model, and as a result there is a fair amount of redundant processing to make it render friendly every frame. For example:

  • ComputeMemoryChartView::MetricLabel - Returns a passed in overridden name if exists, otherwise metric name if metric exists.

  • ComputeMemoryChartView::MetricValueText - Converts metric value to str, appends unit.

  • Arrows and blocks searching for for which blocks they connect to.

There is a rocprofvis_memory_chart_model, but it is a collecting of helper functions and does not hold any data. This could be expanded to provide a "friendly" data representation. Rough idea being that it would store a bunch of these:

struct Metric
{
  int category, table, entry
  string name
  string value
}

struct Block
{
  int id,
  string name,
  vector<Metric> metrics
  Imvec2 x,ypos
  Imvec2 length,width
}

struct Arrow
{
  int id,
  int name,
  Metric metric
  Block* source
  Block* target
}

Then your ComputeMemoryChartView would update subsections of this only when needed:

  • On workload change, your entire layout changes, so you would create fresh Blocks and Arrows.
  • On kernel change, you go through your Arrows and Blocks, and update only the metric related data.

The sizing and positioning updates need to remain in render, but everything else would be ready as is for render to consume.

Comment thread src/view/src/model/compute/rocprofvis_memory_chart_model.cpp
Comment thread src/view/src/compute/rocprofvis_compute_memory_chart.cpp Outdated
Comment thread src/view/src/model/compute/rocprofvis_memory_chart_model.cpp
Comment thread src/view/src/compute/rocprofvis_compute_memory_chart.cpp Outdated
Comment thread src/view/src/model/compute/rocprofvis_compute_model_types.h Outdated
dhingora-amd and others added 4 commits September 17, 2026 11:40
Build the layout/index/strings on data changes instead of every frame:
- Move rocprofvis_memory_chart_model.{h,cpp} to model/compute/.
- Store the parsed MemChartLayout in WorkloadInfo (parsed once by the data
  provider) instead of raw JSON; the view no longer re-parses.
- Add an id->block index (built on layout load) to replace the per-frame
  FindBlock tree scans done for every arrow.
- Cache each item/arrow's resolved label/value; refresh only on layout load
  and metric fetch, not per frame.
- Fetch metrics by individual (category, table) instead of whole categories.
…-json

# Conflicts:
#	.agents/UI.md
#	src/view/src/compute/rocprofvis_compute_memory_chart.cpp
- default: drop no-longer-applicable vL1 and L2 latency metrics
- gfx94x: split MALL, UMC, and HBM into their own columns
- gfx950: add Data Fabric/MALL/UMC/HBM columns (matching gfx94x order),
  move xGMI/PCIe to a trailing column, and retarget L2 arrows to Data Fabric
- view: give arrow-free column gaps a tighter width so unconnected columns
  sit close together; precompute the arrow-crossing set on layout load
  instead of every frame
@tomk-amd

Copy link
Copy Markdown
Collaborator

Merging - but this should be addressed soon if real:

AI Review

The one real gap bug. Skip arrows (column distance greater than 1) mark every intervening gap as arrow-bearing, but they are not drawn through those corridors — they go under the blocks on the highway, or up the left margin. A skip from L2 to HBM would re-open the MALL/UMC gaps this change is trying to close. default.json already has a skip (13 → 1); those gaps stay wide today only because adjacent arrows also cross them.

@tomk-amd
tomk-amd merged commit 96f95ae into main Sep 17, 2026
9 of 10 checks passed
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.

4 participants