import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
OUT = "/tmp/figs"
import os; os.makedirs(OUT, exist_ok=True)
rungs = [
("Predict the training median\n(measure nothing)", 7.588),
("Job configuration only\n(free metadata)", 7.826),
("Cycle count, assume no stalls\n(1 counter)", 1.238),
("Cycle count + fitted constant\n(1 counter)", 1.065),
("Cycle count + all 21 features\n(5 profiling runs)", 1.054),
]
labels = [r[0] for r in rungs]
vals = [r[1] for r in rungs]
fig, ax = plt.subplots(figsize=(8.4, 4.0))
y = np.arange(len(vals))[::-1]
cols = ["0.72", "0.72", "#4477aa", "#4477aa", "#225588"]
ax.barh(y, vals, color=cols, height=0.62)
ax.axvline(1.0, color="k", lw=1.1)
ax.text(1.02, 4.62, "perfect", fontsize=8.5, va="center")
for yi, v in zip(y, vals):
ax.text(v * 1.06, yi, f"{v:.3f}", va="center", fontsize=10)
ax.set_yticks(y); ax.set_yticklabels(labels, fontsize=9.5)
ax.set_xscale("log")
ax.set_xlim(0.9, 14)
ax.set_xticks([1, 2, 5, 10])
ax.set_xticklabels(["1x", "2x", "5x", "10x"])
ax.set_xlabel("typical error factor (1x is exact prediction)", fontsize=10)
ax.set_title("Almost all the accuracy arrives with the first counter",
fontsize=11.5, pad=10)
ax.grid(axis="x", alpha=0.3)
for sp in ("top", "right"): ax.spines[sp].set_visible(False)
fig.tight_layout()
fig.savefig(f"{OUT}/fig_ladder.png", dpi=160)
plt.close(fig)
print("wrote fig_ladder.png")
apps = ["comd", "gromacs", "hpcg", "hpl", "lulesh", "minife", "openfoam", "stream"]
const = [1.046, 1.051, 1.048, 1.078, 1.175, 1.372, 1.068, 1.051]
rf = [1.026, 1.006, 1.117, 1.043, 1.049, 1.067, 1.073, 1.099]
order = np.argsort(const)[::-1]
apps = [apps[i] for i in order]
const = [const[i] for i in order]
rf = [rf[i] for i in order]
fig, ax = plt.subplots(figsize=(8.4, 3.9))
x = np.arange(len(apps)); w = 0.38
ax.bar(x - w/2, [c - 1 for c in const], w, bottom=1,
color="0.72", label="no counters (constant)")
ax.bar(x + w/2, [r - 1 for r in rf], w, bottom=1,
color="#4477aa", label="all 21 counter features")
ax.axhline(1.0, color="k", lw=1.0)
for xi, (c, r) in enumerate(zip(const, rf)):
ax.annotate("", xy=(xi + w/2, r), xytext=(xi - w/2, c),
arrowprops=dict(arrowstyle="->", lw=0.9,
color="green" if r < c else "firebrick"))
ax.set_xticks(x); ax.set_xticklabels(apps, fontsize=10)
ax.set_ylabel("error factor", fontsize=10)
ax.set_ylim(1.0, 1.42)
ax.set_title("Counters help on five applications and hurt on three",
fontsize=11.5, pad=10)
ax.legend(fontsize=9, frameon=False, loc="upper right")
ax.grid(axis="y", alpha=0.3)
for sp in ("top", "right"): ax.spines[sp].set_visible(False)
fig.tight_layout()
fig.savefig(f"{OUT}/fig_perapp.png", dpi=160)
plt.close(fig)
print("wrote fig_perapp.png")