#!/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 inspect
import json
import sys
import unittest
import time
import statistics

sys.path.append("/opt/rocm/share/amd_smi/")

try:
    import amdsmi
except ImportError as exc:
    print(f"ERROR: Could not import amdsmi module: {exc}")
    print("The amdsmi module is required to run performance tests.")
    print("Please ensure amdsmi is installed and available in your Python path.")
    sys.exit(1)

# Error map dictionary
error_map = {
    "0": "AMDSMI_STATUS_SUCCESS",
    "1": "AMDSMI_STATUS_INVAL",
    "2": "AMDSMI_STATUS_NOT_SUPPORTED",
    "3": "AMDSMI_STATUS_NOT_YET_IMPLEMENTED",
    "4": "AMDSMI_STATUS_FAIL_LOAD_MODULE",
    "5": "AMDSMI_STATUS_FAIL_LOAD_SYMBOL",
    "6": "AMDSMI_STATUS_DRM_ERROR",
    "7": "AMDSMI_STATUS_API_FAILED",
    "8": "AMDSMI_STATUS_TIMEOUT",
    "9": "AMDSMI_STATUS_RETRY",
    "10": "AMDSMI_STATUS_NO_PERM",
    "11": "AMDSMI_STATUS_INTERRUPT",
    "12": "AMDSMI_STATUS_IO",
    "13": "AMDSMI_STATUS_ADDRESS_FAULT",
    "14": "AMDSMI_STATUS_FILE_ERROR",
    "15": "AMDSMI_STATUS_OUT_OF_RESOURCES",
    "16": "AMDSMI_STATUS_INTERNAL_EXCEPTION",
    "17": "AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS",
    "18": "AMDSMI_STATUS_INIT_ERROR",
    "19": "AMDSMI_STATUS_REFCOUNT_OVERFLOW",
    "20": "AMDSMI_STATUS_DIRECTORY_NOT_FOUND",
    "21": "AMDSMI_STATUS_IPC_ERROR",
    "30": "AMDSMI_STATUS_BUSY",
    "31": "AMDSMI_STATUS_NOT_FOUND",
    "32": "AMDSMI_STATUS_NOT_INIT",
    "33": "AMDSMI_STATUS_NO_SLOT",
    "34": "AMDSMI_STATUS_DRIVER_NOT_LOADED",
    "39": "AMDSMI_STATUS_MORE_DATA",
    "40": "AMDSMI_STATUS_NO_DATA",
    "41": "AMDSMI_STATUS_INSUFFICIENT_SIZE",
    "42": "AMDSMI_STATUS_UNEXPECTED_SIZE",
    "43": "AMDSMI_STATUS_UNEXPECTED_DATA",
    "44": "AMDSMI_STATUS_NON_AMD_CPU",
    "45": "AMDSMI_STATUS_NO_ENERGY_DRV",
    "46": "AMDSMI_STATUS_NO_MSR_DRV",
    "47": "AMDSMI_STATUS_NO_HSMP_DRV",
    "48": "AMDSMI_STATUS_NO_HSMP_SUP",
    "49": "AMDSMI_STATUS_NO_HSMP_MSG_SUP",
    "50": "AMDSMI_STATUS_HSMP_TIMEOUT",
    "51": "AMDSMI_STATUS_NO_DRV",
    "52": "AMDSMI_STATUS_FILE_NOT_FOUND",
    "53": "AMDSMI_STATUS_ARG_PTR_NULL",
    "54": "AMDSMI_STATUS_AMDGPU_RESTART_ERR",
    "55": "AMDSMI_STATUS_SETTING_UNAVAILABLE",
    "56": "AMDSMI_STATUS_CORRUPTED_EEPROM",
    "0xFFFFFFFE": "AMDSMI_STATUS_MAP_ERROR",
    "0xFFFFFFFF": "AMDSMI_STATUS_UNKNOWN_ERROR",
}

# Global variables needed for performance tests
verbose = 1
has_info_printed = False

# Global constants matching original test file
PASS = "AMDSMI_STATUS_SUCCESS"
FAIL = "AMDSMI_STATUS_INVAL"


