Support MI 350 profiling (#632)

* Add MI 350 hardware information

* Refactor MI GPU YAML file and corresponding interface

* Add SoC file for gfx950 architecture

* Add analysis report configs for MI 350 containing existing metrics

* Add placeholder None valued metrics for previous architectures to make
  baseline comparison work

* Enable testing on MI 350

* Analysis config metric changes
    - SPI changes
        - Update metric formula for default SPI pipe counter
             - Use efficiently collected pipe wise SPI counters
        - Add SPI Wave Occupancy
        - Add Scheduler-Pipe Wave Utilization
        - Update formula for VGPR Writes
        - Add Scheduler-Pipe FIFO Full Rate
   - CPC changes
	- Add CPC SYNC FIFO Full Rate
	- Add CPC CANE Stall Rate
        - Add CPC ADC Utilization
   - SQ changes
        - Add VALU co-issue efficiency
        - Add F6F4 datatype metrics
        - Update formula for total FLOPs by adding F6F4 counters
        - Add LDS STORE / LOAD / ATOMIC metrics
        - Add LDS STORE / LOAD / ATOMIC bandwidth
        - Add LDS FIFO and TA ADDR / CMD / DATA FIFO full rates

* Collect TCP_TCP_LATENCY_sum only for gfx950 (MI 350)

* Do not inject SQ_ACCUM_PREV_HIRES unnecesarily

* Do not hardcode memory and shader clock speeds

* Write num_hbm_channels to sysinfo.csv instead of hbm_bw while profiling

* Move generate sysinfo.csv to pre processing step of profiling

* Add warnings to use --specs-correction for missing sysinfo.csv values during analysis phase

* Update CHANGELOG

* Analysis phase warning to use --specs-correction when needed
This commit is contained in:
vedithal-amd
2025-04-03 02:21:18 -04:00
committed by GitHub
parent f3736778f4
commit f9aa7be97c
366 changed files with 22368 additions and 577 deletions
+208 -10
View File
@@ -14,6 +14,7 @@ import test_utils
# Globals
# TODO: MI350 What are the gpu models in MI 350 series
SUPPORTED_ARCHS = {
"gfx906": {"mi50": ["MI50", "MI60"]},
"gfx908": {"mi100": ["MI100"]},
@@ -21,12 +22,14 @@ SUPPORTED_ARCHS = {
"gfx940": {"mi300": ["MI300A_A0"]},
"gfx941": {"mi300": ["MI300X_A0"]},
"gfx942": {"mi300": ["MI300A_A1", "MI300X_A1"]},
"gfx950": {"mi350": ["MI350"]},
}
MI300_CHIP_IDS = {
CHIP_IDS = {
"29856": "MI300A_A1",
"29857": "MI300X_A1",
"29858": "MI308X",
"30112": "MI350",
}
@@ -106,6 +109,25 @@ ALL_CSVS_MI300 = sorted(
"timestamps.csv",
]
)
ALL_CSVS_MI350 = sorted(
[
"SQ_IFETCH_LEVEL.csv",
"SQ_INST_LEVEL_LDS.csv",
"SQ_INST_LEVEL_SMEM.csv",
"SQ_INST_LEVEL_VMEM.csv",
"SQ_LEVEL_WAVES.csv",
"pmc_perf.csv",
"pmc_perf_0.csv",
"pmc_perf_1.csv",
"pmc_perf_2.csv",
"pmc_perf_3.csv",
"pmc_perf_4.csv",
"pmc_perf_5.csv",
"pmc_perf_6.csv",
"pmc_perf_7.csv",
"sysinfo.csv",
]
)
ROOF_ONLY_FILES = sorted(
[
@@ -290,9 +312,9 @@ def gpu_soc():
## 3) Deduce gpu model name from arch
gpu_model = list(SUPPORTED_ARCHS[gpu_arch].keys())[0].upper()
if gpu_model == "MI300":
if chip_id in MI300_CHIP_IDS:
gpu_model = MI300_CHIP_IDS[chip_id]
if gpu_model not in ("MI50", "MI100", "MI200"):
if chip_id in CHIP_IDS:
gpu_model = CHIP_IDS[chip_id]
return gpu_model
@@ -303,6 +325,9 @@ soc = gpu_soc()
if "MI300" in soc:
os.environ["ROCPROF"] = "rocprofv2"
if "MI350" in soc:
os.environ["ROCPROF"] = "rocprofv3"
Baseline_dir = str(Path("tests/workloads/vcopy/" + soc).resolve())
@@ -491,6 +516,8 @@ def test_path(binary_handler_profile_rocprof_compute):
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI200)
elif "MI300" in soc:
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI300)
elif "MI350" in soc:
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI350)
else:
print("This test is not supported for {}".format(soc))
assert 0
@@ -502,7 +529,7 @@ def test_path(binary_handler_profile_rocprof_compute):
@pytest.mark.misc
def test_roof_kernel_names(binary_handler_profile_rocprof_compute):
if soc == "MI100":
if soc in ("MI100", "MI350"):
# roofline is not supported on MI100
assert True
# Do not continue testing
@@ -517,7 +544,7 @@ def test_roof_kernel_names(binary_handler_profile_rocprof_compute):
# assert successful run
assert returncode == 0
file_dict = test_utils.check_csv_files(workload_dir, 1, num_kernels)
if soc == "MI200" or "MI300" in soc:
if soc == "MI200" in soc or "MI300" in soc:
assert sorted(list(file_dict.keys())) == sorted(
ROOF_ONLY_FILES + ["kernelName_legend.pdf"]
)
@@ -546,6 +573,8 @@ def test_device_filter(binary_handler_profile_rocprof_compute):
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI200)
elif "MI300" in soc:
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI300)
elif "MI350" in soc:
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI350)
else:
print("Testing isn't supported yet for {}".format(soc))
assert 0
@@ -574,6 +603,8 @@ def test_kernel(binary_handler_profile_rocprof_compute):
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI200)
elif "MI300" in soc:
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI300)
elif "MI350" in soc:
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI350)
else:
print("Testing isn't supported yet for {}".format(soc))
assert 0
@@ -625,6 +656,24 @@ def test_block_SQ(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs = [
"SQ_IFETCH_LEVEL.csv",
"SQ_INST_LEVEL_LDS.csv",
"SQ_INST_LEVEL_SMEM.csv",
"SQ_INST_LEVEL_VMEM.csv",
"SQ_LEVEL_WAVES.csv",
"pmc_perf.csv",
"pmc_perf_0.csv",
"pmc_perf_1.csv",
"pmc_perf_2.csv",
"pmc_perf_3.csv",
"pmc_perf_4.csv",
"pmc_perf_5.csv",
"pmc_perf_6.csv",
"pmc_perf_7.csv",
"sysinfo.csv",
]
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -652,6 +701,8 @@ def test_block_SQC(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs.remove("timestamps.csv")
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -684,6 +735,8 @@ def test_block_TA(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs.remove("timestamps.csv")
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -721,6 +774,15 @@ def test_block_TD(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs = [
"pmc_perf.csv",
"pmc_perf_0.csv",
"pmc_perf_1.csv",
"pmc_perf_2.csv",
"pmc_perf_3.csv",
"sysinfo.csv",
]
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -771,6 +833,8 @@ def test_block_TCP(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs.remove("timestamps.csv")
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -825,6 +889,8 @@ def test_block_TCC(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs.remove("timestamps.csv")
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -857,6 +923,23 @@ def test_block_SPI(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs = [
"pmc_perf.csv",
"pmc_perf_0.csv",
"pmc_perf_1.csv",
"pmc_perf_2.csv",
"pmc_perf_3.csv",
"pmc_perf_4.csv",
"pmc_perf_5.csv",
"pmc_perf_6.csv",
"pmc_perf_7.csv",
"pmc_perf_8.csv",
"pmc_perf_9.csv",
"pmc_perf_10.csv",
"pmc_perf_11.csv",
"sysinfo.csv",
]
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -886,6 +969,19 @@ def test_block_CPC(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs = [
"pmc_perf.csv",
"pmc_perf_0.csv",
"pmc_perf_1.csv",
"pmc_perf_2.csv",
"pmc_perf_3.csv",
"pmc_perf_4.csv",
"pmc_perf_5.csv",
"pmc_perf_6.csv",
"pmc_perf_7.csv",
"sysinfo.csv",
]
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -910,6 +1006,8 @@ def test_block_CPF(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs.remove("timestamps.csv")
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
validate(
@@ -959,6 +1057,24 @@ def test_block_SQ_CPC(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs = [
"SQ_IFETCH_LEVEL.csv",
"SQ_INST_LEVEL_LDS.csv",
"SQ_INST_LEVEL_SMEM.csv",
"SQ_INST_LEVEL_VMEM.csv",
"SQ_LEVEL_WAVES.csv",
"pmc_perf.csv",
"pmc_perf_0.csv",
"pmc_perf_1.csv",
"pmc_perf_2.csv",
"pmc_perf_3.csv",
"pmc_perf_4.csv",
"pmc_perf_5.csv",
"pmc_perf_6.csv",
"pmc_perf_7.csv",
"sysinfo.csv",
]
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -1009,6 +1125,24 @@ def test_block_SQ_TA(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs = [
"SQ_IFETCH_LEVEL.csv",
"SQ_INST_LEVEL_LDS.csv",
"SQ_INST_LEVEL_SMEM.csv",
"SQ_INST_LEVEL_VMEM.csv",
"SQ_LEVEL_WAVES.csv",
"pmc_perf.csv",
"pmc_perf_0.csv",
"pmc_perf_1.csv",
"pmc_perf_2.csv",
"pmc_perf_3.csv",
"pmc_perf_4.csv",
"pmc_perf_5.csv",
"pmc_perf_6.csv",
"pmc_perf_7.csv",
"sysinfo.csv",
]
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -1055,6 +1189,24 @@ def test_block_SQ_SPI(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs = [
"SQ_IFETCH_LEVEL.csv",
"SQ_INST_LEVEL_LDS.csv",
"SQ_INST_LEVEL_SMEM.csv",
"SQ_INST_LEVEL_VMEM.csv",
"SQ_LEVEL_WAVES.csv",
"pmc_perf.csv",
"pmc_perf_0.csv",
"pmc_perf_1.csv",
"pmc_perf_2.csv",
"pmc_perf_3.csv",
"pmc_perf_4.csv",
"pmc_perf_5.csv",
"pmc_perf_6.csv",
"pmc_perf_7.csv",
"sysinfo.csv",
]
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -1106,6 +1258,24 @@ def test_block_SQ_SQC_TCP_CPC(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs = [
"SQ_IFETCH_LEVEL.csv",
"SQ_INST_LEVEL_LDS.csv",
"SQ_INST_LEVEL_SMEM.csv",
"SQ_INST_LEVEL_VMEM.csv",
"SQ_LEVEL_WAVES.csv",
"pmc_perf.csv",
"pmc_perf_0.csv",
"pmc_perf_1.csv",
"pmc_perf_2.csv",
"pmc_perf_3.csv",
"pmc_perf_4.csv",
"pmc_perf_5.csv",
"pmc_perf_6.csv",
"pmc_perf_7.csv",
"sysinfo.csv",
]
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -1171,6 +1341,24 @@ def test_block_SQ_SPI_TA_TCC_CPF(binary_handler_profile_rocprof_compute):
"sysinfo.csv",
"timestamps.csv",
]
if soc == "MI350":
expected_csvs = [
"SQ_IFETCH_LEVEL.csv",
"SQ_INST_LEVEL_LDS.csv",
"SQ_INST_LEVEL_SMEM.csv",
"SQ_INST_LEVEL_VMEM.csv",
"SQ_LEVEL_WAVES.csv",
"pmc_perf.csv",
"pmc_perf_0.csv",
"pmc_perf_1.csv",
"pmc_perf_2.csv",
"pmc_perf_3.csv",
"pmc_perf_4.csv",
"pmc_perf_5.csv",
"pmc_perf_6.csv",
"pmc_perf_7.csv",
"sysinfo.csv",
]
assert sorted(list(file_dict.keys())) == sorted(expected_csvs)
@@ -1196,6 +1384,8 @@ def test_dispatch_0(binary_handler_profile_rocprof_compute):
assert sorted(list(file_dict.keys())) == ALL_CSVS_MI200
elif "MI300" in soc:
assert sorted(list(file_dict.keys())) == ALL_CSVS_MI300
elif "MI350" in soc:
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI350)
else:
print("Testing isn't supported yet for {}".format(soc))
assert 0
@@ -1226,6 +1416,8 @@ def test_dispatch_0_1(binary_handler_profile_rocprof_compute):
assert sorted(list(file_dict.keys())) == ALL_CSVS_MI200
elif "MI300" in soc:
assert sorted(list(file_dict.keys())) == ALL_CSVS_MI300
elif "MI350" in soc:
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI350)
else:
print("Testing isn't supported yet for {}".format(soc))
assert 0
@@ -1253,6 +1445,8 @@ def test_dispatch_2(binary_handler_profile_rocprof_compute):
assert sorted(list(file_dict.keys())) == ALL_CSVS_MI200
elif "MI300" in soc:
assert sorted(list(file_dict.keys())) == ALL_CSVS_MI300
elif "MI350" in soc:
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI350)
else:
print("Testing isn't supported yet for {}".format(soc))
assert 0
@@ -1283,6 +1477,8 @@ def test_join_type_grid(binary_handler_profile_rocprof_compute):
assert sorted(list(file_dict.keys())) == ALL_CSVS_MI200
elif "MI300" in soc:
assert sorted(list(file_dict.keys())) == ALL_CSVS_MI300
elif "MI350" in soc:
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI350)
else:
print("Testing isn't supported yet for {}".format(soc))
assert 0
@@ -1310,6 +1506,8 @@ def test_join_type_kernel(binary_handler_profile_rocprof_compute):
assert sorted(list(file_dict.keys())) == ALL_CSVS_MI200
elif "MI300" in soc:
assert sorted(list(file_dict.keys())) == ALL_CSVS_MI300
elif "MI350" in soc:
assert sorted(list(file_dict.keys())) == sorted(ALL_CSVS_MI350)
else:
print("Testing isn't supported yet for {}".format(soc))
assert 0
@@ -1326,7 +1524,7 @@ def test_join_type_kernel(binary_handler_profile_rocprof_compute):
@pytest.mark.sort
def test_roof_sort_dispatches(binary_handler_profile_rocprof_compute):
# only test 1 device for roofline
if soc == "MI100":
if soc in ("MI100", "MI350"):
# roofline is not supported on MI100
assert True
# Do not continue testing
@@ -1356,7 +1554,7 @@ def test_roof_sort_dispatches(binary_handler_profile_rocprof_compute):
@pytest.mark.sort
def test_roof_sort_kernels(binary_handler_profile_rocprof_compute):
# only test 1 device for roofline
if soc == "MI100":
if soc in ("MI100", "MI350"):
# roofline is not supported on MI100
assert True
# Do not continue testing
@@ -1386,7 +1584,7 @@ def test_roof_sort_kernels(binary_handler_profile_rocprof_compute):
@pytest.mark.mem
def test_roof_mem_levels_vL1D(binary_handler_profile_rocprof_compute):
# only test 1 device for roofline
if soc == "MI100":
if soc in ("MI100", "MI350"):
# roofline is not supported on MI100
assert True
# Do not continue testing
@@ -1416,7 +1614,7 @@ def test_roof_mem_levels_vL1D(binary_handler_profile_rocprof_compute):
@pytest.mark.mem
def test_roof_mem_levels_LDS(binary_handler_profile_rocprof_compute):
# only test 1 device for roofline
if soc == "MI100":
if soc in ("MI100", "MI350"):
# roofline is not supported on MI100
assert True
# Do not continue testing