diff --git a/src/feelpp/benchmarking/json_report/figures/plotly/plotlyFigures.py b/src/feelpp/benchmarking/json_report/figures/plotly/plotlyFigures.py index ea1719021..1ea417ced 100644 --- a/src/feelpp/benchmarking/json_report/figures/plotly/plotlyFigures.py +++ b/src/feelpp/benchmarking/json_report/figures/plotly/plotlyFigures.py @@ -44,6 +44,8 @@ def createSliderAnimation(self, df): for i, dim in enumerate(anim_dimension_values): frame_df = df.xs(dim, level=secondary_axis, axis=0) frame_traces = self.createTraces(frame_df) + if not isinstance(frame_traces, list): + frame_traces = [frame_traces] traces_per_frame.append(len(frame_traces)) for trace in frame_traces: diff --git a/src/feelpp/benchmarking/reframe/__main__.py b/src/feelpp/benchmarking/reframe/__main__.py index ff8c4eabc..1f55e4ac9 100644 --- a/src/feelpp/benchmarking/reframe/__main__.py +++ b/src/feelpp/benchmarking/reframe/__main__.py @@ -123,6 +123,55 @@ def main_cli(): os.remove(os.path.join(report_folder_path,"report.json")) os.rmdir(report_folder_path) + + #================= MERGE RESTORED SESSION REPORTS =============# + if "--restore-session" in parser.args.reframe_args: + reframe_args = parser.args.reframe_args.split(" ") + restore_session_index = reframe_args.index("--restore-session") + restore_session_path = reframe_args[restore_session_index + 1] + if not os.path.exists(restore_session_path) or not os.path.isfile(restore_session_path): + raise FileNotFoundError(f"Restore session path {restore_session_path} does not exist") + with open(restore_session_path,"r") as f: + restored_report = json.load(f) + with open(os.path.join(report_folder_path,"reframe_report.json"),"r") as f: + current_report = json.load(f) + restored_report["runs"].extend(current_report["runs"]) + restored_report["session_info"]["num_cases"] = max([run["num_cases"] for run in restored_report["runs"]]) + restored_report["session_info"]["num_failures"] = min([run["num_failures"] for run in restored_report["runs"]]) + + with open(restore_session_path,"w") as f: + json.dump(restored_report,f,indent=4) + + #Update logs and partials + new_logs_dir = os.path.join(report_folder_path,"logs") + restored_logs_dir = os.path.join(os.path.dirname(restore_session_path),"logs") + #Copy new logs into restored, overwrite if existant + if os.path.exists(restored_logs_dir): + if os.path.exists(new_logs_dir): + for log_file in os.listdir(new_logs_dir): + shutil.copy(os.path.join(new_logs_dir,log_file),restored_logs_dir) + else: + if os.path.exists(new_logs_dir): + shutil.copytree(new_logs_dir,restored_logs_dir) + + new_partials_dir = os.path.join(report_folder_path,"partials") + restored_partials_dir = os.path.join(os.path.dirname(restore_session_path),"partials") + #Copy new partials into restored, overwrite if existant + if os.path.exists(restored_partials_dir): + if os.path.exists(new_partials_dir): + for partial_file in os.listdir(new_partials_dir): + shutil.copy(os.path.join(new_partials_dir,partial_file),restored_partials_dir) + else: + if os.path.exists(new_partials_dir): + shutil.copytree(new_partials_dir,restored_partials_dir) + + #Remove current report folder + if os.path.exists(report_folder_path): + shutil.rmtree(report_folder_path) + #======================================================# + + + # ================== MOVE RESULTS (OPTION)============# if parser.args.move_results: if not os.path.exists(parser.args.move_results): diff --git a/src/feelpp/benchmarking/reframe/schemas/defaultJsonReport.py b/src/feelpp/benchmarking/reframe/schemas/defaultJsonReport.py index 9e603114d..ed253a034 100644 --- a/src/feelpp/benchmarking/reframe/schemas/defaultJsonReport.py +++ b/src/feelpp/benchmarking/reframe/schemas/defaultJsonReport.py @@ -27,7 +27,7 @@ class DefaultPlot(Plot): { "type":"DataTable", "name":"parameter_table", "ref":"reframe_df", "table_options":{ "computed_columns":{ "logs_link":"f'link:logs/{row[\"testcases.hashcode\"]}.html[Logs]'" }, - "group_by":{"columns":["testcases.hashcode"], "agg":"first"}, + "group_by":{"columns":["testcases.hashcode"], "agg":"last"}, "format":{ "testcases.time_total":"%.3f", "result":{"pass": "🟢", "fail": "🔴", "abort": "🟠"} } } } @@ -135,7 +135,7 @@ def applyDefaultContent(self): "filter":{ "placeholder":"Filter testcases..." } }, { "type":"table","ref":"perfvar_table", "layout":{ - "rename":{"perfvalue":"Performance Variable"}, "column_order":["perfvalue"] + "rename":{"perfvalue":"Performance Variable"}, "column_order":["perfvalue"] } } ] }) diff --git a/src/feelpp/benchmarking/report/plugins/reframeReport.py b/src/feelpp/benchmarking/report/plugins/reframeReport.py index 6ee6a6059..64e6b7a78 100644 --- a/src/feelpp/benchmarking/report/plugins/reframeReport.py +++ b/src/feelpp/benchmarking/report/plugins/reframeReport.py @@ -35,8 +35,8 @@ def summarizeReports(df: pd.DataFrame, repository_type): leaf_summary = df.groupby("leaves").agg( num_runs=("runs.run_index", lambda x: x.max() + 1), date=("date", "first"), - num_cases=("runs.num_cases", "first"), - num_failures=("runs.num_failures", "first"), + num_cases=("session_info.num_cases", "first"), + num_failures=("session_info.num_failures", "first"), result=("result", lambda x: "pass" if (x == "pass").all() else "fail"), repo_value=(repository_type, "first"), ) @@ -59,7 +59,8 @@ def summarizeReports(df: pd.DataFrame, repository_type): @staticmethod - def runsToDf(runs): + def runsToDf(report): + runs = report.get("runs",[]) runs_dfs = [] for run in runs: run_df = pd.DataFrame.from_dict(run,orient="index").T.drop(columns="testcases") @@ -97,10 +98,17 @@ def runsToDf(runs): testcases_df = pd.concat(testcases,axis=0) runs_dfs.append(pd.concat([testcases_df,run_df.loc[run_df.index.repeat(perfvar_df.shape[0])].reset_index(drop=True)],axis=1)) - return pd.concat(runs_dfs,axis=0) + runs_df = pd.concat(runs_dfs,axis=0) + session_info = report.get("session_info",{}) + for k,v in session_info.items(): + if isinstance(v,dict) or isinstance(v,list): + runs_df[f"session_info.{k}"] = str(v) + else: + runs_df[f"session_info.{k}"] = v + return runs_df def runsToDfPreprocessor(rfm_report): if rfm_report: - return ReframeReportPlugin.runsToDf(rfm_report.get("runs",[])) - return pd.DataFrame() \ No newline at end of file + return ReframeReportPlugin.runsToDf(rfm_report) + return pd.DataFrame() diff --git a/src/feelpp/benchmarking/report/templates/dashboardOverview.adoc.j2 b/src/feelpp/benchmarking/report/templates/dashboardOverview.adoc.j2 index 04a0d1e1a..da1a3c873 100644 --- a/src/feelpp/benchmarking/report/templates/dashboardOverview.adoc.j2 +++ b/src/feelpp/benchmarking/report/templates/dashboardOverview.adoc.j2 @@ -9,8 +9,8 @@ {% if "leaves" in aggregated["data"] %} {% set agg = { "date":"first", - "runs.num_failures": "max", - "runs.num_cases": "max" + "session_info.num_failures": "first", + "session_info.num_cases": "first" } %} {% if "machines" in aggregated["data"].columns %} @@ -37,8 +37,8 @@ {% for row in df.to_dict(orient="records") %} {% set row_url = "leaves/"+row["leaves"]+"/leaf.adoc" %} -{% set total = row["runs.num_cases"] %} -{% set failures = row["runs.num_failures"] %} +{% set total = row["session_info.num_cases"] %} +{% set failures = row["session_info.num_failures"] %} {% set success_pct = ((total - failures) / total * 100) if total > 0 else 0 %} {% set pct_fmt = "%.0f"|format(success_pct) %}