The cudnn Python package: pybind11-backed graph API plus pure-Python frontend-only OSS kernels (CuTeDSL). See README.md in this directory for the package inventory and ../../AGENTS.md for build/test commands.
import cudnnmust work without torch/cutlass/cuda-python installed. Everything that needs them is exported lazily via_LAZY_OPTIONAL_IMPORTSin__init__.py— a module-level__getattr__imports the submodule on first attribute access and re-raises failures asImportErrorpointing atpip install nvidia-cudnn-frontend[cutedsl].- Never add an eager
import torch/import cutlassto__init__.pyor anything it imports transitively.api_base.pyitself imports them at top level, which is why kernel classes must only be reachable through the lazy table. - Reuse the existing
[cutedsl]extra (pyproject.tomloptional-dependencies) unless a kernel truly needs a new package.
python/cudnn/<operation>/ # or grouped_gemm/<op>/, discrete_grouped_gemm/<op>/, sdpa/<direction>/
├── __init__.py # exports API class + wrapper via __all__
├── api.py # APIBase subclass + <operation>_wrapper() function
└── <kernel_module>.py # CuTeDSL kernel implementation(s); some families use csrc/ per-arch trees
Shared helpers (schedulers, metadata utils, e.g. grouped_gemm/moe_*.py) stay internal to the family package — never exported through cudnn.
Every OSS kernel API extends APIBase and implements:
check_support() -> bool— validate dtype/shape/stride/arch/config via the_check_tensor_*/_value_error_ifhelpers; must setself._is_supported. Works onTensorDesc(metadata-only tensors), so it runs without GPU storage.compile()— callsself._ensure_support_checked(), builds andcute.compiles the kernel, caches inself._compiled_kernel.execute(..., current_stream=None)— runs the cached kernel.
__call__ = compile-if-needed + execute. High-level wrappers (<op>_wrapper_sm100(...)) allocate outputs and return a TupleDict (dict that also unpacks as a tuple) with stable, documented key order. FP4x2 packing: use _tensor_shape/_tensor_stride, which double the innermost dim when interpret_uint8_as_fp4x2 is set.
- Kernel package under the closest existing family (layout above).
APIBasesubclass + wrapper inapi.py.- Exports: family
__init__.py__all__and_LAZY_OPTIONAL_IMPORTSinpython/cudnn/__init__.py; register any new package dir inpyproject.tomlpackages list. - Docs: page under
docs/fe-oss-apis/(family subdir) + link it fromdocs/fe-oss-apis/overview.md. - Tests:
test/python/fe_api/<family>/test_<op>.py(+_utils.py/reference), covering check_support pass/fail and numerical reference comparison.
The cutedsl-kernel-integration skill (skills/cutedsl-kernel-integration/) documents this workflow in detail, including how to classify a kernel into a family — follow it for any kernel integration.
wrapper.pyGraphcontext manager (the pythonic graph builder) requires cuDNN backend ≥ 9.12 (backend_version() >= 91200) and builds plans on__exit__.- Torch custom ops live in
experimental/ops/(pattern doc:docs/adding_torch_custom_ops.md); they cache built graphs per config and use stable_UIDsenums. - dtype conversions go through
datatypes.py, which probes torch/cutlass availability lazily — keep it that way. - Formatting: black, line length 160.