about summary refs log tree commit diff stats
path: root/archive/2024/winter/bsc_dichler/scripts/plot
diff options
context:
space:
mode:
Diffstat (limited to 'archive/2024/winter/bsc_dichler/scripts/plot')
-rw-r--r--archive/2024/winter/bsc_dichler/scripts/plot/cas.py92
-rw-r--r--archive/2024/winter/bsc_dichler/scripts/plot/contiguous.py72
-rw-r--r--archive/2024/winter/bsc_dichler/scripts/plot/contiguous_tagging.py91
-rw-r--r--archive/2024/winter/bsc_dichler/scripts/plot/malloc.py122
-rw-r--r--archive/2024/winter/bsc_dichler/scripts/plot/non_contiguous.py99
-rw-r--r--archive/2024/winter/bsc_dichler/scripts/plot/parallel_non_contiguous.py117
6 files changed, 593 insertions, 0 deletions
diff --git a/archive/2024/winter/bsc_dichler/scripts/plot/cas.py b/archive/2024/winter/bsc_dichler/scripts/plot/cas.py
new file mode 100644
index 000000000..e6f3a08e1
--- /dev/null
+++ b/archive/2024/winter/bsc_dichler/scripts/plot/cas.py
@@ -0,0 +1,92 @@
+from pathlib import Path
+import pandas as pd
+import matplotlib.pyplot as plt
+import numpy as np
+
+
+def plot(output_root: Path, format):
+    output_root = output_root / Path("cas")
+    csv_file1 = output_root / Path("run.csv")
+    csv_file2 = output_root / Path("run_mte.csv")
+
+    df1 = pd.read_csv(csv_file1, sep=";")
+    df2 = pd.read_csv(csv_file2, sep=";")
+
+    df1["duration"] = df1["duration"] / 1_000_000_000
+    df2["duration"] = df2["duration"] / 1_000_000_000
+
+    grouped1 = df1.groupby("cores")["duration"].agg(["mean", "std"]).reset_index()
+    grouped2 = df2.groupby("cores")["duration"].agg(["mean", "std"]).reset_index()
+
+    merged = pd.merge(grouped1, grouped2, on="cores", suffixes=("_1", "_2"))
+
+    _, ax1 = plt.subplots(figsize=(10, 6))
+
+    library = ["1 Thread", "2 Threads", "3 Threads", "4 Threads"]
+    x = np.arange(len(library))
+    bar_width = 0.35
+
+    ax1.bar(
+        x - bar_width / 2,
+        merged["mean_1"],
+        yerr=merged["std_1"],
+        width=bar_width,
+        capsize=5,
+        label="MTE disabled",
+        color="#fc9272",
+        edgecolor="black",
+        linewidth=2,
+    )
+    ax1.bar(
+        x + bar_width / 2,
+        merged["mean_2"],
+        yerr=merged["std_2"],
+        width=bar_width,
+        capsize=5,
+        label="MTE enabled",
+        color="#a6bddb",
+        edgecolor="black",
+        linewidth=2,
+    )
+
+    for i, row in merged.iterrows():
+        x_start = i - 0.05
+
+        y_start = row["mean_2"]
+        y_end = row["mean_1"]
+
+        if (y_start - row["std_2"]) <= (y_end + row["std_1"]):
+            continue
+
+        ax1.annotate(
+            f"",
+            xy=(x_start - 0.25 / 2, y_start),
+            xytext=(x_start - 0.25 / 2, y_end + 0.05 * y_end),
+            arrowprops=dict(arrowstyle="->", color="red", lw=2),
+            color="red",
+            ha="center",
+        )
+
+        percentage = y_start / y_end
+        ax1.text(
+            x_start - 0.25 / 2,
+            y_start + ((y_end - y_start) / 2),
+            f"{percentage:.2f}×",
+            color="red",
+            fontweight="bold",
+            bbox=dict(facecolor="white", alpha=1.0, edgecolor="none"),
+            ha="center",
+        )
+
+    plt.xticks(x, library)
+    ax1.set_ylabel("Time (s)")
+    ax1.set_xlabel(r"#Threads")
+
+    ax1.spines["top"].set_visible(False)
+    ax1.spines["right"].set_visible(False)
+    ax1.set_title("Lower is better ↓", color="navy")
+    ax1.legend(loc="upper left")
+    ax1.set_ylim(ymin=0)
+
+    output = output_root / Path(f"result.{format}")
+    plt.savefig(output, format=format)
diff --git a/archive/2024/winter/bsc_dichler/scripts/plot/contiguous.py b/archive/2024/winter/bsc_dichler/scripts/plot/contiguous.py
new file mode 100644
index 000000000..24981138e
--- /dev/null
+++ b/archive/2024/winter/bsc_dichler/scripts/plot/contiguous.py
@@ -0,0 +1,72 @@
+from pathlib import Path
+import pandas as pd
+import matplotlib.pyplot as plt
+
+
+def plot(output_root: Path, format):
+    output_root = output_root / Path("contiguous")
+    csv_file1 = output_root / Path("load16.csv")
+    csv_file2 = output_root / Path("load16_mte.csv")
+
+    df1 = pd.read_csv(csv_file1, sep=";")
+    df2 = pd.read_csv(csv_file2, sep=";")
+
+    df1["kb"] = df1["len"] * 64 // 1024
+    df2["kb"] = df2["len"] * 64 // 1024
+
+    grouped1 = df1.groupby("kb")["duration"].agg(["mean", "std"]).reset_index()
+    grouped2 = df2.groupby("kb")["duration"].agg(["mean", "std"]).reset_index()
+
+    merged = pd.merge(grouped1, grouped2, on="kb", suffixes=("_1", "_2"))
+
+    _, ax1 = plt.subplots(figsize=(10, 6))
+
+    ax1.errorbar(
+        merged["kb"],
+        merged["mean_1"],
+        yerr=merged["std_1"],
+        fmt="o-",
+        color="#a6bddb",
+        capsize=5,
+        label="MTE disabled",
+    )
+    ax1.errorbar(
+        merged["kb"],
+        merged["mean_2"],
+        yerr=merged["std_2"],
+        fmt="s-",
+        color="#fc9272",
+        capsize=5,
+        label="MTE enabled",
+    )
+
+    merged["lower_1"] = merged["mean_1"] - merged["std_1"]
+    merged["lower_2"] = merged["mean_2"] - merged["std_2"]
+    merged["upper_1"] = merged["mean_1"] + merged["std_1"]
+    merged["upper_2"] = merged["mean_2"] + merged["std_2"]
+
+    ax1.set_xscale("log", base=2)
+    ax1.set_yscale("log", base=2)
+
+    ax1.legend(loc="upper left")
+    ax1.grid(True, which="both", linestyle="--", linewidth=0.5)
+
+    xticks = grouped1["kb"].to_numpy()
+    xticks_filtered = [x for i, x in enumerate(xticks) if i % 2 == 0]
+    xtick_labels = [
+        f"{int(x/1024)} MiB" if x >= 1024 else f"{int(x)} KiB" for x in xticks_filtered
+    ]
+
+    plt.xticks(xticks_filtered, xtick_labels, rotation=45, ha="right")
+
+    plt.title("Lower is better ↓", color="navy")
+    plt.ylabel("Time (ns - logarithmic scale)")
+    plt.xlabel("Memory size (logarithmic scale)")
+
+    ax1.spines["top"].set_visible(False)
+    ax1.spines["right"].set_visible(False)
+
+    plt.tight_layout()
+
+    output = output_root / Path(f"result.{format}")
+    plt.savefig(output, format=format)
diff --git a/archive/2024/winter/bsc_dichler/scripts/plot/contiguous_tagging.py b/archive/2024/winter/bsc_dichler/scripts/plot/contiguous_tagging.py
new file mode 100644
index 000000000..df6a3eba1
--- /dev/null
+++ b/archive/2024/winter/bsc_dichler/scripts/plot/contiguous_tagging.py
@@ -0,0 +1,91 @@
+from pathlib import Path
+import pandas as pd
+import matplotlib.pyplot as plt
+import numpy as np
+
+
+def plot(output_root: Path, format):
+    output_root = output_root / Path("contiguous_tagging")
+    labels = ["malloc", "stg", "st2g", "ldg", "ldr", "str"]
+    csv_files = [
+        output_root / Path("tag_malloc.csv"),
+        output_root / Path("tag_stg.csv"),
+        output_root / Path("tag_st2g.csv"),
+        output_root / Path("ldg.csv"),
+        output_root / Path("load.csv"),
+        output_root / Path("store.csv"),
+    ]
+
+    dfs = []
+    for file in csv_files:
+        df = pd.read_csv(file, sep=";")
+        df["duration"] = df["duration"]
+
+        df["duration_per_op"] = df["duration"] / df["ops"]
+        g = df.groupby("size")["duration_per_op"].agg(["mean", "std"]).reset_index()
+
+        dfs.append(g)
+
+    _, ax1 = plt.subplots(figsize=(10, 6))
+
+    library = [""]
+    colors = [
+        "#a6bddb",
+        "#fc9272",
+        "#99d8c9",
+        "#c994c7",
+        "#fdbb84",
+        "#efedf5",
+        "skyblue",
+    ]
+    bar_width = 0.8 / len(csv_files)
+    x = np.arange(len(library))
+
+    group_mins = {}
+    group_maxs = {}
+
+    hatches = ["", "", "", "", "", "", ""]
+    for i in range(len(csv_files)):
+        df = dfs[i]
+        mean_values = df["mean"].values
+
+        for j, size in enumerate(df["size"].values):
+            x_pos = x[j] + (i - (len(csv_files) - 1) / 2) * bar_width
+            ax1.text(
+                x_pos,
+                mean_values[j],
+                f"{mean_values[j]:.3f}",
+                ha="center",
+                va="bottom",
+                color="black",
+            )
+            if size not in group_mins or mean_values[j] < group_mins[size][1]:
+                group_mins[size] = (x_pos, mean_values[j])  # Store (x, min mean)
+            if size not in group_maxs or mean_values[j] > group_maxs[size][1]:
+                group_maxs[size] = (x_pos, mean_values[j])  # Store (x, max mean)
+
+        _ = ax1.bar(
+            x + (i - (len(csv_files) - 1) / 2) * bar_width,
+            mean_values,
+            yerr=df["std"],
+            width=bar_width,
+            capsize=5,
+            label=labels[i],
+            color=colors[i % len(colors)],
+            edgecolor="black",
+            hatch=hatches[i],
+            linewidth=2,
+        )
+
+    ax1.set_ylabel("Time (ns)")
+    ax1.set_xlabel("Single instruction")
+    ax1.legend(labels=labels, loc="upper right")
+    plt.title("Lower is better ↓", color="navy")
+    ax1.spines["top"].set_visible(False)
+    ax1.spines["right"].set_visible(False)
+    plt.xticks(x, library, ha="right")
+    ax1.set_ylim(ymin=0)
+    plt.tight_layout()
+
+    output = output_root / Path(f"result.{format}")
+    plt.savefig(output, format=format)
diff --git a/archive/2024/winter/bsc_dichler/scripts/plot/malloc.py b/archive/2024/winter/bsc_dichler/scripts/plot/malloc.py
new file mode 100644
index 000000000..50a21aa18
--- /dev/null
+++ b/archive/2024/winter/bsc_dichler/scripts/plot/malloc.py
@@ -0,0 +1,122 @@
+from pathlib import Path
+import pandas as pd
+import matplotlib.pyplot as plt
+import numpy as np
+
+
+def run(csv_file1, csv_file2, duration_type, output, format):
+    df1 = pd.read_csv(csv_file1, sep=";")
+    df2 = pd.read_csv(csv_file2, sep=";")
+
+    def norm(df):
+        df["duration_allocation"] = df["duration_allocation"] / df["allocation"] / 1000
+        df["duration_deallocation"] = (
+            df["duration_deallocation"] / df["allocation"] / 1000
+        )
+
+    norm(df1)
+    norm(df2)
+
+    grouped1 = (
+        df1.groupby("size")[["duration_allocation", "duration_deallocation"]]
+        .agg(["mean", "std"])
+        .reset_index()
+    )
+    grouped2 = (
+        df2.groupby("size")[["duration_allocation", "duration_deallocation"]]
+        .agg(["mean", "std"])
+        .reset_index()
+    )
+
+    _, ax1 = plt.subplots(figsize=(12, 6))
+
+    library = [
+        "16 Bytes",
+        "128 Bytes",
+        "256 Bytes",
+        "1024 Bytes",
+        "2048 Bytes",
+        "4096 Bytes",
+        "8192 Bytes",
+    ]
+    x = np.arange(len(library))
+    bar_width = 0.35
+
+    bars1 = ax1.bar(
+        x - bar_width / 2,
+        grouped1[duration_type]["mean"],
+        yerr=grouped1[duration_type]["std"],
+        width=bar_width,
+        capsize=5,
+        label="MTE disabled",
+        color="#a6bddb",
+        edgecolor="black",
+        linewidth=2,
+    )
+    bars2 = ax1.bar(
+        x + bar_width / 2,
+        grouped2[duration_type]["mean"],
+        yerr=grouped2[duration_type]["std"],
+        width=bar_width,
+        capsize=5,
+        label="MTE enabled",
+        color="#fc9272",
+        edgecolor="black",
+        linewidth=2,
+    )
+
+    for i in range(len(bars1)):
+        height2 = bars2[i].get_height()
+        height1 = bars1[i].get_height()
+
+        ax1.annotate(
+            "",
+            xy=(x[i] - bar_width / 2, height2),
+            xytext=(x[i] - bar_width / 2, height1),
+            arrowprops=dict(arrowstyle="->", color="red", lw=2),
+            color="red",
+            ha="center",
+        )
+
+        difference = height2 / height1
+        ax1.text(
+            i - bar_width / 2 - 0.04,
+            height1 + ((height2 - height1) / 2) - 0.08,
+            f"{difference:.2f}×",
+            color="red",
+            fontweight="bold",
+            bbox=dict(facecolor="white", alpha=1.0, edgecolor="none"),
+            ha="center",
+        )
+
+    plt.ylabel("Time (µs)")
+    ax1.set_xlabel("Batch size")
+    ax1.legend(loc="upper left")
+    plt.title("Lower is better ↓", color="navy")
+
+    ax1.spines["top"].set_visible(False)
+    ax1.spines["right"].set_visible(False)
+    plt.tight_layout()
+
+    plt.xticks(x, library)
+    plt.tight_layout()
+    plt.savefig(output, format=format)
+
+
+def plot(output_root: Path, format):
+    output_root = output_root / Path("malloc")
+
+    run(
+        output_root / Path("malloc.csv"),
+        output_root / Path("malloc_mte.csv"),
+        "duration_allocation",
+        output_root / Path(f"result-alloc.{format}"),
+        format,
+    )
+    run(
+        output_root / Path("malloc.csv"),
+        output_root / Path("malloc_mte.csv"),
+        "duration_deallocation",
+        output_root / Path(f"result-dealloc.{format}"),
+        format,
+    )
diff --git a/archive/2024/winter/bsc_dichler/scripts/plot/non_contiguous.py b/archive/2024/winter/bsc_dichler/scripts/plot/non_contiguous.py
new file mode 100644
index 000000000..ddfae4322
--- /dev/null
+++ b/archive/2024/winter/bsc_dichler/scripts/plot/non_contiguous.py
@@ -0,0 +1,99 @@
+from pathlib import Path
+import pandas as pd
+import matplotlib.pyplot as plt
+
+
+def plot(output_root: Path, format):
+    output_root = output_root / Path("non_contiguous")
+    mte_enabled_csv = output_root / Path("load_mte.csv")
+    mte_disabled_csv = output_root / Path("load.csv")
+
+    enabled_df = pd.read_csv(mte_enabled_csv, sep=";")
+    disabled_df = pd.read_csv(mte_disabled_csv, sep=";")
+
+    for df in [enabled_df, disabled_df]:
+        df["duration"] = df["duration"] / 1_000_000
+        df["kb"] = df["len"] * 16 // 1024
+
+    enabled_grouped = (
+        enabled_df.groupby("kb")["duration"].agg(["mean", "std"]).reset_index()
+    )
+    disabled_grouped = (
+        disabled_df.groupby("kb")["duration"].agg(["mean", "std"]).reset_index()
+    )
+
+    _, ax1 = plt.subplots(figsize=(10, 6))
+    ax1.errorbar(
+        enabled_grouped["kb"],
+        enabled_grouped["mean"],
+        yerr=enabled_grouped["std"],
+        capsize=5,
+        color="#a6bddb",
+        linewidth=2.5,
+        label="MTE enabled",
+    )
+    ax1.errorbar(
+        disabled_grouped["kb"],
+        disabled_grouped["mean"],
+        yerr=disabled_grouped["std"],
+        capsize=5,
+        color="#fc9272",
+        linewidth=2.5,
+        label="MTE disabled",
+    )
+
+    ax1.set_xscale("log", base=2)
+    ax1.set_yscale("log", base=2)
+
+    tick_positions = enabled_grouped["kb"].iloc[::2]
+    tick_labels = [
+        f"{v} KiB" if v < 1024 else f"{v // 1024} MiB" for v in tick_positions
+    ]
+    ax1.set_xticks(tick_positions)
+    ax1.set_xticklabels(tick_labels, rotation=45, ha="right")
+
+    plt.xticks()
+    plt.yticks()
+
+    enabled_grouped["lower"] = enabled_grouped["mean"] - enabled_grouped["std"]
+    disabled_grouped["lower"] = disabled_grouped["mean"] - disabled_grouped["std"]
+    enabled_grouped["upper"] = enabled_grouped["mean"] + enabled_grouped["std"]
+    disabled_grouped["upper"] = disabled_grouped["mean"] + disabled_grouped["std"]
+
+    overlap = (disabled_grouped["lower"] <= enabled_grouped["upper"]) & (
+        disabled_grouped["upper"] >= enabled_grouped["lower"]
+    )
+
+    enabled_grouped["percentage_diff"] = (
+        (enabled_grouped["mean"] - disabled_grouped["mean"]) / enabled_grouped["mean"]
+    ) * 100
+    enabled_grouped.loc[overlap, "percentage_diff"] = 0
+
+    ax2 = ax1.twinx()
+    ax2.plot(
+        enabled_grouped["kb"],
+        enabled_grouped["percentage_diff"],
+        "r--",
+        label="% Difference",
+    )
+    ax2.set_ylabel("Difference (%)", fontsize=12)
+    ax2.set_ylim(
+        min(enabled_grouped["percentage_diff"]),
+        max(enabled_grouped["percentage_diff"]) + 10,
+    )
+
+    h1, l1 = ax1.get_legend_handles_labels()
+    h2, l2 = ax2.get_legend_handles_labels()
+
+    ax1.legend(loc="upper left", handles=h1 + h2, labels=l1 + l2)
+
+    ax1.set_ylabel("Time (ns - logarithmic scale)")
+    ax1.set_xlabel("Memory size (logarithmic scale)")
+
+    plt.title("Lower is better ↓", color="navy")
+
+    ax1.grid(True, which="both", linestyle=":", linewidth=0.5)
+    plt.tight_layout()
+
+    output = output_root / Path(f"result.{format}")
+    plt.savefig(output, format=format)
diff --git a/archive/2024/winter/bsc_dichler/scripts/plot/parallel_non_contiguous.py b/archive/2024/winter/bsc_dichler/scripts/plot/parallel_non_contiguous.py
new file mode 100644
index 000000000..f766fcedc
--- /dev/null
+++ b/archive/2024/winter/bsc_dichler/scripts/plot/parallel_non_contiguous.py
@@ -0,0 +1,117 @@
+from pathlib import Path
+import pandas as pd
+import matplotlib.pyplot as plt
+
+
+def run(csv_files: list[Path], output: Path, format):
+    _, ax1 = plt.subplots(figsize=(10, 6))
+    labels = ["MTE disabled", "MTE enabled"]
+
+    data = []
+    unique_threads = set()
+    tick_positions = None
+    for file in csv_files:
+        df = pd.read_csv(file, sep=";")
+        df["duration"] = df["duration"] // 1_000
+        g = (
+            df.groupby(["len", "threads"])["duration"]
+            .agg(["mean", "std"])
+            .reset_index()
+        )
+        g["kb"] = (g["len"] * 16) / 1024
+        data.append(g)
+        unique_threads.update(g["threads"].unique())
+        tick_positions = g["kb"].unique()
+
+    unique_threads = sorted(unique_threads)
+
+    thread_colors = {1: "tomato", 2: "#56B4E9", 3: "#009E73", 4: "#E69F00"}
+
+    line_styles = ["-", "--"]
+
+    handles = []
+    labels_legend = []
+
+    for thread in unique_threads:
+        for idx, g in enumerate(data):
+            subset = g[g["threads"] == thread]
+            if subset.empty:
+                continue
+
+            line = ax1.errorbar(
+                subset["kb"],
+                subset["mean"],
+                yerr=subset["std"],
+                fmt="o",
+                linestyle=line_styles[idx],
+                capsize=5,
+                color=thread_colors.get(thread, "black"),
+            )
+
+            label = (
+                f"1 Thread - {labels[idx]}"
+                if thread == 1
+                else f"{thread} Threads - {labels[idx]}"
+            )
+            handles.append(line[0])
+            labels_legend.append(label)
+
+    ax1.legend(
+        handles=handles,
+        labels=labels_legend,
+        ncol=2,
+        loc="upper left",
+        fancybox=True,
+        shadow=False,
+    )
+
+    ax1.set_xscale("log", base=2)
+    ax1.set_yscale("log", base=2)
+
+    ax1.grid(True, which="both", linestyle="--", linewidth=0.5)
+    tick_labels = []
+    xticks_filtered = [x for i, x in enumerate(tick_positions) if i % 2 == 0]
+    for idx, v in enumerate(xticks_filtered):
+        l = ""
+        if v < 1024:
+            if v < 1:
+                l = "1 KiB"
+            else:
+                l = f"{v} KiB"
+        else:
+            l = f"{v // 1024} MiB"
+
+        tick_labels.append(l)
+
+    ax1.set_xticks(xticks_filtered)
+    ax1.set_xticklabels(tick_labels, rotation=45, ha="right")
+    ax1.set_ylabel("Time (ns - logarithmic scale)")
+    ax1.set_xlabel("Memory size (logarithmic scale)")
+
+    ax1.spines["top"].set_visible(False)
+    ax1.spines["right"].set_visible(False)
+
+    plt.title("Lower is better ↓", color="navy")
+    plt.tight_layout()
+    plt.savefig(output, format=format)
+
+
+def plot(output_root: Path, format):
+    output_root = output_root / Path("parallel_non_contiguous")
+
+    run(
+        [
+            output_root / Path("write.csv"),
+            output_root / Path("write_mte.csv"),
+        ],
+        output_root / Path(f"result-write.{format}"),
+        format,
+    )
+    run(
+        [
+            output_root / Path("load.csv"),
+            output_root / Path("load_mte.csv"),
+        ],
+        output_root / Path(f"result-read.{format}"),
+        format,
+    )