فهرست منبع

label fix | read out peaks accurately | print adjustment

Snej69420 4 ماه پیش
والد
کامیت
6a3b8ca3d2
3فایلهای تغییر یافته به همراه117 افزوده شده و 13 حذف شده
  1. 113 9
      benchmarks/mean.py
  2. 3 3
      benchmarks/memory_peaks.py
  3. 1 1
      benchmarks/model_properties.py

+ 113 - 9
benchmarks/mean.py

@@ -7,8 +7,11 @@ BASE_DIR = Path(__file__).resolve().parent
 
 ENGINES = {
     "agents": "Results/Agents/Time/{model}_{type}.csv",
-    "pypdevs-min": "Results/PyPDEVS/Time/minimal/{model}_{type}.csv",
+    "pypdevs-minimal": "Results/PyPDEVS/Time/minimal/{model}_{type}.csv",
+    "pypdevs-classic": "Results/PyPDEVS/Time/classic/{model}_{type}.csv",
     "pypdevs-parallel": "Results/PyPDEVS/Time/parallel/{model}_{type}.csv",
+    "pypdevs-dynamic": "Results/PyPDEVS/Time/dynamic/{model}_{type}.csv",
+    "pypdevs-dynamic-classic": "Results/PyPDEVS/Time/dynamic-classic/{model}_{type}.csv",
 }
 
 # Configured dimensions per model scenario
@@ -30,7 +33,7 @@ def format_to_latex(mean, std):
         return f"${mean:.3f} \\pm 0.000$"
 
     std_magnitude = int(np.floor(np.log10(abs(std))))
-    decimal_places = -std_magnitude + 1
+    decimal_places = -std_magnitude
 
     if decimal_places >= 0:
         return f"${mean:.{decimal_places}f} \\pm {std:.{decimal_places}f}$"
@@ -100,6 +103,50 @@ def get_metrics(engine, model, data_type, custom_depth=None, custom_width=None):
     except Exception:
         return None, None
 
+def get_dual_metrics(engine, model, data_type, custom_depth=None, custom_width=None):
+    """
+    Locates file, removes outliers using the IQR method based on total_time,
+    and returns both the Total (sum) and Sim-only metrics.
+    """
+    template = ENGINES.get(engine)
+    if not template:
+        return (None, None), (None, None)
+
+    file_path = BASE_DIR / template.format(model=model, type=data_type)
+    if not file_path.exists():
+        return (None, None), (None, None)
+
+    depth = custom_depth if custom_depth is not None else MODEL_DIMENSIONS[model]["depth"]
+    width = custom_width if custom_width is not None else MODEL_DIMENSIONS[model]["width"]
+
+    try:
+        df = pd.read_csv(file_path)
+
+        df["total_time"] = df["simulation_time"] + df["creation_time"] + df["setup_time"]
+
+        group_params = [c for c in ["depth", "width", "number"] if c in df.columns]
+
+        if group_params:
+            q1 = df.groupby(group_params)["total_time"].transform(lambda x: x.quantile(0.25))
+            q3 = df.groupby(group_params)["total_time"].transform(lambda x: x.quantile(0.75))
+
+            iqr = q3 - q1
+            lower = q1 - 1.5 * iqr
+            upper = q3 + 1.5 * iqr
+
+            df = df[(df["total_time"] >= lower) & (df["total_time"] <= upper)]
+
+        filtered_df = df[(df["depth"] == depth) & (df["width"] == width)]
+        if filtered_df.empty:
+            return (None, None), (None, None)
+
+        tot_mean, tot_std = filtered_df["total_time"].mean(), filtered_df["total_time"].std()
+        sim_mean, sim_std = filtered_df["simulation_time"].mean(), filtered_df["simulation_time"].std()
+
+        return (tot_mean, tot_std), (sim_mean, sim_std)
+    except Exception:
+        return (None, None), (None, None)
+
 def handle_single(args):
     """Computes a single measurement point using manual overrides or rules if omitted."""
     depth = args.depth if args.depth is not None else MODEL_DIMENSIONS[args.model]["depth"]
@@ -124,7 +171,7 @@ def handle_comparison(args):
     print("Generating Engine Performance Matrix Table...\n")
 
     table_data = {}
-    for engine in ["pypdevs-parallel", "pypdevs-min", "agents"]:
+    for engine in ENGINES.keys():
         row_cells = []
         for model in MODELS:
             mean_val, std_val = get_metrics(engine, model, "baseline")
@@ -132,9 +179,12 @@ def handle_comparison(args):
         table_data[engine] = row_cells
 
     labels = {
-        "pypdevs-parallel": "PyPDEVS (parallel)",
-        "pypdevs-min": "PyPDEVS (min)     ",
-        "agents": "Agents.jl          ",
+        "pypdevs-minimal": "PyPDEVS (m)",
+        "pypdevs-classic": "PyPDEVS (c)",
+        "pypdevs-parallel": "PyPDEVS (p)",
+        "pypdevs-dynamic": "PyPDEVS (d)",
+        "pypdevs-dynamic-classic": "PyPDEVS (dc)",
+        "agents": "Agents.jl",
     }
 
     latex_table = (
@@ -145,19 +195,70 @@ def handle_comparison(args):
         "        \\textbf{Engine} & {\\textbf{LI (200x200)}} & {\\textbf{HI (200x200)}} & {\\textbf{HO (200x200)}} & {\\textbf{HOmod (40x40)}} \\\\\n"
         "        \\midrule\n"
     )
-    for eng in ["pypdevs-parallel", "pypdevs-min", "agents"]:
+    for eng in ENGINES.keys():
+        print(eng)
         latex_table += f"        {labels[eng]} & {' & '.join(table_data[eng])} \\\\\n"
 
     latex_table += (
         "        \\bottomrule\n"
         "    \\end{tabular}\n"
-        "    \\caption{Performance comparison of different DEVS simulation engines.}\n"
+        "    \\caption{Performance comparison of different DEVS simulation engines in seconds.}\n"
         "    \\label{tab:devstone-performance}\n"
         "\\end{table}"
     )
     print(latex_table)
 
 
+def handle_devstone_comparison(args):
+    """Generates the dual-metric comparison table (Total vs. Sim)."""
+    print("Generating Dual-Metric Engine Comparison Table...\n")
+
+    labels = {
+        "pypdevs-minimal": "PyPDEVS (m)",
+        "pypdevs-classic": "PyPDEVS (c)",
+        "pypdevs-parallel": "PyPDEVS (p)",
+        "pypdevs-dynamic": "PyPDEVS (d)",
+        "pypdevs-dynamic-classic": "PyPDEVS (dc)",
+        "agents": "Agents.jl",
+    }
+
+    latex_table = (
+        "\\begin{table}[htbp]\n"
+        "    \\centering\n"
+        "    \\begin{tabular}{llcccc}\n"
+        "        \\toprule\n"
+        "        \\textbf{Engine} & \\textbf{Phase} & {\\textbf{LI (200x200)}} & {\\textbf{HI (200x200)}} & {\\textbf{HO (200x200)}} & {\\textbf{HOmod (40x40)}} \\\\\n"
+        "        \\midrule\n"
+    )
+
+    for eng in ENGINES.keys():
+        tot_cells = []
+        sim_cells = []
+        for model in MODELS:
+            tot_metrics, sim_metrics = get_dual_metrics(eng, model, "baseline")
+
+            if tot_metrics[0] is not None:
+                tot_cells.append(format_to_latex(tot_metrics[0], tot_metrics[1]))
+                sim_cells.append(format_to_latex(sim_metrics[0], sim_metrics[1]))
+            else:
+                tot_cells.append("-")
+                sim_cells.append("-")
+
+        latex_table += f"        \\multirow{{2}}{{*}}{{{labels[eng]}}} & Total & {' & '.join(tot_cells)} \\\\\n"
+        latex_table += f"         & Sim. Only & {' & '.join(sim_cells)} \\\\\n"
+        latex_table += "        \\midrule\n"
+
+    latex_table = latex_table.rstrip("\\midrule\n") + "\\bottomrule\n"
+
+    latex_table += (
+        "    \\end{tabular}\n"
+        "    \\caption{Comparison of total execution time versus isolated simulation execution time in seconds.}\n"
+        "    \\label{tab:devstone-dual-comparison}\n"
+        "\\end{table}"
+    )
+    print(latex_table)
+
+
 def handle_translation(args):
     """Generates two separate cross-functional Translation strategy tables with fixed dimensions."""
     print("Generating Comparative Translation Function Tables...\n")
@@ -194,7 +295,7 @@ def handle_translation(args):
         latex_table += (
             "        \\bottomrule\n"
             "    \\end{tabular}\n"
-            f"    \\caption{{Performance comparison of translation functions under {engine_labels[engine]}.}}\n"
+            f"    \\caption{{Performance comparison of translation functions under {engine_labels[engine]} in seconds.}}\n"
             f"    \\label{{tab:translation-performance-{engine.replace('-', '_')}}}\n"
             "\\end{table}\n"
         )
@@ -214,6 +315,7 @@ def main():
     p_single.add_argument("-w", "--width", type=int, default=None, help="Force override width constraint")
 
     subparsers.add_parser("comparison", help="Generate Engine Comparison Table (Fixed sizes automatically applied).")
+    subparsers.add_parser("devstone-comparison", help="Generate Engine Comparison Table showing Total and Sim times separately.")
     subparsers.add_parser("translation", help="Generate Translation Strategy Tables (Fixed sizes automatically applied).")
 
     args = parser.parse_args()
@@ -222,6 +324,8 @@ def main():
         handle_single(args)
     elif args.command == "comparison":
         handle_comparison(args)
+    elif args.command == "devstone-comparison":
+        handle_devstone_comparison(args)
     elif args.command == "translation":
         handle_translation(args)
 

+ 3 - 3
benchmarks/memory_peaks.py

@@ -1,10 +1,10 @@
 import sqlite3
 
-# db_path = 'benchmarks/Results/Agents/Memory/HI.sqlite'
-db_path = 'benchmarks/Results/PyPDEVS/Memory/parallel/HI.sqlite'
+db_path = 'benchmarks/Results/Agents/Memory/HO.sqlite'
+# db_path = 'benchmarks/Results/PyPDEVS/Memory/parallel/HI.sqlite'
 # db_path = 'benchmarks/Results/PyPDEVS/Memory/minimal/LI.sqlite'
 
-process_name = 'python3'
+process_name = 'julia'
 
 memory_unit = "MB"  # Options: Bytes, KB, MB, GB, KiB, MiB, GiB
 time_unit = "s"  # Options: ms, s, m, h

+ 1 - 1
benchmarks/model_properties.py

@@ -101,7 +101,7 @@ def model_properties(model: str, width: int, depth: int) -> dict:
 
 def display_model_properties(model: str, width: int, depth: int):
     properties = model_properties(model, width, depth)
-    print(f"Model: {model}")
+    print(f"Model: {model} {depth}x{width}")
     for key, value in properties.items():
         print(f"Number of {key}: {value:,}")
     print("="*50)