hardware-counters
size_diag.py
"""
Which Cirrus runs are too short, and how should sizes be scaled?
The cross-platform experiment held problem sizes identical to ARCHER2 for
comparability. On a 288-core Zen 5 node many runs then finish in well under a
second, where fixed overheads (MPI_Init, I/O, CrayPat) dominate and the
efficiency factor collapses. This quantifies the problem per application so
the size-scaled sweep targets the right ones.
It also checks which benchmarks are ALREADY weak-scaling: HPCG's nx/ny/nz and
LULESH's -s are PER-RANK sizes, so their total work already grows with rank
count. STREAM, HPL, miniFE and CoMD take global sizes, so fixed size means
strong scaling and shrinking runtime.
"""
import pandas as pd, numpy as np
D = "/work/project/project/user"
df = pd.read_csv(f"{D}/data/cirrus_persets.csv")
df = df[df.runtime_s > 0]
g = df.groupby(["app", "ncore", "size"]).runtime_s.median().reset_index()
print("=== median runtime (s) by app x cores, at the LARGEST size of each app ===")
big = g.loc[g.groupby("app")["size"].idxmax()][["app", "size"]]
for _, r in big.iterrows():
sub = g[(g.app == r.app) & (g["size"] == r["size"])].sort_values("ncore")
line = " ".join(f"c{int(c)}={t:6.2f}" for c, t in zip(sub.ncore, sub.runtime_s))
print(f" {r.app:8s} size={int(r['size']):>9} {line}")
print("\n=== fraction of runs under 1 s, per app ===")
frac = (df.assign(short=df.runtime_s < 1.0).groupby("app").short.mean() * 100)
for a, v in frac.sort_values(ascending=False).items():
flag = " <-- needs bigger problems" if v > 25 else ""
print(f" {a:8s} {v:5.1f}%{flag}")
print("\n=== does runtime FALL with cores (strong) or hold (weak)? ===")
for a in sorted(g.app.unique()):
sub = g[g.app == a]
s = sub.loc[sub.groupby("ncore")["size"].idxmax()].sort_values("ncore")
if len(s) < 3:
continue
lo, hi = s.iloc[0].runtime_s, s.iloc[-1].runtime_s
ratio = lo / max(hi, 1e-9)
kind = "STRONG (runtime falls)" if ratio > 2 else "weak-ish (runtime holds)"
print(f" {a:8s} c{int(s.iloc[0].ncore)}={lo:7.2f}s -> c{int(s.iloc[-1].ncore)}={hi:6.2f}s "
f"({ratio:5.1f}x) {kind}")
print("\n=== suggested scaled sizes to reach a 10-60 s target on 288 cores ===")
print(" weak scaling: keep work per rank constant, so")
print(" global 3D size ~ base * cbrt(nranks) (miniFE, CoMD)")
print(" HPL matrix N ~ base * sqrt(nranks) (memory per rank constant)")
print(" HPCG, LULESH already per-rank; increase the base instead")