Skip to content

feat: add BF16 grouped GEMM MoE kernels#415

Open
saltyminty wants to merge 4 commits into
NVIDIA:developfrom
saltyminty:fix/mingyangw/integrate-bf16-moe-grouped-gemm-kernels-into-cudnn-frontend
Open

feat: add BF16 grouped GEMM MoE kernels#415
saltyminty wants to merge 4 commits into
NVIDIA:developfrom
saltyminty:fix/mingyangw/integrate-bf16-moe-grouped-gemm-kernels-into-cudnn-frontend

Conversation

@saltyminty

@saltyminty saltyminty commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add BF16 grouped GEMM, GLU, dGLU, and WGrad APIs for dense and discrete MoE layouts
  • route BF16 and block-scaled implementations through the shared public APIs
  • document the BF16 contract and extend the existing grouped-GEMM sweeps, including discrete N-major weights

Kernel provenance

Validation

  • PYTHONPATH=python:test/python python -m pytest test/python/fe_api/test_grouped_gemm_glu.py::test_grouped_gemm_glu_wrapper_bf16 test/python/fe_api/test_grouped_gemm_dglu.py::test_grouped_gemm_dglu_wrapper_bf16 -q (6 passed on SM100)
  • targeted Python compilation checks
  • pre-commit (Black and Black-Jupyter passed; Clang format had no applicable files)

Notes

  • The task's dedicated performance gate was waived; no canonical benchmark result is included.

Summary by CodeRabbit

  • New Features
    • Added experimental SM100+ grouped GEMM support for BF16 across unfused, GLU, dGLU, and Wgrad, with unified dense vs discrete MoE weight/output modes and wrapper-backed backend dispatch with compilation/execution caching.
    • Exposed new SM100 unfused grouped GEMM symbols and expanded GLU/dGLU/wgrad API coverage.
  • Documentation
    • Added/expanded SM100 grouped GEMM guides with BF16 contracts, backend dispatch tables, scheduling/cache notes, and updated “latest news” kernel listings.
    • Updated installation guidance for the grouped GEMM operation docs.
  • Tests
    • Added end-to-end BF16 wrapper tests for unfused, GLU, dGLU, and Wgrad (dense/discrete), plus export-discovery and cache-behavior checks.
  • Refactor
    • Improved public symbol discovery with lazy exports and more accurate directory listings.
  • Style
    • Enabled faster formatting via black --fast.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3a50f3c6-ff68-4407-bfa1-8f2379b60ae1

📥 Commits

Reviewing files that changed from the base of the PR and between 869cebb and dba72a4.

📒 Files selected for processing (3)
  • python/cudnn/__init__.py
  • python/cudnn/grouped_gemm/grouped_gemm_dglu/_blockscaled_api.py
  • test/python/fe_api/grouped_gemm/test_grouped_gemm_dglu.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/python/fe_api/grouped_gemm/test_grouped_gemm_dglu.py
  • python/cudnn/init.py
  • python/cudnn/grouped_gemm/grouped_gemm_dglu/_blockscaled_api.py

📝 Walkthrough

Walkthrough

Adds experimental SM100 BF16 grouped GEMM APIs for unfused, GLU, dGLU, and Wgrad operations. Each operation supports dense (contiguous weight tensors) and discrete (per-expert pointer arrays) MoE weight layouts, unified backend dispatch between BF16 and legacy block-scaled variants, persistent tile scheduling, CUTLASS/CuTe kernels, tensor validation, and compilation caching. Includes CUDA kernel implementations, descriptor-first lifecycle facades, extensive documentation, and BF16 numerical test fixtures.

Changes

SM100 grouped GEMM APIs

