diff --git a/projects/rocprofiler-compute/CHANGELOG.md b/projects/rocprofiler-compute/CHANGELOG.md index bb1a80a58f..2c1e0fc4db 100644 --- a/projects/rocprofiler-compute/CHANGELOG.md +++ b/projects/rocprofiler-compute/CHANGELOG.md @@ -6,6 +6,8 @@ Full documentation for ROCm Compute Profiler is available at [https://rocm.docs. ### Added +* Support Roofline plot on CLI (single run) + * Stochastic (hardware-based) PC sampling has been enabled for AMD Instinct MI300X series and later accelerators. * Sorting of PC sampling by type: offset or count. @@ -60,7 +62,7 @@ Full documentation for ROCm Compute Profiler is available at [https://rocm.docs. * Add --rocprofiler-sdk-library-path runtime option to choose the path to rocprofiler-sdk library to be used * Using rocprof v1 / v2 / v3 interfaces will trigger a deprecation warning to use rocprofiler-sdk interface -* Support MEM chart on CLI(single run) +* Support MEM chart on CLI (single run) * Add deprecation warning for database update mode. diff --git a/projects/rocprofiler-compute/src/config.py b/projects/rocprofiler-compute/src/config.py index 2cdcbd63d6..f758a65038 100644 --- a/projects/rocprofiler-compute/src/config.py +++ b/projects/rocprofiler-compute/src/config.py @@ -26,4 +26,7 @@ from pathlib import Path # NB: Creating a new module to share global vars across modules rocprof_compute_home = Path(__file__).resolve().parent -prog = "rocprofiler-compute" +PROJECT_NAME = "rocprofiler-compute" + +HIDDEN_COLUMNS = ["Tips", "coll_level"] +HIDDEN_SECTIONS = [400, 1900, 2000] diff --git a/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_cli.py b/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_cli.py index 83895dd707..22ceece5e0 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_cli.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_cli.py @@ -79,6 +79,7 @@ class cli_analysis(OmniAnalyze_Base): def run_analysis(self): """Run CLI analysis.""" super().run_analysis() + if self.get_args().list_stats: tty.show_kernel_stats( self.get_args(), @@ -89,6 +90,26 @@ class cli_analysis(OmniAnalyze_Base): self._output, ) else: + roof_plot = None + # 1. check if not baseline && compatible soc: + if (len(self.get_args().path)) == 1 and self._runs[ + self.get_args().path[0][0] + ].sys_info.iloc[0]["gpu_arch"] in [ + "gfx90a", + "gfx940", + "gfx941", + "gfx942", + "gfx950", + ]: + # add roofline plot to cli output + roof_obj = self.get_socs()[ + self._runs[self.get_args().path[0][0]].sys_info.iloc[0]["gpu_arch"] + ].roofline_obj + + if roof_obj: + # NOTE: using default data type + roof_plot = roof_obj.cli_generate_plot(roof_obj.get_dtype()[0]) + tty.show_all( self.get_args(), self._runs, @@ -97,4 +118,5 @@ class cli_analysis(OmniAnalyze_Base): ], self._output, self._profiling_config, + roof_plot=roof_plot, ) diff --git a/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_webui.py b/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_webui.py index 7f72c7f651..30627f18fb 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_webui.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_webui.py @@ -32,13 +32,12 @@ import dash_bootstrap_components as dbc from dash import dcc, html from dash.dependencies import Input, Output, State +from config import HIDDEN_COLUMNS, PROJECT_NAME from rocprof_compute_analyze.analysis_base import OmniAnalyze_Base from utils import file_io, parser from utils.gui import build_bar_chart, build_table_chart from utils.logger import console_debug, console_error, demarcate -PROJECT_NAME = "rocprofiler-compute" - class webui_analysis(OmniAnalyze_Base): def __init__(self, args, supported_archs): @@ -50,7 +49,7 @@ class webui_analysis(OmniAnalyze_Base): self.arch = None self.__hidden_sections = ["Memory Chart", "Roofline"] - self.__hidden_columns = ["Tips", "coll_level"] + self.__hidden_columns = HIDDEN_COLUMNS # define different types of bar charts self.__barchart_elements = { "instr_mix": [1001, 1002], diff --git a/projects/rocprofiler-compute/src/rocprof_compute_base.py b/projects/rocprofiler-compute/src/rocprof_compute_base.py index 6ae7f285f6..828ac9bd48 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_base.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_base.py @@ -322,7 +322,7 @@ class RocProfCompute: profiler.pre_processing() console_debug('starting "run_profiling" and about to start rocprof\'s workload') time_start_prof = time.time() - profiler.run_profiling(self.__version["ver"], config.prog) + profiler.run_profiling(self.__version["ver"], config.PROJECT_NAME) time_end_prof = time.time() console_debug( 'finished "run_profiling" and finished rocprof\'s workload, time taken was {} m {} sec'.format( diff --git a/projects/rocprofiler-compute/src/rocprof_compute_soc/analysis_configs/gfx942/0400_roofline_info.yaml b/projects/rocprofiler-compute/src/rocprof_compute_soc/analysis_configs/gfx942/0400_roofline_info.yaml new file mode 100644 index 0000000000..1474b85cf2 --- /dev/null +++ b/projects/rocprofiler-compute/src/rocprof_compute_soc/analysis_configs/gfx942/0400_roofline_info.yaml @@ -0,0 +1,8 @@ +--- +Panel Config: + id: 400 + title: Roofline + data source: + - None: + id: 401 + title: Roofline \ No newline at end of file diff --git a/projects/rocprofiler-compute/src/rocprof_compute_tui/utils/tui_utils.py b/projects/rocprofiler-compute/src/rocprof_compute_tui/utils/tui_utils.py index c614f0c14c..ef3f87e6d8 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_tui/utils/tui_utils.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_tui/utils/tui_utils.py @@ -2,7 +2,6 @@ import copy import logging import os import re -import sys from collections import defaultdict from datetime import datetime from enum import Enum @@ -10,8 +9,7 @@ from pathlib import Path import pandas as pd -HIDDEN_SECTIONS = [1900, 2000] -HIDDEN_COLUMNS = ["Tips", "coll_level"] +from config import HIDDEN_COLUMNS, HIDDEN_SECTIONS supported_field = [ "Value", diff --git a/projects/rocprofiler-compute/src/roofline.py b/projects/rocprofiler-compute/src/roofline.py index beb3760ccc..37b0e7f3af 100644 --- a/projects/rocprofiler-compute/src/roofline.py +++ b/projects/rocprofiler-compute/src/roofline.py @@ -573,7 +573,6 @@ class Roofline: return fig - @demarcate def cli_generate_plot(self, dtype): """ Plot CLI mode roofline analysis in terminal using plotext @@ -609,8 +608,16 @@ class Roofline: self.__run_parameters["mem_level"].remove("vL1D") self.__run_parameters["mem_level"].append("L1") + roofline_csv = str( + Path(self.__run_parameters["workload_dir"][0][0]).joinpath("roofline.csv") + ) + roofline_csv_exists = Path(roofline_csv).is_file() + if not roofline_csv_exists: + console_log("roofline", "{} does not exist".format(roofline_csv)) + return + app_path = str( - Path(self.__run_parameters["workload_dir"]).joinpath("pmc_perf.csv") + Path(self.__run_parameters["workload_dir"][0][0]).joinpath("pmc_perf.csv") ) roofline_exists = Path(app_path).is_file() if not roofline_exists: @@ -844,6 +851,9 @@ class Roofline: if self.__run_parameters["is_standalone"]: self.standalone_roofline() + def get_dtype(self): + return self.__run_parameters["roofline_data_type"] + def to_int(a): if str(type(a)) == "": diff --git a/projects/rocprofiler-compute/src/utils/gui_components/memchart.py b/projects/rocprofiler-compute/src/utils/gui_components/memchart.py index f8a97e19b3..a15040d0ec 100644 --- a/projects/rocprofiler-compute/src/utils/gui_components/memchart.py +++ b/projects/rocprofiler-compute/src/utils/gui_components/memchart.py @@ -25,10 +25,9 @@ from dash import html from dash_svg import G, Path, Rect, Svg, Text +from config import HIDDEN_COLUMNS from utils.logger import console_error -hidden_columns = ["Tips", "coll_level"] - def insert_chart_data(mem_data, base_data): if len(mem_data) != 1: diff --git a/projects/rocprofiler-compute/src/utils/roofline_calc.py b/projects/rocprofiler-compute/src/utils/roofline_calc.py index 21e99e46b9..b599f10f3c 100644 --- a/projects/rocprofiler-compute/src/utils/roofline_calc.py +++ b/projects/rocprofiler-compute/src/utils/roofline_calc.py @@ -591,7 +591,7 @@ def calc_ai(mspec, sort_type, ret_df): def constuct_roof(roofline_parameters, dtype): benchmark_results = str( - Path(roofline_parameters["workload_dir"]).joinpath("roofline.csv") + Path(roofline_parameters["workload_dir"][0][0]).joinpath("roofline.csv") ) # ----------------------------------------------------- # Initialize roofline data dictionary from roofline.csv diff --git a/projects/rocprofiler-compute/src/utils/tty.py b/projects/rocprofiler-compute/src/utils/tty.py index 6d397482d4..08fbd5487f 100644 --- a/projects/rocprofiler-compute/src/utils/tty.py +++ b/projects/rocprofiler-compute/src/utils/tty.py @@ -28,13 +28,11 @@ from pathlib import Path import pandas as pd from tabulate import tabulate +from config import HIDDEN_COLUMNS, HIDDEN_SECTIONS from utils import mem_chart, parser from utils.logger import console_log, console_warning from utils.utils import convert_metric_id_to_panel_idx -hidden_columns = ["Tips", "coll_level"] -hidden_sections = [1900, 2000] - def string_multiple_lines(source, width, max_rows): """ @@ -61,7 +59,7 @@ def get_table_string(df, transpose=False, decimal=2): ) -def show_all(args, runs, archConfigs, output, profiling_config): +def show_all(args, runs, archConfigs, output, profiling_config, roof_plot=None): """ Show all panels with their data in plain text mode. """ @@ -77,8 +75,12 @@ def show_all(args, runs, archConfigs, output, profiling_config): comparable_columns = parser.build_comparable_columns(args.time_unit) for panel_id, panel in archConfigs.panel_configs.items(): + # show roofline + if panel_id == 400 and roof_plot: + show_roof_plot(roof_plot) + # Skip panels that don't support baseline comparison - if panel_id in hidden_sections: + if panel_id in HIDDEN_SECTIONS: continue ss = "" # store content of all data_source from one pannel @@ -117,7 +119,7 @@ def show_all(args, runs, archConfigs, output, profiling_config): or (args.cols and base_df.columns.get_loc(header) in args.cols) or (type == "raw_csv_table") ): - if header in hidden_columns: + if header in HIDDEN_COLUMNS: pass elif header not in comparable_columns: if ( @@ -149,7 +151,7 @@ def show_all(args, runs, archConfigs, output, profiling_config): cur_df = data.dfs[table_config["id"]] if (type == "raw_csv_table") or ( type == "metric_table" - and (not header in hidden_columns) + and (not header in HIDDEN_COLUMNS) ): if run != base_run: # calc percentage over the baseline @@ -309,6 +311,7 @@ def show_all(args, runs, archConfigs, output, profiling_config): .set_index("Metric") .to_dict()["Value"], ) + ss += "\n" else: ss += ( get_table_string( @@ -323,6 +326,14 @@ def show_all(args, runs, archConfigs, output, profiling_config): print(ss, file=output) +def show_roof_plot(roof_plot): + # TODO: short term solution to display roofline plot + print("\n" + "-" * 80) + print("4. Roofline") + print("4.1 Roofline") + print(roof_plot) + + def show_kernel_stats(args, runs, archConfigs, output): """ Show the kernels and dispatches from "Top Stats" section.