Skip to content

refactor: reduce hopper's gdn prefill compilation time and fix docstring.#2422

Merged
yzh119 merged 17 commits intoflashinfer-ai:mainfrom
yzh119:improve-hopper-gdn-prefill
Feb 4, 2026
Merged

refactor: reduce hopper's gdn prefill compilation time and fix docstring.#2422
yzh119 merged 17 commits intoflashinfer-ai:mainfrom
yzh119:improve-hopper-gdn-prefill

Conversation

@yzh119
Copy link
Collaborator

@yzh119 yzh119 commented Jan 27, 2026

📌 Description

This PR implements these features:

  1. accelerate hopper's gdn prefill compilation time by split compilation
  2. fix the docstring of gdn prefill kernel, instead of [N, H, K, V], it expects [N, H, V, K]

🔍 Related Issues

#2276

🚀 Pull Request Checklist

Thank you for contributing to FlashInfer! Before we review your pull request, please make sure the following items are complete.

✅ Pre-commit Checks

  • I have installed pre-commit by running pip install pre-commit (or used your preferred method).
  • I have installed the hooks with pre-commit install.
  • I have run the hooks manually with pre-commit run --all-files and fixed any reported issues.

If you are unsure about how to set up pre-commit, see the pre-commit documentation.

🧪 Tests

  • Tests have been added or updated as needed.
  • All tests are passing (unittest, etc.).

Reviewer Notes

cc @guangyunh-nv

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced JIT module generation for GDN prefill kernels with template-driven compilation and separate kernel instantiation.
  • Improvements

    • JIT specification now intelligently handles C++ standard flags, applying defaults only when not already specified.
  • Documentation

    • Clarified final state memory layout description for GDN prefill operations.

yzh119 and others added 2 commits January 22, 2026 23:14
…lation

Split the 32 template instantiations (2 dtypes × 16 boolean combinations)
into separate .cu files to enable parallel compilation with ninja. This
significantly reduces build time on multi-core machines.

Changes:
- Add Jinja template for generating kernel instantiation files
- Add extern template declarations to prevent implicit instantiation
- Update JIT module to generate 32 separate kernel files
- Keep original source files for launcher (relative includes work)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @yzh119, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on enhancing the development workflow by significantly reducing the compilation time of GDN prefill kernels on the Hopper architecture through a new split compilation approach. Concurrently, it addresses a documentation inaccuracy by correcting the specified state layout in the GDN prefill kernel's docstring, ensuring clarity and correctness for users.

Highlights

  • Compilation Time Reduction: Accelerated the compilation time for Hopper's GDN prefill kernels by implementing a split compilation strategy.
  • Docstring Correction: Fixed the docstring for the GDN prefill kernel to accurately reflect the final state layout as [N, H, V, K] instead of [N, H, K, V].

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 27, 2026

📝 Walkthrough

Walkthrough

This PR introduces template-driven separate compilation for GDN prefill kernels with SM90 support. It adds a Jinja template for kernel instantiation, generates 32 kernel variants via a new JIT module function, introduces extern template declarations to prevent implicit instantiation, and standardizes include paths across the codebase to use absolute project-scoped paths. A conditional C++ standard flag mechanism was also added to the core JIT spec generator.

Changes

Cohort / File(s) Summary
Template Instantiation & Extern Declarations
csrc/gdn_prefill_sm90_kernel_inst.jinja, csrc/flat_prefill_kernel_delta_rule_sm90_extern.inc
Added Jinja template for generating explicit kernel instantiations and header with extern template declarations for delta-rule prefill kernels to prevent implicit instantiation across 32 combinations (2 dtypes × 16 boolean parameters).
Kernel Source Updates
csrc/gdn_prefill_launcher.cu, csrc/prefill_kernel_delta_rule_sm90.cu
Updated include paths to use absolute project-scoped paths and added inclusion of extern template declarations header.
JIT Module Generator
flashinfer/jit/gdn.py
Introduced gen_gdn_prefill_sm90_module() to dynamically generate 32 kernel instantiations from Jinja template, manage generated files, and return multi-file JitSpec. Replaces hard-coded sources with template-driven approach.
JIT Core Infrastructure
flashinfer/jit/core.py
Renamed parameter extra_include_dirs to extra_include_paths in gen_jit_spec() and added conditional logic to apply default C++17 standard flags only when not already specified in extra compilation flags.
Include Path Standardization
include/flashinfer/flat/ampere/collective/flat_collective_*.hpp, include/flashinfer/flat/common.hpp, include/flashinfer/flat/hopper/collective/flat_collective_*.hpp, include/flashinfer/flat/hopper/kernel/flat_kernel_*.hpp, include/flashinfer/flat/prefill/prefill_kernel_delta_rule_sm90.cuh
Updated relative include paths to use absolute flashinfer-scoped paths (e.g., flat/...flashinfer/flat/...) across 9 header files for consistent module resolution.
Documentation
flashinfer/gdn_prefill.py, tests/gdn/test_prefill_delta_rule.py
Updated docstring to reflect final state layout as k-last instead of k-major, and clarified test comments for postprocessing interpretation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

v0.6.2, run-ci

Suggested reviewers

  • aleozlx
  • djmmoss
  • kahyunnam
  • cyx-6
  • bkryu
  • jiahanc

Poem

🐰 With whiskers twitching bright and keen,
Template kernels now convene,
Paths are lit by flashinfer's gleam,
Instantiations fulfill our dream!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately reflects the main changes: reducing Hopper's GDN prefill compilation time through refactoring and fixing a docstring issue.
Description check ✅ Passed The pull request description includes the required sections with clear objectives: accelerating Hopper's GDN prefill compilation through split compilation and fixing the docstring. Related issues are linked, and the pre-commit checks and tests sections are completed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively reduces the compilation time for the GDN prefill kernel by splitting the template instantiations into separate compilation units, which is a great improvement for developer productivity. The use of Jinja2 to generate the instantiation files is a clean solution. The docstring fix for the state layout is also a welcome correction. I've added one suggestion to improve the maintainability of the new extern template declaration file by using macros to reduce code duplication. Overall, this is a solid contribution.

Copy link
Collaborator

@guangyunh-nv guangyunh-nv left a comment

Choose a reason for hiding this comment

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

LGTM

@yzh119
Copy link
Collaborator Author

yzh119 commented Jan 27, 2026

/bot run

@flashinfer-bot
Copy link
Collaborator

GitLab MR !269 has been created, and the CI pipeline #42635345 is currently running. I'll report back once the pipeline job completes.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@flashinfer/jit/gdn.py`:
- Around line 81-86: Replace the hard-coded sm90a_nvcc_flags usage with a
CompilationContext-derived nvcc flags list: create a CompilationContext(), call
CompilationContext.get_nvcc_flags_list(supported_major_versions=[9]) to get
nvcc_flags, append ["-DFLAT_SM90A_ENABLED","-std=c++20"], and pass that as
extra_cuda_cflags to gen_jit_spec (keep
extra_include_paths=[jit_env.FLASHINFER_CSRC_DIR] unchanged); update references
to sm90a_nvcc_flags in this function to use the new nvcc_flags variable and
ensure CompressionContext is imported or available.
🧹 Nitpick comments (2)
flashinfer/jit/gdn.py (2)

33-38: Optional: Replace Unicode multiplication sign with ASCII x.

The linter flags × (U+00D7 MULTIPLICATION SIGN) as ambiguous. While readable, using ASCII x improves portability across different editors and terminal encodings.

Suggested fix
-    """Generate JIT module for GDN prefill kernel with separate compilation.
-
-    This generates 32 separate kernel instantiation files (2 dtypes × 16 boolean combinations)
+    """Generate JIT module for GDN prefill kernel with separate compilation.
+
+    This generates 32 separate kernel instantiation files (2 dtypes x 16 boolean combinations)

46-47: Optional: Specify explicit encoding when opening files.

Adding encoding="utf-8" ensures consistent behavior across platforms with different default encodings.

Suggested fix
-    with open(jit_env.FLASHINFER_CSRC_DIR / "gdn_prefill_sm90_kernel_inst.jinja") as f:
+    with open(jit_env.FLASHINFER_CSRC_DIR / "gdn_prefill_sm90_kernel_inst.jinja", encoding="utf-8") as f:
         kernel_inst_templ = jinja2.Template(f.read())

Comment on lines 81 to 86
return gen_jit_spec(
name="gdn_prefill_launcher",
sources=[
jit_env.FLASHINFER_CSRC_DIR / "gdn_prefill_launcher.cu",
jit_env.FLASHINFER_CSRC_DIR
/ "flat"
/ "prefill"
/ "prefill_kernel_delta_rule_sm90.cu",
],
uri,
source_paths,
extra_cuda_cflags=sm90a_nvcc_flags + ["-DFLAT_SM90A_ENABLED", "-std=c++20"],
extra_include_paths=[jit_env.FLASHINFER_CSRC_DIR],
)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check gen_jit_spec function signature and supported_major_versions usage
rg -n "supported_major_versions" --type py -B 2 -A 2

Repository: flashinfer-ai/flashinfer

Length of output: 7679


🏁 Script executed:

# Find gen_jit_spec definition
rg -n "def gen_jit_spec" --type py -A 10

Repository: flashinfer-ai/flashinfer

Length of output: 829


🏁 Script executed:

# Check for other JIT module generators to see usage patterns
fd "\.py$" flashinfer/jit/ | head -10 | xargs grep -l "gen_jit_spec" | xargs -I {} sh -c 'echo "=== {} ===" && grep -A 5 "gen_jit_spec(" {}'

Repository: flashinfer-ai/flashinfer

Length of output: 4164


🏁 Script executed:

cat -n flashinfer/jit/gdn.py

Repository: flashinfer-ai/flashinfer

Length of output: 3736


🏁 Script executed:

grep -n "sm90a_nvcc_flags" flashinfer/jit/core.py | head -20

Repository: flashinfer-ai/flashinfer

Length of output: 92


🏁 Script executed:

# Get context around the definition
rg -n "sm90a_nvcc_flags\s*=" flashinfer/jit/core.py -B 2 -A 2

Repository: flashinfer-ai/flashinfer

Length of output: 238


🏁 Script executed:

sed -n '120,135p' flashinfer/jit/core.py

Repository: flashinfer-ai/flashinfer

Length of output: 810


🏁 Script executed:

# Check how other SM90-specific generators handle the architecture restriction
rg -n "SM90\|sm_90" flashinfer/jit/ --type py -B 3 -A 3 | grep -E "(supported_major_versions|sm90)" | head -30

Repository: flashinfer-ai/flashinfer

Length of output: 50


🏁 Script executed:

head -30 flashinfer/jit/gdn.py

Repository: flashinfer-ai/flashinfer

Length of output: 839


🏁 Script executed:

# Check if CompilationContext is available and how it's used
rg -n "CompilationContext\|current_compilation_context" flashinfer/jit/ --type py | head -20

Repository: flashinfer-ai/flashinfer

Length of output: 50


🏁 Script executed:

# Check what common_nvcc_flags contains
sed -n '1,130p' flashinfer/jit/core.py | grep -A 10 "common_nvcc_flags"

Repository: flashinfer-ai/flashinfer

Length of output: 567


Refactor to use CompilationContext.get_nvcc_flags_list(supported_major_versions=[9]) pattern.

Per coding guidelines for JIT modules, supported_major_versions should be specified when creating nvcc flags. Other JIT modules (fused_moe.py, xqa.py, mamba, gemm, comm, attention) consistently use CompilationContext().get_nvcc_flags_list(supported_major_versions=[...]) before passing flags to gen_jit_spec(). This module should follow the same pattern instead of using the pre-defined sm90a_nvcc_flags constant:

compilation_context = CompilationContext()
nvcc_flags = compilation_context.get_nvcc_flags_list(supported_major_versions=[9])
nvcc_flags += ["-DFLAT_SM90A_ENABLED", "-std=c++20"]
return gen_jit_spec(
    uri,
    source_paths,
    extra_cuda_cflags=nvcc_flags,
    extra_include_paths=[jit_env.FLASHINFER_CSRC_DIR],
)
🧰 Tools
🪛 Ruff (0.14.14)

84-84: Consider iterable unpacking instead of concatenation

Replace with iterable unpacking

(RUF005)

🤖 Prompt for AI Agents
In `@flashinfer/jit/gdn.py` around lines 81 - 86, Replace the hard-coded
sm90a_nvcc_flags usage with a CompilationContext-derived nvcc flags list: create
a CompilationContext(), call
CompilationContext.get_nvcc_flags_list(supported_major_versions=[9]) to get
nvcc_flags, append ["-DFLAT_SM90A_ENABLED","-std=c++20"], and pass that as
extra_cuda_cflags to gen_jit_spec (keep
extra_include_paths=[jit_env.FLASHINFER_CSRC_DIR] unchanged); update references
to sm90a_nvcc_flags in this function to use the new nvcc_flags variable and
ensure CompressionContext is imported or available.

@flashinfer-bot
Copy link
Collaborator

[FAILED] Pipeline #42635345: 11/20 passed

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@csrc/flat/prefill/prefill_kernel_delta_rule_sm90_extern.inc`:
- Around line 1-64: This file uses cudaStream_t and fixed-width integer types in
the extern template declaration for launch_delta_rule_prefill_kernel_gbai but
doesn't include headers that define them; add explicit includes for the CUDA
stream type and integer types (e.g., include <cuda_runtime.h> or <cuda.h> for
cudaStream_t and <cstdint> for int32_t/int64_t) at the top of this .inc so the
extern template declaration (launch_delta_rule_prefill_kernel_gbai<...>) is
self-contained and no longer relies on transitive includes.

In `@flashinfer/aot.py`:
- Around line 446-447: The early return that unconditionally returns only
gen_gdn_prefill_sm90_module() must be gated behind an explicit flag so normal
AOT generation still runs; update the code around the temporary return in aot.py
to check a configuration or environment variable (e.g.,
FLASHINFER_ONLY_GDN_PREFILL or a passed-in option) and only return
[gen_gdn_prefill_sm90_module()] when that flag is truthy, otherwise fall through
to the existing full generation path that builds all AOT kernels; ensure the
flag defaults to false and document/rename any helper variable so callers can
opt into the temporary behavior without shipping a crippled build.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@flashinfer/jit/gdn.py`:
- Around line 32-48: The docstring/comment in this module uses the Unicode
multiplication sign "×" (e.g., "2 dtypes × 16 boolean combinations") which
triggers lint/confusable warnings; replace that character with the ASCII letter
"x" (so it reads "2 dtypes x 16 boolean combinations") to avoid Ruff warnings.
Update the text near the top of the file where uri = "gdn_prefill_sm90",
gen_directory is created and the comment about generating "32 separate instance
files" so the change is adjacent to the kernel instantiation template loading
(kernel_inst_templ) and the surrounding docstring/comment.

@yzh119 yzh119 force-pushed the improve-hopper-gdn-prefill branch from 1322d60 to e5236d7 Compare February 3, 2026 14:22
@yzh119
Copy link
Collaborator Author

yzh119 commented Feb 3, 2026

The PR should be ready now.

@yzh119 yzh119 merged commit 6ae5bfe into flashinfer-ai:main Feb 4, 2026
25 of 39 checks passed
raayandhar pushed a commit to raayandhar/flashinfer that referenced this pull request Feb 5, 2026
…ing. (flashinfer-ai#2422)

<!-- .github/pull_request_template.md -->

## 📌 Description

This PR implements these features:
1. accelerate hopper's gdn prefill compilation time by split compilation
2. fix the docstring of gdn prefill kernel, instead of [N, H, K, V], it
expects [N, H, V, K]

## 🔍 Related Issues

flashinfer-ai#2276 

## 🚀 Pull Request Checklist

Thank you for contributing to FlashInfer! Before we review your pull
request, please make sure the following items are complete.

### ✅ Pre-commit Checks

- [x] I have installed `pre-commit` by running `pip install pre-commit`
(or used your preferred method).
- [x] I have installed the hooks with `pre-commit install`.
- [x] I have run the hooks manually with `pre-commit run --all-files`
and fixed any reported issues.

> If you are unsure about how to set up `pre-commit`, see [the
pre-commit documentation](https://pre-commit.com/).

## 🧪 Tests

- [ ] Tests have been added or updated as needed.
- [ ] All tests are passing (`unittest`, etc.).

## Reviewer Notes

cc @guangyunh-nv 


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

* **New Features**
* Enhanced JIT module generation for GDN prefill kernels with
template-driven compilation and separate kernel instantiation.

* **Improvements**
* JIT specification now intelligently handles C++ standard flags,
applying defaults only when not already specified.

* **Documentation**
* Clarified final state memory layout description for GDN prefill
operations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
@ameynaik-hub ameynaik-hub mentioned this pull request Feb 5, 2026
5 tasks
@coderabbitai coderabbitai bot mentioned this pull request Mar 16, 2026
5 tasks
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.

3 participants