From 288bca17eae0f841fe79832af2dc77c828a935b2 Mon Sep 17 00:00:00 2001 From: xuchen-amd Date: Tue, 16 Sep 2025 14:20:33 -0400 Subject: [PATCH] [rocprofiler-compute] refactor bug fixes (#994) --- .../rocprof_compute_profile/profiler_base.py | 30 +++++++++++++------ .../src/rocprof_compute_tui/analysis_tui.py | 2 +- .../src/rocprof_compute_tui/config.py | 3 -- .../src/rocprof_compute_tui/tui_app.py | 2 +- .../utils/kernel_view_config.yaml | 20 ++++++------- .../rocprof_compute_tui/views/main_view.py | 4 +-- .../widgets/menu_bar/menu_bar.py | 5 ++-- 7 files changed, 37 insertions(+), 29 deletions(-) diff --git a/projects/rocprofiler-compute/src/rocprof_compute_profile/profiler_base.py b/projects/rocprofiler-compute/src/rocprof_compute_profile/profiler_base.py index 07db98d93d..b637f451f2 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_profile/profiler_base.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_profile/profiler_base.py @@ -147,7 +147,10 @@ class RocProfCompute_Base: for file in result_files: Path(file).unlink() console_debug(f"Deleted file: {file}") - return + return None + + # Collect files to process - normalize to Path objects + files: list[Path] = [] # Set default output directory if not specified if isinstance(args.path, str): @@ -168,7 +171,7 @@ class RocProfCompute_Base: f for f in files if not f.name.endswith("_marker_api_trace.csv") ] elif isinstance(args.path, list): - files = args.path + files = [Path(path) for path in args.path] else: console_error(f"Invalid workload directory. Cannot resolve {args.path}") @@ -176,6 +179,11 @@ class RocProfCompute_Base: df = None for i, file in enumerate(files): current_df = pd.read_csv(file) + + if current_df.empty: + console_warning("join_prof", f"Empty dataframe from {file}") + continue + if args.join_type == "kernel": key = current_df.groupby("Kernel_Name").cumcount() current_df["key"] = current_df.Kernel_Name + " - " + key.astype(str) @@ -190,7 +198,8 @@ class RocProfCompute_Base: ) else: console_error( - f"{args.join_type} is an unrecognized option for --join-type" + "join_prof", + f"{args.join_type} is an unrecognized option for --join-type", ) if df is None: @@ -202,7 +211,8 @@ class RocProfCompute_Base: ) if df is None or df.empty: - return + console_warning("join_prof", "No data available after processing all files") + return None # TODO: check for any mismatch in joins duplicate_cols = { @@ -238,10 +248,11 @@ class RocProfCompute_Base: current_df = df[cols] if not test_df_column_equality(current_df): console_warning( - f"Detected differing {key} values while joining pmc_perf.csv" + "join_prof", + f"Detected differing {key} values while joining pmc_perf.csv", ) else: - console_debug(f"Successfully joined {key} in pmc_perf.csv") + console_debug("join_prof", f"Successfully joined {key} in pmc_perf.csv") # now, we can: #   A) throw away any of the "boring" duplicates @@ -321,7 +332,8 @@ class RocProfCompute_Base: df["End_Timestamp"] = mean_end # finally, join the drop key - df = df.drop(columns=["key"]) + if "key" in df.columns: + df = df.drop(columns=["key"]) # save to file and delete old file(s) # skip if we're being called outside of rocprof-compute @@ -330,8 +342,8 @@ class RocProfCompute_Base: if not args.verbose: for file in files: # Do not remove accumulate counter files - if "SQ_" not in file or "SQC_" not in file: - Path(file).unlink() + if "SQ_" not in file.name or "SQC_" not in file.name: + file.unlink() return None else: return df diff --git a/projects/rocprofiler-compute/src/rocprof_compute_tui/analysis_tui.py b/projects/rocprofiler-compute/src/rocprof_compute_tui/analysis_tui.py index 8e57af6e45..7e7af2c9cc 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_tui/analysis_tui.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_tui/analysis_tui.py @@ -88,7 +88,7 @@ class tui_analysis(OmniAnalyze_Base): # 1. load top kernel parser.load_non_mertrics_table( - workload=self._runs[self.path], dir=self.path, args=self.args + workload=self._runs[self.path], dir_path=self.path, args=self.args ) # 2. Generate kernel-specific dataframes diff --git a/projects/rocprofiler-compute/src/rocprof_compute_tui/config.py b/projects/rocprofiler-compute/src/rocprof_compute_tui/config.py index 66a7995bd5..1b1856ae74 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_tui/config.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_tui/config.py @@ -33,6 +33,3 @@ APP_TITLE = "ROCm Compute Profiler TUI" # Widget configurations DEFAULT_COLLAPSIBLE_STATE = True # True = collapsed by default - -# File paths -DEFAULT_START_PATH = None # None uses cwd diff --git a/projects/rocprofiler-compute/src/rocprof_compute_tui/tui_app.py b/projects/rocprofiler-compute/src/rocprof_compute_tui/tui_app.py index c652f1851c..9353ad3c4a 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_tui/tui_app.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_tui/tui_app.py @@ -116,7 +116,7 @@ class RocprofTUIApp(App): def on_recent_selected(self, selected_dir: Optional[str]) -> None: if selected_dir: - self.main_view.selected_path = selected_dir + self.main_view.selected_path = Path(selected_dir) self.main_view.run_analysis() @on(Button.Pressed, "#menu-open-workload") diff --git a/projects/rocprofiler-compute/src/rocprof_compute_tui/utils/kernel_view_config.yaml b/projects/rocprofiler-compute/src/rocprof_compute_tui/utils/kernel_view_config.yaml index 654b43e373..7e6dde664d 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_tui/utils/kernel_view_config.yaml +++ b/projects/rocprofiler-compute/src/rocprof_compute_tui/utils/kernel_view_config.yaml @@ -4,28 +4,28 @@ # collapsed: true sections: - title: "High Level Analysis" - collapsed: true + collapsed: True class: "sysinfo-section" subsections: - title: "GPU Speed-of-Light" data_path: ["32. GPU Speed-of-Light", "32.1 GPU Speed-of-Light"] - collapsed: true + collapsed: True - title: "Compute Throughput" data_path: ["33. Compute Throughput", "33.1 Compute Throughput"] - collapsed: true + collapsed: True - title: "Memory Throughput" data_path: ["34. Memory Throughput", "34.1 Memory Throughput"] - collapsed: true + collapsed: True - title: "Memory Chart" data_path: ["3. Memory Chart", "3.1 Memory Chart"] - collapsed: true + collapsed: True tui_style: "mem_chart" - title: "Detailed Block Analysis" - collapsed: true + collapsed: True class: "block-section" subsections: - - arch_config_data: true + - arch_config_data: True exclude_keys: - "0. Top Stats" - "1. System Info" @@ -35,12 +35,12 @@ sections: - "32. GPU Speed-of-Light" - "33. Compute Throughput" - "34. Memory Throughput" - collapsed: true + collapsed: True - title: "Source Level Analysis" - collapsed: true + collapsed: True class: "source-section" subsections: - title: "PC Sampling" data_path: ["21. PC Sampling", "21.1 PC Sampling"] - collapsed: true \ No newline at end of file + collapsed: True \ No newline at end of file diff --git a/projects/rocprofiler-compute/src/rocprof_compute_tui/views/main_view.py b/projects/rocprofiler-compute/src/rocprof_compute_tui/views/main_view.py index e395a63c82..d36c4624b4 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_tui/views/main_view.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_tui/views/main_view.py @@ -38,7 +38,6 @@ from textual.reactive import reactive from textual.widgets import DataTable from rocprof_compute_tui.analysis_tui import tui_analysis -from rocprof_compute_tui.config import DEFAULT_START_PATH from rocprof_compute_tui.utils.tui_utils import Logger, LogLevel from rocprof_compute_tui.widgets.center_panel.center_area import CenterPanel from rocprof_compute_tui.widgets.menu_bar.menu_bar import MenuBar @@ -56,7 +55,6 @@ class MainView(Horizontal): def __init__(self) -> None: super().__init__(id="main-container") - self.start_path = Path(DEFAULT_START_PATH) if DEFAULT_START_PATH else Path.cwd() self.logger = Logger() self.logger.info("MainView initialized", update_ui=False) @@ -138,7 +136,7 @@ class MainView(Horizontal): analyzer.sanitize() # 2. Load and process system info and Configure SoC - sysinfo_path = Path(self.selected_path) / "sysinfo.csv" + sysinfo_path = self.selected_path / "sysinfo.csv" if not sysinfo_path.exists(): raise FileNotFoundError(f"sysinfo.csv not found at {sysinfo_path}") diff --git a/projects/rocprofiler-compute/src/rocprof_compute_tui/widgets/menu_bar/menu_bar.py b/projects/rocprofiler-compute/src/rocprof_compute_tui/widgets/menu_bar/menu_bar.py index 2248a12602..2885e8badd 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_tui/widgets/menu_bar/menu_bar.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_tui/widgets/menu_bar/menu_bar.py @@ -20,8 +20,9 @@ # 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. - ############################################################################## + +from pathlib import Path from typing import Any, Optional from textual import on @@ -87,7 +88,7 @@ class MenuBar(Container): def on_recent_selected(selected_dir: Optional[str]) -> None: if selected_dir: - self.parent_main_view.selected_path = selected_dir + self.parent_main_view.selected_path = Path(selected_dir) self.query_one("#file-dropdown", DropdownMenu).add_class("hidden") self.parent_main_view.run_analysis()