Skip to content

Restore pre-1.27 module paths as deprecated aliases; clearer lazy-import errors - #724

Draft
Anerudhan wants to merge 1 commit into
NVIDIA:developfrom
Anerudhan:legacy-import-aliases
Draft

Restore pre-1.27 module paths as deprecated aliases; clearer lazy-import errors#724
Anerudhan wants to merge 1 commit into
NVIDIA:developfrom
Anerudhan:legacy-import-aliases

Conversation

@Anerudhan

Copy link
Copy Markdown
Collaborator

Problem

The 1.27 GEMM reorganization kept every public symbol importable as from cudnn import <symbol>, but the old dotted module paths broke:

import cudnn.grouped_gemm                                    # ModuleNotFoundError
from cudnn.grouped_gemm.grouped_gemm_wgrad.api import ...    # ModuleNotFoundError

The attribute-level aliases in cudnn.__getattr__ cannot satisfy an import statement (import a.b resolves through the import system, not getattr). The package-structure design doc called for sys.modules compatibility aliases, but they were never implemented.

Separately, _load_optional_symbol wrapped every failure as "<name> requires optional dependencies. Install with pip install nvidia-cudnn-frontend[cutedsl]", so an internal packaging bug or a real error inside a fusion module masqueraded as a missing optional dependency — which in turn read as "the API was removed".

Change

  • cudnn/_legacy_aliases.py — a sys.meta_path finder lazily maps every legacy path (cudnn.grouped_gemm*, cudnn.discrete_grouped_gemm*, cudnn.gemm_amax, cudnn.gemm_swiglu, cudnn.gemm_srelu, cudnn.gemm_dsrelu, cudnn.gemm_proj_rope_mxfp8, and their submodules, including the renamed per-fusion children like grouped_gemm_wgradwgrad) onto its canonical cudnn.gemm.cutedsl.* module on first import. After the import, sys.modules[legacy] is sys.modules[canonical] — one module, not a copy — and a DeprecationWarning names the canonical path. Lazy by construction: import cudnn still pulls no framework (the eager-sys.modules approach from the design doc would have violated test_import_boundaries.py). The finder must sit in front of PathFinder, which would otherwise resolve legacy children through the aliased parent's __path__ and execute the same file twice as two distinct modules.
  • _load_optional_symbol — failure classes are now distinguished: a missing third-party module keeps the [cutedsl] install hint (with the underlying error appended), a missing cudnn.* internal module is reported as a packaging bug, and any other exception is surfaced as the real failure. All paths chain via raise ... from.
  • Docs — import-path / 1.27-reorg note in docs/fe-oss-apis/overview.md; alias note in the cudnn.gemm docstring.
  • Teststest/python/test_legacy_import_aliases.py: fresh-interpreter probes for alias identity, the from cudnn.grouped_gemm import grouped_gemm_wgrad fromlist spelling, deprecation warnings, finder idempotence, and both error-message classes.

Verification

  • New suite: 5/5 pass (alias identity verified against real cutlass/cuda-python imports on a GPU box).
  • Existing test/python/test_import_boundaries.py: 8/8 pass — import cudnn remains framework-free and the gnn/ops optional-dependency guidance is unchanged.

🤖 Generated with Claude Code

…ional deps for internal import failures

The 1.27 "Reorganize Gemm fusion" commit kept every symbol importable as
cudnn.<symbol>, but the old dotted module paths (import cudnn.grouped_gemm,
from cudnn.grouped_gemm.grouped_gemm_wgrad.api import ...) broke: the
attribute-level aliases in cudnn.__getattr__ cannot satisfy an import
statement. The design doc called for sys.modules compatibility aliases; this
implements them without violating the import-boundary rule that
`import cudnn` must not pull torch / nvidia-cutlass-dsl:

- cudnn/_legacy_aliases.py: a meta-path finder maps every legacy path
  (cudnn.grouped_gemm*, cudnn.discrete_grouped_gemm*, cudnn.gemm_amax,
  cudnn.gemm_swiglu, cudnn.gemm_srelu, cudnn.gemm_dsrelu,
  cudnn.gemm_proj_rope_mxfp8, and their submodules) onto its canonical
  cudnn.gemm.cutedsl.* module lazily, on first import of the legacy path.
  sys.modules[legacy] is sys.modules[canonical] afterwards, the canonical
  module keeps its own metadata, and a DeprecationWarning names the new path.
  The finder sits in front of PathFinder, which would otherwise resolve
  legacy children through the aliased parent's __path__ and execute the same
  file twice as two distinct modules.

- _load_optional_symbol: only claim "requires optional dependencies. pip
  install nvidia-cudnn-frontend[cutedsl]" when the failure is an ImportError
  of a non-cudnn module; a missing cudnn-internal module is reported as a
  packaging bug and any other exception is surfaced as the real failure. All
  paths chain the underlying error and include its message, so a broken
  environment no longer masquerades as "the API was removed".

- Docs: import-path note in fe-oss-apis/overview.md, alias note in
  cudnn.gemm docstring.

- test/python/test_legacy_import_aliases.py: fresh-interpreter probes for
  alias identity, fromlist spelling, deprecation warning, finder idempotence,
  and both error-message classes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant