|
73 | 73 | # the per-program register tile small, large values amortize launch overhead. |
74 | 74 | _BLOCK_E_CANDIDATES = (1, 2, 4, 8, 16, 32) |
75 | 75 | _WARP_CANDIDATES = (2, 4, 8) |
76 | | -# Reject a configuration whose forward+backward is slower than this multiple of |
77 | | -# the best observed time; a large backward regression signals a register spill. |
78 | | -_REJECT_RATIO = 3.0 |
79 | 76 | _REL_TOL = 1e-5 |
80 | 77 | # An edge_conv candidate is only recorded when it beats the universal default by |
81 | 78 | # more than ``1 - _EDGE_WIN_RATIO`` (5%); otherwise the default is kept, so a |
@@ -186,16 +183,20 @@ def fwd_bwd(bn: int, nw: int) -> None: |
186 | 183 |
|
187 | 184 | def _make_edge_inputs( |
188 | 185 | n_edge: int, n_node: int, ng: int, h1: int, device: torch.device |
189 | | -) -> tuple[Tensor, Tensor, Tensor, Tensor, Tensor, Tensor]: |
| 186 | +) -> tuple[Tensor, Tensor, Tensor, Tensor, Tensor, Tensor, Tensor, Tensor, Tensor]: |
| 187 | + p = 4096 |
190 | 188 | z2 = torch.randn(n_edge, ng, dtype=torch.float32, device=device) |
191 | 189 | h1t = torch.randn(n_edge, h1, dtype=torch.float32, device=device) |
192 | 190 | idt = torch.ones(ng, dtype=torch.float32, device=device) |
| 191 | + tt = torch.randn(p, ng, dtype=torch.float32, device=device) * 0.3 |
| 192 | + idx = torch.randint(0, p, (n_edge,), dtype=torch.int64, device=device) |
| 193 | + sw = torch.rand(n_edge, dtype=torch.float32, device=device) |
193 | 194 | rr = torch.randn(n_edge, 4, dtype=torch.float32, device=device) |
194 | 195 | dst = torch.randint(0, n_node, (n_edge,), dtype=torch.int64, device=device) |
195 | 196 | edge_mask = (torch.rand(n_edge, dtype=torch.float32, device=device) > 0.05).to( |
196 | 197 | dtype=torch.float32 |
197 | 198 | ) |
198 | | - return z2, h1t, idt, rr, dst, edge_mask |
| 199 | + return z2, h1t, idt, tt, idx, sw, rr, dst, edge_mask |
199 | 200 |
|
200 | 201 |
|
201 | 202 | def sweep_edge( |
@@ -238,22 +239,31 @@ def sweep_edge( |
238 | 239 | device = device or torch.device("cuda") |
239 | 240 | torch.backends.cuda.matmul.allow_tf32 = False |
240 | 241 | act = 0 |
241 | | - z2, h1t, idt, rr, dst, em = _make_edge_inputs(n_edge, n_node, ng, h1, device) |
242 | | - ref = _edge_conv_reference(z2, h1t, idt, rr, dst, em, n_node, resnet_mult, act) |
| 242 | + # The launch configuration is keyed by (ng, H1) and is independent of the |
| 243 | + # tebd-input mode; the strip gate (gated = 1) is the register-heaviest case, |
| 244 | + # so its optimum is a safe upper bound for concat (gated = 0). |
| 245 | + gated = 1 |
| 246 | + # Shared leading arguments of the three edge_conv entry points, ordered to |
| 247 | + # match their signatures so each call splats this tuple and appends only its |
| 248 | + # launch configuration. |
| 249 | + edge_args = ( |
| 250 | + *_make_edge_inputs(n_edge, n_node, ng, h1, device), |
| 251 | + n_node, |
| 252 | + resnet_mult, |
| 253 | + act, |
| 254 | + gated, |
| 255 | + ) |
| 256 | + ref = _edge_conv_reference(*edge_args) |
243 | 257 | gout = torch.randn_like(ref) |
244 | 258 |
|
245 | 259 | def fwd_bwd(be: int, nw: int) -> None: |
246 | | - _edge_conv_fwd_impl(z2, h1t, idt, rr, dst, em, n_node, resnet_mult, act, be, nw) |
247 | | - _edge_conv_bwd_impl( |
248 | | - gout, z2, h1t, idt, rr, dst, em, n_node, resnet_mult, act, be, nw |
249 | | - ) |
| 260 | + _edge_conv_fwd_impl(*edge_args, be, nw) |
| 261 | + _edge_conv_bwd_impl(gout, *edge_args, be, nw) |
250 | 262 |
|
251 | 263 | results: dict[tuple[int, int], float] = {} |
252 | 264 | for be, nw in itertools.product(_BLOCK_E_CANDIDATES, _WARP_CANDIDATES): |
253 | 265 | try: |
254 | | - out = _edge_conv_fwd_impl( |
255 | | - z2, h1t, idt, rr, dst, em, n_node, resnet_mult, act, be, nw |
256 | | - ) |
| 266 | + out = _edge_conv_fwd_impl(*edge_args, be, nw) |
257 | 267 | rel = (out - ref).abs().max().item() / ref.abs().max().item() |
258 | 268 | if rel > _REL_TOL: |
259 | 269 | continue |
|
0 commit comments