feat: isolate cutlass._mlir imports behind compat gateway (#118) - #121
Conversation
…usionAI#118) All 10 kernel modules previously imported CuTeDSL's private generated bindings (cutlass._mlir.{ir,arith,llvm,vector,nvvm,cute}) directly, so a CutDSL patch release could break kernel emission silently (the 4.5.2->4.5.3 tcgen05_ld/st incident). Add a single-point gateway that lazily loads the private dialects, enforces the pyproject.toml version contract (including the !=4.5.0 exclusion), and probes canary entry points, failing fast with an actionable error. Migrate all consumers to bind their dialect aliases from the gateway. Extend test_cutedsl_compat.py with fault-injection and version-matrix tests that run headless.
CutDSL renamed vector.extractelement to vector.extract in the 4.6 line, which broke store_256b (used by KDA SM100 backward) against nvidia-cutlass-dsl 4.6.2 at JIT time. Route element extraction through the gateway's version-dispatching vector_extract_element helper.
8442bc2 to
2af0dc0
Compare
|
Aligned with #119 (merged) — this PR builds on top of the tcgen05 signature-detection work; no overlap: #119 owns Scope recap
Healthy on the minimal local smoke suite; the automated H100 run is in flight — I'll post the summary when it's back. |
f6ac23d to
45b53d3
Compare
45b53d3 to
2c16cb9
Compare
There was a problem hiding this comment.
Requesting changes based on validation of commit 2c16cb9 on an NVIDIA GB200.
Results:
tests/test_cutedsl_compat.py: 15/15 passed with CuTeDSL 4.5.2 and with an isolated 4.6.2 environment.- All 10 migrated modules imported successfully with 4.5.2.
tests/test_lightning_decode.py: 27/27 passed with 4.5.2.tests/test_ptx_umma_ws.py::test_ws_ss_tf32: failed on this PR with both 4.5.2 and 4.6.2. The same test passes at the base commit (5161546) with 4.5.2, so this PR introduces a regression in a supported environment while still not fixing the 4.6 path.
The gateway direction is good, but the store_256b compatibility path and validation harness need to be fixed before merge.
- vector_extract_element: prefer extractelement (builds the i32 index constant internally) and use the static-position extract(vec, [], [pos]) form on 4.6+, matching the real generated bindings - normalize parsed versions to (major, minor, patch) so '4.5'/'4.7' hit the exclusion and upper bound instead of slipping past - modal_validate: use the module-level TESTS list, pass args without shell=True, and fail the Modal function on nonzero pytest exit - keep ruff lint/format clean (CI runs ruff --all-files)
Adds test_ptx_umma_ws.py (SM100, self-deselects on non-Blackwell via conftest) to the validation suite so the store_256b vector-extract path the reviewer flagged on GB200 is covered, and lets the harness run any GPU/CuTeDSL combination: modal run scripts/modal_validate.py --gpu B200 --cutlass 'nvidia-cutlass-dsl==4.5.2'
The '-m not sm100_only' marker expression deselected the SM100 tests even on B200 (conftest already skips them on non-Blackwell); the GPU was also hardcoded in the summary because env vars do not reach the container, so pass it as an argument.
Validation results (addressing all review comments)All three inline comments are addressed in commits [P1]
|
| Environment | compat | SM90 | SM100 (test_ptx_umma_ws) |
|---|---|---|---|
| H100, CuTeDSL 4.6.2 | 18/18 | prefill+decode green | n/a (conftest skip) |
| B200, CuTeDSL 4.6.2 | green | green | test_ws_ss_tf32, test_ws_ss_f16, test_ws_ss_tf32_collector PASSED (72/72 total) |
| B200, CuTeDSL 4.5.2 | green | green | 72/72 total, incl. test_ws_ss_tf32 PASSED |
The test you failed on GB200 (test_ws_ss_tf32) now passes on Blackwell with both 4.5.2 and 4.6.2 — no regression in the supported environment, and the 4.6 path is fixed. Headless suite: 18/18. Ruff lint + format clean.
Full harness output is pasted inline in the follow-up comment (Modal dashboard links are account-private, so the results are shared here instead).
Full validation output (public copy)The Modal dashboard links above are account-private (Modal app pages are not publicly viewable, and the B200 + CuTeDSL 4.5.2 (supported environment, previously FAILED on GB200){
"branch": "mlir-compat-gateway",
"gpu": "B200",
"cutlass_spec": "nvidia-cutlass-dsl==4.5.2",
"steps": {"clone": "ok", "build": "ok", "probe": "ok", "pytest": "ok"},
"env": "2.9.1+cu129 4.5.2 NVIDIA B200",
"pytest_rc": 0,
"pytest_tail": "tests/test_ptx_umma_ws.py::test_ws_ss_tf32 PASSED [97%]\ntests/test_ptx_umma_ws.py::test_ws_ss_f16 PASSED [98%]\ntests/test_ptx_umma_ws.py::test_ws_ss_tf32_collector PASSED [100%]\n======================= 72 passed, 60 warnings in 44.30s ========================",
"elapsed_s": 215
}B200 + CuTeDSL 4.6.2 (previously FAILED on GB200){
"branch": "mlir-compat-gateway",
"gpu": "B200",
"cutlass_spec": "nvidia-cutlass-dsl>=4.4.2,<4.7,!=4.5.0",
"steps": {"clone": "ok", "build": "ok", "probe": "ok", "pytest": "ok"},
"env": "2.9.1+cu129 4.6.2 NVIDIA B200",
"pytest_rc": 0,
"pytest_tail": "tests/test_ptx_umma_ws.py::test_ws_ss_tf32 PASSED [97%]\ntests/test_ptx_umma_ws.py::test_ws_ss_f16 PASSED [98%]\ntests/test_ptx_umma_ws.py::test_ws_ss_tf32_collector PASSED [100%]\n======================= 72 passed, 56 warnings in 30.37s ========================",
"elapsed_s": 192
}H100 + CuTeDSL 4.6.2 (SM90 coverage; SM100 tests self-skip via conftest)
Headless suite: |
|
Quick status on the pushed head
|
Summary
Closes #118 — isolates all direct
cutlass._mlirusage behind a single compatibility gateway.CuTeDSL's generated MLIR/NVVM bindings (
cutlass._mlir.{ir,arith,llvm,vector,nvvm,cute}) are private implementation detail with no cross-version stability contract — thetcgen05_ld/stbreakage between CutDSL 4.5.2 and 4.5.3 was the first confirmed incident. cuLA imported these directly from 10 kernel modules, so a patch release could break kernel emission silently, delayed until import/JIT time.Changes
cula/ops/_mlir_compat.py— the only module that may touchcutlass._mlir:import culanever touches private bindings)pyproject.toml(>=4.4.2,<4.7,!=4.5.0), enforced with a fail-fastRuntimeErrornaming the offending versionvector_extract_element()helper with cross-version dispatch (see below)vector.extractelementtovector.extractin the 4.6 line; againstnvidia-cutlass-dsl==4.6.2(resolved by our ownpyproject.tomlrange)store_256braisesAttributeErrorat JIT time.store_256bis used by the KDA SM100 backward path. The gateway'svector_extract_elementdispatches to whichever binding exists, restoring 4.6 compatibility.scripts/modal_validate.py— H100/CUDA 12.9 validation harness (runs the headless suite + SM90 prefill/decode tests in onemodal run).Validation status
tests/test_cutedsl_compat.pygreen againstnvidia-cutlass-dsl==4.6.2modal run scripts/modal_validate.py; will attach resultsNotes for reviewers
extractelementcall instore_256bpassed the position as a keyword (position=...); the newvector.extractbinding takes it positionally ((source, dynamic_position, static_position)). The dispatch helper deliberately keeps the exact call shapes per branch._CANARIES/_ANY_OF_CANARIESwhen new private-API usage lands.