YMRohit commited on
Commit
2f6d104
·
verified ·
1 Parent(s): 0118c5e

Add in-Space offgrid/local mode (ZeroGPU H200 + in-process referee)

Browse files
Files changed (1) hide show
  1. referee/chains.py +181 -0
referee/chains.py ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Generative fusion-chain grammar: [+residual] -> {rms|layer}norm -> ×w(+b) -> epilogue.
2
+
3
+ The widest sweep of the reduction->epilogue region (where the compiler under-fuses and the 2B
4
+ wins). References are COMPOSED; teacher kernels are TEMPLATE-GENERATED (scalar-reduce +
5
+ whole-row variants). Everything is harness-filtered downstream — nothing here is trusted.
6
+ """
7
+ from __future__ import annotations
8
+ import torch
9
+
10
+ _C = 0.7978845608028654 # sqrt(2/pi)
11
+
12
+ # epilogue: (torch fn on fp32 tensor, triton expression in fp32 var `n`)
13
+ ACTS = {
14
+ "gelu": (lambda t: 0.5 * t * (1.0 + torch.tanh(_C * (t + 0.044715 * t * t * t))),
15
+ "(0.5 * n * (1.0 + (2.0 * tl.sigmoid(2.0 * (0.7978845608028654 * (n + 0.044715 * n * n * n))) - 1.0)))"),
16
+ "silu": (lambda t: t * torch.sigmoid(t), "(n * tl.sigmoid(n))"),
17
+ "relu2": (lambda t: torch.relu(t) * torch.relu(t), "(tl.maximum(n, 0.0) * tl.maximum(n, 0.0))"),
18
+ # --- expanded grammar (each torch fn EXACTLY matches its triton expr; no approximation) ---
19
+ "tanh": (lambda t: torch.tanh(t), "(2.0 * tl.sigmoid(2.0 * n) - 1.0)"), # identity tanh(x)=2σ(2x)-1
20
+ "sigmoid": (lambda t: torch.sigmoid(t), "tl.sigmoid(n)"),
21
+ "relu": (lambda t: torch.relu(t), "tl.maximum(n, 0.0)"),
22
+ "square": (lambda t: t * t, "(n * n)"),
23
+ # --- 2c round 2: more real activations (each torch fn EXACTLY matches its triton expr) ---
24
+ "abs": (lambda t: torch.abs(t), "tl.abs(n)"),
25
+ "softsign": (lambda t: t / (1.0 + torch.abs(t)), "(n / (1.0 + tl.abs(n)))"),
26
+ "hardsigmoid": (lambda t: torch.clamp(t + 3.0, 0.0, 6.0) / 6.0,
27
+ "(tl.minimum(tl.maximum(n + 3.0, 0.0), 6.0) / 6.0)"), # F.hardsigmoid
28
+ "hardswish": (lambda t: t * torch.clamp(t + 3.0, 0.0, 6.0) / 6.0,
29
+ "(n * tl.minimum(tl.maximum(n + 3.0, 0.0), 6.0) / 6.0)"), # F.hardswish
30
+ # --- V2 round 3: 8 more real, numerically-safe activations. Same exactness rule: the
31
+ # torch lambda IS the triton expression (tanh via the 2*sigmoid(2x)-1 identity;
32
+ # softplus uses F.softplus's threshold=20 guard so exp never overflows). -----------
33
+ "leaky_relu": (lambda t: torch.where(t > 0, t, 0.01 * t),
34
+ "tl.where(n > 0.0, n, 0.01 * n)"),
35
+ "relu6": (lambda t: torch.clamp(t, 0.0, 6.0),
36
+ "tl.minimum(tl.maximum(n, 0.0), 6.0)"),
37
+ "hardtanh": (lambda t: torch.clamp(t, -1.0, 1.0),
38
+ "tl.minimum(tl.maximum(n, -1.0), 1.0)"),
39
+ "elu": (lambda t: torch.where(t > 0, t, torch.exp(torch.clamp(t, max=0.0)) - 1.0),
40
+ "tl.where(n > 0.0, n, tl.exp(tl.minimum(n, 0.0)) - 1.0)"),
41
+ "selu": (lambda t: 1.0507009873554805 * torch.where(
42
+ t > 0, t, 1.6732632423543772 * (torch.exp(torch.clamp(t, max=0.0)) - 1.0)),
43
+ "(1.0507009873554805 * tl.where(n > 0.0, n, "
44
+ "1.6732632423543772 * (tl.exp(tl.minimum(n, 0.0)) - 1.0)))"),
45
+ "softplus": (lambda t: torch.where(t > 20.0, t, torch.log(1.0 + torch.exp(torch.clamp(t, max=20.0)))),
46
+ "tl.where(n > 20.0, n, tl.log(1.0 + tl.exp(tl.minimum(n, 20.0))))"),
47
+ "mish": (lambda t: t * torch.tanh(torch.where(
48
+ t > 20.0, t, torch.log(1.0 + torch.exp(torch.clamp(t, max=20.0))))),
49
+ "(n * (2.0 * tl.sigmoid(2.0 * tl.where(n > 20.0, n, "
50
+ "tl.log(1.0 + tl.exp(tl.minimum(n, 20.0))))) - 1.0))"),
51
+ "gelu_erf": (lambda t: 0.5 * t * (1.0 + torch.erf(t * 0.7071067811865476)),
52
+ "(0.5 * n * (1.0 + tl.erf(n * 0.7071067811865476)))"), # EXACT gelu
53
+ }
54
+ NORMS = ["rms", "layer"]
55
+ RESID = [False, True]
56
+ ACTNAMES = ["gelu", "silu", "relu2", "tanh", "sigmoid", "relu", "square",
57
+ "abs", "softsign", "hardsigmoid", "hardswish",
58
+ "leaky_relu", "relu6", "hardtanh", "elu", "selu", "softplus", "mish", "gelu_erf"]
59
+
60
+
61
+ def chain_name(norm, residual, act):
62
+ return ("add_" if residual else "") + ("rmsnorm" if norm == "rms" else "layernorm") + "_" + act
63
+
64
+
65
+ def chain_kind(norm, residual):
66
+ return ("add_" if residual else "") + ("rms" if norm == "rms" else "ln") # -> input signature
67
+
68
+
69
+ def chain_reference(norm, residual, act, eps=None):
70
+ eps = eps if eps is not None else (1e-6 if norm == "rms" else 1e-5)
71
+ fn = ACTS[act][0]
72
+ def ref(*args):
73
+ if residual and norm == "rms":
74
+ x, r, w = args; h = x.float() + r.float(); b = None
75
+ elif residual:
76
+ x, r, w, b = args; h = x.float() + r.float()
77
+ elif norm == "rms":
78
+ x, w = args; h = x.float(); b = None
79
+ else:
80
+ x, w, b = args; h = x.float()
81
+ if norm == "rms":
82
+ n = h * torch.rsqrt(h.pow(2).mean(-1, keepdim=True) + eps) * w.float()
83
+ else:
84
+ mu = h.mean(-1, keepdim=True); hc = h - mu
85
+ n = hc * torch.rsqrt((hc * hc).mean(-1, keepdim=True) + eps) * w.float() + b.float()
86
+ return fn(n).to(args[0].dtype)
87
+ return ref
88
+
89
+
90
+ # ---- teacher-kernel templates -----------------------------------------------------------
91
+ def _kernel(norm, residual, act_expr, eps, variant):
92
+ """variant: 'scalar' (loop+scalar accumulator) or 'whole' (single block per row)."""
93
+ ptrs = "x_ptr, " + ("r_ptr, " if residual else "") + "w_ptr, " + ("b_ptr, " if norm == "layer" else "") + "y_ptr"
94
+ sig = "x, " + ("residual, " if residual else "") + "w" + (", b" if norm == "layer" else "")
95
+ launch = "x, " + ("residual, " if residual else "") + "w" + (", b" if norm == "layer" else "") + ", y"
96
+ radv = " r_ptr += row * stride;" if residual else ""
97
+ hload = ("tl.load(x_ptr + cols, mask=MM, other=0.0).to(tl.float32)"
98
+ + (" + tl.load(r_ptr + cols, mask=MM, other=0.0).to(tl.float32)" if residual else ""))
99
+ # bias load indent differs: scalar variant loads it INSIDE the apply for-loop (8 spaces),
100
+ # whole-row loads it flat (4 spaces). Wrong indent -> IndentationError.
101
+ bload8 = " b = tl.load(b_ptr + cols, mask=MM, other=0.0).to(tl.float32)\n" if norm == "layer" else ""
102
+ bload4 = " b = tl.load(b_ptr + cols, mask=MM, other=0.0).to(tl.float32)\n" if norm == "layer" else ""
103
+ if norm == "rms":
104
+ normed = "h * rr * w"
105
+ else:
106
+ normed = "(h - mu) * rr * w + b"
107
+
108
+ if variant == "scalar":
109
+ if norm == "rms":
110
+ reduce_block = f''' s = 0.0
111
+ for off in range(0, N, BLOCK):
112
+ cols = off + tl.arange(0, BLOCK); MM = cols < N
113
+ h = {hload}
114
+ s += tl.sum(h * h)
115
+ rr = tl.rsqrt(s / N + eps)'''
116
+ else:
117
+ reduce_block = f''' s = 0.0
118
+ for off in range(0, N, BLOCK):
119
+ cols = off + tl.arange(0, BLOCK); MM = cols < N
120
+ s += tl.sum({hload})
121
+ mu = s / N
122
+ v = 0.0
123
+ for off in range(0, N, BLOCK):
124
+ cols = off + tl.arange(0, BLOCK); MM = cols < N
125
+ d = tl.where(MM, ({hload}) - mu, 0.0); v += tl.sum(d * d)
126
+ rr = tl.rsqrt(v / N + eps)'''
127
+ body = f'''@triton.jit
128
+ def _k({ptrs}, stride, N, eps, BLOCK: tl.constexpr):
129
+ row = tl.program_id(0); x_ptr += row * stride;{radv} y_ptr += row * stride
130
+ {reduce_block}
131
+ for off in range(0, N, BLOCK):
132
+ cols = off + tl.arange(0, BLOCK); MM = cols < N
133
+ h = {hload}
134
+ w = tl.load(w_ptr + cols, mask=MM, other=0.0).to(tl.float32)
135
+ {bload8} n = {normed}
136
+ tl.store(y_ptr + cols, {act_expr}, mask=MM)
137
+ def run({sig}):
138
+ M, N = x.shape; y = torch.empty_like(x)
139
+ _k[(M,)]({launch}, x.stride(0), N, {eps}, BLOCK=1024)
140
+ return y
141
+ '''
142
+ else: # whole-row single block
143
+ if norm == "rms":
144
+ stat = " rr = tl.rsqrt(tl.sum(h * h) / N + eps)"
145
+ else:
146
+ stat = (" mu = tl.sum(h) / N\n hc = tl.where(MM, h - mu, 0.0)\n"
147
+ " rr = tl.rsqrt(tl.sum(hc * hc) / N + eps)")
148
+ normed = "hc * rr * w + b"
149
+ body = f'''@triton.jit
150
+ def _k({ptrs}, stride, N, eps, BLOCK: tl.constexpr):
151
+ row = tl.program_id(0); x_ptr += row * stride;{radv} y_ptr += row * stride
152
+ cols = tl.arange(0, BLOCK); MM = cols < N
153
+ h = {hload}
154
+ {stat}
155
+ w = tl.load(w_ptr + cols, mask=MM, other=0.0).to(tl.float32)
156
+ {bload4} n = {normed}
157
+ tl.store(y_ptr + cols, {act_expr}, mask=MM)
158
+ def run({sig}):
159
+ M, N = x.shape; y = torch.empty_like(x)
160
+ _k[(M,)]({launch}, x.stride(0), N, {eps}, BLOCK=triton.next_power_of_2(N))
161
+ return y
162
+ '''
163
+ return body
164
+
165
+
166
+ def chain_structures(norm, residual, act):
167
+ eps = 1e-6 if norm == "rms" else 1e-5
168
+ expr = ACTS[act][1]
169
+ return [_kernel(norm, residual, expr, eps, "scalar"), _kernel(norm, residual, expr, eps, "whole")]
170
+
171
+
172
+ def all_chains():
173
+ """[(name, kind, reference_fn, [kernel_src, ...]), ...] for the full grammar."""
174
+ out = []
175
+ for norm in NORMS:
176
+ for residual in RESID:
177
+ for act in ACTNAMES:
178
+ name = chain_name(norm, residual, act)
179
+ out.append((name, chain_kind(norm, residual), chain_reference(norm, residual, act),
180
+ chain_structures(norm, residual, act)))
181
+ return out