Layer / File(s) Summary
Unfused BF16 grouped GEMM foundation
python/cudnn/grouped_gemm/grouped_gemm_unfused/*
Adds GroupedGemmSm100 lifecycle facade and grouped_gemm_wrapper_sm100 wrapper for unfused BF16 grouped GEMM with dense/discrete MoE support, persistent scheduling, and workspace caching.
Shared dispatch, stream, and scheduler utilities
python/cudnn/grouped_gemm/grouped_gemm_utils.py, python/cudnn/grouped_gemm/moe_sched_extension.py, python/cudnn/grouped_gemm/moe_kernel_helpers.py, python/cudnn/grouped_gemm/moe_utils.py
Adds GroupedGemmBackend enum for BF16/block-scaled selection, _torch_stream_context for CUDA stream handling, select_grouped_gemm_backend dispatch logic, BF16 validation helpers, scheduler extensions for grouped GEMM/Wgrad, and tensor-map descriptor construction for wgrad.
Unified GLU forward fusion (BF16 + block-scaled)
python/cudnn/grouped_gemm/grouped_gemm_glu/*
Adds GroupedGemmGluBf16API and GroupedGemmGluBlockScaledAPI with unified backend selection via GroupedGemmGluSm100 facade; MoEGroupedGemmGluBiasBf16Kernel implements persistent BF16 kernel with fused GLU/bias epilogue; wrapper validates, caches, and executes via selected backend.
Unified dGLU backward fusion (BF16 + block-scaled)
python/cudnn/grouped_gemm/grouped_gemm_dglu/*
Adds GroupedGemmDgluBf16API and GroupedGemmDgluBlockScaledAPI with unified dispatch; MoEGroupedGemmDgluDbiasBf16Kernel implements persistent dSwiGLU/dGeGLU backward with optional dBias reduction; wrapper selects backend and handles scale-control validation.
Unified Wgrad gradient computation (BF16 + block-scaled)
python/cudnn/grouped_gemm/grouped_gemm_wgrad/*
Adds GroupedGemmWgradBf16API and GroupedGemmWgradBlockScaledAPI with unified backend selection; MoEGroupedGemmWgradBF16Kernel supports Tensor2D and TensorRagged input layouts with dense/discrete expert output modes; WgradTensormapConstructor builds per-expert descriptors.
Documentation and numerical validation
docs/fe-oss-apis/gemm_fusions/*, docs/fe-oss-apis/overview.md, README.md, test/python/fe_api/*, .pre-commit-config.yaml, python/cudnn/__init__.py
Documents BF16 contracts, operation math, tensor layouts, error handling, and output modes; updates README and overview listings; adds GroupedGemmSm100/grouped_gemm_wrapper_sm100 to module exports and lazy imports; provides test fixtures, Torch reference implementations, BF16-tolerant assertions, and wrapper parameter coverage for unfused/GLU/dGLU/Wgrad.

Estimated code review effort: 5 (Critical) | ~120 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.47% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and matches the main change: adding BF16 grouped GEMM MoE kernels.
Description check ✅ Passed The description covers the main changes, provenance, and validation, though it does not fully follow the repository template sections.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@saltyminty

Copy link
Copy Markdown
Collaborator Author

@cudnn-ci-bot run

@cudnn-ci-bot

Copy link
Copy Markdown

Backend pipeline not launched

Reason: PR base branch 'main' does not match 'develop'

@saltyminty
saltyminty changed the base branch from main to develop July 22, 2026 22:00
@saltyminty
saltyminty force-pushed the fix/mingyangw/integrate-bf16-moe-grouped-gemm-kernels-into-cudnn-frontend branch from 54de6f4 to a06ad15 Compare July 22, 2026 22:05
@saltyminty

Copy link
Copy Markdown
Collaborator Author

@cudnn-ci-bot run

@cudnn-ci-bot

Copy link
Copy Markdown

🚀 Running mirror pipeline

Branch: cudnn-gh/pr-415-a06ad15
Pipeline: 59148876

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
python/cudnn/grouped_gemm/moe_kernel_helpers.py (1)

809-809: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer a def over an assigned lambda (Ruff E731).

A local def is_power_of_2(x): return x > 0 and (x & (x - 1)) == 0 reads better and matches the existing is_power_of_2 helpers already defined elsewhere in the package.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cudnn/grouped_gemm/moe_kernel_helpers.py` at line 809, Replace the
assigned lambda with a local def named is_power_of_2, preserving its positive
power-of-two check exactly and matching the existing helper style elsewhere in
the package.

Source: Linters/SAST tools

python/cudnn/grouped_gemm/grouped_gemm_unfused/api.py (1)

21-21: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant __all__ shadowed later in the module.

This __all__ = ["GroupedGemmBf16API"] is overwritten by the __all__ at Line 381, so it has no effect and misleadingly implies GroupedGemmBf16API is exported. Remove this early assignment.

♻️ Proposed cleanup
-__all__ = ["GroupedGemmBf16API"]
-
-
 from ._bf16_api import GroupedGemmBf16API
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cudnn/grouped_gemm/grouped_gemm_unfused/api.py` at line 21, Remove the
early __all__ assignment near GroupedGemmBf16API; retain the later module-level
__all__ definition as the sole export declaration.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@python/cudnn/__init__.py`:
- Around line 277-278: The module’s __all__ currently exports every
non-underscore global, including internal imports and helper names. Update
_EAGER_PUBLIC_NAMES in python/cudnn/__init__.py to use an explicit
intended-public symbol list or exclude the identified helpers/imports, then
append Graph and wrapper as before.

In `@python/cudnn/grouped_gemm/grouped_gemm_dglu/_blockscaled_api.py`:
- Around line 1254-1274: In the non-BF16 launch path of execute, record both
b_ptrs and sfb_ptrs on current_stream via the existing _record_pointer_stream
mechanism before invoking self._compiled_kernel. Match the BF16 path’s
pointer-stream recording behavior while leaving kernel arguments unchanged.

In `@python/cudnn/grouped_gemm/grouped_gemm_wgrad/_bf16_api.py`:
- Line 49: Update the input_order annotations in
python/cudnn/grouped_gemm/grouped_gemm_wgrad/_bf16_api.py:49 and
python/cudnn/grouped_gemm/grouped_gemm_wgrad/_blockscaled_api.py:48 to use
Python 3.9-compatible Union[WGradInputOrder, str] syntax, or add the future
annotations import in both modules. Preserve the existing defaults and
annotation meaning.

In `@test/python/fe_api/test_grouped_gemm_dglu_bf16_utils.py`:
- Line 4: Remove the internal “!35” token from the module docstring and the
corresponding docstrings near the affected test utilities, replacing it with
descriptive wording such as “the reference oracle” while preserving their
meaning.

---

Nitpick comments:
In `@python/cudnn/grouped_gemm/grouped_gemm_unfused/api.py`:
- Line 21: Remove the early __all__ assignment near GroupedGemmBf16API; retain
the later module-level __all__ definition as the sole export declaration.

In `@python/cudnn/grouped_gemm/moe_kernel_helpers.py`:
- Line 809: Replace the assigned lambda with a local def named is_power_of_2,
preserving its positive power-of-two check exactly and matching the existing
helper style elsewhere in the package.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ff467305-d18f-4386-b3f1-7358bbedd70c

📥 Commits

Reviewing files that changed from the base of the PR and between 3a9ed3f and a06ad15.

📒 Files selected for processing (36)
  • README.md
  • docs/fe-oss-apis/gemm_fusions/grouped_gemm.md
  • docs/fe-oss-apis/gemm_fusions/grouped_gemm_dglu.md
  • docs/fe-oss-apis/gemm_fusions/grouped_gemm_glu.md
  • docs/fe-oss-apis/gemm_fusions/grouped_gemm_wgrad.md
  • docs/fe-oss-apis/overview.md
  • python/cudnn/__init__.py
  • python/cudnn/grouped_gemm/__init__.py
  • python/cudnn/grouped_gemm/grouped_gemm_dglu/_bf16_api.py
  • python/cudnn/grouped_gemm/grouped_gemm_dglu/_blockscaled_api.py
  • python/cudnn/grouped_gemm/grouped_gemm_dglu/api.py
  • python/cudnn/grouped_gemm/grouped_gemm_dglu/moe_grouped_gemm_dglu_dbias.py
  • python/cudnn/grouped_gemm/grouped_gemm_glu/_bf16_api.py
  • python/cudnn/grouped_gemm/grouped_gemm_glu/_blockscaled_api.py
  • python/cudnn/grouped_gemm/grouped_gemm_glu/api.py
  • python/cudnn/grouped_gemm/grouped_gemm_glu/moe_grouped_gemm_glu_bias.py
  • python/cudnn/grouped_gemm/grouped_gemm_unfused/__init__.py
  • python/cudnn/grouped_gemm/grouped_gemm_unfused/_bf16_api.py
  • python/cudnn/grouped_gemm/grouped_gemm_unfused/api.py
  • python/cudnn/grouped_gemm/grouped_gemm_unfused/moe_grouped_gemm.py
  • python/cudnn/grouped_gemm/grouped_gemm_utils.py
  • python/cudnn/grouped_gemm/grouped_gemm_wgrad/_bf16_api.py
  • python/cudnn/grouped_gemm/grouped_gemm_wgrad/_blockscaled_api.py
  • python/cudnn/grouped_gemm/grouped_gemm_wgrad/api.py
  • python/cudnn/grouped_gemm/grouped_gemm_wgrad/moe_grouped_gemm_wgrad.py
  • python/cudnn/grouped_gemm/moe_kernel_helpers.py
  • python/cudnn/grouped_gemm/moe_sched_extension.py
  • python/cudnn/grouped_gemm/moe_utils.py
  • test/python/fe_api/grouped_gemm/test_grouped_gemm_dglu.py
  • test/python/fe_api/grouped_gemm/test_grouped_gemm_glu.py
  • test/python/fe_api/grouped_gemm/test_grouped_gemm_wgrad.py
  • test/python/fe_api/test_grouped_gemm_bf16.py
  • test/python/fe_api/test_grouped_gemm_bf16_utils.py
  • test/python/fe_api/test_grouped_gemm_dglu_bf16_utils.py
  • test/python/fe_api/test_grouped_gemm_glu_bf16_utils.py
  • test/python/fe_api/test_grouped_gemm_wgrad_bf16_utils.py

Comment thread python/cudnn/__init__.py Outdated
Comment thread python/cudnn/grouped_gemm/grouped_gemm_dglu/_blockscaled_api.py
Comment thread python/cudnn/grouped_gemm/grouped_gemm_wgrad/_bf16_api.py Outdated
Comment thread test/python/fe_api/test_grouped_gemm_dglu_bf16_utils.py Outdated
@Anerudhan Anerudhan added cat-feature Requests for new functionality, APIs, examples, or behavior improvements. mod-cutedsl CuTeDSL kernels, generated kernels, examples, or related integration work. labels Jul 22, 2026
@Anerudhan Anerudhan added this to the Frontend 1.27.0 milestone Jul 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.pre-commit-config.yaml (1)

18-18: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Retain Black’s safety check unless the tradeoff is intentional.

--fast skips Black’s AST equivalence check, reducing protection against formatter-induced semantic changes in pre-commit and CI. Remove it unless the performance benefit is required and the pinned Black revision is verified to support this tradeoff.

Proposed change
-        args: ["--line-length", "160", "--fast"]
+        args: ["--line-length", "160"]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.pre-commit-config.yaml at line 18, Update the Black hook configuration’s
args to remove the “--fast” option, preserving Black’s default AST equivalence
safety check while retaining the existing line-length setting.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.pre-commit-config.yaml:
- Line 18: Update the Black hook configuration’s args to remove the “--fast”
option, preserving Black’s default AST equivalence safety check while retaining
the existing line-length setting.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 59399c70-de0b-4ab7-95e4-c2158b710c0c

📥 Commits

Reviewing files that changed from the base of the PR and between a06ad15 and 7202d80.

📒 Files selected for processing (4)
  • .pre-commit-config.yaml
  • test/python/fe_api/grouped_gemm/test_grouped_gemm_dglu.py
  • test/python/fe_api/grouped_gemm/test_grouped_gemm_glu.py
  • test/python/fe_api/grouped_gemm/test_grouped_gemm_wgrad.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/python/fe_api/grouped_gemm/test_grouped_gemm_glu.py
  • test/python/fe_api/grouped_gemm/test_grouped_gemm_wgrad.py
  • test/python/fe_api/grouped_gemm/test_grouped_gemm_dglu.py

@saltyminty

Copy link
Copy Markdown
Collaborator Author

@cudnn-ci-bot run

@cudnn-ci-bot

Copy link
Copy Markdown

🚀 Running mirror pipeline

Branch: cudnn-gh/pr-415-dba72a4
Pipeline: 59163103

@Anerudhan

Copy link
Copy Markdown
Collaborator

@cudnn-ci-bot run

@cudnn-ci-bot

Copy link
Copy Markdown

🚀 Running mirror pipeline

Branch: cudnn-gh/pr-415-dba72a4
Pipeline: 59281796

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

Labels

cat-feature Requests for new functionality, APIs, examples, or behavior improvements. mod-cutedsl CuTeDSL kernels, generated kernels, examples, or related integration work.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants