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

[ROCm/rocprofiler-compute commit: f9aa7be97c]
This commit is contained in:
vedithal-amd
2025-04-03 02:21:18 -04:00
committed by GitHub
parent 1273a5e2a9
commit 27585a8a2b
366 changed files with 22368 additions and 577 deletions
+19 -64
View File
@@ -43,16 +43,32 @@ import pandas as pd
import config
from utils.logger import console_debug, console_error, console_log, console_warning
from utils.mi_gpu_spec import get_mi300_num_xcds
from utils.mi_gpu_spec import get_num_xcds
rocprof_cmd = ""
rocprof_args = ""
spi_pipe_counter_regexs = [r"SPI_CS\d+_(.*)", r"SPI_CSQ_P\d+_(.*)"]
def is_tcc_channel_counter(counter):
return counter.startswith("TCC") and counter.endswith("]")
def is_spi_pipe_counter(counter):
for pattern in spi_pipe_counter_regexs:
if re.match(pattern, counter):
return True
return False
def get_base_spi_pipe_counter(counter):
for pattern in spi_pipe_counter_regexs:
match = re.match(pattern, counter)
if match:
return match.group(1)
return ""
def using_v1():
return "ROCPROF" not in os.environ.keys() or (
@@ -571,12 +587,7 @@ def run_prof(
# set required env var for mi300
new_env = None
if (
mspec.gpu_model.lower() == "mi300x_a0"
or mspec.gpu_model.lower() == "mi300x_a1"
or mspec.gpu_model.lower() == "mi300a_a0"
or mspec.gpu_model.lower() == "mi300a_a1"
):
if mspec.gpu_model.lower() not in ("mi50", "mi60", "mi210", "mi250", "mi250x"):
new_env = os.environ.copy()
new_env["ROCPROFILER_INDIVIDUAL_XCC_MODE"] = "1"
@@ -661,7 +672,7 @@ def run_prof(
if new_env and not using_v3() and not using_v1():
# flatten tcc for applicable mi300 input
f = path(workload_dir + "/out/pmc_1/results_" + fbase + ".csv")
xcds = total_xcds(mspec.gpu_model, mspec.compute_partition)
xcds = get_num_xcds(mspec.gpu_model, mspec.compute_partition)
df = flatten_tcc_info_across_xcds(f, xcds, int(mspec._l2_banks))
df.to_csv(f, index=False)
@@ -1065,62 +1076,6 @@ def flatten_tcc_info_across_xcds(file, xcds, tcc_channel_per_xcd):
return df
def total_xcds(gpu_model, compute_partition):
"""
Returns the number of xcds for a gpu model and compute_partition pair.
"""
# For mi300 chips, return result from mi_gpu_spec
result = get_mi300_num_xcds(gpu_model, compute_partition)
if result:
return result
# For other systems, use manual check
# check MI300 has a valid compute partition
mi300a_model = ["mi300a_a0", "mi300a_a1"]
mi300x_model = ["mi300x_a0", "mi300x_a1"]
mi308x_model = ["mi308x"]
if (
gpu_model.lower() in mi300a_model + mi300x_model + mi308x_model
and compute_partition == "NA"
):
console_error("Invalid compute partition found for {}".format(gpu_model))
if gpu_model.lower() not in mi300a_model + mi300x_model + mi308x_model:
return 1
# from the whitepaper
# https://www.amd.com/content/dam/amd/en/documents/instinct-tech-docs/white-papers/amd-cdna-3-white-paper.pdf
if compute_partition.lower() == "spx":
if gpu_model.lower() in mi300a_model:
return 6
if gpu_model.lower() in mi300x_model:
return 8
if gpu_model.lower() in mi308x_model:
return 4
if compute_partition.lower() == "tpx":
if gpu_model.lower() in mi300a_model:
return 2
if compute_partition.lower() == "dpx":
if gpu_model.lower() in mi300x_model:
return 4
if gpu_model.lower() in mi308x_model:
return 2
if compute_partition.lower() == "qpx":
if gpu_model.lower() in mi300x_model:
return 2
if compute_partition.lower() == "cpx":
if gpu_model.lower() in mi300x_model:
return 1
if gpu_model.lower() in mi308x_model:
return 1
# TODO implement other archs here as needed
console_error(
"Unknown compute partition / arch found for {} / {}".format(
compute_partition, gpu_model
)
)
def get_submodules(package_name):
"""List all submodules for a target package"""
import importlib