Skip to content

Dml dev - #3347

Closed
MenglingD wants to merge 7 commits into
flashinfer-ai:mainfrom
windog-labs:dml-dev
Closed

Dml dev#3347
MenglingD wants to merge 7 commits into
flashinfer-ai:mainfrom
windog-labs:dml-dev

Conversation

@MenglingD

@MenglingD MenglingD commented May 18, 2026

Copy link
Copy Markdown

📌 Description

🔍 Related Issues

🚀 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

Summary by CodeRabbit

  • Chores

    • Build system streamlined with profile-based configuration for different deployment scenarios.
    • Removed Boost dependency from floating-point conversion utilities.
    • Enhanced automatic CUDA architecture detection in build scripts.
  • Performance

    • Optimized kernel threadblock sizing for attention operations.
    • Improved CUDA graph compatibility for variable-length sequence processing.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR introduces AOT build profile support enabling selection between full and lightweight ("edge_fm") kernel generation, adds CUDA graph compatibility via dynamic KV lengths, extends GQA group size support to 6 and 7, and updates build scripts to auto-detect profiles and CUDA architectures.

Changes

AOT Build Profile System and CUDA Graph Enhancements

Layer / File(s) Summary
Build Profile Configuration Foundations
flashinfer/aot.py
Introduces normalize_build_profile, get_config_for_profile, and resolve_build_config to support selecting between "full" and "edge_fm" profiles with user-provided overrides and normalization/aliasing.
Build System Integration - Profile Threading
flashinfer/aot.py
Threads profile parameter through compile_and_package_modules and register_default_modules, adds CLI --profile argument, updates main() to resolve configuration via profiles, and removes legacy get_default_config().
Build Script Profile and Architecture Selection
flashinfer-jit-cache/build_backend.py, scripts/build_flashinfer_jit_cache_whl.sh, scripts/task_test_jit_cache_package_build_import.sh, scripts/verify_all_modules_compiled.py
Updates build and test scripts to default FLASHINFER_AOT_BUILD_PROFILE based on CI environment detection, replaces CUDA architecture list derivation with runtime device capability querying, and wires profile parameter through _compile_jit_cache.
CUDA Graph KV Length Support
include/flashinfer/attention/default_decode_params.cuh
Extends SingleDecodeParams with d_kv_len device pointer and max_kv_len host member; updates constructors and get_kv_len to conditionally use device-provided KV length for CUDA graph execution.
Decode Kernel Updates for CUDA Graph and GQA Extensions
include/flashinfer/attention/decode.cuh, include/flashinfer/utils.cuh
Implements early-exit for out-of-bounds KV chunks, adds thread count heuristics for GQA group sizes 6 and 7, updates grid sizing to use max_kv_len, and extends DISPATCH_GQA_GROUP_SIZE macro.
Variant and FP16 Helper Updates
include/flashinfer/attention/variant_helper.cuh, include/flashinfer/fp16.h
Adds m_to_float conversion helpers for safe inf-comparison in attention output transform, introduces cuda_fp16.h include, and replaces Boost fabs dependency with local constexpr_fabs in FP16 conversion logic.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • flashinfer-ai/flashinfer#3275: Both PRs modify CUDA architecture list detection in build scripts, including host/aarch64 branching logic for runtime device capability querying.
  • flashinfer-ai/flashinfer#3205: Both PRs update the same JIT/AOT build and test scripts (scripts/build_flashinfer_jit_cache_whl.sh and scripts/task_test_jit_cache_package_build_import.sh) to wire environment-driven build parameters including CUDA architecture selection.

Suggested labels

run-ci

Suggested reviewers

  • yongwww
  • yzh119
  • sricketts
  • cyx-6
  • samuellees
  • kahyunnam
  • bkryu
  • aleozlx
  • jimmyzho

Poem

A rabbit hops with glee, through profiles grand,
edge_fm fast or full in every land,
CUDA graphs dance with lengths that dynamically grow,
GQA's 6 and 7 join the decoder show! 🐰✨

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'Dml dev' is vague and does not clearly convey the actual changes made in the pull request, which involve CUDA graph optimizations, GQA tuning, and build improvements. Replace with a specific title that reflects the main changes, such as 'Add CUDA graph support and GQA decode tuning with build profile optimization' or similar.
Description check ⚠️ Warning The description contains only the template placeholders without any concrete details about the changes, related issues, or implementation notes. Fill in the Description section with a summary of the key changes, link any related issues, and provide reviewer notes highlighting areas of focus.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces AOT build profiles to customize kernel compilation and adds CUDA graph support for single decode kernels by allowing dynamic sequence lengths via device pointers. It also optimizes GQA performance for specific group sizes on sm80 and removes a Boost dependency in the FP16 headers. Review feedback suggests centralizing the CI-detection logic for build profiles to reduce duplication, optimizing configuration management by using shallow copies instead of deep copies, and improving code maintainability by replacing magic numbers with named constants.

Comment thread flashinfer/aot.py
Comment on lines +139 to +149
- activation / norm / rope / page / sampling / topk helpers

It intentionally excludes heavyweight optional families such as XQA, MoE,
communication kernels, FP8 attention variants, and large head-dim matrices
that are not used in edge-fm today.
"""
return {
"fa2_head_dim": [(64, 64), (128, 128)],
"fa3_head_dim": [(64, 64), (128, 128)],
"f16_dtype": [torch.float16, torch.bfloat16],
"f8_dtype": [],

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.

medium

The logic for determining the default build profile (checking for CI environments to decide between "full" and "edge_fm") is currently duplicated in build_backend.py and several shell scripts. It would be more maintainable to centralize this logic here within normalize_build_profile.

Suggested change
- activation / norm / rope / page / sampling / topk helpers
It intentionally excludes heavyweight optional families such as XQA, MoE,
communication kernels, FP8 attention variants, and large head-dim matrices
that are not used in edge-fm today.
"""
return {
"fa2_head_dim": [(64, 64), (128, 128)],
"fa3_head_dim": [(64, 64), (128, 128)],
"f16_dtype": [torch.float16, torch.bfloat16],
"f8_dtype": [],
def normalize_build_profile(profile: Optional[str]) -> str:
profile_name = (profile or os.environ.get("FLASHINFER_AOT_BUILD_PROFILE"))
if profile_name is None:
if any(
os.environ.get(var)
for var in ("CI", "GITHUB_ACTIONS", "JENKINS_HOME", "JENKINS_URL")
):
profile_name = "full"
else:
profile_name = "edge_fm"
profile_name = profile_name.strip().lower().replace("-", "_")
aliases = {
"default": "full",
"minimal": "edge_fm",
"fast": "edge_fm",
"dev": "edge_fm",
"edgefm": "edge_fm",
}
return aliases.get(profile_name, profile_name)

Comment thread flashinfer/aot.py
"default": "full",
"minimal": "edge_fm",
"fast": "edge_fm",
"dev": "edge_fm",

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.

medium

copy.deepcopy is likely unnecessary here because get_config_for_profile returns a fresh dictionary created by get_default_config or get_edge_fm_fast_config. A simple assignment or .copy() would be more efficient.

Suggested change
"dev": "edge_fm",
final_config = get_config_for_profile(normalized).copy()

Comment on lines +87 to 96
if any(
os.environ.get(var)
for var in ("CI", "GITHUB_ACTIONS", "JENKINS_HOME", "JENKINS_URL")
):
build_profile = "full"
else:
build_profile = "edge_fm"
os.environ["FLASHINFER_AOT_BUILD_PROFILE"] = build_profile

# Set up build directory

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.

medium

This logic for determining the default build profile is duplicated. If normalize_build_profile in flashinfer/aot.py is updated to handle CI-aware defaults, this block can be simplified to rely on that centralized logic.

    build_profile = aot.normalize_build_profile(None)
    os.environ["FLASHINFER_AOT_BUILD_PROFILE"] = build_profile

o_ptr[i] = DTypeO(0);
}
if (lse != nullptr && tx == 0) {
lse[kv_chunk_idx * num_qo_heads + qo_head_idx] = -5e4;

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.

medium

The magic number -5e4 is used here as a very small LSE value to ensure this chunk has no contribution during state merging. It would be clearer to use a named constant or at least add a comment explaining why this specific value was chosen (e.g., to avoid NaN issues with -inf during reduction in MergeStates).

@MenglingD MenglingD closed this May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants