From 881639452af7eba0e57002a57583d210b767da41 Mon Sep 17 00:00:00 2001 From: ggottipa-amd Date: Mon, 8 Dec 2025 06:21:56 -0600 Subject: [PATCH 1/6] Converting kernel-names from web ui into kernel ids for filtering. --- .../rocprof_compute_analyze/analysis_webui.py | 51 ++++++++++++++----- projects/rocprofiler-compute/src/roofline.py | 8 +++ projects/rocprofiler-compute/src/utils/gui.py | 8 +-- .../rocprofiler-compute/src/utils/parser.py | 17 +++++-- 4 files changed, 64 insertions(+), 20 deletions(-) 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 52fd62b8f33..159782d3fd6 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_webui.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_webui.py @@ -152,9 +152,27 @@ def generate_from_filter( console_debug("analysis", f"gui gpu filter is {gcd_filter}") console_debug("analysis", f"gui top-n filter is {top_n_filt}") - base_data[base_run].filter_kernel_ids = ( - [str(k) for k in kernel_filter] if kernel_filter else [] - ) + # Convert kernel names to kernel ids + kernel_ids = [] + if kernel_filter: + # Need to load raw kernel data to do the name->ID lookup + # Use raw_pmc to build a temporary mapping + if all([isinstance(k, int) for k in kernel_filter]): + kernel_ids = [str(k) for k in kernel_filter] + else: + raw_pmc = base_data[base_run].raw_pmc + for kernel_item in kernel_filter: + try: + # Already an ID + kernel_id = str(int(kernel_item)) + kernel_ids.append(kernel_id) + except (ValueError, TypeError): + matching_indices = raw_pmc[raw_pmc[('pmc_perf', 'Kernel_Name')] == kernel_item].index.tolist() + kernel_ids.extend([str(idx) for idx in matching_indices]) + + + base_data[base_run].filter_kernel_ids = kernel_ids + base_data[base_run].filter_gpu_ids = ( [int(g) for g in gcd_filter] if gcd_filter else [] ) @@ -174,6 +192,16 @@ def generate_from_filter( kernel_verbose=args.kernel_verbose, ) + + # All filtering will occur here + parser.load_table_data( + workload=base_data[base_run], + dir_path=self.dest_dir, + is_gui=True, + args=args, + config=self._profiling_config, + ) + # Only display basic metrics if no filters are applied if not (disp_filt or kernel_filter or gcd_filter): basic_dfs_keep = [1, 2, 101, 201, 301, 401, 402] @@ -193,15 +221,6 @@ def generate_from_filter( if key in basic_panels_keep } - # All filtering will occur here - parser.load_table_data( - workload=base_data[base_run], - dir_path=self.dest_dir, - is_gui=True, - args=args, - config=self._profiling_config, - ) - # ~~~~~~~~~~~~~~~~~~~~~~~ # Generate GUI content # ~~~~~~~~~~~~~~~~~~~~~~~ @@ -252,6 +271,11 @@ def generate_from_filter( .lower() ) + console_debug('kernel_filter', kernel_filter) + console_debug('kernel_ids', kernel_ids) + + console_debug('base_data',base_data[base_run].dfs.keys()) + console_debug('panel_configs',panel_configs.keys()) # Build content for a single panel html_section = [] # Iterate over each table per section @@ -261,7 +285,8 @@ def generate_from_filter( # The sys info table need to add index back if t_type == "raw_csv_table" and "Info" in original_df.keys(): - original_df.reset_index(inplace=True) + if original_df.index.name is not None and 'level_0' not in original_df.columns: + original_df.reset_index(inplace=True) content = determine_chart_type( original_df=original_df, diff --git a/projects/rocprofiler-compute/src/roofline.py b/projects/rocprofiler-compute/src/roofline.py index 57f47bc67d1..2af4924dc1f 100644 --- a/projects/rocprofiler-compute/src/roofline.py +++ b/projects/rocprofiler-compute/src/roofline.py @@ -563,6 +563,14 @@ def generate_plot( subplot_row = 1 skipAI = False + else: + console_warning('fig is None and no kernel names data provided') + # New figure without kernel names table + fig = make_subplots( + rows=1, + cols=1, + subplot_titles=["Roofline Analysis - NO DATA"], + ) else: # Adding to existing figure if hasattr(fig, "_grid_ref") and fig._grid_ref is not None: diff --git a/projects/rocprofiler-compute/src/utils/gui.py b/projects/rocprofiler-compute/src/utils/gui.py index 36fbd2c4bc0..a6c06bfcf3c 100644 --- a/projects/rocprofiler-compute/src/utils/gui.py +++ b/projects/rocprofiler-compute/src/utils/gui.py @@ -133,7 +133,7 @@ def discrete_background_color_bins( #################### def create_instruction_mix_bar_chart(display_df: pd.DataFrame, df_unit: str) -> px.bar: display_df = display_df.copy() - display_df["Avg"] = display_df["Avg"].apply(lambda x: int(x) if x != "" else 0) + display_df["Avg"] = display_df["Avg"].apply(lambda x: int(x) if x not in ["","N/A",None] else 0) return px.bar( display_df, @@ -150,7 +150,7 @@ def create_multi_bar_charts( display_df: pd.DataFrame, table_id: int, df_unit: str ) -> list[px.bar]: display_df = display_df.copy() - display_df["Avg"] = display_df["Avg"].apply(lambda x: int(x) if x != "" else 0) + display_df["Avg"] = display_df["Avg"].apply(lambda x: int(x) if x not in ["","N/A",None] else 0) nested_bar = multi_bar_chart(table_id, display_df) charts = [] @@ -175,7 +175,7 @@ def create_multi_bar_charts( def create_sol_charts(display_df: pd.DataFrame, table_id: int) -> list[px.bar]: display_df = display_df.copy() - display_df["Avg"] = display_df["Avg"].apply(lambda x: float(x) if x != "" else 0.0) + display_df["Avg"] = display_df["Avg"].apply(lambda x: float(x) if x not in ["","N/A",None] else 0.0) charts = [] @@ -216,7 +216,7 @@ def create_sol_charts(display_df: pd.DataFrame, table_id: int) -> list[px.bar]: elif table_id == 1101: # Special formatting reference 'Pct of Peak' value display_df["Pct of Peak"] = display_df["Pct of Peak"].apply( - lambda x: float(x) if x != "" else 0.0 + lambda x: float(x) if x not in ["","N/A",None] else 0.0 ) charts.append( px.bar( diff --git a/projects/rocprofiler-compute/src/utils/parser.py b/projects/rocprofiler-compute/src/utils/parser.py index e76df4b90eb..243f9dfafd1 100755 --- a/projects/rocprofiler-compute/src/utils/parser.py +++ b/projects/rocprofiler-compute/src/utils/parser.py @@ -197,6 +197,8 @@ def to_int( if a is None: return None elif isinstance(a, (int, float, np.integer)): + if pd.isna(a): + return None return int(a) elif isinstance(a, pd.Series): return a.astype(int) @@ -486,11 +488,17 @@ def update_denominator_string(equation: str, normal_unit: str) -> str: return "" equation_string = str(equation) - + if "$denom" in equation_string: + print(f"DEBUG: normal_unit='{normal_unit}', keys={list(SUPPORTED_DENOM.keys())}") + if normal_unit in SUPPORTED_DENOM.keys(): equation_string = re.sub( r"\$denom", SUPPORTED_DENOM[normal_unit], equation_string ) + else: + # ADD THIS WARNING + if "$denom" in equation_string: + print(f"WARNING: normal_unit '{normal_unit}' not in SUPPORTED_DENOM!") return equation_string @@ -808,7 +816,7 @@ def build_metric_value_string( for id, df in dfs.items(): if dfs_type[id] == "metric_table": for expr in df.columns: - if expr in schema.SUPPORTED_FIELD: + if any(expr.lower() == field.lower() for field in schema.SUPPORTED_FIELD): # NB: apply all build-in before building the whole string df[expr] = df[expr].apply( update_denominator_string, normal_unit=normal_unit @@ -997,7 +1005,7 @@ def eval_metric( if dfs_type[df_id] == "metric_table": for row_id, row in df.iterrows(): for expr in df.columns: - if expr in schema.SUPPORTED_FIELD and expr.lower() != "alias": + if any(expr.lower() == field.lower() for field in schema.SUPPORTED_FIELD) and expr.lower() != "alias": if row[expr]: exprs_to_eval.append((df_id, row_id, expr, row[expr])) @@ -1011,7 +1019,10 @@ def eval_metric( row[expr] = "" for df_id, row_id, col, expr in exprs_to_eval: + console_warning(f"DEBUG: Evaluating {col} for row {row_id}") + console_warning(f"DEBUG: Expression: {expr[:100]}...") eval_result = metric_evaluator.eval_expression(expr) + console_warning(f"DEBUG: Result type: {type(eval_result)}, value: {str(eval_result)[:50]}") dfs[df_id].loc[row_id, col] = eval_result # Check for metrics exceeding theoretical peak due to dual-issue validate_dual_issue_metrics(dfs, dfs_type, sys_info, raw_pmc_df) From 3d1750ed75ac4a910a4543ec41f3ecdb7ead1d34 Mon Sep 17 00:00:00 2001 From: ggottipa-amd Date: Mon, 8 Dec 2025 06:27:13 -0600 Subject: [PATCH 2/6] Removing debug prints. --- projects/rocprofiler-compute/src/utils/parser.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/projects/rocprofiler-compute/src/utils/parser.py b/projects/rocprofiler-compute/src/utils/parser.py index 243f9dfafd1..c048bc63462 100755 --- a/projects/rocprofiler-compute/src/utils/parser.py +++ b/projects/rocprofiler-compute/src/utils/parser.py @@ -488,17 +488,10 @@ def update_denominator_string(equation: str, normal_unit: str) -> str: return "" equation_string = str(equation) - if "$denom" in equation_string: - print(f"DEBUG: normal_unit='{normal_unit}', keys={list(SUPPORTED_DENOM.keys())}") - if normal_unit in SUPPORTED_DENOM.keys(): equation_string = re.sub( r"\$denom", SUPPORTED_DENOM[normal_unit], equation_string ) - else: - # ADD THIS WARNING - if "$denom" in equation_string: - print(f"WARNING: normal_unit '{normal_unit}' not in SUPPORTED_DENOM!") return equation_string From 2d2025f8b47f7e91c45cb2d0a3269681ed19af98 Mon Sep 17 00:00:00 2001 From: ggottipa-amd Date: Tue, 9 Dec 2025 09:48:24 -0600 Subject: [PATCH 3/6] Reverting the kernel id to kernel name conversion added in prev commit from webui.py . --- .../rocprof_compute_analyze/analysis_webui.py | 57 ++++++------------- 1 file changed, 17 insertions(+), 40 deletions(-) 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 159782d3fd6..ae78bf050a1 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_webui.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_webui.py @@ -152,27 +152,9 @@ def generate_from_filter( console_debug("analysis", f"gui gpu filter is {gcd_filter}") console_debug("analysis", f"gui top-n filter is {top_n_filt}") - # Convert kernel names to kernel ids - kernel_ids = [] - if kernel_filter: - # Need to load raw kernel data to do the name->ID lookup - # Use raw_pmc to build a temporary mapping - if all([isinstance(k, int) for k in kernel_filter]): - kernel_ids = [str(k) for k in kernel_filter] - else: - raw_pmc = base_data[base_run].raw_pmc - for kernel_item in kernel_filter: - try: - # Already an ID - kernel_id = str(int(kernel_item)) - kernel_ids.append(kernel_id) - except (ValueError, TypeError): - matching_indices = raw_pmc[raw_pmc[('pmc_perf', 'Kernel_Name')] == kernel_item].index.tolist() - kernel_ids.extend([str(idx) for idx in matching_indices]) - - - base_data[base_run].filter_kernel_ids = kernel_ids - + base_data[base_run].filter_kernel_ids = ( + [str(k) for k in kernel_filter] if kernel_filter else [] + ) base_data[base_run].filter_gpu_ids = ( [int(g) for g in gcd_filter] if gcd_filter else [] ) @@ -192,16 +174,6 @@ def generate_from_filter( kernel_verbose=args.kernel_verbose, ) - - # All filtering will occur here - parser.load_table_data( - workload=base_data[base_run], - dir_path=self.dest_dir, - is_gui=True, - args=args, - config=self._profiling_config, - ) - # Only display basic metrics if no filters are applied if not (disp_filt or kernel_filter or gcd_filter): basic_dfs_keep = [1, 2, 101, 201, 301, 401, 402] @@ -213,13 +185,24 @@ def generate_from_filter( for key in base_data[base_run].dfs if key in basic_dfs_keep } - base_data[base_run].dfs = filtered_dfs + # base_data[base_run].dfs = filtered_dfs panel_configs = { key: panel_configs[key] for key in panel_configs if key in basic_panels_keep } + else: + filtered_dfs = base_data[base_run].dfs + + # All filtering will occur here + parser.load_table_data( + workload=base_data[base_run], + dir_path=self.dest_dir, + is_gui=True, + args=args, + config=self._profiling_config, + ) # ~~~~~~~~~~~~~~~~~~~~~~~ # Generate GUI content @@ -271,22 +254,16 @@ def generate_from_filter( .lower() ) - console_debug('kernel_filter', kernel_filter) - console_debug('kernel_ids', kernel_ids) - - console_debug('base_data',base_data[base_run].dfs.keys()) - console_debug('panel_configs',panel_configs.keys()) # Build content for a single panel html_section = [] # Iterate over each table per section for data_source in panel["data source"]: for t_type, table_config in data_source.items(): - original_df = base_data[base_run].dfs[table_config["id"]] + original_df = filtered_dfs[table_config["id"]] # The sys info table need to add index back if t_type == "raw_csv_table" and "Info" in original_df.keys(): - if original_df.index.name is not None and 'level_0' not in original_df.columns: - original_df.reset_index(inplace=True) + original_df.reset_index(inplace=True) content = determine_chart_type( original_df=original_df, From 902f8242361b0755d272ecbf34ab2b2fe8bdcda5 Mon Sep 17 00:00:00 2001 From: ggottipa-amd Date: Wed, 10 Dec 2025 09:24:10 -0600 Subject: [PATCH 4/6] Using sum on GRBM counters to fix Error - unhashable type: 'Series'. --- .../rocprofiler-compute/src/utils/parser.py | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/projects/rocprofiler-compute/src/utils/parser.py b/projects/rocprofiler-compute/src/utils/parser.py index c048bc63462..9b5e7f0a251 100755 --- a/projects/rocprofiler-compute/src/utils/parser.py +++ b/projects/rocprofiler-compute/src/utils/parser.py @@ -80,9 +80,9 @@ # Build-in defined in mongodb variables: BUILD_IN_VARS: dict[str, str] = { - "GRBM_GUI_ACTIVE_PER_XCD": "(GRBM_GUI_ACTIVE / $num_xcd)", - "GRBM_COUNT_PER_XCD": "(GRBM_COUNT / $num_xcd)", - "GRBM_SPI_BUSY_PER_XCD": "(GRBM_SPI_BUSY / $num_xcd)", + "GRBM_GUI_ACTIVE_PER_XCD": "(SUM(GRBM_GUI_ACTIVE) / $num_xcd)", + "GRBM_COUNT_PER_XCD": "(SUM(GRBM_COUNT) / $num_xcd)", + "GRBM_SPI_BUSY_PER_XCD": "(SUM(GRBM_SPI_BUSY) / $num_xcd)", "numActiveCUs": "TO_INT(MIN((((ROUND(AVG(((4 * SQ_BUSY_CU_CYCLES) / \ $GRBM_GUI_ACTIVE_PER_XCD)), 0) / $max_waves_per_cu) * 8) + \ MIN(MOD(ROUND(AVG(((4 * SQ_BUSY_CU_CYCLES) / \ @@ -320,13 +320,18 @@ def __init__( def eval_expression(self, expr: str) -> Union[str, float, int]: """Evaluate a single expression with proper local context.""" + if isinstance(expr, (int, float)): + if pd.isna(expr): + return "N/A" + return expr + if expr in {"", "N/A", None}: + return "N/A" try: # Create comprehensive local context local_expr_context = {} local_expr_context.update({"raw_pmc_df": self.raw_pmc_df}) local_expr_context.update(self.sys_vars) local_expr_context.update(self.empirical_peaks) - # Add utility functions to local context local_expr_context.update({ "to_min": to_min, @@ -348,10 +353,17 @@ def eval_expression(self, expr: str) -> Union[str, float, int]: local_expr_context, ) - if eval_result is None or np.isnan(eval_result).any(): + if eval_result in {"N/A", None}: return "N/A" - else: - return eval_result + # Only check for NaN if eval_result is numeric (not string) + if isinstance(eval_result, (int, float, np.number, pd.Series, np.ndarray)): + if hasattr(eval_result, 'any'): + if np.isnan(eval_result).any(): + return "N/A" + else: + if np.isnan(eval_result): + return "N/A" + return eval_result except (TypeError, NameError, KeyError) as exception: if "empirical_peak" in str(exception): @@ -375,6 +387,8 @@ def eval_expression(self, expr: str) -> Union[str, float, int]: console_warning(f"Missing data: {exception}. Using empty value.") return "" + except ValueError as value_error: + raise value_error def build_eval_string(equation: str, coll_level: str, config: dict) -> str: """ @@ -918,9 +932,9 @@ def calc_builtin_vars( # First pass: calculate per-XCD values for variable_key, variable_value in BUILD_IN_VARS.items(): + if "PER_XCD" not in variable_key: continue - # NB: assume all built-in vars from pmc_perf.csv for now eval_string = build_eval_string( variable_value, schema.PMC_PERF_FILE_PREFIX, config @@ -928,14 +942,16 @@ def calc_builtin_vars( try: # Create temporary evaluator for this calculation # Pass sys_vars so that $num_xcd and other system variables are available + temporary_evaluator = MetricEvaluator(raw_pmc_df, sys_vars, {}) calculation_result = temporary_evaluator.eval_expression(eval_string) builtin_vars_collection[f"ammolite__{variable_key}"] = calculation_result - except (TypeError, NameError, KeyError, AttributeError): + except (TypeError, NameError, KeyError, AttributeError) as exception: builtin_vars_collection[f"ammolite__{variable_key}"] = None # Second pass: calculate remaining variables that depend on per-XCD values for variable_key, variable_value in BUILD_IN_VARS.items(): + if "PER_XCD" in variable_key: continue @@ -951,6 +967,7 @@ def calc_builtin_vars( except (TypeError, NameError, KeyError, AttributeError): builtin_vars_collection[f"ammolite__{variable_key}"] = None + return builtin_vars_collection @@ -1012,10 +1029,8 @@ def eval_metric( row[expr] = "" for df_id, row_id, col, expr in exprs_to_eval: - console_warning(f"DEBUG: Evaluating {col} for row {row_id}") - console_warning(f"DEBUG: Expression: {expr[:100]}...") eval_result = metric_evaluator.eval_expression(expr) - console_warning(f"DEBUG: Result type: {type(eval_result)}, value: {str(eval_result)[:50]}") + # console_warning(f"{expr} Evaluates to: {type(eval_result)}, value: {str(eval_result)}") dfs[df_id].loc[row_id, col] = eval_result # Check for metrics exceeding theoretical peak due to dual-issue validate_dual_issue_metrics(dfs, dfs_type, sys_info, raw_pmc_df) From 51d53ae56bbd74a8e186637ffd47b40073d7fa53 Mon Sep 17 00:00:00 2001 From: ggottipa-amd Date: Thu, 11 Dec 2025 06:43:44 -0600 Subject: [PATCH 5/6] Removed dict while validating eval_result. --- .../rocprofiler-compute/src/utils/parser.py | 43 +++++++++++++++---- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/projects/rocprofiler-compute/src/utils/parser.py b/projects/rocprofiler-compute/src/utils/parser.py index 9b5e7f0a251..0826fa07a13 100755 --- a/projects/rocprofiler-compute/src/utils/parser.py +++ b/projects/rocprofiler-compute/src/utils/parser.py @@ -80,9 +80,9 @@ # Build-in defined in mongodb variables: BUILD_IN_VARS: dict[str, str] = { - "GRBM_GUI_ACTIVE_PER_XCD": "(SUM(GRBM_GUI_ACTIVE) / $num_xcd)", - "GRBM_COUNT_PER_XCD": "(SUM(GRBM_COUNT) / $num_xcd)", - "GRBM_SPI_BUSY_PER_XCD": "(SUM(GRBM_SPI_BUSY) / $num_xcd)", + "GRBM_GUI_ACTIVE_PER_XCD": "(GRBM_GUI_ACTIVE / $num_xcd)", + "GRBM_COUNT_PER_XCD": "(GRBM_COUNT / $num_xcd)", + "GRBM_SPI_BUSY_PER_XCD": "(GRBM_SPI_BUSY / $num_xcd)", "numActiveCUs": "TO_INT(MIN((((ROUND(AVG(((4 * SQ_BUSY_CU_CYCLES) / \ $GRBM_GUI_ACTIVE_PER_XCD)), 0) / $max_waves_per_cu) * 8) + \ MIN(MOD(ROUND(AVG(((4 * SQ_BUSY_CU_CYCLES) / \ @@ -319,7 +319,8 @@ def __init__( self.empirical_peaks = empirical_peaks def eval_expression(self, expr: str) -> Union[str, float, int]: - """Evaluate a single expression with proper local context.""" + """Evaluate a single expression with proper local context.""" + if isinstance(expr, (int, float)): if pd.isna(expr): return "N/A" @@ -347,13 +348,38 @@ def eval_expression(self, expr: str) -> Union[str, float, int]: "to_concat": to_concat, }) + # # Debug print for GRBM expressions + # if isinstance(expr,str) and "grbm" in expr.lower() and "ammolite__num_xcd" in expr: + # console_warning("Local context keys:",local_expr_context) + # console_warning(f"=== EVAL DEBUG for: {expr} ===") + + # if 'raw_pmc_df' in local_expr_context: + # pmc_df = local_expr_context['raw_pmc_df'] + # console_warning(f"raw_pmc_df type: {type(pmc_df)}") + + # grbm_col = pmc_df['pmc_perf']['GRBM_GUI_ACTIVE'] + # console_warning(f"GRBM_GUI_ACTIVE type: {type(grbm_col)}") + # console_warning(f"GRBM_GUI_ACTIVE shape: {getattr(grbm_col, 'shape', 'No shape')}") + # console_warning(f"GRBM_GUI_ACTIVE values: {grbm_col}") + # console_warning("GRBM_GUI_ACTIVE index:",grbm_col.index) + # else: + # console_error("raw_pmc_df not found in local_expr_context.") + + # # Print num_xcd + # num_xcd = local_expr_context.get('ammolite__num_xcd') + # console_warning(f"ammolite__num_xcd type: {type(num_xcd)}") + # console_warning(f"ammolite__num_xcd value: {num_xcd}") + eval_result = eval( compile(expr, "", "eval"), {}, local_expr_context, ) - - if eval_result in {"N/A", None}: + console_warning(f"Evaluated expression '{expr}' with result: {eval_result}") + + if eval_result is None: + return "N/A" + if isinstance(eval_result, str) and eval_result == "N/A": return "N/A" # Only check for NaN if eval_result is numeric (not string) if isinstance(eval_result, (int, float, np.number, pd.Series, np.ndarray)): @@ -366,6 +392,7 @@ def eval_expression(self, expr: str) -> Union[str, float, int]: return eval_result except (TypeError, NameError, KeyError) as exception: + if "empirical_peak" in str(exception): console_warning(f"Missing empirical peak data: {exception}.") return "N/A" @@ -374,6 +401,7 @@ def eval_expression(self, expr: str) -> Union[str, float, int]: return "N/A" except AttributeError as attribute_error: + if str(attribute_error) == "'NoneType' object has no attribute 'get'": console_warning( f"Failed to evaluate expression '{expr}': {attribute_error}." @@ -387,9 +415,6 @@ def eval_expression(self, expr: str) -> Union[str, float, int]: console_warning(f"Missing data: {exception}. Using empty value.") return "" - except ValueError as value_error: - raise value_error - def build_eval_string(equation: str, coll_level: str, config: dict) -> str: """ Convert user defined equation string to eval executable string. From 76c5be2b1f1fc2b1b38a26dae13642bba3a6bc9f Mon Sep 17 00:00:00 2001 From: ggottipa-amd Date: Fri, 12 Dec 2025 06:10:45 -0600 Subject: [PATCH 6/6] Fixing SUPPORTED_DENOM, removed $ from GRBM_GUI_ACTIVE_PER_XCD. --- .../rocprof_compute_analyze/analysis_webui.py | 7 ++--- .../rocprofiler-compute/src/utils/parser.py | 27 +++++++++++-------- 2 files changed, 20 insertions(+), 14 deletions(-) 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 ae78bf050a1..d6c3d88027f 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_webui.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_analyze/analysis_webui.py @@ -152,9 +152,10 @@ def generate_from_filter( console_debug("analysis", f"gui gpu filter is {gcd_filter}") console_debug("analysis", f"gui top-n filter is {top_n_filt}") - base_data[base_run].filter_kernel_ids = ( - [str(k) for k in kernel_filter] if kernel_filter else [] - ) + base_data[base_run].filter_kernel_ids = (kernel_filter if kernel_filter else []) + console_warning('kernel_filter',kernel_filter) + console_warning('base_data[base_run].filter_kernel_ids',base_data[base_run].filter_kernel_ids) + base_data[base_run].filter_gpu_ids = ( [int(g) for g in gcd_filter] if gcd_filter else [] ) diff --git a/projects/rocprofiler-compute/src/utils/parser.py b/projects/rocprofiler-compute/src/utils/parser.py index 0826fa07a13..bdf9d237af6 100755 --- a/projects/rocprofiler-compute/src/utils/parser.py +++ b/projects/rocprofiler-compute/src/utils/parser.py @@ -73,7 +73,7 @@ # } SUPPORTED_DENOM: dict[str, str] = { "per_wave": "SQ_WAVES", - "per_cycle": "$GRBM_GUI_ACTIVE_PER_XCD", + "per_cycle": "GRBM_GUI_ACTIVE_PER_XCD", "per_second": "((End_Timestamp - Start_Timestamp) / 1000000000)", "per_kernel": "1", } @@ -375,12 +375,11 @@ def eval_expression(self, expr: str) -> Union[str, float, int]: {}, local_expr_context, ) - console_warning(f"Evaluated expression '{expr}' with result: {eval_result}") + if 'denom' in expr: + console_warning(f"Evaluated expression '{expr}' with result: {eval_result}") if eval_result is None: return "N/A" - if isinstance(eval_result, str) and eval_result == "N/A": - return "N/A" # Only check for NaN if eval_result is numeric (not string) if isinstance(eval_result, (int, float, np.number, pd.Series, np.ndarray)): if hasattr(eval_result, 'any'): @@ -397,22 +396,22 @@ def eval_expression(self, expr: str) -> Union[str, float, int]: console_warning(f"Missing empirical peak data: {exception}.") return "N/A" else: - console_warning(f"Failed to evaluate expression '{expr}': {exception}.") + # console_warning(f"Failed to evaluate expression '{expr}': {exception}.") return "N/A" except AttributeError as attribute_error: if str(attribute_error) == "'NoneType' object has no attribute 'get'": - console_warning( - f"Failed to evaluate expression '{expr}': {attribute_error}." - ) + # console_warning( + # f"Failed to evaluate expression '{expr}': {attribute_error}." + # ) return "N/A" else: console_error("analysis", str(attribute_error)) return "N/A" except pd.errors.IntCastingNaNError as exception: - console_warning(f"Missing data: {exception}. Using empty value.") + # console_warning(f"Missing data: {exception}. Using empty value.") return "" def build_eval_string(equation: str, coll_level: str, config: dict) -> str: @@ -525,13 +524,19 @@ def update_denominator_string(equation: str, normal_unit: str) -> str: """ if not equation: return "" - + # console_warning(f"normal_unit in build_metric_value_string: {normal_unit}") equation_string = str(equation) if normal_unit in SUPPORTED_DENOM.keys(): equation_string = re.sub( r"\$denom", SUPPORTED_DENOM[normal_unit], equation_string ) - + else: + console_error( + f"Normalization unit '{normal_unit}' is not supported. " + "Skiped updating $denom." + ) + if 'denom' in equation_string: + console_error(f"Updated equation with denom:{equation} --> {equation_string}") return equation_string