parse_cirrus.py
import re, subprocess, csv, sys, os
from pathlib import Path
CPROOT = "/opt/cray/pe/perftools/25.03.0"
PR = f"{CPROOT}/bin/pat_report"
D = os.environ.get("DISS_ROOT", "/work/project/project/user")
BASE = Path(f"{D}/runs/sweep")
OUT = Path(f"{D}/data")
VAL = re.compile(r"^ (?P<n>[A-Z][A-Za-z0-9_:]*)\s+"
r"(?:(?:[\d.]+)\s*(?:[GMK]/sec|W)\s+)?"
r"(?P<v>\d[\d,]*(?:\.\d+)?)\s*"
r"(?:ops|instr|cycles|J|refs|misses|hits)?\s*$")
TIME = re.compile(r"^ Thread Time\s+([\d.]+)\s+secs")
env = dict(os.environ, CRAYPAT_ROOT=CPROOT)
def parse(exp):
try:
out = subprocess.run([PR, "-O", "hwpc", str(exp)], env=env,
capture_output=True, text=True, timeout=600).stdout
except Exception:
return None, {}
vals, t = {}, None
for line in out.splitlines():
if "PAT_RT_PERFCTR" in line:
break
mt = TIME.match(line)
if mt:
t = float(mt.group(1)); continue
m = VAL.match(line)
if m and m.group("n") not in ("Thread", "Total", "Average", "CrayPat"):
try:
vals[m.group("n")] = float(m.group("v").replace(",", ""))
except ValueError:
pass
return t, vals
rows = []
for d in sorted(BASE.glob("*_c*_s*_t*")):
m = re.match(r"([a-z]+)_c(\d+)_s(\d+)_t(\d+)$", d.name)
if not m or not d.is_dir():
continue
app, nc, size, nt = m.group(1), int(m.group(2)), int(m.group(3)), int(m.group(4))
for s in "ABCDE":
exp = d / f"exp_{s}"
if not exp.exists():
continue
t, vals = parse(exp)
if t is None or not vals:
continue
rows.append({"platform": "cirrus", "app": app, "ncore": nc, "size": size,
"nthread": nt, "nrank": nc // max(nt, 1), "cset": s,
"runtime_s": t, **vals})
print(f"{d.name}", file=sys.stderr)
lead = ["platform", "app", "ncore", "nthread", "nrank", "size", "cset", "runtime_s"]
keys = lead + sorted({k for r in rows for k in r} - set(lead))
OUT.mkdir(parents=True, exist_ok=True)
with open(OUT / "cirrus_persets.csv", "w", newline="") as fh:
w = csv.DictWriter(fh, fieldnames=keys); w.writeheader(); w.writerows(rows)
print(f"\nwrote cirrus_persets.csv: {len(rows)} rows x {len(keys)} cols")
from collections import Counter
print("by app:", dict(Counter(r["app"] for r in rows)))
print("counters seen:", sorted(k for k in keys if k[0].isupper()))