Download TB-eval/tb_eval/perf/efficiency.py from amd/geak_eval: direct link, hf CLI and curl.
- Browser
- Download file 12.2 kB
-
https://huggingface.co/amd/geak_eval/resolve/main/TB-eval/tb_eval/perf/efficiency.py
- Command line
-
hf download hf://amd/geak_eval/TB-eval/tb_eval/perf/efficiency.py
-
curl -L -o efficiency.py https://huggingface.co/amd/geak_eval/resolve/main/TB-eval/tb_eval/perf/efficiency.py
12.2 kB
| # Copyright(C) [2025] Advanced Micro Devices, Inc. All rights reserved. | |
| import os | |
| import shutil | |
| import json | |
| from .base import BasePerfEval | |
| from ..helpers.helper import run_shell | |
| from ..constants import TBG_PERF_GOLD_DATA_ROOT, ROCM_PERF_GOLD_DATA_ROOT | |
| class PerformanceEvalTBG(BasePerfEval): | |
| """ | |
| Performance evaluation for the TBG model. | |
| This class inherits from BasePerfEval and implements the evaluate method. | |
| """ | |
| ref_folder = TBG_PERF_GOLD_DATA_ROOT | |
| def __init__(self, name :str='PerformanceEvalTBG'): | |
| """ | |
| Initialize the PerformanceEvalTBG instance. | |
| Args: | |
| name (str): The name of the performance evaluation instance. | |
| """ | |
| super().__init__(name=name) | |
| def evaluate(self, exec_folder: str, gen_perf_folder: str=None, golden_metrics_folder:str=None) -> dict: | |
| """ | |
| Evaluate the performance of the TBG model on the given data. | |
| Args: | |
| folder: Root location with kernels to evaluate. | |
| Returns: | |
| A dictionary containing the evaluation results. | |
| """ | |
| ref_folder = self.ref_folder | |
| print(f"Running performance analysis for {exec_folder}") | |
| assert os.path.exists(exec_folder), f"Execution folder {exec_folder} does not exist." | |
| gen_perf_folder = os.path.join(exec_folder, 'gen_perf') if gen_perf_folder is None else gen_perf_folder | |
| ## if gen_perf_folder exists, remove it | |
| if os.path.exists(gen_perf_folder): | |
| print(f"Removing existing performance folder: {gen_perf_folder}") | |
| shutil.rmtree(gen_perf_folder) | |
| os.makedirs( gen_perf_folder, exist_ok=True) | |
| exec_folder = os.path.abspath(exec_folder) | |
| gen_perf_folder = os.path.abspath(gen_perf_folder) | |
| curr_dir = os.path.dirname(os.path.abspath(__file__)) | |
| print("Writing files to the performance folder...") | |
| cmd = [f'python3 {curr_dir}/run_bench/write_file.py --input_folder_path {exec_folder} --result_folder_path {gen_perf_folder}'] | |
| if golden_metrics_folder: | |
| cmd[-1] += f' --golden_metrics_folder {golden_metrics_folder}' | |
| write_status, write_stdout, write_stderr = run_shell(cmd) | |
| print(f"Write status: {write_status}, stdout: {write_stdout}, stderr: {write_stderr}") | |
| perf_stdout = None | |
| if write_status: | |
| print("Files written successfully to the performance folder. Running them...") | |
| cmd = [f"python3 {curr_dir}/run_bench/multiprocess_gpu_run.py --root_dir {gen_perf_folder}"] | |
| mp_run_status, mp_run_stdout, mp_run_stderr = run_shell(cmd) | |
| print(f"Multiprocess GPU run status: {mp_run_status}, stdout: {mp_run_stdout}, stderr: {mp_run_stderr}") | |
| if mp_run_status: | |
| print("Multiprocess GPU run completed successfully. Running performance analysis...") | |
| cmd = [f"python3 {curr_dir}/2_efficiency.py --gen_folder {gen_perf_folder} --ref_folder {ref_folder}"] | |
| perf_status, perf_stdout, perf_stderr = run_shell(cmd) | |
| print(f"Performance analysis status: {perf_status}, stdout: {perf_stdout}, stderr: {perf_stderr}") | |
| if perf_status: | |
| print(f"Performance analysis completed successfully for {exec_folder}.") | |
| with open(os.path.join(exec_folder, 'performance_analysis.txt'), 'w') as f: | |
| f.write(f"Performance analysis for {exec_folder}:\n") | |
| f.write(perf_stdout) | |
| else: | |
| assert False, f"Failed to run 2_efficiency.py: {perf_stderr}" | |
| else: | |
| assert False, f"Failed to run multiprocess_gpu_run.py: {mp_run_stderr}" | |
| else: | |
| assert False, f"Failed to write files: {write_stderr}" | |
| print(f"DONE with performance analysis for {exec_folder}") | |
| parser_perf_data = self.parse(gen_perf_folder) | |
| return parser_perf_data | |
| def parse(self, perf_data_path:str) -> dict: | |
| eff_fname = os.path.join(perf_data_path, 'efficiency.json') | |
| parsed_perf_data = {} | |
| if os.path.exists(eff_fname): | |
| with open(eff_fname, 'r') as f: | |
| perf_data = json.load(f) | |
| parsed_perf_data = perf_data | |
| return parsed_perf_data | |
| class PerformanceEvalROCm(BasePerfEval): | |
| """ | |
| Performance evaluation for the ROCm kernels. | |
| This class inherits from BaseEval and implements the evaluate method. | |
| """ | |
| ref_folder = ROCM_PERF_GOLD_DATA_ROOT | |
| def __init__(self, name: str = 'PerformanceEvalROCm', ref_folder: str = None): | |
| """ | |
| Initialize the PerformanceEvalROCm instance. | |
| Args: | |
| name (str): The name of the performance evaluation instance. | |
| """ | |
| super().__init__(name=name) | |
| if ref_folder is not None: | |
| self.ref_folder = ref_folder | |
| else: | |
| self.ref_folder = ROCM_PERF_GOLD_DATA_ROOT | |
| def evaluate(self, exec_folder: str, gen_perf_folder: str = None, golden_metrics_folder: str = None) -> dict: | |
| """ | |
| Evaluate the performance of ROCm kernels. | |
| Args: | |
| exec_folder: Root location with kernels (py files with pytest functions) to evaluate. | |
| gen_perf_folder: Folder where performance JSONs will be stored. Defaults to exec_folder/perf. | |
| golden_metrics_folder: Not used in this evaluation. | |
| Returns: | |
| A dictionary containing the evaluation results (ms and efficiency for each file). | |
| """ | |
| print(f"Running ROCm performance analysis for {exec_folder}") | |
| assert os.path.exists(exec_folder), f"Execution folder {exec_folder} does not exist." | |
| if gen_perf_folder is None: | |
| gen_perf_folder = os.path.join(exec_folder, 'perf') | |
| if os.path.exists(gen_perf_folder): | |
| print(f"Removing existing performance folder: {gen_perf_folder}") | |
| shutil.rmtree(gen_perf_folder) | |
| os.makedirs(gen_perf_folder, exist_ok=True) | |
| print(f"Ensured gen_perf_folder exists at: {gen_perf_folder}") | |
| exec_folder_abs = os.path.abspath(exec_folder) | |
| gen_perf_folder_abs = os.path.abspath(gen_perf_folder) | |
| curr_dir = os.path.dirname(os.path.abspath(__file__)) | |
| py_files = [f for f in os.listdir(exec_folder_abs) if os.path.isfile(os.path.join(exec_folder_abs, f)) and f.endswith('.py')] | |
| if not py_files: | |
| print(f"No .py files found in {exec_folder_abs}. Skipping pytest execution.") | |
| else: | |
| print(f"Found .py files to test: {py_files}") | |
| for py_file_name in py_files: | |
| py_file_path = os.path.join(exec_folder_abs, py_file_name) | |
| # Define the specific tests to run in order: test_performance then test_save_performance_results | |
| tests_to_run_specifiers = f"{py_file_path}::test_performance {py_file_path}::test_save_performance_results" | |
| print(f"Running pytest for {py_file_path} (test_performance then test_save_performance_results)...") | |
| cmd_pytest = [f"pytest {tests_to_run_specifiers}"] | |
| # Pass gen_perf_folder_abs as an environment variable so tests can use it | |
| test_env = os.environ.copy() | |
| test_env["PERF_OUTPUT_DIR"] = gen_perf_folder_abs | |
| global_timeout = 30*60 | |
| try: | |
| pytest_status, pytest_stdout, pytest_stderr = run_shell(cmd_pytest, env=test_env, timeout=global_timeout) | |
| except TimeoutError as e: | |
| pytest_status = False | |
| pytest_stdout = None | |
| pytest_stderr = str(e) | |
| print(f"Pytest execution timed out for {py_file_path} (test_performance & test_save_performance_results): {pytest_stderr}") | |
| print(f"Pytest run for {py_file_path} (test_performance & test_save_performance_results) status: {pytest_status}") | |
| if pytest_stdout: | |
| print(f"Stdout: {pytest_stdout}") | |
| if pytest_stderr: | |
| print(f"Stderr: {pytest_stderr}") | |
| if not pytest_status: | |
| assert False, f"Pytest execution failed for {py_file_path} (test_performance & test_save_performance_results): {pytest_stderr}" | |
| print("All pytest runs completed.") | |
| efficiency_script_path = os.path.join(curr_dir, "ROCm", "efficiency.py") | |
| # Attempt to find ROCm folder if it's a sibling to the 'perf' directory (where this script might be) | |
| if not os.path.exists(efficiency_script_path): | |
| # curr_dir is .../perf, so os.path.dirname(curr_dir) is the parent of 'perf' | |
| alt_efficiency_script_path = os.path.join(os.path.dirname(curr_dir), "ROCm", "efficiency.py") | |
| if os.path.exists(alt_efficiency_script_path): | |
| efficiency_script_path = alt_efficiency_script_path | |
| else: | |
| # Check if ROCm is a direct subdirectory of the current script's location | |
| potential_path = os.path.join(curr_dir, "ROCm", "efficiency.py") | |
| if os.path.exists(potential_path): | |
| efficiency_script_path = potential_path | |
| else: | |
| assert False, f"Efficiency script not found. Checked: {os.path.join(curr_dir, 'ROCm', 'efficiency.py')} and {alt_efficiency_script_path}" | |
| cmd_efficiency = [f"python3 {efficiency_script_path} --gen_folder {gen_perf_folder_abs} --ref_folder {self.ref_folder}"] | |
| print(f"Running efficiency script: {' '.join(cmd_efficiency)}") | |
| eff_status, eff_stdout, eff_stderr = run_shell(cmd_efficiency) | |
| print(f"Efficiency script status: {eff_status}") | |
| if eff_stdout: | |
| print(f"Stdout: {eff_stdout}") | |
| if eff_stderr: | |
| print(f"Stderr: {eff_stderr}") | |
| if not eff_status: | |
| assert False, f"Failed to run efficiency script {efficiency_script_path}: {eff_stderr}" | |
| print(f"ROCm performance analysis script completed for {exec_folder}.") | |
| try: | |
| with open(os.path.join(exec_folder_abs, 'rocm_performance_analysis.txt'), 'w') as f: | |
| f.write(f"ROCm Performance analysis for {exec_folder_abs}:\n") | |
| f.write(f"Pytest phase produced outputs in {gen_perf_folder_abs}\n\n") | |
| f.write("Efficiency script stdout:\n") | |
| f.write(eff_stdout or "N/A") | |
| if eff_stderr: | |
| f.write("\n\nEfficiency script stderr:\n") | |
| f.write(eff_stderr) | |
| except Exception as e: | |
| print(f"Failed to write rocm_performance_analysis.txt: {e}") | |
| parsed_perf_data = self.parse(gen_perf_folder_abs) | |
| return parsed_perf_data | |
| def parse(self, perf_data_path: str) -> dict: | |
| """ | |
| Parse the all_perf_results.json file generated by the ROCm efficiency script. | |
| Args: | |
| perf_data_path: Path to the folder containing all_perf_results.json (this is gen_perf_folder). | |
| Returns: | |
| A dictionary containing the parsed performance data (ms and efficiency). | |
| """ | |
| eff_fname = os.path.join(perf_data_path, 'all_perf_results.json') | |
| parsed_perf_data = {} | |
| if os.path.exists(eff_fname): | |
| print(f"Parsing performance data from {eff_fname}") | |
| try: | |
| with open(eff_fname, 'r') as f: | |
| perf_data = json.load(f) | |
| parsed_perf_data = perf_data | |
| except json.JSONDecodeError as e: | |
| print(f"Error decoding JSON from {eff_fname}: {e}. Returning empty data.") | |
| except Exception as e: | |
| print(f"An unexpected error occurred while parsing {eff_fname}: {e}. Returning empty data.") | |
| else: | |
| print(f"Performance results file not found: {eff_fname}. Returning empty data.") | |
| return parsed_perf_data | |
| get_perf_evaluators = { | |
| 'tbg': PerformanceEvalTBG, | |
| 'rocm': PerformanceEvalROCm | |
| } |