a838b0c07b
* Fix test case for MI 308 * Use consistent naming of GPUs in comment
157 lines
5.8 KiB
Python
157 lines
5.8 KiB
Python
##############################################################################
|
|
# MIT License
|
|
#
|
|
# Copyright (c) 2026 Advanced Micro Devices, Inc. All Rights Reserved.
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in
|
|
# all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
# THE SOFTWARE.
|
|
|
|
##############################################################################
|
|
|
|
import pandas as pd
|
|
import pytest
|
|
import test_utils
|
|
|
|
config = {}
|
|
config["memcopy"] = ["tests/memcopy"]
|
|
config["cleanup"] = True
|
|
|
|
soc = test_utils.gpu_soc()
|
|
|
|
# workload -> gfx -> metric definition
|
|
VALIDATE_METRICS = {
|
|
"memcopy": {
|
|
"MI100": [
|
|
{
|
|
"name": "HBM Bandwidth",
|
|
"metric_id": "4.1.8",
|
|
"csv_file": "4.1_Roofline_Performance_Rates.csv",
|
|
"column": "Value",
|
|
"expected_values": [1044.48],
|
|
},
|
|
],
|
|
"MI200": [
|
|
{
|
|
"name": "HBM Bandwidth",
|
|
"metric_id": "4.1.8",
|
|
"csv_file": "4.1_Roofline_Performance_Rates.csv",
|
|
"column": "Value",
|
|
"expected_values": [1389.17],
|
|
},
|
|
],
|
|
"MI300": [
|
|
{
|
|
"name": "HBM Bandwidth",
|
|
"metric_id": "4.1.9",
|
|
"csv_file": "4.1_Roofline_Performance_Rates.csv",
|
|
"column": "Value",
|
|
# MI 300 series contains MI 325X GPU which
|
|
# uses improved HBM3E instead of HBM3 used in
|
|
# MI 300X GPU. Hence, multiple expected values
|
|
# to cover both cases.
|
|
# MI 308 has lower bandwidth.
|
|
# MI 300X: 3910.62 GB/s
|
|
# MI 325X: 4287.31 GB/s
|
|
# MI 308: 2003.45 GB/s
|
|
"expected_values": [2003.45, 3910.62, 4287.31],
|
|
},
|
|
],
|
|
"MI350": [
|
|
{
|
|
"name": "HBM Bandwidth",
|
|
"metric_id": "4.1.10",
|
|
"csv_file": "4.1_Roofline_Performance_Rates.csv",
|
|
"column": "Value",
|
|
"expected_values": [5690.42],
|
|
},
|
|
],
|
|
# Ignore warmup dispatch
|
|
# Collect roofline block
|
|
"profile_options": ["-d", "2-1001", "-b", "4"],
|
|
"roof": True,
|
|
}
|
|
}
|
|
|
|
|
|
@pytest.mark.path
|
|
def test_validate_metrics(
|
|
binary_handler_profile_rocprof_compute, binary_handler_analyze_rocprof_compute
|
|
):
|
|
for workload in VALIDATE_METRICS.keys():
|
|
metrics = VALIDATE_METRICS[workload].get(soc, [])
|
|
metric_ids = [metric["metric_id"] for metric in metrics]
|
|
if not metric_ids:
|
|
print(
|
|
f"Skipping metric validation for {workload} on {soc}. "
|
|
"No metrics to validate."
|
|
)
|
|
continue
|
|
|
|
profile_workload_dir = test_utils.get_output_dir(param_id=f"{workload}_profile")
|
|
analysis_workload_dir = test_utils.get_output_dir(
|
|
param_id=f"{workload}_analysis"
|
|
)
|
|
try:
|
|
# Ensure non zero length of profile df
|
|
options = VALIDATE_METRICS[workload].get("profile_options", [])
|
|
_ = binary_handler_profile_rocprof_compute(
|
|
config,
|
|
profile_workload_dir,
|
|
options,
|
|
check_success=True,
|
|
roof=VALIDATE_METRICS[workload].get("roof", False),
|
|
app_name=workload,
|
|
)
|
|
_ = test_utils.check_csv_files(
|
|
profile_workload_dir, num_devices=1, num_kernels=1
|
|
)
|
|
|
|
# Check whether metric values are correct
|
|
code = binary_handler_analyze_rocprof_compute([
|
|
"analyze",
|
|
"--output-name",
|
|
f"{analysis_workload_dir}",
|
|
"--output-format",
|
|
"csv",
|
|
"-b",
|
|
*metric_ids,
|
|
"--path",
|
|
profile_workload_dir,
|
|
])
|
|
assert code == 0
|
|
|
|
for metric in metrics:
|
|
actual = pd.read_csv(f"{analysis_workload_dir}/{metric['csv_file']}")[
|
|
metric["column"]
|
|
].values[0]
|
|
expected_values = metric["expected_values"]
|
|
# 5% tolerance in checking - assert if actual matches any expected value
|
|
matches = [
|
|
abs(actual - expected) / expected <= 0.05
|
|
for expected in expected_values
|
|
]
|
|
diffs = [(abs(actual - exp) / exp * 100) for exp in expected_values]
|
|
assert any(matches), (
|
|
f"{metric['name']} ({metric['metric_id']}): "
|
|
f"actual={actual}, expected_values={expected_values}, "
|
|
f"diffs={diffs} (tolerance: 5%)"
|
|
)
|
|
finally:
|
|
test_utils.clean_output_dir(config["cleanup"], analysis_workload_dir)
|
|
test_utils.clean_output_dir(config["cleanup"], profile_workload_dir)
|