一键导入
verify-pmc-metrics
Mock-based rigorous PMC metric validation — tests sentinel filtering, value ranges, and architecture-specific behavior across Perfetto and RocPD
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Mock-based rigorous PMC metric validation — tests sentinel filtering, value ranges, and architecture-specific behavior across Perfetto and RocPD
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Given a TheRock nightly build (URL or run-id), return the rocm-systems pin_sha used in that build
Check whether a given rocm-systems commit is included in a specific TheRock nightly build
Find the first TheRock nightly build that includes a given rocm-systems commit
Reviews Pull Requests or local diffs with an 8-agent fan-out covering static analysis, dead code, code smells + quality (naming, complexity, single-responsibility, magic numbers), language rules (C++/Python/CMake), architecture, simplification, performance (hot-path classification, allocations, locks, I/O), and undefined behaviour (signed overflow, lifetime, strict aliasing, data races, sanitizer coverage; C/C++/unsafe-Rust only). Use when the user asks to "review this PR", "review the diff", "audit this branch", "/pr-review", or when staging changes before push.
Walk through a PR review interactively, one finding at a time. Generate review via pr-review, then for each issue present analysis + proposed inline comment, let user accept/edit/skip, accumulate into a PENDING GitHub review, submit at end.
Use when user wants to list, analyze, review, or summarize GitHub PR comments on a pull request number or URL
基于 SOC 职业分类
| name | verify-pmc-metrics |
| description | Mock-based rigorous PMC metric validation — tests sentinel filtering, value ranges, and architecture-specific behavior across Perfetto and RocPD |
Deterministic validation of AMD SMI Performance Monitoring Counter (PMC) metrics using the mock system (AMD_SMI_MOCK_CONFIG). Tests sentinel filtering, expected value ranges, positive presence of configured metrics, and negative absence of unsupported metrics across all output formats.
GPU firmware returns these values for unsupported/unavailable metrics. They must NEVER appear in output.
| Type | Hex | Decimal | Float (Perfetto) | Where Used |
|---|---|---|---|---|
uint16_t | 0xFFFF | 65535 | 65535.0 | Temperature, activity %, power, voltage, clocks, PCIe width/speed, VCN/JPEG arrays |
uint32_t | 0xFFFFFFFF | 4294967295 | 4294967295.0 | Various 32-bit fields |
uint64_t | 0xFFFFFFFFFFFFFFFF | 18446744073709551615 | 1.8446744073709552e+19 | PCIe bandwidth, XGMI data, memory |
Perfetto stores counter values as doubles, so UINT64_MAX appears as 1.8446744073709552e+19. Both exact and float representations must be checked.
| Metric | device.hpp | perfetto_policy.hpp | perfetto_processor.cpp | rocpd_processor.cpp |
|---|---|---|---|---|
| VCN/JPEG (uint16) | Support check only | Filtered | Filtered | NOT filtered |
| XGMI (uint64) | Zeroed via populate_if_supported() | N/A | Double-checked | Filtered |
| PCIe (uint16/64) | Zeroed via populate_if_supported() | N/A | Relies on zero check | NOT filtered |
| NIC RDMA | N/A | N/A | No filtering | No filtering |
Known leakage risks:
Two architectures test complementary metric subsets. Located in ~/worktree/rocm-systems/amd-smi-mocks/.
mock_mi300x.yaml)Data-center GPU with per-XCP metrics, HBM, and NIC.
| Category | What's Configured | Expected Range | Notes |
|---|---|---|---|
| Temperature | hotspot only | [55, 75] | No temperature_edge (sentineled) |
| HBM Temperature | 4 active / 4 total | [40, 60] | Array: active entries have values, rest sentineled |
| Power | current_socket_power | [300, 500] | Watts |
| GFX Busy | gfx_activity | [80, 100] | % |
| UMC Busy | umc_activity | [0, 10] | % |
| MM Busy | NOT configured | N/A | Should be absent (sentineled) |
| VCN Busy | per-XCP, 4 active engines | [0, 10] | Per-XCP format, NOT device-level VCN Activity |
| JPEG Busy | per-XCP, 32 active engines | [0, 10] | Per-XCP format, NOT device-level JPEG Activity |
| PCIe Width | Fixed 16 | 16 | Lanes |
| PCIe Speed | Fixed 32000 | 32000 | MT/s |
| XGMI | NOT configured | N/A | Should be absent (sentineled) |
| SDMA | 2 processes | varies | Cumulative byte counters |
| Memory | vram_used | varies | Derived from vram_used / vram_total |
| Voltages | NOT configured | N/A | Should be absent (sentineled) |
| Fan | NOT configured | N/A | Should be absent (sentineled) |
| NIC RDMA | 6 stats configured | [0, 1000000] | RX/TX bytes, packets, CNP |
mock_navi48.yaml)Consumer GPU with device-level metrics, no XCP, no NIC.
| Category | What's Configured | Expected Range | Notes |
|---|---|---|---|
| Temperature | edge, hotspot, mem | [35, 75] | Has temperature_edge |
| HBM Temperature | NOT configured | N/A | Should be absent (sentineled) |
| Power | current_socket_power | [20, 30] | Watts |
| GFX Busy | gfx_activity | [0, 10] | % |
| UMC Busy | umc_activity | [0, 5] | % |
| MM Busy | mm_activity | [0, 10] | % (present, unlike MI300X) |
| VCN Activity | device-level, 1 active / 4 total | [0, 10] | Device-level, NOT per-XCP |
| JPEG Activity | NOT configured | N/A | Should be absent (sentineled) |
| PCIe Width | Fixed 16 | 16 | Lanes |
| PCIe Speed | Fixed 2500 | 2500 | MT/s |
| XGMI | NOT configured | N/A | Should be absent |
| SDMA | 1 process | varies | Cumulative byte counters |
| Memory | vram_used | varies | Derived |
| Voltages | gfx, soc, mem configured | [700, 1200] | mV |
| Fan | rpm and max configured | [800, 1200] | RPM |
| NIC | No NIC devices | N/A | No NIC tracks should appear |
| # | Format | Environment Variables |
|---|---|---|
| 1 | Perfetto Standard | ROCPROFSYS_TRACE=1 |
| 2 | Perfetto Legacy | ROCPROFSYS_TRACE=1 ROCPROFSYS_TRACE_LEGACY=true |
| 3 | RocPD | ROCPROFSYS_USE_ROCPD=1 |
| Format | GPU Pattern | NIC Pattern |
|---|---|---|
| Standard | GPU [N] <Metric> (S) | NIC [N] <Metric> (S) |
| Legacy | GPU <Metric> [N] (S) | NIC <device_name> <Metric> [N] (S) |
Legacy also uses abbreviated forms: Pkts vs Packets.
| Run ID | Config | Format | Extra Env |
|---|---|---|---|
| mi300-perfetto | mock_mi300x.yaml | Perfetto Standard | ROCPROFSYS_SAMPLING_AINICS="all" |
| mi300-legacy | mock_mi300x.yaml | Perfetto Legacy | ROCPROFSYS_SAMPLING_AINICS="all" |
| mi300-rocpd | mock_mi300x.yaml | RocPD | ROCPROFSYS_SAMPLING_AINICS="all" |
| navi-perfetto | mock_navi48.yaml | Perfetto Standard | — |
| navi-legacy | mock_navi48.yaml | Perfetto Legacy | — |
| navi-rocpd | mock_navi48.yaml | RocPD | — |
Common env for ALL runs:
AMD_SMI_MOCK_CONFIG=<path-to-yaml>ROCPROFSYS_AMD_SMI_METRICS="all"Workload: ./transpose (mock generates all metric values regardless of workload type).
build/debug, build/release, or build/)cd into build dir, source share/rocprofiler-systems/setup-env.shldd bin/rocprof-sys-run | grep yaml (yaml-cpp must be linked)~/worktree/rocm-systems/amd-smi-mocks/mock_mi300x.yaml and mock_navi48.yamltranspose workload existsRun 6 profiling sessions. Use /tmp/pmc-validate-<run-id>/ output paths.
source share/rocprofiler-systems/setup-env.sh
# MI300X — Perfetto Standard
AMD_SMI_MOCK_CONFIG=~/worktree/rocm-systems/amd-smi-mocks/mock_mi300x.yaml \
ROCPROFSYS_OUTPUT_PATH=/tmp/pmc-validate-mi300-perfetto \
ROCPROFSYS_TRACE=1 \
ROCPROFSYS_AMD_SMI_METRICS="all" \
ROCPROFSYS_SAMPLING_AINICS="all" \
bin/rocprof-sys-run -- ./transpose
# MI300X — Perfetto Legacy
AMD_SMI_MOCK_CONFIG=~/worktree/rocm-systems/amd-smi-mocks/mock_mi300x.yaml \
ROCPROFSYS_OUTPUT_PATH=/tmp/pmc-validate-mi300-legacy \
ROCPROFSYS_TRACE=1 \
ROCPROFSYS_TRACE_LEGACY=true \
ROCPROFSYS_AMD_SMI_METRICS="all" \
ROCPROFSYS_SAMPLING_AINICS="all" \
bin/rocprof-sys-run -- ./transpose
# MI300X — RocPD
AMD_SMI_MOCK_CONFIG=~/worktree/rocm-systems/amd-smi-mocks/mock_mi300x.yaml \
ROCPROFSYS_OUTPUT_PATH=/tmp/pmc-validate-mi300-rocpd \
ROCPROFSYS_USE_ROCPD=1 \
ROCPROFSYS_AMD_SMI_METRICS="all" \
ROCPROFSYS_SAMPLING_AINICS="all" \
bin/rocprof-sys-run -- ./transpose
# Navi 48 — Perfetto Standard
AMD_SMI_MOCK_CONFIG=~/worktree/rocm-systems/amd-smi-mocks/mock_navi48.yaml \
ROCPROFSYS_OUTPUT_PATH=/tmp/pmc-validate-navi-perfetto \
ROCPROFSYS_TRACE=1 \
ROCPROFSYS_AMD_SMI_METRICS="all" \
bin/rocprof-sys-run -- ./transpose
# Navi 48 — Perfetto Legacy
AMD_SMI_MOCK_CONFIG=~/worktree/rocm-systems/amd-smi-mocks/mock_navi48.yaml \
ROCPROFSYS_OUTPUT_PATH=/tmp/pmc-validate-navi-legacy \
ROCPROFSYS_TRACE=1 \
ROCPROFSYS_TRACE_LEGACY=true \
ROCPROFSYS_AMD_SMI_METRICS="all" \
bin/rocprof-sys-run -- ./transpose
# Navi 48 — RocPD
AMD_SMI_MOCK_CONFIG=~/worktree/rocm-systems/amd-smi-mocks/mock_navi48.yaml \
ROCPROFSYS_OUTPUT_PATH=/tmp/pmc-validate-navi-rocpd \
ROCPROFSYS_USE_ROCPD=1 \
ROCPROFSYS_AMD_SMI_METRICS="all" \
bin/rocprof-sys-run -- ./transpose
This is the most important validation phase. A single leaked sentinel value is a FAIL.
Load each trace with MCP tools, then run:
-- SENTINEL CHECK: Find ANY sentinel value in PMC counters
SELECT t.name, c.value, c.ts
FROM counter c JOIN counter_track t ON c.track_id = t.id
WHERE t.name LIKE '%(S)%'
AND (c.value = 65535
OR c.value = 4294967295
OR c.value = 18446744073709551615
OR c.value = 1.8446744073709552e+19
OR c.value >= 1.844e+19)
LIMIT 20;
-- Expected: 0 rows. ANY result is a FAIL.
sqlite3 <db-file> "
SELECT p.name, e.value
FROM rocpd_pmc_event e JOIN rocpd_info_pmc p ON e.pmc_id = p.id
WHERE e.value IN (65535, 4294967295, 18446744073709551615)
OR e.value > 1e18
LIMIT 20;
"
# Expected: 0 rows. ANY result is a FAIL.
Verify that all configured metrics appear in output with expected value ranges.
-- ALL PMC TRACKS: Get every metric with stats
SELECT t.name,
COUNT(*) as samples,
MIN(c.value) as min_val,
MAX(c.value) as max_val,
ROUND(AVG(c.value), 2) as avg_val
FROM counter c JOIN counter_track t ON c.track_id = t.id
WHERE t.name LIKE '%(S)%'
GROUP BY t.name
ORDER BY t.name;
sqlite3 <db-file> "
SELECT p.name, COUNT(*) as samples,
MIN(e.value) as min_val, MAX(e.value) as max_val,
ROUND(AVG(e.value), 2) as avg_val
FROM rocpd_pmc_event e JOIN rocpd_info_pmc p ON e.pmc_id = p.id
GROUP BY p.name ORDER BY p.name;
"
| Metric | Perfetto Standard Track | Expected Range | Notes |
|---|---|---|---|
| Temperature (hotspot) | GPU [0] Temperature (S) | [55, 75] | Celsius |
| Power | GPU [0] Current Power (S) | [300, 500] | Watts |
| GFX Busy | GPU [0] GFX Busy (S) | [80, 100] | % |
| UMC Busy | GPU [0] UMC Busy (S) | [0, 10] | % |
| Memory Usage | GPU [0] Memory Usage (S) | >0 | MB, derived from vram |
| VCN Busy | GPU [0] VCN Busy ... (S) | [0, 10] | Per-XCP, 4 active engines |
| JPEG Busy | GPU [0] JPEG Busy ... (S) | [0, 10] | Per-XCP, 32 active engines |
| PCIe Width | GPU [0] PCIe Link Width (S) | 16 | Fixed |
| PCIe Speed | GPU [0] PCIe Link Speed (S) | 32000 | Fixed MT/s |
| SDMA Usage | GPU [0] SDMA Usage (S) | >=0 | Derived from cumulative counters |
| NIC RX Bytes | NIC [0] RX RDMA Bytes (S) | [0, 1000000] | |
| NIC TX Bytes | NIC [0] TX RDMA Bytes (S) | [0, 1000000] | |
| NIC RX Packets | NIC [0] RX RDMA Packets (S) | [0, 1000000] | |
| NIC TX Packets | NIC [0] TX RDMA Packets (S) | [0, 1000000] | |
| NIC RX CNP | NIC [0] RX CNP Packets (S) | [0, 1000000] | |
| NIC TX CNP | NIC [0] TX CNP Packets (S) | [0, 1000000] |
| Metric | Perfetto Standard Track | Expected Range | Notes |
|---|---|---|---|
| Temperature (edge) | GPU [0] Temperature (S) | [35, 55] | Has edge temp |
| Power | GPU [0] Current Power (S) | [20, 30] | Watts |
| GFX Busy | GPU [0] GFX Busy (S) | [0, 10] | % |
| UMC Busy | GPU [0] UMC Busy (S) | [0, 5] | % |
| MM Busy | GPU [0] MM Busy (S) | [0, 10] | % (absent on MI300X) |
| VCN Activity | GPU [0] VCN Activity ... (S) | [0, 10] | Device-level, 1 active |
| Memory Usage | GPU [0] Memory Usage (S) | >0 | MB |
| PCIe Width | GPU [0] PCIe Link Width (S) | 16 | Fixed |
| PCIe Speed | GPU [0] PCIe Link Speed (S) | 2500 | Fixed MT/s |
| SDMA Usage | GPU [0] SDMA Usage (S) | >=0 | 1 process |
For each metric with a known range, verify no values fall outside:
-- Example: MI300 power should be [300, 500]
SELECT t.name, c.value
FROM counter c JOIN counter_track t ON c.track_id = t.id
WHERE t.name LIKE '%Current Power%' AND t.name LIKE '%(S)%'
AND (c.value < 300 OR c.value > 500)
LIMIT 10;
-- Expected: 0 rows
Repeat for each metric with known range bounds from the mock config.
Verify that metrics NOT configured in the mock do NOT appear in output.
| Absent Metric | Perfetto Pattern | RocPD Pattern |
|---|---|---|
| Temperature Edge | %Temperature Edge% or %temperature_edge% | device_temp_edge |
| MM Busy | %MM Busy% or %mm_activity% | device_busy_mm |
| VCN Activity (device-level) | %VCN Activity% | device_vcn_activity |
| JPEG Activity (device-level) | %JPEG Activity% | device_jpeg_activity |
| XGMI | %XGMI% | device_xgmi% |
| Voltage | %Voltage% | device_voltage% |
| Fan | %Fan% | device_fan% |
| Absent Metric | Perfetto Pattern | RocPD Pattern |
|---|---|---|
| HBM Temperature | %HBM Temp% | device_temp_hbm% |
| VCN Busy (per-XCP) | %VCN Busy% | N/A |
| JPEG Busy (per-XCP) | %JPEG Busy% | N/A |
| JPEG Activity | %JPEG Activity% | device_jpeg_activity% |
| XGMI | %XGMI% | device_xgmi% |
| NIC | %NIC% | nic_% |
-- MI300X: Verify absent metrics
SELECT t.name FROM counter_track t
WHERE t.name LIKE '%(S)%'
AND (t.name LIKE '%Temperature Edge%'
OR t.name LIKE '%MM Busy%'
OR t.name LIKE '%VCN Activity%'
OR t.name LIKE '%JPEG Activity%'
OR t.name LIKE '%XGMI%'
OR t.name LIKE '%Voltage%'
OR t.name LIKE '%Fan%');
-- Expected: 0 rows
-- Navi 48: Verify absent metrics
SELECT t.name FROM counter_track t
WHERE t.name LIKE '%(S)%'
AND (t.name LIKE '%HBM Temp%'
OR t.name LIKE '%VCN Busy%'
OR t.name LIKE '%JPEG Busy%'
OR t.name LIKE '%JPEG Activity%'
OR t.name LIKE '%XGMI%'
OR t.name LIKE '%NIC%');
-- Expected: 0 rows
# MI300X
sqlite3 <db-file> "
SELECT DISTINCT p.name FROM rocpd_info_pmc p
WHERE p.name IN ('device_busy_mm', 'device_temp_edge')
OR p.name LIKE 'device_vcn_activity%'
OR p.name LIKE 'device_jpeg_activity%'
OR p.name LIKE 'device_xgmi%'
OR p.name LIKE 'device_voltage%'
OR p.name LIKE 'device_fan%';
"
# Expected: 0 rows
# Navi 48
sqlite3 <db-file> "
SELECT DISTINCT p.name FROM rocpd_info_pmc p
WHERE p.name LIKE 'device_temp_hbm%'
OR p.name LIKE 'device_jpeg_activity%'
OR p.name LIKE 'device_xgmi%'
OR p.name LIKE 'nic_%';
"
# Expected: 0 rows
For each architecture, verify that the same set of metrics appears across all 3 formats (accounting for naming differences):
-- Compare metric counts between Standard and Legacy Perfetto
-- Both should have the same number of unique PMC track names
SELECT COUNT(DISTINCT t.name) FROM counter_track t WHERE t.name LIKE '%(S)%';
For RocPD, compare the set of distinct rocpd_info_pmc.name values against Perfetto track names.
Discrepancies between formats indicate a bug in one of the output processors.
rm -rf /tmp/pmc-validate-mi300-perfetto /tmp/pmc-validate-mi300-legacy /tmp/pmc-validate-mi300-rocpd
rm -rf /tmp/pmc-validate-navi-perfetto /tmp/pmc-validate-navi-legacy /tmp/pmc-validate-navi-rocpd
# PMC Validation Report (Mock-Based)
**Date**: YYYY-MM-DD
**Build**: <build_dir>
**Branch**: <branch>
## Sentinel Check Results
| Config | Format | Sentinel Values Found | Status |
|--------|--------|--------------------|--------|
| MI300X | Perfetto | 0 | PASS |
| MI300X | Legacy | 0 | PASS |
| MI300X | RocPD | 0 | PASS |
| Navi 48 | Perfetto | 0 | PASS |
| Navi 48 | Legacy | 0 | PASS |
| Navi 48 | RocPD | 0 | PASS |
## Positive Validation (Configured Metrics)
| Config | Metric | Perfetto | Legacy | RocPD | Range OK |
|--------|--------|----------|--------|-------|----------|
| MI300X | Power | PASS (N, [300-500]) | PASS | PASS | YES |
| MI300X | Temperature | PASS (N, [55-75]) | PASS | PASS | YES |
| ... | ... | ... | ... | ... | ... |
| Navi 48 | Power | PASS (N, [20-30]) | PASS | PASS | YES |
| ... | ... | ... | ... | ... | ... |
## Negative Validation (Unsupported Metrics)
| Config | Metric Should Be Absent | Perfetto | Legacy | RocPD |
|--------|------------------------|----------|--------|-------|
| MI300X | temperature_edge | PASS (absent) | PASS | PASS |
| MI300X | MM Busy | PASS (absent) | PASS | PASS |
| MI300X | XGMI | PASS (absent) | PASS | PASS |
| Navi 48 | HBM Temperature | PASS (absent) | PASS | PASS |
| Navi 48 | JPEG Activity | PASS (absent) | PASS | PASS |
| Navi 48 | NIC | PASS (absent) | PASS | PASS |
| ... | ... | ... | ... | ... |
## Cross-Format Consistency
| Config | Perfetto Metrics | Legacy Metrics | RocPD Metrics | Match |
|--------|-----------------|----------------|---------------|-------|
| MI300X | N | N | N | YES |
| Navi 48 | N | N | N | YES |
## Issues Found
[List with severity: CRITICAL / HIGH / MEDIUM / LOW]
## Conclusion
[Overall assessment]
Save report to: planning/pmc-validation-report.md in the project worktree.
| Issue | Description | Impact |
|---|---|---|
| Perfetto double precision | UINT64_MAX stored as 1.8446744073709552e+19 | Must check >= 1.844e+19 in addition to exact values |
| Legacy timing | Short workloads (<0.5s) may get 0-1 samples in Legacy format | Use transpose which runs ~2.4s |
| SDMA cumulative | SDMA values are cumulative byte counters, not instantaneous rates | Delta calculation needed for rate validation |
| Mock workload independence | Mock generates values regardless of workload type | VCN/JPEG don't need decode binaries |
| yaml-cpp dependency | Mock requires yaml-cpp linked into the build | Check with ldd before running |
| Invalid timestamps (Legacy) | First sample may have invalid timestamp, dropped with warning | Reduces sample count by 1-2 |
| Outcome | Next Step |
|---|---|
| Sentinel found | planning-bugfix — plan fix for the leaking pipeline stage |
| Missing configured metric | planning-bugfix — investigate why metric isn't reaching output |
| Unsupported metric present | planning-bugfix — sentinel filtering gap |
| All checks pass | git-prepare-pull-request to submit |
This skill is also agent-level knowledge for the orchestrator's Tester agent.