Skip to content

feat: enable trigger_completion_at_end=False for MNNVL backend - #3323

Open
b8zhong wants to merge 2 commits into
flashinfer-ai:mainfrom
bzhng-development:brayden/trigger-completion-mnnvl
Open

b8zhong wants to merge 2 commits into
flashinfer-ai:mainfrom
bzhng-development:brayden/trigger-completion-mnnvl

Conversation

@b8zhong

@b8zhong b8zhong commented May 14, 2026

Copy link
Copy Markdown
Contributor

To achieve parity with TRTLLM

SGLang before:
Screenshot 2026-05-13 at 10 03 46 PM
After:
Screenshot 2026-05-13 at 10 04 12 PM

TRTLLM:
Screenshot 2026-05-13 at 10 06 24 PM

# B300
mpirun --allow-run-as-root -np 8 pytest tests/comm/test_allreduce_unified_api.py -s
============================================================ 152 passed, 132 warnings in 357.65s (0:05:57) =============================================================


=========================================================================== warnings summary ===========================================================================
flashinfer/gemm/kernels/grouped_gemm_masked_blackwell.py:2060
  /sgl-workspace/flashinfer/flashinfer/gemm/kernels/grouped_gemm_masked_blackwell.py:2060: DeprecationWarning: tcgen05.OperandMajorMode is deprecated, use cute.nvgpu.OperandMajorMode instead
    a_major_mode: tcgen05.OperandMajorMode,

flashinfer/gemm/kernels/grouped_gemm_masked_blackwell.py:2062
  /sgl-workspace/flashinfer/flashinfer/gemm/kernels/grouped_gemm_masked_blackwell.py:2062: DeprecationWarning: tcgen05.OperandMajorMode is deprecated, use cute.nvgpu.OperandMajorMode instead
    b_major_mode: tcgen05.OperandMajorMode,

flashinfer/gdn_kernels/blackwell/gated_delta_net_chunked.py:99
flashinfer/gdn_kernels/blackwell/gated_delta_net_chunked.py:99
  /sgl-workspace/flashinfer/flashinfer/gdn_kernels/blackwell/gated_delta_net_chunked.py:99: DeprecationWarning: tcgen05.OperandMajorMode is deprecated, use cute.nvgpu.OperandMajorMode instead
    from cutlass.cute.nvgpu.tcgen05 import OperandMajorMode

tests/comm/test_allreduce_unified_api.py: 152 warnings
  /usr/local/lib/python3.12/dist-packages/torch/distributed/c10d_logger.py:83: UserWarning: barrier(): using the device under current context. You can specify `device_id` in `init_process_group` to mute this warning.
    return func(*args, **kwargs)

