Skip to content

Commit 06e419a

Browse files
charles-typfacebook-github-bot
authored andcommitted
Consolidate ARM + AMD perf report scripts under --arch
Reviewed By: YifanYuan3 Differential Revision: D115318779
1 parent 090a4a3 commit 06e419a

20 files changed

Lines changed: 4995 additions & 4130 deletions

File tree

benchpress/plugins/hooks/perf_monitors/topdown.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@ def __init__(self, interval, job_uuid, subdir=None, **kwargs):
646646
"nv-perf-collector",
647647
perf_collect_script_name="collect_nvda_neoversev2_perf_counters.sh",
648648
perf_postproc_script_name="generate_arm_perf_report.py",
649+
perf_postproc_args=["--arch", "grace"],
649650
subdir=subdir,
650651
)
651652

@@ -660,7 +661,8 @@ def __init__(self, interval, job_uuid, subdir=None, **kwargs):
660661
job_uuid,
661662
"nv3-perf-collector",
662663
perf_collect_script_name="collect_neoversev3_perf_counters.sh",
663-
perf_postproc_script_name="generate_arm_neoversev3_perf_report.py",
664+
perf_postproc_script_name="generate_arm_perf_report.py",
665+
perf_postproc_args=["--arch", "neoversev3"],
664666
subdir=subdir,
665667
)
666668

perfutils/README.md

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,62 @@ collect_amd_zen4_perf_counters.sh
1818
## AMD Zen5 Engineer Samples
1919
- Data Collection: collect_amd_zen5_perf_counters.sh
2020
- Data Processing: generate_amd_perf_report.py --arch zen5es
21-
## ARM (NVIDIA Grace)
21+
## ARM (NVIDIA Grace, Neoverse V2)
2222
- Data Collection: collect_nvda_neoversev2_perf_counters.sh
23-
- Data Processing: generate_arm_perf_report.py
23+
- Data Processing: generate_arm_perf_report.py --arch grace
24+
## ARM (Neoverse V3)
25+
- Data Collection: collect_neoversev3_perf_counters.sh
26+
- Data Processing: generate_arm_perf_report.py --arch neoversev3
27+
## ARM (Google Axion, Neoverse V2)
28+
- Data Collection: collect_axion_neoversev2_perf_counters.sh
29+
- Data Processing: generate_arm_perf_report.py --arch axion
2430
## ARM (Other)
2531

2632
Use [topdown tool](https://learn.arm.com/install-guides/topdown-tool/).
2733

34+
## Report generator organization (ARM + AMD)
35+
36+
Both vendors' report generators share one design: a thin `--arch` CLI entry
37+
point over a per-vendor package, and both packages share a single
38+
vendor-agnostic core (`perf_report/core.py`) that defines rendering, series
39+
aggregation, and the `--arch` registry exactly once.
40+
41+
```
42+
perfutils/
43+
perf_report/
44+
core.py # shared: renderers, aggregation, ArchSpec +
45+
# register_arch + ARCH_REGISTRY (one registry
46+
# for every CPU of every vendor)
47+
generate_arm_perf_report.py # thin CLI: parse --arch, look up registry, run
48+
arm_perf/
49+
core.py # ARM-specific: read_csv (PMU dedup), single
50+
# socket, duration, CMN uncore helpers
51+
arches/{grace,neoversev3,axion}.py
52+
generate_amd_perf_report.py # thin CLI (mirror of ARM)
53+
amd_perf/
54+
core.py # AMD-specific: read_csv (socket/numcpus),
55+
# multi-socket, drop_first_interval,
56+
# DRAM channel/freq discovery
57+
metrics.py # AMD derived-metric functions (shared across
58+
# Zen generations)
59+
arches/{zen3,zen4,zen5,zen5es}.py
60+
```
61+
62+
**Adding a new CPU (either vendor)** is an additive change — no edits to shared
63+
code, to a CLI entry point, or to any other CPU's module:
64+
65+
1. Create `<vendor>_perf/arches/<cpu>.py` that builds the CPU's metric list and
66+
calls `register_arch("<cpu>", metrics, vendor=..., align=..., ...)` at import
67+
time (import shared helpers from `<vendor>_perf.core`). For AMD, add any new
68+
metric functions to `amd_perf/metrics.py`.
69+
2. Add `<cpu>` to that vendor package's `arches/__init__.py` import list and to
70+
the `:<vendor>_perf` library in `BUCK`.
71+
72+
Per-CPU quirks are declarative data on the registry entry rather than branches
73+
in any `main()`: e.g. `align="shortest"` (Grace / Neoverse V3) vs
74+
`align="longest"` (Axion / all AMD) selects how derived-metric series are
75+
aligned when concatenated.
76+
2877

2978
## Note
3079
When working with AMD Zen5-based CPUs, the `generate_amd_perf_report.py` has to also run on the same CPU; while for other architectures, the `generate_[cpu]_report.py` can be run on any machine.

perfutils/amd_perf/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
#
4+
# This source code is licensed under the MIT license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# pyre-unsafe
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
#
4+
# This source code is licensed under the MIT license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# pyre-unsafe
8+
9+
"""AMD CPU report modules.
10+
11+
Importing this package imports every per-CPU module, each of which calls
12+
``core.register_arch`` at import time. To add a new AMD CPU, drop a new module
13+
here and add it to the import list below -- no other file changes.
14+
"""
15+
16+
try:
17+
from cea.chips.benchpress.perfutils.amd_perf.arches import ( # noqa: F401
18+
zen3,
19+
zen4,
20+
zen5,
21+
zen5es,
22+
)
23+
except ModuleNotFoundError: # standalone / OSS: run from perfutils/ dir
24+
from amd_perf.arches import ( # noqa: F401 # pyre-ignore[21]
25+
zen3,
26+
zen4,
27+
zen5,
28+
zen5es,
29+
)

perfutils/amd_perf/arches/zen3.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
#
4+
# This source code is licensed under the MIT license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# pyre-unsafe
8+
9+
"""AMD Zen3 (EPYC Milan) -- core PMU + memory bandwidth"""
10+
11+
try:
12+
from cea.chips.benchpress.perfutils.amd_perf.core import register_arch
13+
except ModuleNotFoundError: # standalone / OSS: run from perfutils/ dir
14+
from amd_perf.core import register_arch # pyre-ignore[21]
15+
try:
16+
from cea.chips.benchpress.perfutils.amd_perf.metrics import (
17+
avg_mab_latency,
18+
backend_stalls,
19+
branch_mispred_rate,
20+
dtlb_mpki,
21+
frontend_stalls,
22+
frontend_stalls_due_to_ic_miss,
23+
ipc,
24+
itlb_mpki,
25+
l1_1g_dtlb_mpki,
26+
l1_2m_dtlb_mpki,
27+
l1_4k_dtlb_mpki,
28+
l1_dcache_miss_rate,
29+
l1_dcache_mpki,
30+
l1_icache_fills_l2_ratio,
31+
l1_icache_fills_sys_ratio,
32+
l1_icache_mab_demand_requests_rate,
33+
l1_icache_mab_prefetch_requests_rate,
34+
l1_icache_miss_rate,
35+
l1_icache_mpki,
36+
l2_1g_itlb_mpki,
37+
l2_2m_itlb_mpki,
38+
l2_4k_itlb_mpki,
39+
l2_code_miss_rate,
40+
l2_code_mpki,
41+
l2_data_miss_rate,
42+
l2_data_mpki,
43+
l2_dtlb_mpki,
44+
l2_itlb_mpki,
45+
llc_avg_load_to_use_lat_clks,
46+
llc_miss_rate,
47+
llc_mpki,
48+
mem_read_bw_MBps,
49+
mem_write_bw_MBps,
50+
mips,
51+
timestamp,
52+
uops_dispatched_decoder_per_instructions,
53+
uops_dispatched_opcache_per_instructions,
54+
uops_per_instructions,
55+
)
56+
except ModuleNotFoundError: # standalone / OSS: run from perfutils/ dir
57+
from amd_perf.metrics import ( # pyre-ignore[21]
58+
avg_mab_latency,
59+
backend_stalls,
60+
branch_mispred_rate,
61+
dtlb_mpki,
62+
frontend_stalls,
63+
frontend_stalls_due_to_ic_miss,
64+
ipc,
65+
itlb_mpki,
66+
l1_1g_dtlb_mpki,
67+
l1_2m_dtlb_mpki,
68+
l1_4k_dtlb_mpki,
69+
l1_dcache_miss_rate,
70+
l1_dcache_mpki,
71+
l1_icache_fills_l2_ratio,
72+
l1_icache_fills_sys_ratio,
73+
l1_icache_mab_demand_requests_rate,
74+
l1_icache_mab_prefetch_requests_rate,
75+
l1_icache_miss_rate,
76+
l1_icache_mpki,
77+
l2_1g_itlb_mpki,
78+
l2_2m_itlb_mpki,
79+
l2_4k_itlb_mpki,
80+
l2_code_miss_rate,
81+
l2_code_mpki,
82+
l2_data_miss_rate,
83+
l2_data_mpki,
84+
l2_dtlb_mpki,
85+
l2_itlb_mpki,
86+
llc_avg_load_to_use_lat_clks,
87+
llc_miss_rate,
88+
llc_mpki,
89+
mem_read_bw_MBps,
90+
mem_write_bw_MBps,
91+
mips,
92+
timestamp,
93+
uops_dispatched_decoder_per_instructions,
94+
uops_dispatched_opcache_per_instructions,
95+
uops_per_instructions,
96+
)
97+
98+
99+
def metrics(grouped_df):
100+
metrics = [
101+
timestamp(grouped_df),
102+
mips(grouped_df),
103+
ipc(grouped_df),
104+
uops_per_instructions(grouped_df),
105+
uops_dispatched_opcache_per_instructions(grouped_df),
106+
uops_dispatched_decoder_per_instructions(grouped_df),
107+
frontend_stalls(grouped_df),
108+
frontend_stalls_due_to_ic_miss(grouped_df),
109+
backend_stalls(grouped_df),
110+
branch_mispred_rate(grouped_df),
111+
avg_mab_latency(grouped_df),
112+
l1_icache_mab_demand_requests_rate(grouped_df),
113+
l1_icache_mab_prefetch_requests_rate(grouped_df),
114+
l1_icache_miss_rate(grouped_df),
115+
l1_icache_mpki(grouped_df),
116+
l1_icache_fills_l2_ratio(grouped_df),
117+
l1_icache_fills_sys_ratio(grouped_df),
118+
l1_dcache_miss_rate(grouped_df),
119+
l1_dcache_mpki(grouped_df),
120+
l2_code_miss_rate(grouped_df),
121+
l2_code_mpki(grouped_df),
122+
l2_data_miss_rate(grouped_df),
123+
l2_data_mpki(grouped_df),
124+
llc_miss_rate(grouped_df),
125+
llc_mpki(grouped_df),
126+
llc_avg_load_to_use_lat_clks(grouped_df),
127+
itlb_mpki(grouped_df),
128+
l2_itlb_mpki(grouped_df),
129+
l2_4k_itlb_mpki(grouped_df),
130+
l2_2m_itlb_mpki(grouped_df),
131+
l2_1g_itlb_mpki(grouped_df),
132+
dtlb_mpki(grouped_df),
133+
l1_4k_dtlb_mpki(grouped_df),
134+
l1_2m_dtlb_mpki(grouped_df),
135+
l1_1g_dtlb_mpki(grouped_df),
136+
l2_dtlb_mpki(grouped_df),
137+
]
138+
metrics.append(mem_read_bw_MBps(grouped_df))
139+
metrics.append(mem_write_bw_MBps(grouped_df))
140+
return metrics
141+
142+
143+
register_arch(
144+
"zen3",
145+
metrics,
146+
vendor="amd",
147+
align="longest",
148+
description="Zen3 (EPYC Milan) -- core PMU + memory bandwidth",
149+
)

0 commit comments

Comments
 (0)