class TestAmdSmiPythonPerformance(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.
    """

    # Class-level attributes to prevent IndexError and AttributeError
    compute_partition_types = [
        ("SPX", amdsmi.AmdSmiComputePartitionType.SPX, PASS)
        if hasattr(amdsmi, "AmdSmiComputePartitionType")
        else ("SPX", None, PASS),
        ("DPX", amdsmi.AmdSmiComputePartitionType.DPX, PASS)
        if hasattr(amdsmi, "AmdSmiComputePartitionType")
        else ("DPX", None, PASS),
        ("TPX", amdsmi.AmdSmiComputePartitionType.TPX, PASS)
        if hasattr(amdsmi, "AmdSmiComputePartitionType")
        else ("TPX", None, PASS),
        ("QPX", amdsmi.AmdSmiComputePartitionType.QPX, PASS)
        if hasattr(amdsmi, "AmdSmiComputePartitionType")
        else ("QPX", None, PASS),
        ("CPX", amdsmi.AmdSmiComputePartitionType.CPX, PASS)
        if hasattr(amdsmi, "AmdSmiComputePartitionType")
        else ("CPX", None, PASS),
        ("INVALID", amdsmi.AmdSmiComputePartitionType.INVALID, FAIL)
        if hasattr(amdsmi, "AmdSmiComputePartitionType")
        else ("INVALID", None, FAIL),
    ]

    freq_inds = [
        ("MIN", amdsmi.AmdSmiFreqInd.MIN, PASS)
        if hasattr(amdsmi, "AmdSmiFreqInd")
        else ("MIN", None, PASS),
        ("MAX", amdsmi.AmdSmiFreqInd.MAX, PASS)
        if hasattr(amdsmi, "AmdSmiFreqInd")
        else ("MAX", None, PASS),
        ("INVALID", amdsmi.AmdSmiFreqInd.INVALID, FAIL)
        if hasattr(amdsmi, "AmdSmiFreqInd")
        else ("INVALID", None, FAIL),
    ]

    dev_perf_levels = [
        ("AUTO", amdsmi.AmdSmiDevPerfLevel.AUTO, PASS)
        if hasattr(amdsmi, "AmdSmiDevPerfLevel")
        else ("AUTO", None, PASS),
        ("LOW", amdsmi.AmdSmiDevPerfLevel.LOW, PASS)
        if hasattr(amdsmi, "AmdSmiDevPerfLevel")
        else ("LOW", None, PASS),
        ("HIGH", amdsmi.AmdSmiDevPerfLevel.HIGH, PASS)
        if hasattr(amdsmi, "AmdSmiDevPerfLevel")
        else ("HIGH", None, PASS),
        ("MANUAL", amdsmi.AmdSmiDevPerfLevel.MANUAL, PASS)
        if hasattr(amdsmi, "AmdSmiDevPerfLevel")
        else ("MANUAL", None, PASS),
        ("STABLE_STD", amdsmi.AmdSmiDevPerfLevel.STABLE_STD, PASS)
        if hasattr(amdsmi, "AmdSmiDevPerfLevel")
        else ("STABLE_STD", None, PASS),
        ("STABLE_PEAK", amdsmi.AmdSmiDevPerfLevel.STABLE_PEAK, PASS)
        if hasattr(amdsmi, "AmdSmiDevPerfLevel")
        else ("STABLE_PEAK", None, PASS),
        ("STABLE_MIN_MCLK", amdsmi.AmdSmiDevPerfLevel.STABLE_MIN_MCLK, PASS)
        if hasattr(amdsmi, "AmdSmiDevPerfLevel")
        else ("STABLE_MIN_MCLK", None, PASS),
        ("STABLE_MIN_SCLK", amdsmi.AmdSmiDevPerfLevel.STABLE_MIN_SCLK, PASS)
        if hasattr(amdsmi, "AmdSmiDevPerfLevel")
        else ("STABLE_MIN_SCLK", None, PASS),
        ("DETERMINISM", amdsmi.AmdSmiDevPerfLevel.DETERMINISM, PASS)
        if hasattr(amdsmi, "AmdSmiDevPerfLevel")
        else ("DETERMINISM", None, PASS),
        ("UNKNOWN", amdsmi.AmdSmiDevPerfLevel.UNKNOWN, FAIL)
        if hasattr(amdsmi, "AmdSmiDevPerfLevel")
        else ("UNKNOWN", None, FAIL),
    ]

    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

        # Initialize empty lists for robustness - will be populated if amdsmi is available
        self.status_types = []
        self.clk_types = []
        self.io_bw_encodings = []
        self.event_groups = []
        self.gpu_blocks = []
        self.memory_types = []
        self.processor_types = []
        self.reg_types = []
        self.voltage_metrics = []
        self.voltage_types = []
        self.link_types = []
        self.temperature_types = []
        self.utilization_counter_types = []
        self.event_types = []
        self.counter_commands = []
        self.power_profile_preset_masks = []
        self.temperature_metrics = []
        self.clk_limit_types = []
        self.memory_partition_types = []

        # Try to populate with actual amdsmi attributes if available
        self._populate_amdsmi_attributes()

        # Initialize AMDSMI
        self.processors = []
        try:
            amdsmi.amdsmi_init()
            self.processors = amdsmi.amdsmi_get_processor_handles()
        except Exception as e:
            print(f"ERROR: Failed to initialize AMDSMI: {e}")
            raise

    def setUp(self):
        """Setup for performance tests - re-initialize AMDSMI before each test."""
        # Print device info once per test run if verbose
        global has_info_printed
        if verbose and has_info_printed is False:
            has_info_printed = True
            for i, gpu in enumerate(self.processors):
                try:
                    # Print asic info
                    msg = f"asic info(gpu={i})"
                    ret = amdsmi.amdsmi_get_gpu_asic_info(gpu)
                    self._print(msg, ret)
                except amdsmi.AmdSmiLibraryException as e:
                    raise e
            for i, gpu in enumerate(self.processors):
                try:
                    # Print board info
                    msg = f"board info(gpu={i})"
                    ret = amdsmi.amdsmi_get_gpu_board_info(gpu)
                    self._print(msg, ret)
                except amdsmi.AmdSmiLibraryException as e:
                    raise e

        # 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:
            print(f"ERROR: Failed to initialize AMDSMI in setUp: {e}")
            raise

    def _populate_amdsmi_attributes(self):
        """Try to populate attribute lists with amdsmi enums if available."""
        # This method safely tries to access amdsmi attributes and populates lists
        # If amdsmi is not available or missing attributes, it silently continues

        # Wrap all attribute access in a try-catch to handle missing amdsmi properly
        try:
            if hasattr(amdsmi, "AmdSmiStatus"):
                self.status_types = [
                    ("SUCCESS", amdsmi.AmdSmiStatus.SUCCESS, self.PASS),
                    ("INVAL", amdsmi.AmdSmiStatus.INVAL, self.PASS),
                    ("NOT_SUPPORTED", amdsmi.AmdSmiStatus.NOT_SUPPORTED, self.PASS),
                    ("UNKNOWN_ERROR", amdsmi.AmdSmiStatus.UNKNOWN_ERROR, self.PASS),
                ]
        except (AttributeError, Exception):
            pass

        # Add more attribute populations as needed - this is a safe fallback approach

    def tearDown(self):
        """Cleanup after performance tests."""
        try:
            amdsmi.amdsmi_shut_down()
        except Exception:
            pass  # Ignore cleanup errors

    def _print_func_name(self, msg=""):
        """Helper method to print function name for consistency with original tests."""
        if verbose == 2:
            print(f"{inspect.currentframe().f_back.f_code.co_name}: {msg}")

    def _log_test_start(self, api_name, device_type, device_id, **kwargs):
        """Helper method to log the start of a test."""
        if verbose:
            extra_info = " ".join([f"{k}={v}" for k, v in kwargs.items()])
            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 verbose and stats:
            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."""
        if verbose:
            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."""
        if verbose:
            extra_msg = f" - {extra_info}" if extra_info else ""
            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."""
        if verbose:
            print(f"Performance test completed for {api_name} on {device_type_plural}")
            print()  # Add empty line for readability

    def _print(self, msg, result):
        """Helper method for printing test results."""
        if verbose:
            if isinstance(result, dict) or isinstance(result, list):
                if msg:
                    print(msg)
                print(json.dumps(result, sort_keys=False, indent=4, default=str))
            else:
                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 not verbose:
            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 as e:
            print(msg, flush=True)
            # 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
        """
        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:
                result = 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

        # Print results if verbose
        if verbose:
            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._print_func_name("Starting performance test for amdsmi_clean_gpu_local_data")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_clk_freq")
        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 self.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:
                    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._print_func_name("Starting performance test for amdsmi_get_clock_info")
        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 self.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:
                    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._print_func_name("Starting performance test for amdsmi_get_energy_count")
        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:
                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._print_func_name("Starting performance test for amdsmi_get_esmi_err_msg")
        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 self.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:
                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._print_func_name("Starting performance test for amdsmi_get_fw_info")

        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:
                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._print_func_name(
            "Starting performance test for amdsmi_get_gpu_accelerator_partition_profile"
        )

        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:
                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._print_func_name(
            "Starting performance test for amdsmi_get_gpu_accelerator_partition_profile_config"
        )

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_activity")
        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_asic_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_bad_page_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_bad_page_threshold")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_bdf_id")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_board_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_cache_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_compute_partition")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_compute_process_gpus")
        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:
            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._print_func_name("Starting performance test for amdsmi_get_gpu_compute_process_info")

        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:
            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._print_func_name(
            "Starting performance test for amdsmi_get_gpu_compute_process_info_by_pid"
        )
        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:
            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._print_func_name("Starting performance test for amdsmi_get_gpu_device_bdf")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_device_uuid")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_driver_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_ecc_count")

        for i, processor in enumerate(self.processors):
            for gpu_block_name, gpu_block, gpu_block_cond in self.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:
                    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._print_func_name("Starting performance test for amdsmi_get_gpu_ecc_enabled")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_ecc_status")
        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 self.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:
                    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._print_func_name("Starting performance test for amdsmi_get_gpu_enumeration_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_fan_rpms")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_id")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_kfd_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_mem_overdrive_level")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_memory_partition")

        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:
                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._print_func_name(
            "Starting performance test for amdsmi_get_gpu_memory_partition_config"
        )
        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_memory_reserved_pages")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_memory_total")

        for i, processor in enumerate(self.processors):
            for memory_type_name, memory_type, memory_type_cond in self.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, mem_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:
                    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._print_func_name("Starting performance test for amdsmi_get_gpu_memory_usage")

        for i, processor in enumerate(self.processors):
            for memory_type_name, memory_type, memory_type_cond in self.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, mem_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:
                    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._print_func_name("Starting performance test for amdsmi_get_gpu_metrics_header_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_metrics_info")
        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_od_volt_curve_regions")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_od_volt_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_overdrive_level")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_pci_bandwidth")
        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_pci_replay_counter")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_pci_throughput")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_perf_level")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_pm_metrics_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_power_profile_presets")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_process_isolation")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_process_list")

        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:
                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._print_func_name(
            "Starting performance test for amdsmi_get_gpu_ras_block_features_enabled"
        )

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_ras_feature_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_reg_table_info")
        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 self.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:
                    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._print_func_name("Starting performance test for amdsmi_get_gpu_revision")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_subsystem_id")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_subsystem_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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_topo_numa_affinity")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_total_ecc_count")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_vbios_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_vendor_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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_virtualization_mode")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_volt_metric")

        for i, processor in enumerate(self.processors):
            for voltage_type_name, voltage_type, voltage_type_cond in self.voltage_types:
                for (
                    voltage_metric_name,
                    voltage_metric,
                    voltage_metric_cond,
                ) in self.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:
                        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._print_func_name("Starting performance test for amdsmi_get_gpu_vram_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_vram_usage")

        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:
                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_vram_vendor(self):
        self._print_func_name("Starting performance test for amdsmi_get_gpu_vram_vendor")

        for i, processor in enumerate(self.processors):
            self._log_test_start("amdsmi_get_gpu_vram_vendor", "Processor", i)

            self._print_api_result(amdsmi.amdsmi_get_gpu_vram_vendor, i, processor)

            stats = self._measure_api_performance(
                amdsmi.amdsmi_get_gpu_vram_vendor, f"get_gpu_vram_vendor_gpu_{i}", processor
            )

            self.perf_results[f"get_gpu_vram_vendor_gpu_{i}"] = stats

            if stats["successful_runs"] > 0:
                self._print_performance_results(stats)
            else:
                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_vendor", "Processors", "get_gpu_vram_vendor"
        )

    def test_performance_get_gpu_xcd_counter(self):
        self._print_func_name("Starting performance test for amdsmi_get_gpu_xcd_counter")
        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:
                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._print_func_name("Starting performance test for amdsmi_get_gpu_xgmi_link_status")
        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:
                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._print_func_name("Starting performance test for amdsmi_get_lib_version")

        self._log_test_start("amdsmi_get_lib_version", "System", "global")

        # No processor needed for library version
        try:
            ret = amdsmi.amdsmi_get_lib_version()
            print(f"### test amdsmi_get_lib_version()")
            self._print("", ret)
        except amdsmi.AmdSmiLibraryException as e:
            print(f"### test amdsmi_get_lib_version()")
            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:
            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._print_func_name("Starting performance test for amdsmi_get_link_metrics")
        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:
                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._print_func_name("Starting performance test for amdsmi_get_link_topology_nearest")

        for i, processor in enumerate(self.processors):
            for link_type_name, link_type, link_type_cond in self.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:
                    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._print_func_name(
            "Starting performance test for amdsmi_get_minmax_bandwidth_between_processors"
        )

        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:
                    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._print_func_name("Starting performance test for amdsmi_get_pcie_info")
        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:
                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._print_func_name("Starting performance test for amdsmi_get_power_info")

        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:
                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._print_func_name(
            "Starting performance test for amdsmi_get_processor_count_from_handles"
        )

        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)
            print(f"### test amdsmi_get_processor_count_from_handles()")
            self._print("", ret)
        except amdsmi.AmdSmiLibraryException as e:
            print(f"### test amdsmi_get_processor_count_from_handles()")
            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:
            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._print_func_name("Starting performance test for amdsmi_get_processor_handle_from_bdf")

        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:
                        print(
                            f"  WARNING: GPU {i} - Handle mismatch! Expected: {processor.value}, Received: {ret.value}"
                        )
                else:
                    print(
                        f"  GPU {i}: All calls failed - {stats['errors'][0]['error_info'] if stats['errors'] else 'Unknown'}"
                    )
            except Exception as e:
                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._print_func_name("Starting performance test for amdsmi_get_processor_handles")

        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:
            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._print_func_name("Starting performance test for amdsmi_get_processor_handles_by_type")

        socket_handles = amdsmi.amdsmi_get_socket_handles()

        for index, socket_handle in enumerate(socket_handles):
            for processor_name, processor_type, processor_cond in self.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:
                    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._print_func_name("Starting performance test for amdsmi_get_processor_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_processor_type")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_socket_handles")

        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:
            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._print_func_name("Starting performance test for amdsmi_get_socket_info")

        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:
                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._print_func_name("Starting performance test for amdsmi_get_temp_metric")
        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 self.temperature_types:
                for (
                    temperature_metric_name,
                    temperature_metric,
                    temperature_metric_cond,
                ) in self.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:
                        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._print_func_name("Starting performance test for amdsmi_get_threads_per_core")
        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()
            print(f"### test amdsmi_get_threads_per_core()")
            self._print("", ret)
        except amdsmi.AmdSmiLibraryException as e:
            print(f"### test amdsmi_get_threads_per_core()")
            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:
            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._print_func_name("Starting performance test for amdsmi_get_utilization_count")
        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 self.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:
                    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._print_func_name("Starting performance test for amdsmi_get_violation_status")
        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:
                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._print_func_name("Starting performance test for amdsmi_get_xgmi_info")

        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:
                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._print_func_name("Starting performance test for GPU counter workflow")

        if self.TODO_SKIP_FAIL:
            self.skipTest("Skipping test_performance_gpu_counter as it fails (Error opening file).")

        for i, processor in enumerate(self.processors):
            for event_type_name, event_type, event_type_cond in self.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 self.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:
                        print(f"  GPU {i} {event_type_name}: Counter workflow failed - {e}")
                else:
                    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._print_func_name("Starting performance test for amdsmi_gpu_counter_group_supported")

        for i, processor in enumerate(self.processors):
            for event_group_name, event_group, event_group_cond in self.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:
                    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._print_func_name("Starting performance test for amdsmi_get_gpu_available_counters")

        for i, processor in enumerate(self.processors):
            for event_group_name, event_group_type, event_group_cond in self.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:
                    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._print_func_name("Starting performance test for amdsmi_gpu_validate_ras_eeprom")

        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:
                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._print_func_name("Starting performance test for amdsmi_gpu_xgmi_error_status")
        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:
                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._print_func_name("Starting performance test for amdsmi_init")

        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:
            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._print_func_name("Starting performance test for amdsmi_shut_down")

        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:
            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._print_func_name("Starting performance test for amdsmi_is_P2P_accessible")

        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:
                        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._print_func_name("Starting performance test for GPU event notification workflow")
        if self.TODO_SKIP_FAIL:
            self.skipTest("Skipping test_gpu_event as it fails (File Error).")
        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:
                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._print_func_name("Starting performance test for amdsmi_reset_gpu")

        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:
                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._print_func_name("Starting performance test for amdsmi_reset_gpu_fan")

        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:
                    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._print_func_name("Starting performance test for amdsmi_reset_gpu_xgmi_error")
        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:
                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._print_func_name("Starting performance test for amdsmi_set_clk_freq")

        if self.TODO_SKIP_FAIL:
            self.skipTest("Skipping test_performance_set_clk_freq as it fails (Perm failure).")

        for i, processor in enumerate(self.processors):
            for clk_type_name, clk_type, clk_cond in self.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:
                        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:
                    amdsmi.amdsmi_set_clk_freq(processor, clk_type_name, frequency[current])
                except amdsmi.AmdSmiLibraryException:
                    pass

        self._log_performance_summary("amdsmi_set_clk_freq", "GPUs", "set_clk_freq")

    def test_performance_set_gpu_accelerator_partition_profile(self):
        self._print_func_name(
            "Starting performance test for amdsmi_set_gpu_accelerator_partition_profile"
        )

        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:
                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._print_func_name("Starting performance test for amdsmi_set_gpu_clk_limit")

        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 self.clk_types:
                for clk_limit_type_name, clk_limit_type, clk_limit_cond in self.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:
                        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_clk_range(self):
        self._print_func_name("Starting performance test for amdsmi_set_gpu_clk_range")

        # Use TODO placeholder values like original test
        min_clk_value = 100
        max_clk_value = 200

        for i, processor in enumerate(self.processors):
            for clk_type_name, clk_type, clk_cond in self.clk_types:
                self._log_test_start(
                    "amdsmi_set_gpu_clk_range",
                    "Processor",
                    i,
                    min_clk_value=min_clk_value,
                    max_clk_value=max_clk_value,
                    clk_type=clk_type_name,
                )

                stats = self._measure_api_performance(
                    amdsmi.amdsmi_set_gpu_clk_range,
                    f"set_gpu_clk_range_processor_{i}_clk_{clk_type_name}",
                    processor,
                    min_clk_value,
                    max_clk_value,
                    clk_type,
                )

                self.perf_results[f"set_gpu_clk_range_processor_{i}_clk_{clk_type_name}"] = stats

                if stats["successful_runs"] > 0:
                    self._print_performance_results(stats)
                else:
                    print(
                        f"  Processor {i} clk={clk_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}")

        self._log_performance_summary("amdsmi_set_gpu_clk_range", "Processors", "set_gpu_clk_range")

    def test_performance_set_gpu_compute_partition(self):
        self._print_func_name("Starting performance test for amdsmi_set_gpu_compute_partition")

        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 = self.compute_partition_types[0][1]

                    # Find the default partition type
                    for (
                        compute_partition_type_name,
                        compute_partition_type,
                        compute_partition_type_cond,
                    ) in self.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:
                            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:
                    print(f"  Processor {i}: Could not get default compute partition")
            else:
                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._print_func_name("Starting performance test for GPU fan speed workflow")

        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:
                    print(f"  Processor {i}: Could not complete fan speed workflow")
            else:
                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._print_func_name("Starting performance test for amdsmi_set_gpu_memory_partition")

        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 self.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:
                    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._print_func_name("Starting performance test for amdsmi_set_gpu_memory_partition_mode")

        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 self.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:
                    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._print_func_name("Starting performance test for amdsmi_set_gpu_od_clk_info")

        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 self.freq_inds:
                for clk_type_name, clk_type, clk_cond in self.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:
                        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._print_func_name("Starting performance test for amdsmi_set_gpu_od_volt_info")

        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:
                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._print_func_name("Starting performance test for GPU overdrive level workflow")

        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:
                    print(f"  Processor {i}: Could not complete overdrive workflow")
            else:
                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._print_func_name("Starting performance test for GPU PCI bandwidth workflow")

        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:
                    print(f"  Processor {i}: Could not complete PCI bandwidth workflow")
            else:
                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._print_func_name("Starting performance test for amdsmi_set_gpu_perf_determinism_mode")

        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:
                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._print_func_name("Starting performance test for GPU perf level workflow")

        # Check if dev_perf_levels is populated, skip test if not
        if not self.dev_perf_levels:
            self.skipTest("dev_perf_levels not initialized - skipping performance level test")
            return

        dev_perf_level_current = self.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 self.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:
                            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:
                    print(f"  Processor {i}: Could not complete perf level workflow")
            else:
                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._print_func_name("Starting performance test for amdsmi_set_gpu_power_profile")

        for i, processor in enumerate(self.processors):
            for (
                power_profile_preset_mask_name,
                power_profile_preset_mask,
                power_profile_preset_masks_cond,
            ) in self.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:
                    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._print_func_name("Starting performance test for amdsmi_set_gpu_process_isolation")

        # 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:
                    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._print_func_name("Starting performance test for power cap workflow")

        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:
                    print(f"  Processor {i}: Could not complete power cap workflow")
            else:
                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._print_func_name("Starting performance test for SoC pstate workflow")

        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):
                    print(f"  Processor {i}: Could not complete SoC pstate workflow")
            else:
                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._print_func_name("Starting performance test for XGMI PLPD workflow")

        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):
                    print(f"  Processor {i}: Could not complete XGMI PLPD workflow")
            else:
                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._print_func_name("Starting performance test for amdsmi_status_code_to_string")

        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))
                print(f"### test amdsmi_status_code_to_string(error={error_num})")
                self._print("", ret)
            except amdsmi.AmdSmiLibraryException as e:
                print(f"### test amdsmi_status_code_to_string(error={error_num})")
                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:
                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._print_func_name("Starting performance test for amdsmi_topo_get_link_type")

        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:
                    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._print_func_name("Starting performance test for amdsmi_topo_get_link_weight")

        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:
                    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._print_func_name("Starting performance test for amdsmi_topo_get_numa_node_number")

        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:
                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._print_func_name("Starting performance test for amdsmi_topo_get_p2p_status")

        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:
                    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._print_func_name("Starting performance test for amdsmi_get_gpu_busy_percent")

        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:
                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)
# =============================================================================


def generate_reports_from_output():
    """
    Generate enhanced and table reports from test output.
    This function replicates the Python report generation from perf_test.sh.
    """
    import os
    import re
    from datetime import datetime
    from statistics import mean

    script_dir = os.path.dirname(os.path.abspath(__file__))

    # Read the captured test output
    log_file = os.path.join(script_dir, "_perf_test.log")
    if not os.path.exists(log_file):
        print(f"⚠️  Warning: Performance log not found: {log_file}")
        return False

    with open(log_file, "r") as f:
        content = f.read()

    # Parse test results
    lines = content.split("\n")
    tests = []
    current_test = None
    workflow_tests = []

    for line in lines:
        line = line.strip()
        if not line:
            continue

        if line.startswith("Testing "):
            parts = line.replace("Testing ", "").split(" on ")
            api_name = parts[0]
            current_test = {"name": api_name}
            workflow_tests = []

        elif line.startswith("Performance ") and "avg" in line and current_test:
            avg_match = re.search(r"(\d+\.\d+)ms avg", line)
            err_match = re.search(r"(\d+) errors", line)

            if avg_match and err_match:
                perf_line_match = re.match(
                    r"Performance\s+(\S+?)(?:_processor_\d+|_gpu_\d+|_socket_\d+|_system)?:", line
                )

                perf_test = {"avg_ms": float(avg_match.group(1)), "errors": int(err_match.group(1))}

                if perf_line_match:
                    perf_test["name"] = perf_line_match.group(1)
                else:
                    perf_test["name"] = current_test["name"]

                workflow_tests.append(perf_test)

        elif "All calls failed" in line and current_test:
            if workflow_tests and "avg_ms" not in workflow_tests[-1]:
                time_match = re.search(r"(\d+\.\d+)ms avg", line)
                if time_match:
                    workflow_tests[-1]["avg_ms"] = float(time_match.group(1))
                    workflow_tests[-1]["errors"] = 11

        elif re.match(r"\s*\d+\s*\|\s*AMDSMI_STATUS_", line) and workflow_tests:
            error_match = re.search(r"(\d+)\s*\|\s*(AMDSMI_STATUS_\w+)", line)
            if error_match and workflow_tests:
                workflow_tests[-1]["error_name"] = error_match.group(2)

        elif line.startswith("Performance test completed for") and current_test:
            for perf_test in workflow_tests:
                if "avg_ms" in perf_test:
                    api_name = perf_test["name"]

                    if perf_test["errors"] > 0 and "error_name" not in perf_test:
                        if "fan" in api_name.lower() or "overdrive" in api_name.lower():
                            perf_test["error_name"] = "AMDSMI_STATUS_NOT_SUPPORTED"
                        else:
                            perf_test["error_name"] = "AMDSMI_STATUS_NOT_SUPPORTED"

                    perf_test["category"] = (
                        "FUNCTIONAL" if perf_test["errors"] == 0 else "ERROR_MEASUREMENT"
                    )
                    tests.append(perf_test)

            workflow_tests = []
            current_test = None

    # Separate tests by category
    functional_tests = sorted(
        [t for t in tests if t["category"] == "FUNCTIONAL"], key=lambda x: x["avg_ms"]
    )
    error_tests = sorted(
        [t for t in tests if t["category"] == "ERROR_MEASUREMENT"], key=lambda x: x["avg_ms"]
    )

    # Generate Enhanced Report
    enhanced_file = os.path.join(script_dir, "_perf_test_enhanced.log")
    with open(enhanced_file, "w") as f:
        f.write("╔" + "═" * 78 + "╗\n")
        f.write("║" + " AMD SMI PYTHON PERFORMANCE TEST RESULTS".center(78) + "║\n")
        f.write(
            "║"
            + f" Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
            + " " * (78 - len(f" Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"))
            + "║\n"
        )
        f.write("╚" + "═" * 78 + "╝\n\n")

        total = len(tests)
        f.write("📊 SUMMARY STATISTICS\n")
        f.write("─" * 50 + "\n")
        f.write(f"Total Tests Executed: {total}\n")
        f.write(
            f"✅ Working APIs: {len(functional_tests)} ({len(functional_tests) / total * 100:.1f}%)\n"
        )
        f.write(
            f"⚠️  APIs with Expected Errors: {len(error_tests)} ({len(error_tests) / total * 100:.1f}%)\n\n"
        )

        if functional_tests:
            avg_times = [t["avg_ms"] for t in functional_tests]
            f.write("⚡ PERFORMANCE METRICS (Working APIs Only)\n")
            f.write("─" * 50 + "\n")
            f.write(f"Fastest API: {min(avg_times):.3f}ms\n")
            f.write(f"Slowest API: {max(avg_times):.3f}ms\n")
            f.write(f"Average Time: {mean(avg_times):.3f}ms\n\n")

            f.write("🏆 TOP 10 FASTEST APIs\n")
            f.write("─" * 50 + "\n")
            for i, test in enumerate(functional_tests[:10], 1):
                f.write(f"{i:2d}. {test['name']} - {test['avg_ms']:.3f}ms\n")
            f.write("\n")

    print(f"✅ Enhanced report: {enhanced_file}")

    # Generate Table Report
    table_file = os.path.join(script_dir, "_perf_test_table.log")
    with open(table_file, "w") as f:
        f.write("╔" + "═" * 168 + "╗\n")
        f.write("║" + "AMD SMI PYTHON PERFORMANCE TEST RESULTS".center(168) + "║\n")
        f.write("║" + "TABLE FORMAT".center(168) + "║\n")
        f.write("╠" + "═" * 168 + "╣\n")
        gen_text = f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
        f.write("║ " + gen_text + " " * (166 - len(gen_text)) + " ║\n")
        f.write("╚" + "═" * 168 + "╝\n\n")

        total = len(tests)
        f.write("📊 SUMMARY STATISTICS\n")
        f.write("═" * 170 + "\n")
        f.write(f"Total Tests Executed   : {total}\n")
        f.write(
            f"✅ Functional Tests    : {len(functional_tests)} ({len(functional_tests) / total * 100:.1f}%)\n"
        )
        f.write(
            f"⚠️  Error Measurements  : {len(error_tests)} ({len(error_tests) / total * 100:.1f}%)\n\n"
        )

        if functional_tests:
            avg_times = [t["avg_ms"] for t in functional_tests]
            fastest = min(functional_tests, key=lambda x: x["avg_ms"])
            slowest = max(functional_tests, key=lambda x: x["avg_ms"])

            f.write(f"⚡ Fastest API          : {min(avg_times):.3f}ms ({fastest['name']})\n")
            f.write(f"🐌 Slowest API          : {max(avg_times):.3f}ms ({slowest['name']})\n")
            f.write(f"📈 Average Time         : {mean(avg_times):.3f}ms\n")
        f.write("\n")

        if functional_tests:
            f.write("✅ FUNCTIONAL TESTS (APIs Returning Valid Data)\n")
            f.write("═" * 170 + "\n")
            f.write(
                "┌──────┬───────────────────────────────────────────────────────────────────┬─────────────┬─────────────────────────────────────────────┐\n"
            )
            f.write(
                "│ Rank │ API Name                                                          │ Time (ms)   │ Status                                      │\n"
            )
            f.write(
                "├──────┼───────────────────────────────────────────────────────────────────┼─────────────┼─────────────────────────────────────────────┤\n"
            )

            for i, test in enumerate(functional_tests, 1):
                name = test["name"][:65] + "..." if len(test["name"]) > 65 else test["name"]
                f.write(f"│ {i:4d} │ {name:<65} │ {test['avg_ms']:>9.3f}   │ {'':<40}✅ │\n")

            f.write(
                "└──────┴───────────────────────────────────────────────────────────────────┴─────────────┴─────────────────────────────────────────────┘\n\n"
            )

        if error_tests:
            f.write("⚠️ ERROR MEASUREMENT TESTS (APIs Correctly Returning Expected Errors)\n")
            f.write("═" * 170 + "\n")
            f.write(
                "┌──────┬───────────────────────────────────────────────────────────────────┬─────────────┬──────────────────────────────────────────┐\n"
            )
            f.write(
                "│ #    │ API Name                                                          │ Time (ms)   │ Error Code                               │\n"
            )
            f.write(
                "├──────┼───────────────────────────────────────────────────────────────────┼─────────────┼──────────────────────────────────────────┤\n"
            )

            for i, test in enumerate(error_tests, 1):
                name = test["name"][:65] + "..." if len(test["name"]) > 65 else test["name"]
                error_info = test.get("error_name", f"{test['errors']} errors")
                if len(error_info) > 40:
                    error_info = error_info[:37] + "..."
                f.write(f"│ {i:4d} │ {name:<65} │ {test['avg_ms']:>9.3f}   │ {error_info:<40} │\n")

            f.write(
                "└──────┴───────────────────────────────────────────────────────────────────┴─────────────┴──────────────────────────────────────────┘\n\n"
            )

        # Performance categories
        if tests:
            f.write("🏃 PERFORMANCE CATEGORIES\n")
            f.write("═" * 170 + "\n")
            ultra_fast = [t for t in tests if t["avg_ms"] < 0.01]
            fast = [t for t in tests if 0.01 <= t["avg_ms"] < 0.1]
            medium = [t for t in tests if 0.1 <= t["avg_ms"] < 1.0]
            slow = [t for t in tests if t["avg_ms"] >= 1.0]

            f.write(f"🚀 Ultra Fast (< 0.01ms)    : {len(ultra_fast):2d} tests\n")
            f.write(f"⚡ Fast (0.01-0.1ms)        : {len(fast):2d} tests\n")
            f.write(f"🚶 Medium (0.1-1.0ms)       : {len(medium):2d} tests\n")
            f.write(f"🐌 Slow (>= 1.0ms)          : {len(slow):2d} tests\n\n")

        f.write("═" * 170 + "\n")
        f.write(f"Report generated by AMD SMI Performance Test (Python Version)\n")
        f.write(f"For detailed logs, see: _perf_test.log and _perf_test_err.log\n\n")
        f.write('📝 NOTE: "Error Measurement Tests" are successful performance measurements\n')
        f.write(
            "   of APIs that correctly return expected error codes (e.g., AMDSMI_STATUS_NOT_SUPPORTED)\n"
        )
        f.write("   These are NOT test failures - they are successful timing measurements.\n")
        f.write("═" * 170 + "\n")

    print(f"✅ Table report: {table_file}")
    print(f"✅ Raw output: {log_file}")

    return True


if __name__ == "__main__":
    import os
    import sys
    import subprocess
    from datetime import datetime

    # Check if user wants simple unittest mode (no report generation)
    if "--unittest-only" in sys.argv:
        sys.argv.remove("--unittest-only")
        unittest.main()
        sys.exit(0)

    script_dir = os.path.dirname(os.path.abspath(__file__))

    # Print header
    print("\n" + "═" * 80)
    print("AMD SMI PYTHON PERFORMANCE TEST".center(80))
    print("═" * 80 + "\n")

    print(f"📍 Test directory: {script_dir}")
    print(f"📄 Test file: {__file__}")
    print(f"🕐 Started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")

    # Step 1: Clean previous results
    print("\n[STEP 1] Cleaning previous results...")
    log_files = [
        "_perf_test.log",
        "_perf_test_err.log",
        "_perf_test_enhanced.log",
        "_perf_test_table.log",
    ]
    removed = 0
    for log_file in log_files:
        full_path = os.path.join(script_dir, log_file)
        if os.path.exists(full_path):
            os.remove(full_path)
            removed += 1

    if removed > 0:
        print(f"✅ Cleaned {removed} previous result file(s)")
    else:
        print("ℹ️  No previous results to clean")

    # Step 2: Run performance tests with output capture
    print("\n[STEP 2] Running performance tests...")
    print("⏳ Executing tests...")

    log_file = os.path.join(script_dir, "_perf_test.log")
    err_file = os.path.join(script_dir, "_perf_test_err.log")

    # Run tests with unittest and capture output
    with open(log_file, "w") as f_out, open(err_file, "w") as f_err:
        # Run the tests using unittest directly
        loader = unittest.TestLoader()
        suite = loader.loadTestsFromTestCase(TestAmdSmiPythonPerformance)
        runner = unittest.TextTestRunner(stream=f_err, verbosity=2)

        # Redirect stdout to capture performance output
        old_stdout = sys.stdout
        sys.stdout = f_out

        result = runner.run(suite)

        sys.stdout = old_stdout

    # Also display output to console
    with open(log_file, "r") as f:
        output_preview = f.readlines()
        # Show last 20 lines of output
        print("\n".join(output_preview[-20:]))

    if result.wasSuccessful():
        print("✅ Performance tests completed successfully")
    else:
        print("⚠️  Performance tests completed with some issues")

    # Step 3: Generate reports
    print("\n[STEP 3] Generating reports...")

    if generate_reports_from_output():
        # Step 4: Show results summary
        print("\n[STEP 4] Results Summary")
        print("═" * 80)
        print("                    🎉 TEST COMPLETE".center(80))
        print("═" * 80 + "\n")

        print("📊 Generated Output Files:\n")
        for log_file in log_files:
            full_path = os.path.join(script_dir, log_file)
            if os.path.exists(full_path):
                size = os.path.getsize(full_path) / 1024
                desc = {
                    "_perf_test_enhanced.log": "Enhanced Summary Report",
                    "_perf_test_table.log": "Tabular Results Report",
                    "_perf_test_err.log": "Error Log & Test Status",
                    "_perf_test.log": "Complete Test Output",
                }.get(log_file, "Output File")

                print(f"  {desc} ({size:.1f} KB)")
                print(f"  → {full_path}\n")

        # Show preview of enhanced report
        print("📈 Quick Stats Preview:")
        print("═" * 80)
        enhanced_path = os.path.join(script_dir, "_perf_test_enhanced.log")
        if os.path.exists(enhanced_path):
            with open(enhanced_path, "r") as f:
                lines = f.readlines()
                # Show first 15 lines
                print("".join(lines[:15]))
        print("═" * 80 + "\n")

        print(f"✅ All reports generated in: {script_dir}")
        print(f"🕐 Finished: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        print("\n" + "═" * 80 + "\n")
    else:
        print("⚠️  Report generation failed")
        sys.exit(1)

    # Exit with appropriate code
    sys.exit(0 if result.wasSuccessful() else 1)
