Skip to content

Commit ce90574

Browse files
committed
refactor: RULE #1 - kill B1-B3 staged silent fallbacks (22 raises with where+what)
Replace forbidden silent fallbacks with immediate raises; keep genuine feature-absent detection. - B1 _cuda_eager.py (6 killed, 6 kept): killed the kernel-launch/writeback except->return None swallows (sparse_mla/mamba3 fwd+bwd/fp8-quant/fp8-apply/m2rnn cuda-eager) that hid real CUDA bugs or silently degraded to MLX-autograd ref; kept the torch-import + cuda_eager_available + shape/dtype applicability probes. - B2 m2rnn_path_c.py (10 killed) + sparse_mla_fp8_path_c.py (5 killed/narrowed): killed the except->return None wrapping compile/lowering of the clear path (compile crash != not-applicable; availability is probed separately and preserves where+what); narrowed apply_simplify catches to ImportError so a real crash in the pass propagates; kept typed availability/Status probes. - B3 _engine_dispatch.py (1 killed): killed the engine-succeeded-but-MSL-extraction-None -> silent legacy-shim substitution (the MSL-instead-of-tvm-ffi fallback) -> now raises, directing to explicit CPPMEGA_MLX_TILELANG_ENGINE=shim; kept the genuine engine-absent ImportError branch. Metal: clear paths still work (m2rnn/mamba3 117 passed/5skip; sparse_mla_fp8 93 passed). Rewrote test_dispatch..._falls_back_on_extraction_failure -> ..._raises_on_extraction_failure (it was green ONLY due to the B3 silent shim). Remaining failures pre-existing on origin (DLPack contiguity, path_b kernel-name). Flagged follow-up: force_path_c gated-off-by-default sites (~2690/3295/3303).
1 parent 80070d2 commit ce90574

5 files changed

Lines changed: 260 additions & 85 deletions

File tree

cppmega_mlx/nn/_tilelang/_cuda_eager.py

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,15 @@ def sparse_mla_fwd_cuda_eager(
264264
)
265265
kernel(q_t, kv_t, idx_t, sc_t, out_t, lse_t)
266266
torch.cuda.synchronize()
267-
except Exception:
268-
return None
267+
except Exception as exc:
268+
# RULE #1: a CUDA kernel launch/writeback failure here is a real bug in
269+
# the selected Sparse-MLA fwd kernel, not a "feature absent" signal. Do
270+
# NOT return None to a silent fallback — raise with where+what.
271+
raise RuntimeError(
272+
f"_cuda_eager.sparse_mla_fwd_cuda_eager: TileLang-CUDA Sparse-MLA "
273+
f"fwd kernel launch/writeback failed "
274+
f"({type(exc).__name__}: {exc})."
275+
) from exc
269276

270277
out = _torch_cuda_to_mlx(
271278
out_t.reshape(shapes.batch, shapes.seq_len, shapes.heads, shapes.d_v),
@@ -431,8 +438,15 @@ def mamba3_mimo_fwd_cuda_eager(
431438
)
432439
kernel(x_t, B_t, C_t, z_t, A_t, dt_t, D_t, h0_t, y_t, hl_t)
433440
torch.cuda.synchronize()
434-
except Exception:
435-
return None
441+
except Exception as exc:
442+
# RULE #1: a kernel launch/writeback failure is a real bug in the
443+
# vendored Mamba3 MIMO fwd kernel, not "feature absent". Raise loud
444+
# instead of returning None into a silent pure-MLX-scan fallback.
445+
raise RuntimeError(
446+
f"_cuda_eager.mamba3_mimo_fwd_cuda_eager: TileLang-CUDA Mamba3 MIMO "
447+
f"fwd kernel launch/writeback failed "
448+
f"({type(exc).__name__}: {exc})."
449+
) from exc
436450

437451
y = _torch_cuda_to_mlx(y_t, x.dtype)
438452
h_last = _torch_cuda_to_mlx(hl_t, h0.dtype)
@@ -719,8 +733,16 @@ def mamba3_mimo_bwd_cuda_eager(
719733
dh0_t,
720734
)
721735
torch.cuda.synchronize()
722-
except Exception:
723-
return None
736+
except Exception as exc:
737+
# RULE #1: a kernel launch/writeback failure is a real bug in the
738+
# vendored Mamba3 MIMO bwd kernel, not "feature absent". Raise loud
739+
# instead of returning None into a silent MLX-autograd reference VJP
740+
# fallback (which would mask a broken gradient kernel).
741+
raise RuntimeError(
742+
f"_cuda_eager.mamba3_mimo_bwd_cuda_eager: TileLang-CUDA Mamba3 MIMO "
743+
f"bwd kernel launch/writeback failed "
744+
f"({type(exc).__name__}: {exc})."
745+
) from exc
724746

725747
# Reduce the per-(b,h,p) lane partials over the P axis (matches the Metal
726748
# bf16-snapshot reduction axes exactly).
@@ -864,8 +886,16 @@ def fp8_per_token_quant_cuda_eager(x: mx.array) -> tuple[mx.array, mx.array] | N
864886
scale_t = torch.zeros(rows, dtype=torch.float32, device="cuda")
865887
kernel(x_t, fp8_t, scale_t)
866888
torch.cuda.synchronize()
867-
except Exception:
868-
return None
889+
except Exception as exc:
890+
# RULE #1: a kernel launch/writeback failure is a real bug in the FP8
891+
# per-token quant producer kernel, not "feature absent". Raise loud
892+
# instead of returning None (the caller would otherwise re-raise a
893+
# generic guard that hides the real producer-kernel error).
894+
raise RuntimeError(
895+
f"_cuda_eager.fp8_per_token_quant_cuda_eager: TileLang-CUDA per-token "
896+
f"FP8 quant kernel launch/writeback failed "
897+
f"({type(exc).__name__}: {exc})."
898+
) from exc
869899

870900
fp8 = _torch_cuda_to_mlx(fp8_t.reshape(x.shape), mx.uint8)
871901
scale = _torch_cuda_to_mlx(scale_t.reshape(x.shape[:-1]), mx.float32)
@@ -1017,8 +1047,16 @@ def fp8_sparse_mla_apply_cuda_eager(
10171047
lse_t,
10181048
)
10191049
torch.cuda.synchronize()
1020-
except Exception:
1021-
return None
1050+
except Exception as exc:
1051+
# RULE #1: a kernel launch/writeback failure is a real bug in the
1052+
# prepared-buffer FP8 Sparse-MLA apply kernel, not "feature absent".
1053+
# Raise loud instead of returning None into the caller's
1054+
# non-force_path_c silent `return None` degraded path.
1055+
raise RuntimeError(
1056+
f"_cuda_eager.fp8_sparse_mla_apply_cuda_eager: TileLang-CUDA "
1057+
f"prepared-buffer FP8 Sparse-MLA apply kernel launch/writeback "
1058+
f"failed ({type(exc).__name__}: {exc})."
1059+
) from exc
10221060

10231061
out = _torch_cuda_to_mlx(
10241062
out_t.reshape(batch, seq_len, heads, d_v), mx_out_dtype
@@ -1304,8 +1342,17 @@ def m2rnn_mapped_packed_post_fwd_cuda_eager(
13041342
)
13051343
kernel(ci_t, W_t, xf_t, h0_t, D_t, proj_t, h_last_t, tanh_t, post_t)
13061344
torch.cuda.synchronize()
1307-
except Exception:
1308-
return None
1345+
except Exception as exc:
1346+
# RULE #1: a kernel launch/writeback failure is a real bug in the
1347+
# vendored m2rnn mapped-packed-post fwd kernel, not "feature absent".
1348+
# Raise loud instead of returning None (the caller would otherwise
1349+
# re-raise a generic "dispatch failed" that hides the real error, or
1350+
# fall back to the pure-MLX reference scan).
1351+
raise RuntimeError(
1352+
f"_cuda_eager.m2rnn_mapped_packed_post_fwd_cuda_eager: TileLang-CUDA "
1353+
f"m2rnn mapped-packed-post fwd kernel launch/writeback failed "
1354+
f"({type(exc).__name__}: {exc})."
1355+
) from exc
13091356

13101357
post = _torch_cuda_to_mlx(post_t, out_dtype)
13111358
h_last = _torch_cuda_to_mlx(h_last_t, out_dtype)

cppmega_mlx/nn/_tilelang/_engine_dispatch.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -360,16 +360,23 @@ def _engine_with_msl_extraction(
360360

361361
lowering = extract_msl_from_engine_artifact(artifact, target=target)
362362
if lowering is None:
363-
if not _MSL_EXTRACTION_FALLBACK_WARNED:
364-
warnings.warn(
365-
"cppmega_mlx._tilelang: engine_with_msl_extraction returned "
366-
"None (non-metal target or artifact had no kernel_source); "
367-
"falling back to MSL shim.",
368-
UserWarning,
369-
stacklevel=2,
370-
)
371-
_MSL_EXTRACTION_FALLBACK_WARNED = True
372-
return _shim_lower(prim_func, target, pass_configs=pass_configs)
363+
# RULE #1: the engine lowering SUCCEEDED (we are past the ImportError
364+
# guard) but MSL extraction returned None. That is NOT "engine absent" —
365+
# it is extraction silently failing (non-metal target, or a metal
366+
# artifact with no kernel_source). Falling back to the legacy MSL-string
367+
# shim here is exactly the forbidden "MSL-instead-of-tvm-ffi" silent
368+
# fallback: it papers over a real extraction bug with a different
369+
# (legacy) lowering. Raise with where+what; if the caller genuinely
370+
# wants the shim they must route explicitly via CPPMEGA_MLX_TILELANG_ENGINE=shim.
371+
raise RuntimeError(
372+
f"_engine_with_msl_extraction: TileLang engine lowering for "
373+
f"target={target!r} succeeded but "
374+
f"extract_msl_from_engine_artifact returned None (non-metal target, "
375+
f"or the engine artifact exposed no kernel_source). Refusing to "
376+
f"silently fall back to the legacy MSL shim (RULE #1) — this points "
377+
f"at a real MSL-extraction bug for this artifact. Set "
378+
f"{_FLAG_ENV}=shim to explicitly use the legacy MSL lowering."
379+
)
373380
return lowering
374381

375382

cppmega_mlx/nn/_tilelang/m2rnn_path_c.py

Lines changed: 90 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3430,8 +3430,17 @@ def _m2rnn_fwd_path_c_full(
34303430
)
34313431
try:
34323432
kernel, lowering = _fwd_kernel_for(batch, seq, heads, k_dim, v_dim, carrier_dtype)
3433-
except Exception:
3434-
return None
3433+
except Exception as exc:
3434+
# RULE #1: a compile failure of the selected M2RNN Path C fwd kernel is a
3435+
# real bug, not a "Path C not applicable" signal (those are the explicit
3436+
# None returns above for dtype/can_run_metal/h0). Availability is probed
3437+
# separately by `_kernel_lowering_status`; here, raise with where+what.
3438+
raise RuntimeError(
3439+
f"_m2rnn_fwd_path_c_full: M2RNN Path C fwd kernel compile/lowering "
3440+
f"failed for batch={batch} seq={seq} heads={heads} k_dim={k_dim} "
3441+
f"v_dim={v_dim} carrier={carrier_dtype} "
3442+
f"({type(exc).__name__}: {exc})."
3443+
) from exc
34353444

34363445
del lowering
34373446
if out is None:
@@ -3537,8 +3546,15 @@ def _m2rnn_bwd_path_c_kernel(
35373546
)
35383547
try:
35393548
kernel, lowering = _bwd_kernel_for(batch, seq, heads, k_dim, v_dim, carrier_dtype)
3540-
except Exception:
3541-
return None
3549+
except Exception as exc:
3550+
# RULE #1: a compile failure of the selected M2RNN Path C bwd kernel is a
3551+
# real bug, not a "Path C not applicable" signal. Raise with where+what.
3552+
raise RuntimeError(
3553+
f"_m2rnn_bwd_path_c_kernel: M2RNN Path C bwd kernel compile/lowering "
3554+
f"failed for batch={batch} seq={seq} heads={heads} k_dim={k_dim} "
3555+
f"v_dim={v_dim} carrier={carrier_dtype} "
3556+
f"({type(exc).__name__}: {exc})."
3557+
) from exc
35423558

35433559
del lowering
35443560
dW, dh0, dk, dq, dv, dxf, _scratch = kernel(
@@ -4145,8 +4161,15 @@ def _m2rnn_packed_fwd_path_c_full(
41454161
v_dim,
41464162
carrier_dtype,
41474163
)
4148-
except Exception:
4149-
return None
4164+
except Exception as exc:
4165+
# RULE #1: compile failure of the selected packed M2RNN Path C fwd
4166+
# kernel is a real bug, not a "not applicable" signal. Raise where+what.
4167+
raise RuntimeError(
4168+
f"_m2rnn_packed_fwd_path_c_full: packed M2RNN Path C fwd kernel "
4169+
f"compile/lowering failed for batch={batch} seq={seq} heads={heads} "
4170+
f"k_dim={k_dim} v_dim={v_dim} carrier={carrier_dtype} "
4171+
f"({type(exc).__name__}: {exc})."
4172+
) from exc
41504173

41514174
del lowering
41524175
if out is None:
@@ -4218,8 +4241,15 @@ def _m2rnn_packed_bwd_path_c_kernel(
42184241
v_dim,
42194242
carrier_dtype,
42204243
)
4221-
except Exception:
4222-
return None
4244+
except Exception as exc:
4245+
# RULE #1: compile failure of the selected packed M2RNN Path C bwd
4246+
# kernel is a real bug, not a "not applicable" signal. Raise where+what.
4247+
raise RuntimeError(
4248+
f"_m2rnn_packed_bwd_path_c_kernel: packed M2RNN Path C bwd kernel "
4249+
f"compile/lowering failed for batch={batch} seq={seq} heads={heads} "
4250+
f"k_dim={k_dim} v_dim={v_dim} carrier={carrier_dtype} "
4251+
f"({type(exc).__name__}: {exc})."
4252+
) from exc
42234253

42244254
del lowering
42254255
dconv_input, dW, dxf, dh0, _scratch = kernel(
@@ -4332,8 +4362,15 @@ def _m2rnn_mapped_packed_fwd_path_c_full(
43324362
v_dim,
43334363
carrier_dtype,
43344364
)
4335-
except Exception:
4336-
return None
4365+
except Exception as exc:
4366+
# RULE #1: compile failure of the selected mapped-packed M2RNN Path C
4367+
# fwd kernel is a real bug, not a "not applicable" signal. Raise.
4368+
raise RuntimeError(
4369+
f"mapped-packed M2RNN Path C fwd kernel compile/lowering failed for "
4370+
f"batch={batch} seq={seq} total_heads={total_heads} k_dim={k_dim} "
4371+
f"v_dim={v_dim} carrier={carrier_dtype} "
4372+
f"({type(exc).__name__}: {exc})."
4373+
) from exc
43374374

43384375
del lowering
43394376
if out is None:
@@ -4447,8 +4484,16 @@ def _m2rnn_mapped_packed_bwd_path_c_kernel(
44474484
dy_dtype,
44484485
"float32",
44494486
)
4450-
except Exception:
4451-
return None
4487+
except Exception as exc:
4488+
# RULE #1: this try wraps shape validation (which raises ValueError on
4489+
# malformed dy/tanh_cache) and the mapped-packed M2RNN Path C bwd kernel
4490+
# compile. Both are real bugs — not "not applicable" signals (those are
4491+
# the explicit `return None` shape checks, which return normally and
4492+
# never reach this except). Raise with where+what instead of swallowing.
4493+
raise RuntimeError(
4494+
f"mapped-packed M2RNN Path C bwd kernel compile/validation failed "
4495+
f"({type(exc).__name__}: {exc})."
4496+
) from exc
44524497

44534498
del lowering
44544499
outputs: M2RNNPackedBwdOwnerOutputs = (
@@ -4592,8 +4637,15 @@ def _m2rnn_mapped_packed_post_fwd_path_c_full(
45924637
projected_dim,
45934638
carrier_dtype,
45944639
)
4595-
except Exception:
4596-
return None
4640+
except Exception as exc:
4641+
# RULE #1: compile failure of the selected mapped-packed-post M2RNN
4642+
# Path C fwd kernel is a real bug, not a "not applicable" signal. Raise.
4643+
raise RuntimeError(
4644+
f"mapped-packed-post M2RNN Path C fwd kernel compile/lowering failed "
4645+
f"for batch={batch} seq={seq} total_heads={total_heads} k_dim={k_dim} "
4646+
f"v_dim={v_dim} projected_dim={projected_dim} carrier={carrier_dtype} "
4647+
f"({type(exc).__name__}: {exc})."
4648+
) from exc
45974649

45984650
del lowering
45994651
h_last, tanh_cache, post = kernel(conv_input, W, xf, h0, D, projected)
@@ -4698,8 +4750,14 @@ def _m2rnn_inline_post_bwd_path_c_kernel(
46984750
carrier_dtype,
46994751
"float32",
47004752
)
4701-
except Exception:
4702-
return None
4753+
except Exception as exc:
4754+
# RULE #1: compile failure of the M2RNN post-residual/gate bwd-from-
4755+
# recurrence kernel is a real bug, not a "not applicable" signal. Raise.
4756+
raise RuntimeError(
4757+
f"M2RNN Path C post-residual/gate bwd-from-recurrence kernel "
4758+
f"compile/lowering failed for batch={batch} seq={seq} "
4759+
f"total_heads={total_heads} ({type(exc).__name__}: {exc})."
4760+
) from exc
47034761

47044762
del lowering
47054763
dy_recurrent, dconv_input, dD, dprojected = _m2rnn_post_bwd_owner_outputs(
@@ -4794,8 +4852,14 @@ def _m2rnn_post_residual_gate_fwd_path_c(
47944852
projected_dim,
47954853
carrier_dtype,
47964854
)
4797-
except Exception:
4798-
return None
4855+
except Exception as exc:
4856+
# RULE #1: compile failure of the M2RNN post-residual/gate fwd kernel is
4857+
# a real bug, not a "not applicable" signal. Raise with where+what.
4858+
raise RuntimeError(
4859+
f"M2RNN Path C post-residual/gate fwd kernel compile/lowering failed "
4860+
f"for batch={batch} seq={seq} total_heads={total_heads} "
4861+
f"carrier={carrier_dtype} ({type(exc).__name__}: {exc})."
4862+
) from exc
47994863

48004864
del lowering
48014865
return kernel(y, conv_input, D, projected)
@@ -4874,8 +4938,14 @@ def _m2rnn_post_residual_gate_bwd_path_c_kernel(
48744938
carrier_dtype,
48754939
"float32",
48764940
)
4877-
except Exception:
4878-
return None
4941+
except Exception as exc:
4942+
# RULE #1: compile failure of the M2RNN post-residual/gate bwd kernel is
4943+
# a real bug, not a "not applicable" signal. Raise with where+what.
4944+
raise RuntimeError(
4945+
f"M2RNN Path C post-residual/gate bwd kernel compile/lowering failed "
4946+
f"for batch={batch} seq={seq} total_heads={total_heads} "
4947+
f"carrier={carrier_dtype} ({type(exc).__name__}: {exc})."
4948+
) from exc
48794949

48804950
del lowering
48814951
dy_recurrent, dconv_input, dD, dprojected = _m2rnn_post_bwd_owner_outputs(

0 commit comments

Comments
 (0)