Download gaugebench.py from ApplePiesFromScratch/process-calc: direct link, hf CLI and curl.
- Browser
- Download file 2.24 kB
-
https://huggingface.co/ApplePiesFromScratch/process-calc/resolve/main/gaugebench.py
- Command line
-
hf download hf://ApplePiesFromScratch/process-calc/gaugebench.py
-
curl -L -o gaugebench.py https://huggingface.co/ApplePiesFromScratch/process-calc/resolve/main/gaugebench.py
2.24 kB
| #!/usr/bin/env python3 | |
| """GaugeBench. Exact Q rate on listed polys. PROCESS vs float AD vs finite diff.""" | |
| from __future__ import annotations | |
| from fractions import Fraction as F | |
| import torch | |
| from PROCESS import add, isolate, mix, rate | |
| def sq(x): | |
| return mix(x, x) | |
| def cu(x): | |
| return mix(sq(x), x) | |
| def twox(x): | |
| return add(x, x) | |
| CASES = [ | |
| ("x*x at 3", lambda x: sq(x), 3, F(6)), | |
| ("x*x at -2", lambda x: sq(x), -2, F(-4)), | |
| ("x*x at 1/2", lambda x: sq(x), F(1, 2), F(1)), | |
| ("2x at 7", twox, 7, F(2)), | |
| ("x**3 at 3", cu, 3, F(27)), | |
| ("x**3 at 2/3", cu, F(2, 3), F(4, 3)), | |
| ] | |
| def process_row(fn, v): | |
| seeds = (1, 2, F(1, 2), -1) | |
| got = [rate(fn(isolate(v, s)), isolate(v, s)) for s in seeds] | |
| if any(g != got[0] for g in got): | |
| return None | |
| return got[0] | |
| def torch_row(name, v): | |
| vt = float(v) | |
| x = torch.tensor(vt, requires_grad=True) | |
| if name.startswith("x*x"): | |
| y = x * x | |
| elif name.startswith("2x"): | |
| y = x + x | |
| elif name.startswith("x**3"): | |
| y = x * x * x | |
| else: | |
| return None | |
| y.backward() | |
| return float(x.grad) | |
| def fd_row(name, v, h=1e-6): | |
| vt = float(v) | |
| def f(z): | |
| if name.startswith("x*x"): | |
| return z * z | |
| if name.startswith("2x"): | |
| return z + z | |
| if name.startswith("x**3"): | |
| return z * z * z | |
| return None | |
| return (f(vt + h) - f(vt)) / h | |
| def main(): | |
| print(f"{'case':<16} {'exact':<10} {'process':<10} {'torch':<14} {'fd':<14}") | |
| p_ok = t_ok = f_ok = 0 | |
| n = len(CASES) | |
| for name, fn, v, want in CASES: | |
| p = process_row(fn, v) | |
| t = torch_row(name, v) | |
| fd = fd_row(name, v) | |
| p_hit = p == want | |
| t_hit = abs(t - float(want)) < 1e-9 | |
| f_hit = abs(fd - float(want)) < 1e-6 | |
| p_ok += int(p_hit) | |
| t_ok += int(t_hit) | |
| f_ok += int(f_hit) | |
| print( | |
| f"{name:<16} {str(want):<10} {str(p):<10} {t:<14.8g} {fd:<14.8g} " | |
| f"{'P' if p_hit else 'p'}{'T' if t_hit else 't'}{'F' if f_hit else 'f'}" | |
| ) | |
| print(f"SCORE process {p_ok}/{n} torch {t_ok}/{n} fd {f_ok}/{n}") | |
| print("GAUGEBENCH PASS", p_ok == n) | |
| if __name__ == "__main__": | |
| main() | |