Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8502,6 +8502,9 @@ rocprofiler-sdk:
- architectures:
- gfx90a
- gfx908
- gfx12
- gfx1200
- gfx1201
block: TA
event: 32
- architectures:
Expand Down
66 changes: 49 additions & 17 deletions projects/rocprofiler-sdk/tests/spm/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,21 @@ def get_name(counter_id):
return itr["name"]

dispatch_counter_map = defaultdict(dict)
dispatch_agent = {}
for record in counter_data:
dispatch_id = record["dispatch_id"]
dispatch_agent[dispatch_id] = record["agent_id"]["handle"]
counter_name = get_name(record["counter_id"]["handle"])
_accumulate_counter(
dispatch_counter_map[dispatch_id], counter_name, record["value"]
)

assert len(dispatch_counter_map) > 0, "No SPM dispatch data found"

counter_name = "TA_TA_BUSY"
for dispatch_id, counter_map in dispatch_counter_map.items():
counter_name, _ = _ta_counter_names(
_agent_name(data, dispatch_agent[dispatch_id])
)
assert (
counter_name in counter_map
), f"Dispatch {dispatch_id} missing {counter_name}"
Expand All @@ -96,27 +100,45 @@ def get_name(counter_id):
), f"Dispatch {dispatch_id} has zero {counter_name}"


def _agent_name(data, agent_handle):
for agent in data["agents"]:
if agent["id"]["handle"] == agent_handle:
return agent["name"]
raise AssertionError(f"No agent with handle {agent_handle}")


def _ta_counter_names(agent_name):
# gfx1250 (MI455) reports TA activity through the VCA block.
if str(agent_name).removesuffix("-strict") == "gfx1250":
return "TX_VCA_VCA_BUSY", "TX_VCA_TOTAL_WAVEFRONTS"
return "TA_TA_BUSY", "TA_TOTAL_WAVEFRONTS"


def _get_counter_value(counters, name):
for itr in counters:
if itr["name"] == name:
return itr["value"]


def _validate_dispatch_counters(dispatch_id, counters):
assert float(_get_counter_value(counters, "TA_TA_BUSY")) > _get_counter_value(
counters, "TA_TOTAL_WAVEFRONTS"
)
def _validate_dispatch_counters(dispatch_id, counters, agent_name):
busy_name, wavefront_name = _ta_counter_names(agent_name)
busy = _get_counter_value(counters, busy_name)
wavefronts = _get_counter_value(counters, wavefront_name)
assert busy is not None, f"Dispatch {dispatch_id} missing {busy_name}"
assert wavefronts is not None, f"Dispatch {dispatch_id} missing {wavefront_name}"
assert float(busy) > float(wavefronts)

assert (
100

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we remove this altogether, why not check if Req != 0 and compute the ratio in that case

* _get_counter_value(counters, "SQC_ICACHE_MISSES")
/ _get_counter_value(counters, "SQC_ICACHE_REQ")
) <= 100
assert (
100
* _get_counter_value(counters, "SQC_ICACHE_HITS")
/ _get_counter_value(counters, "SQC_ICACHE_REQ")
) <= 100
# 100 * value / requests <= 100 is value <= requests. A dispatch can report
# no I-cache traffic once the cache is warm, so a zero request count is valid
# when hits and misses are also zero.
requests = _get_counter_value(counters, "SQC_ICACHE_REQ")
assert requests is not None, f"Dispatch {dispatch_id} missing SQC_ICACHE_REQ"
for name in ("SQC_ICACHE_HITS", "SQC_ICACHE_MISSES"):
value = _get_counter_value(counters, name)
assert value is not None, f"Dispatch {dispatch_id} missing {name}"
assert float(value) <= float(
requests
), f"Dispatch {dispatch_id} {name} {value} exceeds SQC_ICACHE_REQ {requests}"


def _accumulate_counter(counter_map, name, value):
Expand Down Expand Up @@ -166,7 +188,11 @@ def get_name(counter_id):
)

for dispatch_id, counter_map in dispatch_counter_map.items():
_validate_dispatch_counters(dispatch_id, list(counter_map.values()))
_validate_dispatch_counters(
dispatch_id,
list(counter_map.values()),
_agent_name(data, headers[dispatch_id]["agent_id"]["handle"]),
)


def _validate_callback_counter_values(data):
Expand All @@ -179,15 +205,21 @@ def get_name(counter_id):
return itr["name"]

dispatch_counter_map = defaultdict(dict)
dispatch_agent = {}
for record in counter_data:
dispatch_id = record["dispatch_id"]
dispatch_agent[dispatch_id] = record["agent_id"]["handle"]
counter_name = get_name(record["counter_id"]["handle"])
_accumulate_counter(
dispatch_counter_map[dispatch_id], counter_name, record["value"]
)

for dispatch_id, counter_map in dispatch_counter_map.items():
_validate_dispatch_counters(dispatch_id, list(counter_map.values()))
_validate_dispatch_counters(
dispatch_id,
list(counter_map.values()),
_agent_name(data, dispatch_agent[dispatch_id]),
)


if __name__ == "__main__":
Expand Down
4 changes: 4 additions & 0 deletions projects/rocprofiler-sdk/tests/tools/json-tool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,8 +747,12 @@ spm_dispatch_callback(const rocprofiler_spm_dispatch_counting_service_data_t* di
auto wlock = std::unique_lock{m_mutex};
if(search_cache()) return;

// Only counters the agent supports are collected. gfx1250 provides the TX_VCA
// counters in place of the TA counters.
std::set<std::string> counters_to_collect = {"TA_TOTAL_WAVEFRONTS",
"TA_TA_BUSY",
"TX_VCA_TOTAL_WAVEFRONTS",
"TX_VCA_VCA_BUSY",
"SQC_ICACHE_REQ",
"SQC_ICACHE_HITS",
"SQC_ICACHE_MISSES"};
Expand Down
Loading