Skip to content

[#17027][fix] Realign misaligned int32 index slices in FlashInfer GDN decode - #17028

Open
Navjot10 wants to merge 4 commits into
NVIDIA:mainfrom
Navjot10:fix/gdn-decode-state-indices-alignment
Open

[#17027][fix] Realign misaligned int32 index slices in FlashInfer GDN decode#17028
Navjot10 wants to merge 4 commits into
NVIDIA:mainfrom
Navjot10:fix/gdn-decode-state-indices-alignment

Conversation

@Navjot10

@Navjot10 Navjot10 commented Jul 29, 2026

Copy link
Copy Markdown

Description

Fixes #17027.

_flashinfer_gdn_decode (tensorrt_llm/_torch/modules/fla/fused_sigmoid_gating_recurrent.py) passes initial_state_indices to the FlashInfer CuTe-DSL kernel through .int(), which is a no-op on an already-int32 tensor: it returns the same storage and keeps the data pointer of a sliced view (e.g. the decode half state_indices[num_prefills:] of a mixed batch, offset 4 * num_prefills bytes). The kernel asserts 32-byte data alignment on every tensor argument, so such a view is rejected at runtime:

ValueError: Misaligned Tensor data on argument #10 ... expected data alignment=32 bytes

_can_use_flashinfer_gdn_decode does not check alignment, so this is a hard error with no Triton fallback. The hazard is dormant for the current in-tree callers (they pass zero-offset views) but fires for any caller handing this public dispatch API an offset slice at an element offset not divisible by 8.

The fix mirrors the two guards that already exist for this exact bug class:

The clone only happens when the pointer is actually misaligned, so the common aligned case stays zero-copy.

Test Coverage

  • New: tests/unittest/_torch/modules/mamba/test_flashinfer_gdn_decode.py::test_fi_decode_misaligned_index_slice — feeds an int32 index slice with a 4-byte storage offset to _flashinfer_gdn_decode and checks output and final state pool against an aligned-clone baseline. Without this fix, the call raises the misaligned-tensor ValueError. Mirrors the existing test_fi_mtp_verify_misaligned_index_slice. Requires SM90/SM100/SM103 + a FlashInfer build with gdn_kernels.gdn_decode_bf16_state (skips otherwise), so it needs GPU CI.
  • Existing: tests/unittest/_torch/modules/mamba/test_flashinfer_gdn_verify.py (verify-path twin) is unaffected.

PR Checklist

Please review the following before submitting your PR:

  • PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.

  • PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.

  • Test cases are provided for new code paths (see test instructions)

  • If PR introduces API changes, an appropriate PR label is added - either api-compatible or api-breaking. For api-breaking, include BREAKING in the PR title.

  • Any new dependencies have been scanned for license and vulnerabilities

  • CODEOWNERS updated if ownership changes

  • Documentation updated as needed

  • Update tava architecture diagram if there is a significant design change in PR.

  • The reviewers assigned automatically/manually are appropriate for the PR.

  • Please check this after reviewing the above items as appropriate for this PR.

Dev Engineer Review

  • _flashinfer_gdn_decode converts initial_state_indices to int32.
  • The code clones the tensor only when its pointer is not 32-byte aligned.
  • Aligned tensors retain zero-copy behavior.
  • The change matches existing alignment handling.
  • No configuration or test-list files changed.

QA Engineer Review

  • Added test_fi_decode_misaligned_index_slice().
  • The test compares decode outputs and final state pools with an aligned-clone baseline.
  • The test is not listed in tests/integration/test_lists/ for CI or manual QA.
  • Verdict: needs follow-up.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

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: 3f6d4d73-dbda-4756-8782-4ac480b1b5d8

📥 Commits

Reviewing files that changed from the base of the PR and between f7b7f22 and 889e1d5.

📒 Files selected for processing (2)
  • tensorrt_llm/_torch/modules/fla/fused_sigmoid_gating_recurrent.py
  • tests/unittest/_torch/modules/mamba/test_flashinfer_gdn_decode.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tensorrt_llm/_torch/modules/fla/fused_sigmoid_gating_recurrent.py
  • tests/unittest/_torch/modules/mamba/test_flashinfer_gdn_decode.py

Included review availability: Your plan provides up to 12 included reviews per hour; 10 remain after this review.


Walkthrough

The FlashInfer GDN decode path now realigns misaligned int32 state index tensors before kernel dispatch. A CUDA regression test compares outputs and state updates for misaligned and cloned index inputs.

Changes

GDN decode alignment

Layer / File(s) Summary
Decode index realignment
tensorrt_llm/_torch/modules/fla/fused_sigmoid_gating_recurrent.py
initial_state_indices is converted to int32, cloned when its data pointer is not 32-byte aligned, and passed to the FlashInfer kernel after processing.
Misaligned slice regression coverage
tests/unittest/_torch/modules/mamba/test_flashinfer_gdn_decode.py
Adds CUDA and FlashInfer capability gating, constructs a misaligned index slice, and compares decode outputs and state pools against a cloned-index invocation.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 889e1

The change realigns misaligned decode index slices before FlashInfer dispatch and adds focused regression coverage. No concrete current-head merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. 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 uses the required [#17027][fix] format and clearly describes the primary change: realigning misaligned int32 index slices in FlashInfer GDN decode.
Description check ✅ Passed The description explains the issue, root cause, solution, affected API, alignment behavior, regression test, and GPU requirements. It includes the required sections and completed checklist.
Linked Issues check ✅ Passed The changes satisfy #17027 by conditionally cloning misaligned int32 initial_state_indices tensors before the FlashInfer GDN decode kernel call and adding regression coverage for offset slices.
Out of Scope Changes check ✅ Passed The changes are limited to the requested alignment fix and its targeted CUDA regression test. No unrelated code or behavior changes are present.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

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

🤖 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/unittest/_torch/modules/mamba/test_flashinfer_gdn_decode.py`:
- Around line 28-36: Rename the module-level pytest marker skip_unsupported to
an UPPER_SNAKE_CASE constant name, then update its use as the decorator on
test_fi_decode_misaligned_index_slice. Add an explicit None return annotation to
that test function, preserving its existing behavior.
- Around line 21-24: Update the FlashInfer availability check around
gated_delta_rule to catch only the expected missing-module import exception,
allowing initialization and runtime errors to propagate and fail the regression
test instead of being reported as skips.
🪄 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: 3c1489e2-a13d-4dc4-be04-b0ae5c02cacd

📥 Commits

Reviewing files that changed from the base of the PR and between c45ad83 and 585aba3.

📒 Files selected for processing (2)
  • tensorrt_llm/_torch/modules/fla/fused_sigmoid_gating_recurrent.py
  • tests/unittest/_torch/modules/mamba/test_flashinfer_gdn_decode.py

Comment thread tests/unittest/_torch/modules/mamba/test_flashinfer_gdn_decode.py
Comment thread tests/unittest/_torch/modules/mamba/test_flashinfer_gdn_decode.py Outdated
@Navjot10
Navjot10 force-pushed the fix/gdn-decode-state-indices-alignment branch from 87589ed to 5a060cc Compare July 30, 2026 22:58

@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/unittest/_torch/modules/mamba/test_flashinfer_gdn_decode.py`:
- Line 22: Wrap the gated_delta_rule import in the FlashInfer probe test across
multiple lines to satisfy the line-length limit, while preserving the F401
suppression for the intentionally unused import.
🪄 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: a1e5ab65-89cc-410f-90c3-85ed743212ff

📥 Commits

Reviewing files that changed from the base of the PR and between 87589ed and 5a060cc.

📒 Files selected for processing (2)
  • tensorrt_llm/_torch/modules/fla/fused_sigmoid_gating_recurrent.py
  • tests/unittest/_torch/modules/mamba/test_flashinfer_gdn_decode.py

Comment thread tests/unittest/_torch/modules/mamba/test_flashinfer_gdn_decode.py Outdated
@caitlinw-nvidia

Copy link
Copy Markdown

LGTM

@schetlur-nv

Copy link
Copy Markdown
Collaborator

/bot run


pool_ref = state_pool.clone()
out_ref = _flashinfer_gdn_decode(
A_log=A_log,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nit: you could define commonkwargs that then get passed **kwargs to both _flashinfer_gdn_decode calls along with each call's specific args (seems like only initial_state_source and initial_state_indices).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done in 9e04434 — the shared arguments now live in a single common_kwargs dict passed as **common_kwargs to both _flashinfer_gdn_decode calls; each call keeps only its own initial_state_source (per-call state-pool copy) and initial_state_indices (misaligned view vs aligned clone).

@Navjot10
Navjot10 requested a review from a team as a code owner September 4, 2026 16:42
@Navjot10
Navjot10 force-pushed the fix/gdn-decode-state-indices-alignment branch from 9e04434 to 889e1d5 Compare September 4, 2026 16:49
@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

…er GDN decode

_flashinfer_gdn_decode passed initial_state_indices to the FlashInfer
CuTe-DSL kernel through .int(), which is a no-op on an already-int32
tensor and keeps the pointer of a sliced view (e.g. the decode half
state_indices[num_prefills:] of a mixed batch, offset 4*num_prefills
bytes). The kernel asserts 32-byte data alignment on every tensor
argument and rejects such views at runtime with
'Misaligned Tensor data on argument ... expected data alignment=32
bytes'; the dispatch gate does not check alignment, so there is no
Triton fallback.

Clone the index tensor into fresh, allocator-aligned storage when (and
only when) it is misaligned, exactly like _flashinfer_gdn_verify
(NVIDIA#15975) and the a/b activation guards in this same function (NVIDIA#15194).
Adds a CUDA regression test mirroring
test_fi_mtp_verify_misaligned_index_slice for the decode entry point.

Signed-off-by: Navjot10 <83138142+Navjot10@users.noreply.github.com>
…annotation

- Catch (ImportError, RuntimeError) instead of Exception in the FI
  availability probe. This mirrors the guard on the same import in
  fused_sigmoid_gating_recurrent.py and FlashInfer's own
  gdn_kernels/__init__.py: a missing build raises ImportError and a
  CuTe/CUTLASS mismatch raises RuntimeError at module import; in both
  cases production falls back to Triton, so the FI path is unavailable
  and the test should skip rather than error. Anything else still
  propagates as a failure.
- Rename skip_unsupported -> SKIP_UNSUPPORTED (module-level constant).
- Annotate the test with -> None.

Signed-off-by: Navjot10 <83138142+Navjot10@users.noreply.github.com>
…e kwargs

- The FI probe import line exceeded reviewers' preferred length, but the
  parenthesized wrap suggested in review cannot survive this repo's ruff
  config (line-length=100 with isort split-on-trailing-comma=false
  collapses any import that fits on one line). Import the module with an
  alias and probe the symbol via hasattr instead: the line drops to 79
  chars, the '# noqa: F401' suppression becomes unnecessary, and the
  skip/fail semantics are unchanged (a broken submodule import still
  raises ImportError/RuntimeError inside the try, and a build without
  gated_delta_rule still reports unavailable).
- Factor the arguments shared by both _flashinfer_gdn_decode calls into
  common_kwargs; each call now passes only its own state pool copy and
  index tensor (misaligned view vs aligned clone).

Signed-off-by: Navjot10 <83138142+Navjot10@users.noreply.github.com>
Assisted-By: devx/848d9b7d-732b-4283-aa05-274b4dc8e390
@Navjot10
Navjot10 force-pushed the fix/gdn-decode-state-indices-alignment branch from 889e1d5 to 5afcb16 Compare September 4, 2026 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants