Remove PyTorch from the cutedsl dependency extra - #455
Draft
Anerudhan wants to merge 2 commits into
Draft
Conversation
Drops `torch` and `torch-c-dlpack-ext` from `[project.optional-dependencies].cutedsl`
and makes `python/cudnn` importable without PyTorch. Missing PyTorch is now
reported only when a PyTorch-dependent entry point is invoked.
Framework dependency boundary:
- New `cudnn/_deps/torch_dep.py` is the sole runtime `import torch`. The import
is attempted lazily on the first `is_available()`/`require()` call and cached
(module or failure, never retried), so importing the helper -- and therefore
`import cudnn` -- stays PyTorch-free.
- New public `cudnn.TorchNotAvailableError` (subclasses `ImportError`) carries a
canonical message; the lazy optional-symbol loader re-raises it unwrapped.
Import safety:
- 72 modules converted off module-level `import torch` onto `torch_dep.require()`
with postponed annotations plus `if TYPE_CHECKING: import torch`.
- 84 PyTorch-valued parameter defaults became `None`, resolved after `require()`,
with the fixed effective default stated in the docstring; annotations widened
to `Optional[...]`. Effective values are unchanged.
- 23 module-scope PyTorch constants became lazily-resolved accessors.
- `wrapper.Graph` stays deliberately PyTorch-only but now fails fast with
`TorchNotAvailableError` instead of a bare `RuntimeError`.
- `datatypes.is_cutlass_available()` no longer requires PyTorch, so CUTLASS-native
`cutlass.Numeric` types keep working when CUTLASS is present and Torch is not.
Validation:
- New `test/python/tools/audit_no_runtime_torch_import.py` rejects runtime torch
imports (plain/aliased/from/submodule/dynamic), PyTorch-valued defaults, and
unguarded module-scope PyTorch access outside the dependency helper.
- `python -m compileall python/cudnn` is clean.
Known remaining work (tracked in the PR description): the three custom-op modules
(`ops/causal_conv1d.py`, `experimental/ops/{sdpa,moe_grouped_matmul}.py`) still
import torch at module scope. They are lazily loaded, so `import cudnn` is
unaffected, but they need the facade/guarded-implementation split before the
audit passes clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
Completes the import-safety sweep: `python/cudnn` now has no runtime PyTorch import outside `cudnn/_deps/torch_dep.py`, and the audit passes clean. - `ops/causal_conv1d.py`, `experimental/ops/sdpa.py` and `experimental/ops/moe_grouped_matmul.py` become import-safe facades that resolve their public callables on first attribute access via module `__getattr__`, preserving the original function objects and therefore their signatures. - The former module bodies move to `_causal_conv1d_torch.py`, `_sdpa_torch.py` and `_moe_grouped_matmul_torch.py`, each wrapped in a single top-level `if torch_dep.is_available():` block that binds torch through `torch_dep.require()`. Because Python caches modules, the operator schemas, fake implementations, compiler hooks and autograd formulas inside still register exactly once when PyTorch is present, with unchanged operator names. These modules keep real (non-postponed) annotations, which `torch.library.custom_op` needs for schema inference. - `ops/__init__.py` and `experimental/ops/__init__.py` resolve names lazily and deliberately bind from the implementation modules, not the same-named facade submodules: importing e.g. `cudnn.ops.causal_conv1d` sets it as an attribute of the parent package and would otherwise shadow the function of the same name. Adds `test/python/tools/smoke_no_torch_import.py`, which blocks torch with a MetaPathFinder raising ModuleNotFoundError for exactly `torch`/`torch.*`, then imports every submodule and asserts the representative entry points raise `TorchNotAvailableError`. Verified with torch absent and the pybind module stubbed: `import cudnn` does not import torch, 212 submodules import cleanly, none hard-require torch, and `cudnn.Graph`, the causal-conv1d names and both experimental ops all raise `TorchNotAvailableError` with the canonical message. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Removes
torchandtorch-c-dlpack-extfrom[project.optional-dependencies].cutedsl, and makes every module underpython/cudnnimportable without PyTorch. Missing PyTorch is reported only when a PyTorch-dependent entry point is actually invoked.Implements
torch-dependency-removal.md(included in this branch, with review comment C23 applied: the torch import is attempted on first probe, not at helper initialization).Framework dependency boundary
cudnn/_deps/torch_dep.pyis the sole runtimeimport torch. The import is attempted lazily on the firstis_available()/require()call and cached (module or failure, never retried), so importing the helper -- and thereforeimport cudnn-- stays PyTorch-free.cudnn.TorchNotAvailableError(subclassesImportError) with the canonical message. The lazy optional-symbol loader re-raises it unwrapped rather than burying it in the generic optional-dependency hint.Import safety
import torchontotorch_dep.require(), using postponed annotations plusif TYPE_CHECKING: import torch.None, resolved immediately afterrequire(), with the fixed effective default stated in the docstring (e.g.`None` means `torch.float32`) and annotations widened toOptional[...]. Effective values are unchanged.wrapper.Graphremains deliberately PyTorch-only (it allocates Torch outputs/workspace and manages the default Torch stream), but now fails fast withTorchNotAvailableErrorinstead of a bareRuntimeError.datatypes.is_cutlass_available()no longer requires PyTorch -- a real bug fix: CUTLASS-nativecutlass.Numerictypes now keep working when CUTLASS is installed and Torch is not.Custom operators (facade + guarded implementation)
ops/causal_conv1d.py,experimental/ops/sdpa.pyandexperimental/ops/moe_grouped_matmul.pyare now import-safe facades that resolve their public callables on first attribute access, preserving the original function objects and therefore their signatures. The former bodies moved to_causal_conv1d_torch.py/_sdpa_torch.py/_moe_grouped_matmul_torch.py, each wrapped in one top-levelif torch_dep.is_available():block. Module caching means the schemas, fake implementations, compiler hooks and autograd formulas still register exactly once when PyTorch is present, with unchanged operator names. These modules deliberately keep real (non-postponed) annotations, whichtorch.library.custom_opneeds for schema inference.The two package
__init__files bind from the implementation modules rather than the same-named facade submodules -- importingcudnn.ops.causal_conv1dsets it as an attribute of the parent package and would otherwise shadow the function of the same name.Packaging
The extra no longer installs PyTorch. Documented install order: (1) the PyTorch build matching your CUDA environment, (2)
nvidia-cudnn-frontend[cutedsl], (3) optionallytorch-c-dlpack-extto restore its AOT Torch->DLPack fast path. Omitting (3) affects conversion startup/performance, not numerical behavior.Test plan
Passing in this branch:
test/python/tools/audit_no_runtime_torch_import.py-- PASSES across all 226 modules. Rejects runtime torch imports (plain / aliased /from/ submodule / literal-dynamic), PyTorch-valued defaults, and unguarded module-scope PyTorch access outside the dependency helper. Type-checking-only imports and the single guarded block in the three implementation modules are permitted.python -m compileall python/cudnn-- clean.test/python/tools/smoke_no_torch_import.py(new) -- blocks torch with aMetaPathFinderraisingModuleNotFoundErrorfor exactlytorch/torch.*, imports every submodule, and asserts representative entry points raiseTorchNotAvailableError.Executed with PyTorch genuinely absent (and the unbuilt pybind module stubbed, since this branch was authored without a build):
import cudnnsucceeds andtorchis not insys.modulesafterwardsis_torch_available()is False;cudnn.TorchNotAvailableErroris exported and subclassesImportErrorcudnn.Graph(),cudnn.ops.{causal_conv1d,b2b_causal_conv1d}, and both experimental ops each raiseTorchNotAvailableErrorwith the canonical messagecannot import name 'CollectorOp'), which reproduces without the torch blockerStill to run in a proper environment: the clean-venv wheel acceptance check (assert neither distribution appears in
pip list), anenable_tvm_ffi=Trueconversion path with PyTorch but withouttorch-c-dlpack-ext, and the existing PyTorch-installed test suites.Remaining before merge
docs/fe-oss-apis/*,benchmark/dsa/README.md, etc.).python/cudnn/__init__.py's optional-dependency hint andpyproject.tomlare already updated.🤖 Generated with Claude Code