Suite (rustc 1.97.1 tests/ui, 11,881 tests, `makepad check` verdicts): item and signature checks, casts, patterns, attribute and extern safety (E0107, E0207, E0392, E0072, E0204, E0604-E0607, E0023, E0512, E0793, ...); const evaluation (E0080/E0015/E0391/E0493, check_consts, post-monomorphization errors, a sound constant-branch fold, std const fn audit); name resolution and privacy (E0252/E0255, E0603, E0364/E0365, E0451, E0624, E0659, attribute resolution, lexer literal validation, AST validation); feature gates (E0658 from rustc's feature tables) and editions; crash and timeout fixes (generic-arg arity at lowering, autoderef limit). Validation-only checks run only for crates whose errors are reported, so `makepad run` does not pay for them. Cold/warm start (Calculator on an M4 mini): cold 3.94 -> 3.44 s, warm 0.73/0.58 -> 0.44/0.33 s. The app domain reuses the boot's resolved package; build scripts and the provided-source hash run beside the load; cache entries of the startup installs are encoded after the first present (dropped if any source changed since); owner spins read no clock; type folding skips types without the folder's flags; provided-crate crossing types computed on use. Cache: std/framework entries shared across apps, keyed by the loader build id plus each crate's reachable bound set. Codegen: a static's initial image is sized with the normalized layout (fn-local statics with const-length arrays saw one byte under the HAL); headless runs exit on a failure; rwbench/bench_rt restored at the tip. Borrowck: capture analysis and call typing no longer depend on the BIR Tx (first step of the MIR NLL port). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
88 lines
4.8 KiB
Python
88 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Runtime ratio table: each kernel of src/main.rs under rustc --release and under `makepad run`,
|
|
one process per kernel (a compile failure in one cannot hide the others), best of ROUNDS runs
|
|
of each process's best-of-5. Usage: run.py <makepad binary> <target dir> [kernel ...]
|
|
Env: O3_PROFILE_DIR (steady runs replay a recorded O3 profile per kernel: MAKEPAD_RUN_O3_PROFILE), ROUNDS (default 2), STEADY_MS (also time after warming each kernel up for this long:
|
|
the steady state once Relax's O3 has settled; default 2000, 0 = off), NATIVE (prebuilt rustc binary of this crate), MAKEPAD_RUN_OPT etc. pass through to Relax."""
|
|
import os, re, subprocess, sys, platform
|
|
|
|
here = os.path.dirname(os.path.abspath(__file__))
|
|
relax, target = os.path.abspath(sys.argv[1]), os.path.abspath(sys.argv[2])
|
|
rounds = int(os.environ.get("ROUNDS", "2"))
|
|
src = open(os.path.join(here, "src/main.rs")).read()
|
|
names = re.findall(r'\("(\w+)", \w+\),', src)
|
|
if len(sys.argv) > 3:
|
|
names = sys.argv[3:]
|
|
nice = ["nice", "-n", "10"]
|
|
env = dict(os.environ, CARGO_INCREMENTAL="0", CARGO_TARGET_DIR=os.path.join(target, "rustc"))
|
|
# NATIVE=<binary>: a rustc build made elsewhere (bench machines run no cargo builds)
|
|
native = os.environ.get("NATIVE")
|
|
if not native:
|
|
subprocess.run(nice + ["cargo", "build", "--release", "-q", "-j", "4"], cwd=here, env=env, check=True)
|
|
native = os.path.join(target, "rustc/release/relax-bench-rt")
|
|
std = os.environ.get("MAKEPAD_RUN_STD", os.path.join(here, "../std"))
|
|
os.environ.setdefault("BENCH_FONT", os.path.normpath(os.path.join(here, "../../../../widgets/resources/IBMPlexSans-Text.ttf")))
|
|
renv = dict(os.environ, MAKEPAD_RUN_STD=std)
|
|
|
|
def one(cmd, e, name):
|
|
best = None
|
|
for _ in range(rounds):
|
|
try:
|
|
out = subprocess.run(cmd, cwd=here, env=e, capture_output=True, text=True, timeout=300)
|
|
except subprocess.TimeoutExpired:
|
|
return None, "TIMEOUT (300 s)"
|
|
m = re.search(r"^\| " + name + r" ([\d.]+) (\d+)$", out.stdout, re.M)
|
|
if not m:
|
|
return None, (out.stdout + out.stderr)[-400:]
|
|
cm = re.search(r"cpu typeck (\d+) ms, lower (\d+) ms, opt (\d+) ms, codegen (\d+) ms", out.stderr)
|
|
fm = re.search(r"compiled (\d+) fns, (\d+) KB", out.stderr)
|
|
t = float(m.group(1))
|
|
if best is None or t < best[0]:
|
|
best = (t, m.group(2), cm.groups() if cm else None, fm.groups() if fm else None)
|
|
return best, None
|
|
|
|
steady_ms = int(os.environ.get("STEADY_MS", "7000"))
|
|
print("| kernel | rustc ms | Relax ms | Relax/rustc | steady rustc ms | steady Relax ms | steady Relax/rustc | fns | opt+cg ms | sum ok |")
|
|
print("|---|---:|---:|---:|---:|---:|---:|---:|---:|---|")
|
|
ratios = []
|
|
sratios = []
|
|
for n in names:
|
|
a, ea = one(nice + [native, n], os.environ, n)
|
|
runner = relax
|
|
kenv = renv
|
|
b, eb = one(nice + [runner, "run", "--quiet", "relax-bench-rt", "--", n], kenv, n)
|
|
if a is None or b is None:
|
|
print("| %s | %s | %s | ERROR | | | | | | %s |" % (n, a and a[0], b and b[0], (ea or eb or "").replace("\n", " ")[-200:]))
|
|
continue
|
|
r = b[0] / a[0]
|
|
ratios.append(r)
|
|
st = ("", "", "")
|
|
if steady_ms > 0:
|
|
sa, _ = one(nice + [native, n], dict(os.environ, BENCH_WARM_MS=str(steady_ms)), n)
|
|
senv = dict(kenv, BENCH_WARM_MS=str(steady_ms))
|
|
# O3_PROFILE_DIR: steady runs replay one recorded O3 profile per kernel (the first
|
|
# steady run of a kernel without a profile records it), so every compared run (and every
|
|
# binary of an A/B sharing the dir) builds the same hot set from the same inputs; cold rows
|
|
# stay in normal mode
|
|
pdir = os.environ.get("O3_PROFILE_DIR")
|
|
if pdir:
|
|
os.makedirs(pdir, exist_ok=True)
|
|
prof = os.path.join(pdir, n + ".prof")
|
|
senv["MAKEPAD_RUN_O3_PROFILE"] = prof
|
|
if not os.path.exists(prof):
|
|
subprocess.run(nice + [runner, "run", "--quiet", "relax-bench-rt", "--", n], cwd=here, env=senv, capture_output=True, timeout=300)
|
|
sb, _ = one(nice + [runner, "run", "--quiet", "relax-bench-rt", "--", n], senv, n)
|
|
if sa and sb:
|
|
sratios.append(sb[0] / sa[0])
|
|
st = ("%.3f" % sa[0], "%.3f" % sb[0], "%.2f" % (sb[0] / sa[0]))
|
|
cg = "%s+%s" % (b[2][2], b[2][3]) if b[2] else "-"
|
|
print("| %s | %.3f | %.3f | %.2f | %s | %s | %s | %s | %s | %s |" % (n, a[0], b[0], r, st[0], st[1], st[2], b[3][0] if b[3] else "-", cg, "yes" if a[1] == b[1] else "**NO**"), flush=True)
|
|
def geo(rs):
|
|
g = 1.0
|
|
for r in rs:
|
|
g *= r
|
|
return g ** (1.0 / len(rs))
|
|
if ratios:
|
|
print("\ngeomean Relax/rustc: %.2f (%d kernels, %s)" % (geo(ratios), len(ratios), platform.machine()))
|
|
if sratios:
|
|
print("geomean steady Relax/rustc: %.2f (%d kernels, warm-up %d ms)" % (geo(sratios), len(sratios), steady_ms))
|