#!/usr/bin/env python3 # # Copyright (c) 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 ctypes import json import time import unittest import common.common as common from common.common import ERROR_MAP, FAIL, PASS, amdsmi # error_map is derived once from the AmdSmiStatus enum in common.common (single # source of truth); it was previously a hand-maintained duplicate here. error_map = ERROR_MAP class TestGpuBenchmark(unittest.TestCase): """ Standalone Performance testing class for AMDSMI Python APIs. This class does NOT inherit from TestAmdSmiPython to avoid running all regular tests. It only runs performance-specific tests. """ @classmethod def setUpClass(cls): # Shared Common instance for logging parity with the unit/integration # tests (print_func_name, etc.). Created once per class, as they do. cls.common = common.Common(common.verbose) # Print the device header (virtualization / asic / board info) once per run, # the same way the regular tests do via Common.print_device_header(). It uses # the info Common cached at construction (no extra hardware calls) and # self-gates on verbosity, so nothing is emitted in quiet mode. for i in range(len(cls.common.asic_info)): cls.common.print_device_header(i) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Performance test configuration - initialized once self.perf_iterations = 11 # Number of iterations for each performance test self.perf_warmup_iterations = 3 # Number of warmup iterations self.perf_results = {} # Store performance results # Constants - set once instead of in setUp() self.TODO_SKIP_FAIL = False self.TODO_SKIP_NOT_COMPLETE = False self.PASS = PASS self.FAIL = FAIL # Do NOT initialize amdsmi or enumerate hardware here. __init__ runs at # test-discovery time (including for `--list`), and hardware init must # not happen during collection. setUp() performs the real amdsmi_init() # before each test. self.processors = [] def setUp(self): """Setup for performance tests - re-initialize AMDSMI before each test.""" # Re-initialize AMDSMI for each test try: amdsmi.amdsmi_init() if not self.processors: # Only get processors if not already set self.processors = amdsmi.amdsmi_get_processor_handles() except Exception as e: self.common.print(f"ERROR: Failed to initialize AMDSMI in setUp: {e}") raise def tearDown(self): """Cleanup after performance tests.""" try: amdsmi.amdsmi_shut_down() except Exception: pass # Ignore cleanup errors def _log_test_start(self, api_name, device_type, device_id, **kwargs): """Helper method to log the start of a test.""" extra_info = " ".join([f"{k}={v}" for k, v in kwargs.items()]) self.common.print(f"Testing {api_name} on {device_type} {device_id} {extra_info}".strip()) def _log_test_end(self, api_name, device_type, device_id, stats, **kwargs): """Helper method to log the end of a test.""" if stats: self.common.print( f"Completed {api_name} on {device_type} {device_id}: {stats.get('mean_time_ms', 0):.3f}ms avg" ) def _print_performance_results(self, stats): """Helper method to print performance results.""" self.common.print( f" Performance: {stats['mean_time_ms']:.3f}ms avg, {stats['min_time_ms']:.3f}ms min, {stats['max_time_ms']:.3f}ms max" ) def _log_test_completion(self, device_type, device_id, extra_info=""): """Helper method to log test completion.""" extra_msg = f" - {extra_info}" if extra_info else "" self.common.print(f" {device_type} {device_id}: Test completed{extra_msg}") def _log_performance_summary(self, api_name, device_type_plural, test_name): """Helper method to log performance summary.""" self.common.print(f"Performance test completed for {api_name} on {device_type_plural}") self.common.print("") # Add empty line for readability def _print(self, msg, result): """Helper method for printing test results.""" if isinstance(result, dict) or isinstance(result, list): if msg: self.common.print(msg) self.common.print(json.dumps(result, sort_keys=False, indent=4, default=str)) else: self.common.print(f"{msg}: {result}" if msg else result) def _print_api_result(self, api_func, processor_id, *args, label_prefix="gpu", **kwargs): """ Helper method to call an API and print its result before performance measurement. Args: api_func: The API function to call processor_id: The processor/GPU ID *args: Arguments to pass to the API label_prefix: Prefix for the label (default: "gpu") **kwargs: Keyword arguments to pass to the API """ if self.common.verbose <= common.VERBOSITY_QUIET: return func_name = api_func.__name__ msg = f"### test {func_name}({label_prefix}={processor_id})" try: result = api_func(*args, **kwargs) self._print(msg, result) except Exception: self.common.print(msg) # Don't raise - let the performance test measure the errors pass def _run_performance_assertions(self, stats, api_name): """Helper method to run assertions on performance test statistics.""" # Basic performance test assertions self.assertIsInstance(stats, dict, f"Stats should be a dictionary for {api_name}") self.assertIn("iterations", stats, f"Stats should contain iterations for {api_name}") self.assertIn( "successful_runs", stats, f"Stats should contain successful_runs for {api_name}" ) self.assertIn("error_count", stats, f"Stats should contain error_count for {api_name}") # If there were successful runs, check performance metrics if stats.get("successful_runs", 0) > 0: self.assertIn( "mean_time_ms", stats, f"Stats should contain mean_time_ms for {api_name}" ) self.assertIn("min_time_ms", stats, f"Stats should contain min_time_ms for {api_name}") self.assertIn("max_time_ms", stats, f"Stats should contain max_time_ms for {api_name}") self.assertGreaterEqual( stats["mean_time_ms"], 0, f"Mean time should be non-negative for {api_name}" ) self.assertGreaterEqual( stats["min_time_ms"], 0, f"Min time should be non-negative for {api_name}" ) self.assertGreaterEqual( stats["max_time_ms"], 0, f"Max time should be non-negative for {api_name}" ) def _measure_api_performance(self, api_func, api_name, *args, **kwargs): """ Measure the performance of an AMDSMI API function. Args: api_func: The API function to measure api_name: Human-readable name of the API *args: Arguments to pass to the API function **kwargs: Keyword arguments to pass to the API function Returns: dict: Performance statistics including min, max, mean, median times """ errors = [] # Warmup iterations for _ in range(self.perf_warmup_iterations): try: api_func(*args, **kwargs) except Exception: pass # Ignore warmup errors # Bulk measurement - measure total time with counters outside the loop bulk_start_time = time.perf_counter() for i in range(self.perf_iterations): try: api_func(*args, **kwargs) except Exception as e: errors.append({"iteration": i, "error_info": str(e)}) bulk_end_time = time.perf_counter() # Calculate timing from bulk measurement bulk_total_time_ms = (bulk_end_time - bulk_start_time) * 1000 bulk_avg_time_ms = bulk_total_time_ms / self.perf_iterations error_count = len(errors) # Calculate statistics successful_runs = self.perf_iterations - error_count stats = { "api_name": api_name, "iterations": self.perf_iterations, "errors": errors, "error_count": error_count, "successful_runs": successful_runs, "total_time_ms": bulk_total_time_ms, "avg_time_ms": bulk_avg_time_ms, "min_time_ms": bulk_avg_time_ms, # Single measurement, so min=max=avg "max_time_ms": bulk_avg_time_ms, "mean_time_ms": bulk_avg_time_ms, "median_time_ms": bulk_avg_time_ms, } # Store results self.perf_results[api_name] = stats self.common.print( f"Performance {api_name}: {bulk_avg_time_ms:.3f}ms avg, {error_count} errors" ) return stats def test_performance_clean_gpu_local_data(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_clean_gpu_local_data", "Processor", i) self._print_api_result(amdsmi.amdsmi_clean_gpu_local_data, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_clean_gpu_local_data, f"clean_gpu_local_data_processor_{i}", processor ) self.perf_results[f"clean_gpu_local_data_processor_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_clean_gpu_local_data", "Processors", "clean_gpu_local_data" ) def test_performance_get_clk_freq(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_get_clk_freq as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): for clk_type_name, clk_type, clk_cond in common.CLK_TYPES: if not clk_cond: continue self._log_test_start("amdsmi_get_clk_freq", "Processor", i, clk_type=clk_type_name) self._print_api_result(amdsmi.amdsmi_get_clk_freq, i, processor, clk_type) stats = self._measure_api_performance( amdsmi.amdsmi_get_clk_freq, f"get_clk_freq_processor_{i}_type_{clk_type_name}", processor, clk_type, ) self.perf_results[f"get_clk_freq_processor_{i}_type_{clk_type_name}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} clk_type={clk_type_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("amdsmi_get_clk_freq", "Processors", "get_clk_freq") def test_performance_get_clock_info(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_get_clock_info as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): for clk_type_name, clk_type, clk_cond in common.CLK_TYPES: if not clk_cond: continue self._log_test_start( "amdsmi_get_clock_info", "Processor", i, clk_type=clk_type_name ) self._print_api_result(amdsmi.amdsmi_get_clock_info, i, processor, clk_type) stats = self._measure_api_performance( amdsmi.amdsmi_get_clock_info, f"get_clock_info_processor_{i}_type_{clk_type_name}", processor, clk_type, ) self.perf_results[f"get_clock_info_processor_{i}_type_{clk_type_name}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} clk_type={clk_type_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("amdsmi_get_clock_info", "Processors", "get_clock_info") def test_performance_get_energy_count(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_get_energy_count as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_energy_count", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_energy_count, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_energy_count, f"get_energy_count_processor_{i}", processor ) self.perf_results[f"get_energy_count_processor_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("amdsmi_get_energy_count", "Processors", "get_energy_count") def test_performance_get_esmi_err_msg(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest("Skipping test_get_esmi_err_msg as it fails (Unknown Error).") for status_type_name, status_type, status_cond in common.STATUS_TYPES: self._log_test_start("amdsmi_get_esmi_err_msg", "Status", status_type_name) stats = self._measure_api_performance( amdsmi.amdsmi_get_esmi_err_msg, f"get_esmi_err_msg_status_{status_type_name}", status_type, ) self.perf_results[f"get_esmi_err_msg_status_{status_type_name}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Status {status_type_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Status", status_type_name) self._log_performance_summary("amdsmi_get_esmi_err_msg", "Status types", "get_esmi_err_msg") def test_performance_get_fw_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_fw_info", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_fw_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_fw_info, f"get_fw_info_processor_{i}", processor ) self.perf_results[f"get_fw_info_processor_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("amdsmi_get_fw_info", "Processors", "get_fw_info") def test_performance_get_gpu_accelerator_partition_profile(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_accelerator_partition_profile", "Processor", i) self._print_api_result( amdsmi.amdsmi_get_gpu_accelerator_partition_profile, i, processor ) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_accelerator_partition_profile, f"get_gpu_accelerator_partition_profile_processor_{i}", processor, ) self.perf_results[f"get_gpu_accelerator_partition_profile_processor_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_accelerator_partition_profile", "Processors", "get_gpu_accelerator_partition_profile", ) def test_performance_get_gpu_accelerator_partition_profile_config(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start( "amdsmi_get_gpu_accelerator_partition_profile_config", "Processor", i ) self._print_api_result( amdsmi.amdsmi_get_gpu_accelerator_partition_profile_config, i, processor ) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_accelerator_partition_profile_config, f"get_gpu_accelerator_partition_profile_config_processor_{i}", processor, ) self.perf_results[f"get_gpu_accelerator_partition_profile_config_processor_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_accelerator_partition_profile_config", "Processors", "get_gpu_accelerator_partition_profile_config", ) def test_performance_get_gpu_activity(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_get_gpu_activity as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_activity", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_activity, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_activity, f"get_gpu_activity_processor_{i}", processor ) self.perf_results[f"get_gpu_activity_processor_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("amdsmi_get_gpu_activity", "Processors", "get_gpu_activity") def test_performance_get_gpu_asic_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_asic_info", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_gpu_asic_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_asic_info, f"get_gpu_asic_info_gpu_{i}", processor ) self.perf_results[f"get_gpu_asic_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_get_gpu_asic_info", "GPUs", "get_gpu_asic_info") def test_performance_get_gpu_bad_page_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_bad_page_info", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_gpu_bad_page_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_bad_page_info, f"get_gpu_bad_page_info_gpu_{i}", processor ) self.perf_results[f"get_gpu_bad_page_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary( "amdsmi_get_gpu_bad_page_info", "GPUs", "get_gpu_bad_page_info" ) def test_performance_get_gpu_bad_page_threshold(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_bad_page_threshold", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_gpu_bad_page_threshold, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_bad_page_threshold, f"get_gpu_bad_page_threshold_gpu_{i}", processor, ) self.perf_results[f"get_gpu_bad_page_threshold_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary( "amdsmi_get_gpu_bad_page_threshold", "GPUs", "get_gpu_bad_page_threshold" ) def test_performance_get_gpu_bdf_id(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_bdf_id", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_gpu_bdf_id, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_bdf_id, f"get_gpu_bdf_id_gpu_{i}", processor ) self.perf_results[f"get_gpu_bdf_id_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_get_gpu_bdf_id", "GPUs", "get_gpu_bdf_id") def test_performance_get_gpu_board_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_board_info", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_gpu_board_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_board_info, f"get_gpu_board_info_gpu_{i}", processor ) self.perf_results[f"get_gpu_board_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_get_gpu_board_info", "GPUs", "get_gpu_board_info") def test_performance_get_gpu_cache_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_cache_info", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_gpu_cache_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_cache_info, f"get_gpu_cache_info_gpu_{i}", processor ) self.perf_results[f"get_gpu_cache_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_get_gpu_cache_info", "GPUs", "get_gpu_cache_info") def test_performance_get_gpu_compute_partition(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_compute_partition", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_gpu_compute_partition, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_compute_partition, f"get_gpu_compute_partition_gpu_{i}", processor, ) self.perf_results[f"get_gpu_compute_partition_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary( "amdsmi_get_gpu_compute_partition", "GPUs", "get_gpu_compute_partition" ) def test_performance_get_gpu_compute_process_gpus(self): self.common.print_func_name("") if self.TODO_SKIP_NOT_COMPLETE: self.skipTest( "Skipping test_get_gpu_compute_process_gpus as it is not complete (Inval Error)." ) pid = 0 self._log_test_start("amdsmi_get_gpu_compute_process_gpus", "Process", pid) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_compute_process_gpus, f"get_gpu_compute_process_gpus_pid_{pid}", pid, ) self.perf_results[f"get_gpu_compute_process_gpus_pid_{pid}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" PID {pid}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Process", pid) self._log_performance_summary( "amdsmi_get_gpu_compute_process_gpus", "Processes", "get_gpu_compute_process_gpus" ) def test_performance_get_gpu_compute_process_info(self): self.common.print_func_name("") self._log_test_start("amdsmi_get_gpu_compute_process_info", "System", "global") stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_compute_process_info, "get_gpu_compute_process_info_system" ) self.perf_results["get_gpu_compute_process_info_system"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" System: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("System", "global") self._log_performance_summary( "amdsmi_get_gpu_compute_process_info", "System", "get_gpu_compute_process_info" ) def test_performance_get_gpu_compute_process_info_by_pid(self): self.common.print_func_name("") if self.TODO_SKIP_NOT_COMPLETE: self.skipTest( "Skipping test_get_gpu_compute_process_info_by_pid as it not complete (Device not found)." ) pid = 0 self._log_test_start("amdsmi_get_gpu_compute_process_info_by_pid", "Process", pid) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_compute_process_info_by_pid, f"get_gpu_compute_process_info_by_pid_{pid}", pid, ) self.perf_results[f"get_gpu_compute_process_info_by_pid_{pid}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" PID {pid}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Process", pid) self._log_performance_summary( "amdsmi_get_gpu_compute_process_info_by_pid", "Processes", "get_gpu_compute_process_info_by_pid", ) def test_performance_get_gpu_device_bdf(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_device_bdf", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_gpu_device_bdf, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_device_bdf, f"get_gpu_device_bdf_gpu_{i}", processor ) self.perf_results[f"get_gpu_device_bdf_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_get_gpu_device_bdf", "GPUs", "get_gpu_device_bdf") def test_performance_get_gpu_device_uuid(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_device_uuid", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_gpu_device_uuid, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_device_uuid, f"get_gpu_device_uuid_gpu_{i}", processor ) self.perf_results[f"get_gpu_device_uuid_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_get_gpu_device_uuid", "GPUs", "get_gpu_device_uuid") def test_performance_get_gpu_driver_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_driver_info", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_driver_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_driver_info, f"get_gpu_driver_info_gpu_{i}", processor ) self.perf_results[f"get_gpu_driver_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_driver_info", "Processors", "get_gpu_driver_info" ) def test_performance_get_gpu_ecc_count(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): for gpu_block_name, gpu_block, gpu_block_cond in common.GPU_BLOCKS: self._log_test_start( "amdsmi_get_gpu_ecc_count", "Processor", i, block=gpu_block_name ) self._print_api_result(amdsmi.amdsmi_get_gpu_ecc_count, i, processor, gpu_block) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_ecc_count, f"get_gpu_ecc_count_gpu_{i}_block_{gpu_block_name}", processor, gpu_block, ) self.perf_results[f"get_gpu_ecc_count_gpu_{i}_block_{gpu_block_name}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} block {gpu_block_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i, f"block={gpu_block_name}") self._log_performance_summary("amdsmi_get_gpu_ecc_count", "Processors", "get_gpu_ecc_count") def test_performance_get_gpu_ecc_enabled(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_ecc_enabled", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_ecc_enabled, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_ecc_enabled, f"get_gpu_ecc_enabled_gpu_{i}", processor ) self.perf_results[f"get_gpu_ecc_enabled_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_ecc_enabled", "Processors", "get_gpu_ecc_enabled" ) def test_performance_get_gpu_ecc_status(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest("Skipping test_performance_get_gpu_ecc_status as it fails.") for i, processor in enumerate(self.processors): for gpu_block_name, gpu_block, gpu_block_cond in common.GPU_BLOCKS: self._log_test_start( "amdsmi_get_gpu_ecc_status", "Processor", i, block=gpu_block_name ) self._print_api_result(amdsmi.amdsmi_get_gpu_ecc_status, i, processor, gpu_block) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_ecc_status, f"get_gpu_ecc_status_gpu_{i}_block_{gpu_block_name}", processor, gpu_block, ) self.perf_results[f"get_gpu_ecc_status_gpu_{i}_block_{gpu_block_name}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} block {gpu_block_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i, f"block={gpu_block_name}") self._log_performance_summary( "amdsmi_get_gpu_ecc_status", "Processors", "get_gpu_ecc_status" ) def test_performance_get_gpu_enumeration_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_enumeration_info", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_enumeration_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_enumeration_info, f"get_gpu_enumeration_info_gpu_{i}", processor, ) self.perf_results[f"get_gpu_enumeration_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_enumeration_info", "Processors", "get_gpu_enumeration_info" ) def test_performance_get_gpu_fan_rpms(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_fan_rpms", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_fan_rpms, i, processor, sensor_idx=0) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_fan_rpms, f"get_gpu_fan_rpms_gpu_{i}", processor, 0 ) self.perf_results[f"get_gpu_fan_rpms_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("amdsmi_get_gpu_fan_rpms", "Processors", "get_gpu_fan_rpms") def test_performance_get_gpu_id(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_id", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_id, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_id, f"get_gpu_id_gpu_{i}", processor ) self.perf_results[f"get_gpu_id_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("amdsmi_get_gpu_id", "Processors", "get_gpu_id") def test_performance_get_gpu_kfd_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_kfd_info", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_kfd_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_kfd_info, f"get_gpu_kfd_info_gpu_{i}", processor ) self.perf_results[f"get_gpu_kfd_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("amdsmi_get_gpu_kfd_info", "Processors", "get_gpu_kfd_info") def test_performance_get_gpu_mem_overdrive_level(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_mem_overdrive_level", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_mem_overdrive_level, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_mem_overdrive_level, f"get_gpu_mem_overdrive_level_gpu_{i}", processor, ) self.perf_results[f"get_gpu_mem_overdrive_level_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_mem_overdrive_level", "Processors", "get_gpu_mem_overdrive_level" ) def test_performance_get_gpu_memory_partition(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_memory_partition", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_memory_partition, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_memory_partition, f"get_gpu_memory_partition_gpu_{i}", processor, ) self.perf_results[f"get_gpu_memory_partition_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_memory_partition", "Processors", "get_gpu_memory_partition" ) def test_performance_get_gpu_memory_partition_config(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_get_gpu_memory_partition_config as it fails on MI300." ) for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_memory_partition_config", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_memory_partition_config, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_memory_partition_config, f"get_gpu_memory_partition_config_gpu_{i}", processor, ) self.perf_results[f"get_gpu_memory_partition_config_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_memory_partition_config", "Processors", "get_gpu_memory_partition_config", ) def test_performance_get_gpu_memory_reserved_pages(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_memory_reserved_pages", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_memory_reserved_pages, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_memory_reserved_pages, f"get_gpu_memory_reserved_pages_gpu_{i}", processor, ) self.perf_results[f"get_gpu_memory_reserved_pages_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_memory_reserved_pages", "Processors", "get_gpu_memory_reserved_pages" ) def test_performance_get_gpu_memory_total(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): for memory_type_name, memory_type, memory_type_cond in common.MEMORY_TYPES: self._log_test_start( "amdsmi_get_gpu_memory_total", "Processor", i, mem_type=memory_type_name ) self._print_api_result( amdsmi.amdsmi_get_gpu_memory_total, i, processor, memory_type ) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_memory_total, f"get_gpu_memory_total_gpu_{i}_type_{memory_type_name}", processor, memory_type, ) self.perf_results[f"get_gpu_memory_total_gpu_{i}_type_{memory_type_name}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} mem_type {memory_type_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i, f"mem_type={memory_type_name}") self._log_performance_summary( "amdsmi_get_gpu_memory_total", "Processors", "get_gpu_memory_total" ) def test_performance_get_gpu_memory_usage(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): for memory_type_name, memory_type, memory_type_cond in common.MEMORY_TYPES: self._log_test_start( "amdsmi_get_gpu_memory_usage", "Processor", i, mem_type=memory_type_name ) self._print_api_result( amdsmi.amdsmi_get_gpu_memory_usage, i, processor, memory_type ) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_memory_usage, f"get_gpu_memory_usage_gpu_{i}_type_{memory_type_name}", processor, memory_type, ) self.perf_results[f"get_gpu_memory_usage_gpu_{i}_type_{memory_type_name}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} mem_type {memory_type_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i, f"mem_type={memory_type_name}") self._log_performance_summary( "amdsmi_get_gpu_memory_usage", "Processors", "get_gpu_memory_usage" ) def test_performance_get_gpu_metrics_header_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_metrics_header_info", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_metrics_header_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_metrics_header_info, f"get_gpu_metrics_header_info_gpu_{i}", processor, ) self.perf_results[f"get_gpu_metrics_header_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_metrics_header_info", "Processors", "get_gpu_metrics_header_info" ) def test_performance_get_gpu_metrics_info(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_get_gpu_metrics_info as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_metrics_info", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_metrics_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_metrics_info, f"get_gpu_metrics_info_gpu_{i}", processor ) self.perf_results[f"get_gpu_metrics_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_metrics_info", "Processors", "get_gpu_metrics_info" ) def test_performance_get_gpu_od_volt_curve_regions(self): self.common.print_func_name("") num_region = 10 for i, processor in enumerate(self.processors): self._log_test_start( "amdsmi_get_gpu_od_volt_curve_regions", "Processor", i, num_region=num_region ) self._print_api_result(amdsmi.amdsmi_get_gpu_od_volt_curve_regions, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_od_volt_curve_regions, f"get_gpu_od_volt_curve_regions_gpu_{i}", processor, num_region, ) self.perf_results[f"get_gpu_od_volt_curve_regions_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i, f"num_region={num_region}") self._log_performance_summary( "amdsmi_get_gpu_od_volt_curve_regions", "Processors", "get_gpu_od_volt_curve_regions" ) def test_performance_get_gpu_od_volt_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_od_volt_info", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_od_volt_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_od_volt_info, f"get_gpu_od_volt_info_gpu_{i}", processor ) self.perf_results[f"get_gpu_od_volt_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_od_volt_info", "Processors", "get_gpu_od_volt_info" ) def test_performance_get_gpu_overdrive_level(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_overdrive_level", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_overdrive_level, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_overdrive_level, f"get_gpu_overdrive_level_gpu_{i}", processor ) self.perf_results[f"get_gpu_overdrive_level_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_overdrive_level", "Processors", "get_gpu_overdrive_level" ) def test_performance_get_gpu_pci_bandwidth(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_get_gpu_pci_bandwidth as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_pci_bandwidth", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_pci_bandwidth, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_pci_bandwidth, f"get_gpu_pci_bandwidth_gpu_{i}", processor ) self.perf_results[f"get_gpu_pci_bandwidth_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_pci_bandwidth", "Processors", "get_gpu_pci_bandwidth" ) def test_performance_get_gpu_pci_replay_counter(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_pci_replay_counter", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_pci_replay_counter, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_pci_replay_counter, f"get_gpu_pci_replay_counter_gpu_{i}", processor, ) self.perf_results[f"get_gpu_pci_replay_counter_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_pci_replay_counter", "Processors", "get_gpu_pci_replay_counter" ) def test_performance_get_gpu_pci_throughput(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_pci_throughput", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_pci_throughput, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_pci_throughput, f"get_gpu_pci_throughput_gpu_{i}", processor ) self.perf_results[f"get_gpu_pci_throughput_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_pci_throughput", "Processors", "get_gpu_pci_throughput" ) def test_performance_get_gpu_perf_level(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_perf_level", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_perf_level, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_perf_level, f"get_gpu_perf_level_gpu_{i}", processor ) self.perf_results[f"get_gpu_perf_level_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_perf_level", "Processors", "get_gpu_perf_level" ) def test_performance_get_gpu_pm_metrics_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_pm_metrics_info", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_pm_metrics_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_pm_metrics_info, f"get_gpu_pm_metrics_info_gpu_{i}", processor ) self.perf_results[f"get_gpu_pm_metrics_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_pm_metrics_info", "Processors", "get_gpu_pm_metrics_info" ) def test_performance_get_gpu_power_profile_presets(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_power_profile_presets", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_power_profile_presets, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_power_profile_presets, f"get_gpu_power_profile_presets_gpu_{i}", processor, 0, ) self.perf_results[f"get_gpu_power_profile_presets_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_power_profile_presets", "Processors", "get_gpu_power_profile_presets" ) def test_performance_get_gpu_process_isolation(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_process_isolation", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_process_isolation, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_process_isolation, f"get_gpu_process_isolation_gpu_{i}", processor, ) self.perf_results[f"get_gpu_process_isolation_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_process_isolation", "Processors", "get_gpu_process_isolation" ) def test_performance_get_gpu_process_list(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_process_list", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_process_list, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_process_list, f"get_gpu_process_list_gpu_{i}", processor ) self.perf_results[f"get_gpu_process_list_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_process_list", "Processors", "get_gpu_process_list" ) def test_performance_get_gpu_ras_block_features_enabled(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_ras_block_features_enabled", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_ras_block_features_enabled, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_ras_block_features_enabled, f"get_gpu_ras_block_features_enabled_gpu_{i}", processor, ) self.perf_results[f"get_gpu_ras_block_features_enabled_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_ras_block_features_enabled", "Processors", "get_gpu_ras_block_features_enabled", ) def test_performance_get_gpu_ras_feature_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_ras_feature_info", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_ras_feature_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_ras_feature_info, f"get_gpu_ras_feature_info_gpu_{i}", processor, ) self.perf_results[f"get_gpu_ras_feature_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_ras_feature_info", "Processors", "get_gpu_ras_feature_info" ) def test_performance_get_gpu_reg_table_info(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest("Skipping test_performance_get_gpu_reg_table_info as it fails on MI300.") for i, processor in enumerate(self.processors): for reg_type_name, reg_type, reg_type_cond in common.REG_TYPES: self._log_test_start( "amdsmi_get_gpu_reg_table_info", "Processor", i, reg_type=reg_type_name ) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_reg_table_info, f"get_gpu_reg_table_info_gpu_{i}_type_{reg_type_name}", processor, reg_type, ) self.perf_results[f"get_gpu_reg_table_info_gpu_{i}_type_{reg_type_name}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} reg_type {reg_type_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i, f"reg_type={reg_type_name}") self._log_performance_summary( "amdsmi_get_gpu_reg_table_info", "Processors", "get_gpu_reg_table_info" ) def test_performance_get_gpu_revision(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_revision", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_revision, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_revision, f"get_gpu_revision_gpu_{i}", processor ) self.perf_results[f"get_gpu_revision_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("amdsmi_get_gpu_revision", "Processors", "get_gpu_revision") def test_performance_get_gpu_subsystem_id(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_subsystem_id", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_subsystem_id, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_subsystem_id, f"get_gpu_subsystem_id_gpu_{i}", processor ) self.perf_results[f"get_gpu_subsystem_id_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_subsystem_id", "Processors", "get_gpu_subsystem_id" ) def test_performance_get_gpu_subsystem_name(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_subsystem_name", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_subsystem_name, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_subsystem_name, f"get_gpu_subsystem_name_gpu_{i}", processor ) self.perf_results[f"get_gpu_subsystem_name_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_subsystem_name", "Processors", "get_gpu_subsystem_name" ) def test_performance_get_gpu_topo_numa_affinity(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_topo_numa_affinity", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_topo_numa_affinity, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_topo_numa_affinity, f"get_gpu_topo_numa_affinity_gpu_{i}", processor, ) self.perf_results[f"get_gpu_topo_numa_affinity_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_topo_numa_affinity", "Processors", "get_gpu_topo_numa_affinity" ) def test_performance_get_gpu_total_ecc_count(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_total_ecc_count", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_total_ecc_count, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_total_ecc_count, f"get_gpu_total_ecc_count_gpu_{i}", processor ) self.perf_results[f"get_gpu_total_ecc_count_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_total_ecc_count", "Processors", "get_gpu_total_ecc_count" ) def test_performance_get_gpu_vbios_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_vbios_info", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_vbios_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_vbios_info, f"get_gpu_vbios_info_gpu_{i}", processor ) self.perf_results[f"get_gpu_vbios_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_vbios_info", "Processors", "get_gpu_vbios_info" ) def test_performance_get_gpu_vendor_name(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_vendor_name", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_vendor_name, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_vendor_name, f"get_gpu_vendor_name_gpu_{i}", processor ) self.perf_results[f"get_gpu_vendor_name_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_vendor_name", "Processors", "get_gpu_vendor_name" ) def test_performance_get_gpu_virtualization_mode(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_virtualization_mode", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_virtualization_mode, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_virtualization_mode, f"get_gpu_virtualization_mode_gpu_{i}", processor, ) self.perf_results[f"get_gpu_virtualization_mode_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_virtualization_mode", "Processors", "get_gpu_virtualization_mode" ) def test_performance_get_gpu_volt_metric(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): for voltage_type_name, voltage_type, voltage_type_cond in common.VOLTAGE_TYPES: for ( voltage_metric_name, voltage_metric, voltage_metric_cond, ) in common.VOLTAGE_METRICS: self._log_test_start( "amdsmi_get_gpu_volt_metric", "Processor", i, volt_type=voltage_type_name, volt_metric=voltage_metric_name, ) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_volt_metric, f"get_gpu_volt_metric_gpu_{i}_type_{voltage_type_name}_metric_{voltage_metric_name}", processor, voltage_type, voltage_metric, ) self.perf_results[ f"get_gpu_volt_metric_gpu_{i}_type_{voltage_type_name}_metric_{voltage_metric_name}" ] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} volt_type {voltage_type_name} volt_metric {voltage_metric_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion( "Processor", i, f"volt_type={voltage_type_name}, volt_metric={voltage_metric_name}", ) self._log_performance_summary( "amdsmi_get_gpu_volt_metric", "Processors", "get_gpu_volt_metric" ) def test_performance_get_gpu_vram_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_vram_info", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_vram_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_vram_info, f"get_gpu_vram_info_gpu_{i}", processor ) self.perf_results[f"get_gpu_vram_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("amdsmi_get_gpu_vram_info", "Processors", "get_gpu_vram_info") def test_performance_get_gpu_vram_usage(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_vram_usage", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_vram_usage, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_vram_usage, f"get_gpu_vram_usage_gpu_{i}", processor ) self.perf_results[f"get_gpu_vram_usage_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_vram_usage", "Processors", "get_gpu_vram_usage" ) def test_performance_get_gpu_xcd_counter(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_get_gpu_xcd_counter as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_xcd_counter", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_xcd_counter, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_xcd_counter, f"get_gpu_xcd_counter_gpu_{i}", processor ) self.perf_results[f"get_gpu_xcd_counter_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_xcd_counter", "Processors", "get_gpu_xcd_counter" ) def test_performance_get_gpu_xgmi_link_status(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_get_gpu_xgmi_link_status as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_xgmi_link_status", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_xgmi_link_status, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_xgmi_link_status, f"get_gpu_xgmi_link_status_gpu_{i}", processor, ) self.perf_results[f"get_gpu_xgmi_link_status_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_xgmi_link_status", "Processors", "get_gpu_xgmi_link_status" ) def test_performance_get_lib_version(self): self.common.print_func_name("") self._log_test_start("amdsmi_get_lib_version", "System", "global") # No processor needed for library version try: ret = amdsmi.amdsmi_get_lib_version() self.common.print("### test amdsmi_get_lib_version()") self._print("", ret) except amdsmi.AmdSmiLibraryException as e: self.common.print("### test amdsmi_get_lib_version()") self.common.print(f" Error: {e}") stats = self._measure_api_performance(amdsmi.amdsmi_get_lib_version, "get_lib_version") self.perf_results["get_lib_version"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("System", "global") self._log_performance_summary("amdsmi_get_lib_version", "System", "get_lib_version") def test_performance_get_link_metrics(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_get_link_metrics as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_link_metrics", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_link_metrics, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_link_metrics, f"get_link_metrics_gpu_{i}", processor ) self.perf_results[f"get_link_metrics_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("amdsmi_get_link_metrics", "Processors", "get_link_metrics") def test_performance_get_link_topology_nearest(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): for link_type_name, link_type, link_type_cond in common.LINK_TYPES: self._log_test_start( "amdsmi_get_link_topology_nearest", "Processor", f"{i} link_type({link_type_name})", ) stats = self._measure_api_performance( amdsmi.amdsmi_get_link_topology_nearest, f"get_link_topology_nearest_gpu_{i}_{link_type_name}", processor, link_type, ) self.perf_results[f"get_link_topology_nearest_gpu_{i}_{link_type_name}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} link_type({link_type_name}): All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", f"{i} link_type({link_type_name})") self._log_performance_summary( "amdsmi_get_link_topology_nearest", "Processors", "get_link_topology_nearest" ) def test_performance_get_minmax_bandwidth_between_processors(self): self.common.print_func_name("") for i, gpu_i in enumerate(self.processors): for j, gpu_j in enumerate(self.processors): self._log_test_start( "amdsmi_get_minmax_bandwidth_between_processors", "Bandwidth", f"{i}->{j}" ) stats = self._measure_api_performance( amdsmi.amdsmi_get_minmax_bandwidth_between_processors, f"get_minmax_bandwidth_between_processors_{i}_to_{j}", gpu_i, gpu_j, ) self.perf_results[f"get_minmax_bandwidth_between_processors_{i}_to_{j}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Bandwidth {i}->{j}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Bandwidth", f"{i}->{j}") self._log_performance_summary( "amdsmi_get_minmax_bandwidth_between_processors", "Bandwidth", "get_minmax_bandwidth_between_processors", ) def test_performance_get_pcie_info(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_get_pcie_info as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_pcie_info", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_pcie_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_pcie_info, f"get_pcie_info_gpu_{i}", processor ) self.perf_results[f"get_pcie_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("amdsmi_get_pcie_info", "Processors", "get_pcie_info") def test_performance_get_power_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_power_info", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_power_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_power_info, f"get_power_info_gpu_{i}", processor ) self.perf_results[f"get_power_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_power_info") else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_get_power_info", "GPUs", "get_power_info") def test_performance_get_processor_count_from_handles(self): self.common.print_func_name("") self._log_test_start("amdsmi_get_processor_count_from_handles", "Processors", "all") # Print result for all processors try: ret = amdsmi.amdsmi_get_processor_count_from_handles(self.processors) self.common.print("### test amdsmi_get_processor_count_from_handles()") self._print("", ret) except amdsmi.AmdSmiLibraryException as e: self.common.print("### test amdsmi_get_processor_count_from_handles()") self.common.print(f" Error: {e}") stats = self._measure_api_performance( amdsmi.amdsmi_get_processor_count_from_handles, "get_processor_count_from_handles", self.processors, ) self.perf_results["get_processor_count_from_handles"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_processor_count_from_handles") else: self.common.print( f" All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processors", "all") self._log_performance_summary( "amdsmi_get_processor_count_from_handles", "Processors", "get_processor_count_from_handles", ) def test_performance_get_processor_handle_from_bdf(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_processor_handle_from_bdf", "GPU", i) try: # Get BDF for this processor first bdf = amdsmi.amdsmi_get_gpu_device_bdf(processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_processor_handle_from_bdf, f"get_processor_handle_from_bdf_gpu_{i}", bdf, ) self.perf_results[f"get_processor_handle_from_bdf_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_processor_handle_from_bdf") # Validate that the returned handle matches the original processor ret = amdsmi.amdsmi_get_processor_handle_from_bdf(bdf) if processor.value != ret.value: self.common.print( f" WARNING: GPU {i} - Handle mismatch! Expected: {processor.value}, Received: {ret.value}" ) else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) except Exception as e: self.common.print(f" GPU {i}: Error getting BDF - {e}") self._log_test_completion("GPU", i) self._log_performance_summary( "amdsmi_get_processor_handle_from_bdf", "GPUs", "get_processor_handle_from_bdf" ) def test_performance_get_processor_handles(self): self.common.print_func_name("") self._log_test_start("amdsmi_get_processor_handles", "System", "global") self._print_api_result(amdsmi.amdsmi_get_processor_handles, 0, None) stats = self._measure_api_performance( amdsmi.amdsmi_get_processor_handles, "get_processor_handles" ) self.perf_results["get_processor_handles"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_processor_handles") else: self.common.print( f" All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("System", "global") self._log_performance_summary( "amdsmi_get_processor_handles", "System", "get_processor_handles" ) def test_performance_get_processor_handles_by_type(self): self.common.print_func_name("") socket_handles = amdsmi.amdsmi_get_socket_handles() for index, socket_handle in enumerate(socket_handles): for processor_name, processor_type, processor_cond in common.PROCESSOR_TYPES: self._log_test_start( "amdsmi_get_processor_handles_by_type", "Socket", index, processor_type=processor_name, ) stats = self._measure_api_performance( amdsmi.amdsmi_get_processor_handles_by_type, f"get_processor_handles_by_type_socket_{index}_type_{processor_name}", socket_handle, processor_type, ) self.perf_results[ f"get_processor_handles_by_type_socket_{index}_type_{processor_name}" ] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_processor_handles_by_type") else: self.common.print( f" Socket {index} type {processor_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Socket", index, f"processor_type={processor_name}") self._log_performance_summary( "amdsmi_get_processor_handles_by_type", "Sockets", "get_processor_handles_by_type" ) def test_performance_get_processor_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_processor_info", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_processor_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_processor_info, f"get_processor_info_gpu_{i}", processor ) self.perf_results[f"get_processor_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_processor_info") else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_get_processor_info", "GPUs", "get_processor_info") def test_performance_get_processor_type(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_processor_type", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_processor_type, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_processor_type, f"get_processor_type_gpu_{i}", processor ) self.perf_results[f"get_processor_type_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_processor_type") else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_get_processor_type", "GPUs", "get_processor_type") def test_performance_get_socket_handles(self): self.common.print_func_name("") self._log_test_start("amdsmi_get_socket_handles", "System", "global") self._print_api_result(amdsmi.amdsmi_get_socket_handles, 0, None) stats = self._measure_api_performance( amdsmi.amdsmi_get_socket_handles, "get_socket_handles" ) self.perf_results["get_socket_handles"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_socket_handles") else: self.common.print( f" All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("System", "global") self._log_performance_summary("amdsmi_get_socket_handles", "System", "get_socket_handles") def test_performance_get_socket_info(self): self.common.print_func_name("") sockets = amdsmi.amdsmi_get_socket_handles() for i, socket in enumerate(sockets): self._log_test_start("amdsmi_get_socket_info", "Socket", i) self._print_api_result(amdsmi.amdsmi_get_socket_info, i, socket, label_prefix="socket") stats = self._measure_api_performance( amdsmi.amdsmi_get_socket_info, f"get_socket_info_socket_{i}", socket ) self.perf_results[f"get_socket_info_socket_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_socket_info") else: self.common.print( f" Socket {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Socket", i) self._log_performance_summary("amdsmi_get_socket_info", "Sockets", "get_socket_info") def test_performance_get_temp_metric(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_get_temp_metric as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): for ( temperature_type_name, temperature_type, temperature_type_cond, ) in common.TEMPERATURE_TYPES: for ( temperature_metric_name, temperature_metric, temperature_metric_cond, ) in common.TEMPERATURE_METRICS: self._log_test_start( "amdsmi_get_temp_metric", "GPU", i, temperature_type=temperature_type_name, temperature_metric=temperature_metric_name, ) stats = self._measure_api_performance( amdsmi.amdsmi_get_temp_metric, f"get_temp_metric_gpu_{i}_{temperature_type_name}_{temperature_metric_name}", processor, temperature_type, temperature_metric, ) self.perf_results[ f"get_temp_metric_gpu_{i}_{temperature_type_name}_{temperature_metric_name}" ] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_temp_metric") else: self.common.print( f" GPU {i} {temperature_type_name}/{temperature_metric_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion( "GPU", i, f"temperature_type={temperature_type_name}, temperature_metric={temperature_metric_name}", ) self._log_performance_summary("amdsmi_get_temp_metric", "GPUs", "get_temp_metric") def test_performance_get_threads_per_core(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest("Skipping test_get_threads_per_core as it fails (IO Error).") self._log_test_start("amdsmi_get_threads_per_core", "System", 0) # No processor needed for threads per core try: ret = amdsmi.amdsmi_get_threads_per_core() self.common.print("### test amdsmi_get_threads_per_core()") self._print("", ret) except amdsmi.AmdSmiLibraryException as e: self.common.print("### test amdsmi_get_threads_per_core()") self.common.print(f" Error: {e}") stats = self._measure_api_performance( amdsmi.amdsmi_get_threads_per_core, "get_threads_per_core" ) self.perf_results["get_threads_per_core"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_threads_per_core") else: self.common.print( f" System: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("System", 0) self._log_performance_summary( "amdsmi_get_threads_per_core", "System", "get_threads_per_core" ) def test_performance_get_utilization_count(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_get_utilization_count as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): for ( utilization_counter_type_name, utilization_counter_type, utilization_counter_type_cond, ) in common.UTILIZATION_COUNTER_TYPES: self._log_test_start( "amdsmi_get_utilization_count", "GPU", i, utilization_counter_type=utilization_counter_type_name, ) self._print_api_result(amdsmi.amdsmi_get_utilization_count, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_utilization_count, f"get_utilization_count_gpu_{i}_{utilization_counter_type_name}", processor, [utilization_counter_type], ) self.perf_results[ f"get_utilization_count_gpu_{i}_{utilization_counter_type_name}" ] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_utilization_count") else: self.common.print( f" GPU {i} {utilization_counter_type_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion( "GPU", i, f"utilization_counter_type={utilization_counter_type_name}" ) self._log_performance_summary( "amdsmi_get_utilization_count", "GPUs", "get_utilization_count" ) def test_performance_get_violation_status(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_get_violation_status as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_violation_status", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_violation_status, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_violation_status, f"get_violation_status_gpu_{i}", processor ) self.perf_results[f"get_violation_status_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_violation_status") else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_get_violation_status", "GPUs", "get_violation_status") def test_performance_get_xgmi_info(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_xgmi_info", "GPU", i) self._print_api_result(amdsmi.amdsmi_get_xgmi_info, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_xgmi_info, f"get_xgmi_info_gpu_{i}", processor ) self.perf_results[f"get_xgmi_info_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_xgmi_info") else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_get_xgmi_info", "GPUs", "get_xgmi_info") def test_performance_gpu_counter(self): self.common.print_func_name("") # TODO: redesign before enabling. _measure_api_performance() repeats each call # 14x (3 warmup + 11 iterations); for this stateful workflow that calls # amdsmi_gpu_destroy_counter() 14x on the SAME handle, which double-frees and # aborts the whole process ("free(): double free detected in tcache 2"). A correct # benchmark must create/destroy the counter once and only repeat the idempotent # read/control measurements. (A double amdsmi_gpu_destroy_counter() should also be # handled gracefully by the library rather than corrupting the heap.) self.skipTest( "test_performance_gpu_counter: repeated amdsmi_gpu_destroy_counter double-frees " "the counter handle and aborts the process; needs redesign (see TODO)." ) for i, processor in enumerate(self.processors): for event_type_name, event_type, event_type_cond in common.EVENT_TYPES: self._log_test_start("gpu_counter_workflow", "GPU", i, event_type=event_type_name) # Test Create Counter stats_create = self._measure_api_performance( amdsmi.amdsmi_gpu_create_counter, f"gpu_create_counter_gpu_{i}_{event_type_name}", processor, event_type, ) self.perf_results[f"gpu_create_counter_gpu_{i}_{event_type_name}"] = stats_create if stats_create["successful_runs"] > 0: # Get the event_handle from the first successful run try: event_handle = amdsmi.amdsmi_gpu_create_counter(processor, event_type) # Test Read Counter stats_read = self._measure_api_performance( amdsmi.amdsmi_gpu_read_counter, f"gpu_read_counter_gpu_{i}_{event_type_name}", event_handle, ) self.perf_results[f"gpu_read_counter_gpu_{i}_{event_type_name}"] = ( stats_read ) # Test Control Counter for each command for ( counter_command_name, counter_command, counter_commands_cond, ) in common.COUNTER_COMMANDS: stats_control = self._measure_api_performance( amdsmi.amdsmi_gpu_control_counter, f"gpu_control_counter_gpu_{i}_{event_type_name}_{counter_command_name}", event_handle, counter_command, ) self.perf_results[ f"gpu_control_counter_gpu_{i}_{event_type_name}_{counter_command_name}" ] = stats_control # Test Destroy Counter stats_destroy = self._measure_api_performance( amdsmi.amdsmi_gpu_destroy_counter, f"gpu_destroy_counter_gpu_{i}_{event_type_name}", event_handle, ) self.perf_results[f"gpu_destroy_counter_gpu_{i}_{event_type_name}"] = ( stats_destroy ) except amdsmi.AmdSmiLibraryException as e: self.common.print( f" GPU {i} {event_type_name}: Counter workflow failed - {e}" ) else: self.common.print( f" GPU {i} {event_type_name}: Create counter failed - {stats_create['errors'][0]['error_info'] if stats_create['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i, f"event_type={event_type_name}") self._log_performance_summary("gpu_counter_workflow", "GPUs", "gpu_counter") def test_performance_gpu_counter_group_supported(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): for event_group_name, event_group, event_group_cond in common.EVENT_GROUPS: self._log_test_start( "amdsmi_gpu_counter_group_supported", "GPU", i, event_group=event_group_name ) stats = self._measure_api_performance( amdsmi.amdsmi_gpu_counter_group_supported, f"gpu_counter_group_supported_gpu_{i}_{event_group_name}", processor, event_group, ) self.perf_results[f"gpu_counter_group_supported_gpu_{i}_{event_group_name}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_gpu_counter_group_supported") else: self.common.print( f" GPU {i} {event_group_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i, f"event_group={event_group_name}") self._log_performance_summary( "amdsmi_gpu_counter_group_supported", "GPUs", "gpu_counter_group_supported" ) def test_performance_get_gpu_available_counters(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): for event_group_name, event_group_type, event_group_cond in common.EVENT_GROUPS: self._log_test_start( "amdsmi_get_gpu_available_counters", "GPU", i, event_group=event_group_name ) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_available_counters, f"get_gpu_available_counters_gpu_{i}_event_group_{event_group_name}", processor, event_group_type, ) self.perf_results[ f"get_gpu_available_counters_gpu_{i}_event_group_{event_group_name}" ] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_get_gpu_available_counters") else: self.common.print( f" GPU {i} event_group {event_group_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i, f"event_group={event_group_name}") self._log_performance_summary( "amdsmi_get_gpu_available_counters", "GPUs", "get_gpu_available_counters" ) def test_performance_gpu_validate_ras_eeprom(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest("Skipping test_gpu_validate_ras_eepromas it fails (File Error).") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_gpu_validate_ras_eeprom", "GPU", i) stats = self._measure_api_performance( amdsmi.amdsmi_gpu_validate_ras_eeprom, f"gpu_validate_ras_eeprom_gpu_{i}", processor ) self.perf_results[f"gpu_validate_ras_eeprom_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_gpu_validate_ras_eeprom") else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary( "amdsmi_gpu_validate_ras_eeprom", "GPUs", "gpu_validate_ras_eeprom" ) def test_performance_gpu_xgmi_error_status(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest("Skipping test_gpu_xgmi_error_status as it fails on MI300.") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_gpu_xgmi_error_status", "GPU", i) stats = self._measure_api_performance( amdsmi.amdsmi_gpu_xgmi_error_status, f"gpu_xgmi_error_status_gpu_{i}", processor ) self.perf_results[f"gpu_xgmi_error_status_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_gpu_xgmi_error_status") else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary( "amdsmi_gpu_xgmi_error_status", "GPUs", "gpu_xgmi_error_status" ) def test_performance_init(self): self.common.print_func_name("") self._log_test_start("amdsmi_init", "System", "global") # Note: We need to be careful with init/shutdown as they affect the entire library state stats = self._measure_api_performance(amdsmi.amdsmi_init, "init_system") self.perf_results["init_system"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("System", "global") self._log_performance_summary("amdsmi_init", "System", "init") def test_performance_shutdown(self): self.common.print_func_name("") self._log_test_start("amdsmi_shut_down", "System", "global") # Note: We need to be careful with init/shutdown as they affect the entire library state stats = self._measure_api_performance(amdsmi.amdsmi_shut_down, "shutdown_system") self.perf_results["shutdown_system"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("System", "global") self._log_performance_summary("amdsmi_shut_down", "System", "shutdown") def test_performance_is_P2P_accessible(self): self.common.print_func_name("") for i, gpu_i in enumerate(self.processors): for j, gpu_j in enumerate(self.processors): if i != j: # Test P2P access between different processors self._log_test_start("amdsmi_is_P2P_accessible", "P2P", f"{i}->{j}") stats = self._measure_api_performance( amdsmi.amdsmi_is_P2P_accessible, f"is_P2P_accessible_{i}_to_{j}", gpu_i, gpu_j, ) self.perf_results[f"is_P2P_accessible_{i}_to_{j}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_is_P2P_accessible") else: self.common.print( f" P2P {i}->{j}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("P2P", f"{i}->{j}") self._log_performance_summary("amdsmi_is_P2P_accessible", "P2P", "is_P2P_accessible") def test_performance_gpu_event(self): self.common.print_func_name("") # TODO: redesign before enabling. Like the counter workflow, this measures the # stateful init/stop event-notification calls by repeating them 14x, which can # leak or double-free notification resources. A correct benchmark must init/stop # once and only repeat the idempotent set-mask/get-event measurements. self.skipTest( "test_performance_gpu_event: repeated init/stop of event notification is unsafe " "(resource leak/double-free); needs redesign (see TODO)." ) mask = 1 << (amdsmi.AmdSmiEvtNotificationType.GPU_PRE_RESET - 1) | 1 << ( amdsmi.AmdSmiEvtNotificationType.GPU_POST_RESET - 1 ) timeout_ms = 1000 for i, processor in enumerate(self.processors): self._log_test_start("gpu_event_workflow", "GPU", i) # Test Init stats_init = self._measure_api_performance( amdsmi.amdsmi_init_gpu_event_notification, f"init_gpu_event_notification_gpu_{i}", processor, ) self.perf_results[f"init_gpu_event_notification_gpu_{i}"] = stats_init if stats_init["successful_runs"] > 0: self._print_performance_results(stats_init) # Test Is Enabled stats_enabled = self._measure_api_performance( amdsmi.amdsmi_is_gpu_power_management_enabled, f"is_gpu_power_management_enabled_gpu_{i}", processor, ) self.perf_results[f"is_gpu_power_management_enabled_gpu_{i}"] = stats_enabled self._print_performance_results(stats_enabled) # Test Set Mask stats_set_mask = self._measure_api_performance( amdsmi.amdsmi_set_gpu_event_notification_mask, f"set_gpu_event_notification_mask_gpu_{i}", processor, mask, ) self.perf_results[f"set_gpu_event_notification_mask_gpu_{i}"] = stats_set_mask self._print_performance_results(stats_set_mask) # Test Get Event stats_get = self._measure_api_performance( amdsmi.amdsmi_get_gpu_event_notification, f"get_gpu_event_notification_gpu_{i}", timeout_ms, ) self.perf_results[f"get_gpu_event_notification_gpu_{i}"] = stats_get self._print_performance_results(stats_get) # Test Stop stats_stop = self._measure_api_performance( amdsmi.amdsmi_stop_gpu_event_notification, f"stop_gpu_event_notification_gpu_{i}", processor, ) self.perf_results[f"stop_gpu_event_notification_gpu_{i}"] = stats_stop self._print_performance_results(stats_stop) else: self.common.print( f" GPU {i}: Init failed - skipping remaining event workflow tests - {stats_init['errors'][0]['error_info'] if stats_init['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("gpu_event_workflow", "GPUs", "gpu_event") def test_performance_reset_gpu(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest("Skipping test_performance_reset_gpu as it fails (MI350X, Hang).") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_reset_gpu", "GPU", i) # Note: GPU reset is a critical operation, we may want to handle this carefully stats = self._measure_api_performance( amdsmi.amdsmi_reset_gpu, f"reset_gpu_gpu_{i}", processor, critical_operation=True, # This indicates this is a critical system operation ) self.perf_results[f"reset_gpu_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_reset_gpu") else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_reset_gpu", "GPUs", "reset_gpu") def test_performance_reset_gpu_fan(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): # Test different fan sensors fan_sensors = [0, 1] if i == 0 else [0] for sensor_ind in fan_sensors: self._log_test_start("amdsmi_reset_gpu_fan", "GPU", i, sensor_ind=sensor_ind) stats = self._measure_api_performance( amdsmi.amdsmi_reset_gpu_fan, f"reset_gpu_fan_gpu_{i}_sensor_{sensor_ind}", processor, sensor_ind, ) self.perf_results[f"reset_gpu_fan_gpu_{i}_sensor_{sensor_ind}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_reset_gpu_fan") else: self.common.print( f" GPU {i} sensor {sensor_ind}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i, f"sensor_ind={sensor_ind}") self._log_performance_summary("amdsmi_reset_gpu_fan", "GPUs", "reset_gpu_fan") def test_performance_reset_gpu_xgmi_error(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest("Skipping test_reset_gpu_xgmi_error as it fails on MI300.") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_reset_gpu_xgmi_error", "GPU", i) stats = self._measure_api_performance( amdsmi.amdsmi_reset_gpu_xgmi_error, f"reset_gpu_xgmi_error_gpu_{i}", processor ) self.perf_results[f"reset_gpu_xgmi_error_gpu_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_reset_gpu_xgmi_error") else: self.common.print( f" GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("GPU", i) self._log_performance_summary("amdsmi_reset_gpu_xgmi_error", "GPUs", "reset_gpu_xgmi_error") def test_performance_set_clk_freq(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest("Skipping test_performance_set_clk_freq as it fails (Perm failure).") # TODO: actually set the clock and measure the real operation. amdsmi_set_clk_freq() # expects clk_type as the string "sclk"/"mclk"/"fclk"/"socclk" (see # py-interface/amdsmi_interface.py: amdsmi_set_clk_freq), NOT the enum-member name # passed here ("SYS"/"DF"/...). As written every call is rejected with # AmdSmiParameterException and only the rejection path is timed. To do this properly: # - map the settable clk_types (SYS->"sclk", MEM->"mclk", DF->"fclk", SOC->"socclk") # and skip the rest, and # - note this MUTATES GPU clock state on real hardware, so the restore-on-exit logic # must be made robust before enabling it. Same applies to the other set_* benchmarks. for i, processor in enumerate(self.processors): for clk_type_name, clk_type, clk_cond in common.CLK_TYPES: # First get current clock info try: clk_freq_info = amdsmi.amdsmi_get_clk_freq(processor, clk_type) except amdsmi.AmdSmiLibraryException: continue current = clk_freq_info["current"] num_supported = clk_freq_info["num_supported"] frequency = clk_freq_info["frequency"] if num_supported == 0: continue # Test setting each supported frequency for index in range(0, num_supported): freq_bitmask = frequency[index] self._log_test_start( "amdsmi_set_clk_freq", "GPU", i, clk_type=clk_type_name, freq_bitmask=freq_bitmask, ) stats = self._measure_api_performance( amdsmi.amdsmi_set_clk_freq, f"set_clk_freq_gpu_{i}_type_{clk_type_name}_freq_{freq_bitmask}", processor, clk_type_name, freq_bitmask, ) self.perf_results[ f"set_clk_freq_gpu_{i}_type_{clk_type_name}_freq_{freq_bitmask}" ] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) self._run_performance_assertions(stats, "amdsmi_set_clk_freq") else: self.common.print( f" GPU {i} clk_type {clk_type_name} freq {freq_bitmask}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion( "GPU", i, f"clk_type={clk_type_name}, freq_bitmask={freq_bitmask}" ) # Restore original frequency try: if current < num_supported: amdsmi.amdsmi_set_clk_freq(processor, clk_type_name, frequency[current]) except amdsmi.AmdSmiException: pass self._log_performance_summary("amdsmi_set_clk_freq", "GPUs", "set_clk_freq") def test_performance_set_gpu_accelerator_partition_profile(self): self.common.print_func_name("") if self.TODO_SKIP_NOT_COMPLETE: self.skipTest( "Skipping test_performance_set_gpu_accelerator_partition_profile as it is not complete." ) # Use TODO placeholder value like original test profile_index = 0 for i, processor in enumerate(self.processors): self._log_test_start( "amdsmi_set_gpu_accelerator_partition_profile", "Processor", i, profile_index=profile_index, ) stats = self._measure_api_performance( amdsmi.amdsmi_set_gpu_accelerator_partition_profile, f"set_gpu_accelerator_partition_profile_processor_{i}", processor, profile_index, ) self.perf_results[f"set_gpu_accelerator_partition_profile_processor_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_set_gpu_accelerator_partition_profile", "Processors", "set_gpu_accelerator_partition_profile", ) def test_performance_set_gpu_clk_limit(self): self.common.print_func_name("") if self.TODO_SKIP_NOT_COMPLETE: self.skipTest("Skipping test_performance_set_gpu_clk_limit as it is not complete.") # Use TODO placeholder value like original test value = 0 for i, processor in enumerate(self.processors): for clk_type_name, clk_type, clk_cond in common.CLK_TYPES: for clk_limit_type_name, clk_limit_type, clk_limit_cond in common.CLK_LIMIT_TYPES: self._log_test_start( "amdsmi_set_gpu_clk_limit", "Processor", i, clk_type=clk_type_name, clk_limit_type=clk_limit_type_name, value=value, ) stats = self._measure_api_performance( amdsmi.amdsmi_set_gpu_clk_limit, f"set_gpu_clk_limit_processor_{i}_clk_{clk_type_name}_limit_{clk_limit_type_name}", processor, clk_type_name, clk_limit_type_name, value, ) self.perf_results[ f"set_gpu_clk_limit_processor_{i}_clk_{clk_type_name}_limit_{clk_limit_type_name}" ] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} clk={clk_type_name} limit={clk_limit_type_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion( "Processor", i, f"clk_type={clk_type_name}, clk_limit_type={clk_limit_type_name}", ) self._log_performance_summary("amdsmi_set_gpu_clk_limit", "Processors", "set_gpu_clk_limit") def test_performance_set_gpu_compute_partition(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_set_gpu_compute_partition as it fails on MI300." ) for i, processor in enumerate(self.processors): # Get current compute partition first self._log_test_start("amdsmi_get_gpu_compute_partition", "Processor", i) stats_get = self._measure_api_performance( amdsmi.amdsmi_get_gpu_compute_partition, f"get_gpu_compute_partition_processor_{i}", processor, ) self.perf_results[f"get_gpu_compute_partition_processor_{i}"] = stats_get if stats_get["successful_runs"] > 0: self._print_performance_results(stats_get) try: default_compute_partition_name = amdsmi.amdsmi_get_gpu_compute_partition( processor ) default_compute_partition_type = common.COMPUTE_PARTITION_TYPES[0][1] # Find the default partition type for ( compute_partition_type_name, compute_partition_type, compute_partition_type_cond, ) in common.COMPUTE_PARTITION_TYPES: if default_compute_partition_name == compute_partition_type_name: default_compute_partition_type = compute_partition_type # Test setting each partition type stats_set = self._measure_api_performance( amdsmi.amdsmi_set_gpu_compute_partition, f"set_gpu_compute_partition_processor_{i}_type_{compute_partition_type_name}", processor, compute_partition_type, ) self.perf_results[ f"set_gpu_compute_partition_processor_{i}_type_{compute_partition_type_name}" ] = stats_set if stats_set["successful_runs"] > 0: self._print_performance_results(stats_set) else: self.common.print( f" Processor {i} type={compute_partition_type_name}: All calls failed - {stats_set['errors'][0]['error_info'] if stats_set['errors'] else 'Unknown'}" ) # Restore original partition stats_restore = self._measure_api_performance( amdsmi.amdsmi_set_gpu_compute_partition, f"restore_gpu_compute_partition_processor_{i}", processor, default_compute_partition_type, ) self.perf_results[f"restore_gpu_compute_partition_processor_{i}"] = ( stats_restore ) except amdsmi.AmdSmiLibraryException: self.common.print(f" Processor {i}: Could not get default compute partition") else: self.common.print( f" Processor {i}: Get failed - {stats_get['errors'][0]['error_info'] if stats_get['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "set_gpu_compute_partition", "Processors", "set_gpu_compute_partition" ) def test_performance_gpu_fan_speed(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("gpu_fan_speed", "Processor", i) # Test Get GPU Fan Speed (current) stats_get_current = self._measure_api_performance( amdsmi.amdsmi_get_gpu_fan_speed, f"get_gpu_fan_speed_processor_{i}", processor, 0 ) self.perf_results[f"get_gpu_fan_speed_processor_{i}"] = stats_get_current if stats_get_current["successful_runs"] > 0: self._print_performance_results(stats_get_current) try: fan_speed_current = amdsmi.amdsmi_get_gpu_fan_speed(processor, 0) # Test Get GPU Fan Speed Max stats_get_max = self._measure_api_performance( amdsmi.amdsmi_get_gpu_fan_speed_max, f"get_gpu_fan_speed_max_processor_{i}", processor, 0, ) self.perf_results[f"get_gpu_fan_speed_max_processor_{i}"] = stats_get_max self._print_performance_results(stats_get_max) fan_speed_max = amdsmi.amdsmi_get_gpu_fan_speed_max(processor, 0) if fan_speed_current == fan_speed_max: fan_speed = int(fan_speed_max / 2) else: fan_speed = fan_speed_max # Test Set GPU Fan Speed stats_set = self._measure_api_performance( amdsmi.amdsmi_set_gpu_fan_speed, f"set_gpu_fan_speed_processor_{i}", processor, 0, fan_speed, ) self.perf_results[f"set_gpu_fan_speed_processor_{i}"] = stats_set self._print_performance_results(stats_set) # Restore original fan speed stats_restore = self._measure_api_performance( amdsmi.amdsmi_set_gpu_fan_speed, f"restore_gpu_fan_speed_processor_{i}", processor, 0, fan_speed_current, ) self.perf_results[f"restore_gpu_fan_speed_processor_{i}"] = stats_restore self._print_performance_results(stats_restore) except amdsmi.AmdSmiLibraryException: self.common.print(f" Processor {i}: Could not complete fan speed workflow") else: self.common.print( f" Processor {i}: Get failed - {stats_get_current['errors'][0]['error_info'] if stats_get_current['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("gpu_fan_speed_workflow", "Processors", "gpu_fan_speed") def test_performance_set_gpu_memory_partition(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_set_gpu_memory_partition as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): for ( memory_partition_type_name, memory_partition_type, memory_partition_type_cond, ) in common.MEMORY_PARTITION_TYPES: self._log_test_start( "amdsmi_set_gpu_memory_partition", "Processor", i, memory_partition_type=memory_partition_type_name, ) stats = self._measure_api_performance( amdsmi.amdsmi_set_gpu_memory_partition, f"set_gpu_memory_partition_processor_{i}_type_{memory_partition_type_name}", processor, memory_partition_type, ) self.perf_results[ f"set_gpu_memory_partition_processor_{i}_type_{memory_partition_type_name}" ] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} type={memory_partition_type_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion( "Processor", i, f"memory_partition_type={memory_partition_type_name}" ) self._log_performance_summary( "amdsmi_set_gpu_memory_partition", "Processors", "set_gpu_memory_partition" ) def test_performance_set_gpu_memory_partition_mode(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_set_gpu_memory_partition_mode as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): for ( memory_partition_type_name, memory_partition_type, memory_partition_type_cond, ) in common.MEMORY_PARTITION_TYPES: self._log_test_start( "amdsmi_set_gpu_memory_partition_mode", "Processor", i, memory_partition_type=memory_partition_type_name, ) stats = self._measure_api_performance( amdsmi.amdsmi_set_gpu_memory_partition_mode, f"set_gpu_memory_partition_mode_processor_{i}_type_{memory_partition_type_name}", processor, memory_partition_type, ) self.perf_results[ f"set_gpu_memory_partition_mode_processor_{i}_type_{memory_partition_type_name}" ] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} type={memory_partition_type_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion( "Processor", i, f"memory_partition_type={memory_partition_type_name}" ) self._log_performance_summary( "amdsmi_set_gpu_memory_partition_mode", "Processors", "set_gpu_memory_partition_mode" ) def test_performance_set_gpu_od_clk_info(self): self.common.print_func_name("") if self.TODO_SKIP_NOT_COMPLETE: self.skipTest("Skipping test_performance_set_gpu_od_clk_info as it is not complete.") # Use TODO placeholder value like original test value = 200 for i, processor in enumerate(self.processors): for freq_ind_name, freq_ind, freq_ind_cond in common.FREQ_INDS: for clk_type_name, clk_type, clk_cond in common.CLK_TYPES: self._log_test_start( "amdsmi_set_gpu_od_clk_info", "Processor", i, freq_ind=freq_ind_name, value=value, clk_type=clk_type_name, ) stats = self._measure_api_performance( amdsmi.amdsmi_set_gpu_od_clk_info, f"set_gpu_od_clk_info_processor_{i}_freq_{freq_ind_name}_clk_{clk_type_name}", processor, freq_ind, value, clk_type, ) self.perf_results[ f"set_gpu_od_clk_info_processor_{i}_freq_{freq_ind_name}_clk_{clk_type_name}" ] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} freq={freq_ind_name} clk={clk_type_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion( "Processor", i, f"freq_ind={freq_ind_name}, clk_type={clk_type_name}" ) self._log_performance_summary( "amdsmi_set_gpu_od_clk_info", "Processors", "set_gpu_od_clk_info" ) def test_performance_set_gpu_od_volt_info(self): self.common.print_func_name("") if self.TODO_SKIP_NOT_COMPLETE: self.skipTest("Skipping test_performance_set_gpu_od_volt_info as it is not complete.") # Use TODO placeholder values like original test vpoint = 0 clk_value = 0 volt_value = 0 for i, processor in enumerate(self.processors): self._log_test_start( "amdsmi_set_gpu_od_volt_info", "Processor", i, vpoint=vpoint, clk_value=clk_value, volt_value=volt_value, ) stats = self._measure_api_performance( amdsmi.amdsmi_set_gpu_od_volt_info, f"set_gpu_od_volt_info_processor_{i}", processor, vpoint, clk_value, volt_value, ) self.perf_results[f"set_gpu_od_volt_info_processor_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_set_gpu_od_volt_info", "Processors", "set_gpu_od_volt_info" ) def test_performance_set_gpu_overdrive_level(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("gpu_overdrive_level_workflow", "Processor", i) # Test Get GPU Overdrive Level stats_get = self._measure_api_performance( amdsmi.amdsmi_get_gpu_overdrive_level, f"get_gpu_overdrive_level_processor_{i}", processor, ) self.perf_results[f"get_gpu_overdrive_level_processor_{i}"] = stats_get if stats_get["successful_runs"] > 0: self._print_performance_results(stats_get) try: overdrive_value_current = amdsmi.amdsmi_get_gpu_overdrive_level(processor) if overdrive_value_current != 1: overdrive_value = 1 else: overdrive_value = 2 # Test Set GPU Overdrive Level stats_set = self._measure_api_performance( amdsmi.amdsmi_set_gpu_overdrive_level, f"set_gpu_overdrive_level_processor_{i}", processor, overdrive_value, ) self.perf_results[f"set_gpu_overdrive_level_processor_{i}"] = stats_set self._print_performance_results(stats_set) # Restore original overdrive level stats_restore = self._measure_api_performance( amdsmi.amdsmi_set_gpu_overdrive_level, f"restore_gpu_overdrive_level_processor_{i}", processor, overdrive_value_current, ) self.perf_results[f"restore_gpu_overdrive_level_processor_{i}"] = stats_restore self._print_performance_results(stats_restore) except amdsmi.AmdSmiLibraryException: self.common.print(f" Processor {i}: Could not complete overdrive workflow") else: self.common.print( f" Processor {i}: Get failed - {stats_get['errors'][0]['error_info'] if stats_get['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "gpu_overdrive_level_workflow", "Processors", "set_gpu_overdrive_level" ) def test_performance_set_gpu_pci_bandwidth(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_set_gpu_pci_bandwidth as it fails (MI350X, AMDSMI_STATUS_UNEXPECTED_DATA)." ) for i, processor in enumerate(self.processors): self._log_test_start("gpu_pci_bandwidth_workflow", "Processor", i) # Test Get GPU PCI Bandwidth stats_get = self._measure_api_performance( amdsmi.amdsmi_get_gpu_pci_bandwidth, f"get_gpu_pci_bandwidth_processor_{i}", processor, ) self.perf_results[f"get_gpu_pci_bandwidth_processor_{i}"] = stats_get if stats_get["successful_runs"] > 0: self._print_performance_results(stats_get) try: bandwidth_info = amdsmi.amdsmi_get_gpu_pci_bandwidth(processor) current_bandwidth_index = bandwidth_info["transfer_rate"]["current"] if current_bandwidth_index > 0: bitmask = 1 << (current_bandwidth_index - 1) else: bitmask = 1 << (current_bandwidth_index) # Test Set GPU PCI Bandwidth stats_set = self._measure_api_performance( amdsmi.amdsmi_set_gpu_pci_bandwidth, f"set_gpu_pci_bandwidth_processor_{i}", processor, bitmask, ) self.perf_results[f"set_gpu_pci_bandwidth_processor_{i}"] = stats_set self._print_performance_results(stats_set) # Restore original PCI bandwidth bitmask = 1 << (current_bandwidth_index) stats_restore = self._measure_api_performance( amdsmi.amdsmi_set_gpu_pci_bandwidth, f"restore_gpu_pci_bandwidth_processor_{i}", processor, bitmask, ) self.perf_results[f"restore_gpu_pci_bandwidth_processor_{i}"] = stats_restore self._print_performance_results(stats_restore) except amdsmi.AmdSmiLibraryException: self.common.print(f" Processor {i}: Could not complete PCI bandwidth workflow") else: self.common.print( f" Processor {i}: Get failed - {stats_get['errors'][0]['error_info'] if stats_get['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "gpu_pci_bandwidth_workflow", "Processors", "set_gpu_pci_bandwidth" ) def test_performance_set_gpu_perf_determinism_mode(self): self.common.print_func_name("") if self.TODO_SKIP_NOT_COMPLETE: self.skipTest( "Skipping test_performance_set_gpu_perf_determinism_mode as it is not complete." ) # Use TODO placeholder value like original test clk_value = 0 for i, processor in enumerate(self.processors): self._log_test_start( "amdsmi_set_gpu_perf_determinism_mode", "Processor", i, clk_value=clk_value ) stats = self._measure_api_performance( amdsmi.amdsmi_set_gpu_perf_determinism_mode, f"set_gpu_perf_determinism_mode_processor_{i}", processor, clk_value, ) self.perf_results[f"set_gpu_perf_determinism_mode_processor_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_set_gpu_perf_determinism_mode", "Processors", "set_gpu_perf_determinism_mode" ) def test_performance_set_gpu_perf_level(self): self.common.print_func_name("") # Check if dev_perf_levels is populated, skip test if not if not common.DEV_PERF_LEVELS: self.skipTest("dev_perf_levels not initialized - skipping performance level test") return dev_perf_level_current = common.DEV_PERF_LEVELS[0][1] for i, processor in enumerate(self.processors): self._log_test_start("gpu_perf_level_workflow", "Processor", i) # Test Get GPU Perf Level stats_get = self._measure_api_performance( amdsmi.amdsmi_get_gpu_perf_level, f"get_gpu_perf_level_processor_{i}", processor ) self.perf_results[f"get_gpu_perf_level_processor_{i}"] = stats_get if stats_get["successful_runs"] > 0: self._print_performance_results(stats_get) try: dev_perf_level_name_current = amdsmi.amdsmi_get_gpu_perf_level(processor) items = dev_perf_level_name_current.split("_") dev_perf_level_name_current = items[-1] # Test setting each performance level for ( dev_perf_level_name, dev_perf_level, dev_perf_level_cond, ) in common.DEV_PERF_LEVELS: if dev_perf_level_name_current == dev_perf_level_name: dev_perf_level_current = dev_perf_level stats_set = self._measure_api_performance( amdsmi.amdsmi_set_gpu_perf_level, f"set_gpu_perf_level_processor_{i}_level_{dev_perf_level_name}", processor, dev_perf_level, ) self.perf_results[ f"set_gpu_perf_level_processor_{i}_level_{dev_perf_level_name}" ] = stats_set if stats_set["successful_runs"] > 0: self._print_performance_results(stats_set) else: self.common.print( f" Processor {i} level={dev_perf_level_name}: All calls failed - {stats_set['errors'][0]['error_info'] if stats_set['errors'] else 'Unknown'}" ) # Restore original performance level stats_restore = self._measure_api_performance( amdsmi.amdsmi_set_gpu_perf_level, f"restore_gpu_perf_level_processor_{i}", processor, dev_perf_level_current, ) self.perf_results[f"restore_gpu_perf_level_processor_{i}"] = stats_restore self._print_performance_results(stats_restore) except amdsmi.AmdSmiLibraryException: self.common.print(f" Processor {i}: Could not complete perf level workflow") else: self.common.print( f" Processor {i}: Get failed - {stats_get['errors'][0]['error_info'] if stats_get['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("gpu_perf_level_workflow", "Processors", "set_gpu_perf_level") def test_performance_set_gpu_power_profile(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): for ( power_profile_preset_mask_name, power_profile_preset_mask, power_profile_preset_masks_cond, ) in common.POWER_PROFILE_PRESET_MASKS: self._log_test_start( "amdsmi_set_gpu_power_profile", "Processor", i, power_profile=power_profile_preset_mask_name, ) stats = self._measure_api_performance( amdsmi.amdsmi_set_gpu_power_profile, f"set_gpu_power_profile_processor_{i}_profile_{power_profile_preset_mask_name}", processor, 0, power_profile_preset_mask, ) self.perf_results[ f"set_gpu_power_profile_processor_{i}_profile_{power_profile_preset_mask_name}" ] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} profile={power_profile_preset_mask_name}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion( "Processor", i, f"power_profile={power_profile_preset_mask_name}" ) self._log_performance_summary( "amdsmi_set_gpu_power_profile", "Processors", "set_gpu_power_profile" ) def test_performance_set_gpu_process_isolation(self): self.common.print_func_name("") # Use pisolate values from original test pisolates = [1, 0] for i, processor in enumerate(self.processors): for pisolate in pisolates: self._log_test_start( "amdsmi_set_gpu_process_isolation", "Processor", i, pisolate=pisolate ) stats = self._measure_api_performance( amdsmi.amdsmi_set_gpu_process_isolation, f"set_gpu_process_isolation_processor_{i}_pisolate_{pisolate}", processor, pisolate, ) self.perf_results[ f"set_gpu_process_isolation_processor_{i}_pisolate_{pisolate}" ] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i} pisolate={pisolate}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i, f"pisolate={pisolate}") self._log_performance_summary( "amdsmi_set_gpu_process_isolation", "Processors", "set_gpu_process_isolation" ) def test_performance_power_cap(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("power_cap_workflow", "Processor", i) # Test Get Power Cap Info stats_get = self._measure_api_performance( amdsmi.amdsmi_get_power_cap_info, f"get_power_cap_info_processor_{i}", processor ) self.perf_results[f"get_power_cap_info_processor_{i}"] = stats_get if stats_get["successful_runs"] > 0: self._print_performance_results(stats_get) try: power_cap_info = amdsmi.amdsmi_get_power_cap_info(processor) cap = int( (power_cap_info["max_power_cap"] + power_cap_info["min_power_cap"]) / 2 ) # Test Set Power Cap (average of min and max) stats_set = self._measure_api_performance( amdsmi.amdsmi_set_power_cap, f"set_power_cap_processor_{i}", processor, 0, cap, ) self.perf_results[f"set_power_cap_processor_{i}"] = stats_set self._print_performance_results(stats_set) # Restore original power cap cap = power_cap_info["power_cap"] stats_restore = self._measure_api_performance( amdsmi.amdsmi_set_power_cap, f"restore_power_cap_processor_{i}", processor, 0, cap, ) self.perf_results[f"restore_power_cap_processor_{i}"] = stats_restore self._print_performance_results(stats_restore) except amdsmi.AmdSmiLibraryException: self.common.print(f" Processor {i}: Could not complete power cap workflow") else: self.common.print( f" Processor {i}: Get failed - {stats_get['errors'][0]['error_info'] if stats_get['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("power_cap_workflow", "Processors", "power_cap") def test_performance_soc_pstate(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("soc_pstate_workflow", "Processor", i) # Test Get SoC Pstate stats_get = self._measure_api_performance( amdsmi.amdsmi_get_soc_pstate, f"get_soc_pstate_processor_{i}", processor ) self.perf_results[f"get_soc_pstate_processor_{i}"] = stats_get if stats_get["successful_runs"] > 0: self._print_performance_results(stats_get) try: policy_info = amdsmi.amdsmi_get_soc_pstate(processor) num_supported = policy_info["num_supported"] policy_id_current = policy_info["current_id"] policy_id_orig = policy_info["policies"][policy_id_current]["policy_id"] index = 0 if num_supported >= 2: if policy_id_current != 0: index = 1 policy_id = policy_info["policies"][index]["policy_id"] # Test Set SoC Pstate stats_set = self._measure_api_performance( amdsmi.amdsmi_set_soc_pstate, f"set_soc_pstate_processor_{i}", processor, policy_id, ) self.perf_results[f"set_soc_pstate_processor_{i}"] = stats_set self._print_performance_results(stats_set) # Restore original policy stats_restore = self._measure_api_performance( amdsmi.amdsmi_set_soc_pstate, f"restore_soc_pstate_processor_{i}", processor, policy_id_orig, ) self.perf_results[f"restore_soc_pstate_processor_{i}"] = stats_restore self._print_performance_results(stats_restore) except (amdsmi.AmdSmiLibraryException, KeyError, TypeError): self.common.print(f" Processor {i}: Could not complete SoC pstate workflow") else: self.common.print( f" Processor {i}: Get failed - {stats_get['errors'][0]['error_info'] if stats_get['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("soc_pstate_workflow", "Processors", "soc_pstate") def test_performance_xgmi_plpd(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest("Skipping test_performance_xgmi_plpd as it fails on MI300.") for i, processor in enumerate(self.processors): self._log_test_start("xgmi_plpd_workflow", "Processor", i) # Test Get XGMI PLPD stats_get = self._measure_api_performance( amdsmi.amdsmi_get_xgmi_plpd, f"get_xgmi_plpd_processor_{i}", processor ) self.perf_results[f"get_xgmi_plpd_processor_{i}"] = stats_get if stats_get["successful_runs"] > 0: self._print_performance_results(stats_get) try: policy_info = amdsmi.amdsmi_get_xgmi_plpd(processor) num_supported = policy_info["num_supported"] policy_id_current = policy_info["current_id"] policy_id_orig = policy_info["policies"][policy_id_current]["policy_id"] index = 0 if num_supported >= 2: if policy_id_current != 0: index = 1 policy_id = policy_info["policies"][index]["policy_id"] # Test Set XGMI PLPD stats_set = self._measure_api_performance( amdsmi.amdsmi_set_xgmi_plpd, f"set_xgmi_plpd_processor_{i}", processor, policy_id, ) self.perf_results[f"set_xgmi_plpd_processor_{i}"] = stats_set self._print_performance_results(stats_set) # Restore original policy stats_restore = self._measure_api_performance( amdsmi.amdsmi_set_xgmi_plpd, f"restore_xgmi_plpd_processor_{i}", processor, policy_id_orig, ) self.perf_results[f"restore_xgmi_plpd_processor_{i}"] = stats_restore self._print_performance_results(stats_restore) except (amdsmi.AmdSmiLibraryException, KeyError, TypeError): self.common.print(f" Processor {i}: Could not complete XGMI PLPD workflow") else: self.common.print( f" Processor {i}: Get failed - {stats_get['errors'][0]['error_info'] if stats_get['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary("xgmi_plpd_workflow", "Processors", "xgmi_plpd") def test_performance_status_code_to_string(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_status_code_to_string as it fails (Unhashable type)." ) for error_num, error_name in error_map.items(): self._log_test_start("amdsmi_status_code_to_string", "ErrorCode", error_num) # Convert error_num to int, handling both decimal and hex formats try: if isinstance(error_num, str) and error_num.startswith("0x"): error_int = int(error_num, 16) # Parse hex else: error_int = int(error_num) # Parse decimal except (ValueError, TypeError): error_int = 0 # Fallback to 0 on error # Print result for this error code try: ret = amdsmi.amdsmi_status_code_to_string(ctypes.c_uint32(error_int)) self.common.print(f"### test amdsmi_status_code_to_string(error={error_num})") self._print("", ret) except amdsmi.AmdSmiLibraryException as e: self.common.print(f"### test amdsmi_status_code_to_string(error={error_num})") self.common.print(f" Error: {e}") stats = self._measure_api_performance( amdsmi.amdsmi_status_code_to_string, f"status_code_to_string_{error_num}", ctypes.c_uint32(error_int), ) self.perf_results[f"status_code_to_string_{error_num}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Error {error_num}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("ErrorCode", error_num) self._log_performance_summary( "amdsmi_status_code_to_string", "ErrorCodes", "status_code_to_string" ) def test_performance_topo_get_link_type(self): self.common.print_func_name("") for i, gpu_i in enumerate(self.processors): for j, gpu_j in enumerate(self.processors): self._log_test_start("amdsmi_topo_get_link_type", "Link", f"{i}<->{j}") stats = self._measure_api_performance( amdsmi.amdsmi_topo_get_link_type, f"topo_get_link_type_{i}_to_{j}", gpu_i, gpu_j ) self.perf_results[f"topo_get_link_type_{i}_to_{j}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Link {i}<->{j}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Link", f"{i}<->{j}") self._log_performance_summary("amdsmi_topo_get_link_type", "Links", "topo_get_link_type") def test_performance_topo_get_link_weight(self): self.common.print_func_name("") for i, gpu_i in enumerate(self.processors): for j, gpu_j in enumerate(self.processors): self._log_test_start("amdsmi_topo_get_link_weight", "Link", f"{i}<->{j}") stats = self._measure_api_performance( amdsmi.amdsmi_topo_get_link_weight, f"topo_get_link_weight_{i}_to_{j}", gpu_i, gpu_j, ) self.perf_results[f"topo_get_link_weight_{i}_to_{j}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Link {i}<->{j}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Link", f"{i}<->{j}") self._log_performance_summary( "amdsmi_topo_get_link_weight", "Links", "topo_get_link_weight" ) def test_performance_topo_get_numa_node_number(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_topo_get_numa_node_number", "Processor", i) self._print_api_result(amdsmi.amdsmi_topo_get_numa_node_number, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_topo_get_numa_node_number, f"topo_get_numa_node_number_processor_{i}", processor, ) self.perf_results[f"topo_get_numa_node_number_processor_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_topo_get_numa_node_number", "Processors", "topo_get_numa_node_number" ) def test_performance_topo_get_p2p_status(self): self.common.print_func_name("") if self.TODO_SKIP_FAIL: self.skipTest( "Skipping test_performance_topo_get_p2p_status as it fails (Inval parameters)." ) for i, gpu_i in enumerate(self.processors): for j, gpu_j in enumerate(self.processors): self._log_test_start("amdsmi_topo_get_p2p_status", "P2P", f"{i}<->{j}") stats = self._measure_api_performance( amdsmi.amdsmi_topo_get_p2p_status, f"topo_get_p2p_status_{i}_to_{j}", gpu_i, gpu_j, ) self.perf_results[f"topo_get_p2p_status_{i}_to_{j}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" P2P {i}<->{j}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("P2P", f"{i}<->{j}") self._log_performance_summary("amdsmi_topo_get_p2p_status", "P2P", "topo_get_p2p_status") def test_performance_get_gpu_busy_percent(self): self.common.print_func_name("") for i, processor in enumerate(self.processors): self._log_test_start("amdsmi_get_gpu_busy_percent", "Processor", i) self._print_api_result(amdsmi.amdsmi_get_gpu_busy_percent, i, processor) stats = self._measure_api_performance( amdsmi.amdsmi_get_gpu_busy_percent, f"get_gpu_busy_percent_processor_{i}", processor ) self.perf_results[f"get_gpu_busy_percent_processor_{i}"] = stats if stats["successful_runs"] > 0: self._print_performance_results(stats) else: self.common.print( f" Processor {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}" ) self._log_test_completion("Processor", i) self._log_performance_summary( "amdsmi_get_gpu_busy_percent", "Processors", "get_gpu_busy_percent" ) # ============================================================================= # PERFORMANCE TEST REPORTING SYSTEM (Converted from perf_test.sh) # =============================================================================