tests/comm/test_allreduce_unified_api.py: 48 warnings
  /sgl-workspace/flashinfer/flashinfer/comm/allreduce.py:126: DeprecationWarning: use the unified API allreduce.py instead. It will internally call trtllm_create_ipc_workspace_for_all_reduce_fusion.
    self._internal_workspace = trtllm_create_ipc_workspace_for_all_reduce_fusion(

tests/comm/test_allreduce_unified_api.py: 80 warnings
  /sgl-workspace/flashinfer/flashinfer/comm/allreduce.py:825: DeprecationWarning: use the unified API allreduce.py instead. It will internally call trtllm_allreduce_fusion.
    trtllm_allreduce_fusion(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
============================================================ 152 passed, 284 warnings in 357.34s (0:05:57) =============================================================

Summary by CodeRabbit

  • New Features
    • Added trigger_completion_at_end parameter to MNNVL and unified all-reduce/fused all-reduce APIs to control when launch completion is signaled (defaults to True), with PDL/S M90+ behavior respected.
    • Propagated the flag through the CUDA fusion path and updated Python custom-op wrappers accordingly, including RMSNorm-fusion-specific completion timing.
  • Bug Fixes
    • Updated deprecated legacy entry points to preserve prior early-trigger behavior.
  • Tests
    • Extended unified all-reduce tests for the new parameter and added an MNNVL-specific early-trigger coverage test.

@coderabbitai

coderabbitai Bot commented May 14, 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: d8a3b111-aefe-4362-b89c-da446a2264d2

📥 Commits

Reviewing files that changed from the base of the PR and between e2aac3d and a5957c4.

📒 Files selected for processing (3)
  • csrc/trtllm_mnnvl_allreduce.cu
  • flashinfer/comm/allreduce.py
  • flashinfer/comm/trtllm_mnnvl_ar.py
💤 Files with no reviewable changes (3)
  • flashinfer/comm/allreduce.py
  • csrc/trtllm_mnnvl_allreduce.cu
  • flashinfer/comm/trtllm_mnnvl_ar.py

📝 Walkthrough

Walkthrough

This PR adds trigger_completion_at_end to MNNVL allreduce fusion APIs, forwards it through the unified dispatcher and CUDA launcher, and updates kernel templates to trigger programmatic launch completion either early or late based on the flag. Tests cover the new MNNVL early-trigger path.

Changes

MNNVL Trigger Completion End-to-End

Layer / File(s) Summary
Python Public API Extension
flashinfer/comm/trtllm_mnnvl_ar.py
Public MNNVL entry points gain trigger_completion_at_end parameters and docstrings, and deprecated entry points force early-trigger behavior by passing False to the custom op.
Unified Comm API Forwarding
flashinfer/comm/allreduce.py
allreduce_fusion documents completion timing and forwards trigger_completion_at_end into MNNVL backend call sites for all-reduce and fused RMSNorm variants, including quantized paths.
CUDA Launcher Parameter Threading
csrc/trtllm_mnnvl_allreduce.cu
trtllm_mnnvl_allreduce_fusion extends its launcher signature with trigger_completion_at_end and stores it in AllReduceFusionParams before kernel dispatch.
Kernel Template Conditional Triggers
include/flashinfer/comm/trtllm_mnnvl_allreduce.cuh
AllReduceFusionParams, the one-shot and two-shot kernels, and RMSNorm fusion dispatch all gain trigger-completion wiring, with early or late cudaTriggerProgrammaticLaunchCompletion() placement selected from params.triggerCompletionAtEnd and fusion state.
Test Parametrization for Trigger Paths
tests/comm/test_allreduce_unified_api.py
Test helpers accept trigger_completion_at_end, pass it through fused and unfused execution paths, and add a MNNVL-only test case for the early-trigger configuration.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • aleozlx
  • yzh119
  • bkryu
  • nv-yunzheq

Poem

A bunny tuned the launch just so,
Early or late, the kernels go.
One hop, two hop, PDL delight,
Completion lands at day or night. 🐰

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is off-template and omits the required Description, Related Issues, checklist, Tests, and Reviewer Notes sections. Rewrite the PR description using the repository template, including a brief change summary, related issues, checklist items, tests, and reviewer notes.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: enabling early trigger behavior for the MNNVL backend.
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.

@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 the trigger_completion_at_end parameter to the MNNVL all-reduce implementation, allowing control over Programmatic Dependent Launch (PDL) trigger timing for improved kernel overlap. The changes span the C++ dispatch logic, CUDA kernels (one-shot, two-shot, and RMSNorm), and the Python API. Feedback highlights a critical issue in the rmsNormLamport kernel where cudaGridDependencySynchronize() is placed at the end instead of the beginning, which breaks dependency tracking. Additionally, there is a recommendation to ensure that out-of-bounds thread returns do not inadvertently skip PDL triggers in the one-shot kernel.

Comment on lines 978 to 982
#if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ >= 900))
cudaTriggerProgrammaticLaunchCompletion();
if constexpr (!TriggerCompletionAtEnd) {
cudaTriggerProgrammaticLaunchCompletion();
}
#endif

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.

high

For PDL-aware kernels, cudaGridDependencySynchronize() should be called at the very beginning of the kernel to establish the dependency on the previous kernel's trigger. In rmsNormLamport, this call is currently placed at the end of the kernel (line 1101), which is incorrect as it allows the kernel to execute its work before the dependency is satisfied.

Please move the cudaGridDependencySynchronize() call to the start of the kernel, before the early trigger check.

#if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ >= 900))
  cudaGridDependencySynchronize();
  if constexpr (!TriggerCompletionAtEnd) {
    cudaTriggerProgrammaticLaunchCompletion();
  }
#endif

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is the intention of this PR

Comment on lines +698 to +709
// Invariant: every block in the cluster must contain at least one in-bounds
// thread, otherwise an entirely-OOB block would skip the end PDL trigger and
// delay launch dependents until the block "completes normally". The
// adjustGridConfig logic sets blockSize = ceil_div(threadsNeeded,
// clusterSize) (or larger) so OOB count < clusterSize <= blockSize; this
// check guards against future tuning regressions.
int const threadsNeeded = ceil_div(tokenDim, eltsPerThread);
FLASHINFER_CHECK(threadsNeeded > (clusterSize - 1) * blockSize,
"[MNNVL AllReduceOneShot] grid config has at least one fully-OOB "
"block (threadsNeeded=%d, blockSize=%d, clusterSize=%d); PDL end "
"trigger would not be issued by that block",
threadsNeeded, blockSize, clusterSize);

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 check is excellent for ensuring that the adjustGridConfig logic doesn't produce entirely out-of-bounds blocks that would skip the PDL trigger. However, for the TriggerCompletionAtEnd == true case, individual threads that return early due to the OOB check at line 555 will still skip the trigger at line 667. While the cluster-wide check ensures at least one thread per block reaches the trigger, it is generally safer to ensure all threads in a block reach the trigger or that the trigger is called by a specific thread (e.g., threadIdx.x == 0) that is guaranteed to be in-bounds by this check.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The grid-wide invariant we already added (no entirely-OOB block) is the actual correct condition

@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: 1

🤖 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 `@tests/comm/test_allreduce_unified_api.py`:
- Around line 313-344: The new test test_mnnvl_allreduce_trigger_completion
invokes the MNNVL trigger-path but isn't gated for unsupported GPU SM
capability; update the test to check the appropriate flashinfer.utils capability
helper (e.g., is_sm90a_supported() or the correct SM check for MNNVL) at the
start of test_mnnvl_allreduce_trigger_completion and skip the test when the
capability is absent (use pytest.skip or pytest.mark.skipif) before calling
run_allreduce_test so CI won't run unsupported paths.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: fd6daa1f-3684-4fd0-85b0-59f0335ce3fd

📥 Commits

Reviewing files that changed from the base of the PR and between ed0f5f8 and e2aac3d.

📒 Files selected for processing (5)
  • csrc/trtllm_mnnvl_allreduce.cu
  • flashinfer/comm/allreduce.py
  • flashinfer/comm/trtllm_mnnvl_ar.py
  • include/flashinfer/comm/trtllm_mnnvl_allreduce.cuh
  • tests/comm/test_allreduce_unified_api.py

Comment thread tests/comm/test_allreduce_unified_api.py
@nvpohanh

Copy link
Copy Markdown
Contributor

@aleozlx Could you assign someone to review this? Thanks!

…etion-mnnvl

# Conflicts:
#	csrc/trtllm_mnnvl_allreduce.cu
#	flashinfer/comm/allreduce.py
#	flashinfer/comm/trtllm_mnnvl_ar.py
#	include/flashinfer/comm/trtllm_mnnvl_allreduce.cuh

This branch has not been deployed

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants