Skip to content

[TRTLLM-14702][feat] Integrate Kimi K3 KDA decode kernel - #17054

Merged
litaotju merged 10 commits into
NVIDIA:mainfrom
pengbowang-nv:dev-integrate-kimi-k3-kda-decode-kernel
Aug 5, 2026
Merged

[TRTLLM-14702][feat] Integrate Kimi K3 KDA decode kernel#17054
litaotju merged 10 commits into
NVIDIA:mainfrom
pengbowang-nv:dev-integrate-kimi-k3-kda-decode-kernel

Conversation

@pengbowang-nv

@pengbowang-nv pengbowang-nv commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Dev Engineer Review

  • Added the fused KDA decode CUDA kernel and CMake integration.
  • Added compact-head and many-head dispatch paths.
  • Added support for indexed state storage, convolution-cache updates, output normalization, decay variants, and beta sigmoid gating.
  • Added int64_t address calculations and pre-SM80 guards for cp.async paths.
  • Registered the trtllm::kda_decode torch operation and its fake implementation.
  • Added input validation before output allocation.
  • Added flash-linear-attention==0.5.2 for reference validation.
  • No test-list configuration changes were identified.

QA Engineer Review

  • Added test_kda_decode_matches_fla(...) in tests/unittest/_torch/thop/parallel/test_kda_decode.py.
  • The test compares torch.ops.trtllm.kda_decode with fla.ops.kda.fused_recurrent_kda.
  • The test covers head layouts, indexed state updates, convolution-cache updates, slot gaps, output normalization, beta sigmoid behavior, and gate lower bounds.
  • The test verifies state and convolution-cache in-place update semantics.
  • No test-list or CI registration file changes were identified.
  • CI completed successfully with fail-fast disabled and automatic test retries.
  • Verdict: sufficient.

Description

Integrate kimi k3 kda decode kernel as a thop and added related unittest. Note that it requires FlashLinearAttention package as a dependency for accuracy validation, it has been added into requirements-dev.txt. The tests will be included in CI automatically.

Test Coverage

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.

GitHub Bot Help

To see a list of available CI bot commands, please comment /bot help.

litaotju and others added 3 commits July 29, 2026 09:49
Add a fused decode kernel for Kimi Delta Attention (KDA) recurrent-state
update at generation time, with a thop custom op (kda_decode) exposing it
to the PyTorch flow. Supports the K3 head geometry and per-request state
indexing into the mamba cache pool.

Co-authored-by: Pengbo Wang <sephw@nvidia.com>
Co-authored-by: Brian Nguyen (TensorRT) <brnguyen@nvidia.com>
Signed-off-by: Pengbo Wang <221450789+pengbowang-nv@users.noreply.github.com>
Signed-off-by: Pengbo Wang <221450789+pengbowang-nv@users.noreply.github.com>
Signed-off-by: Pengbo Wang <221450789+pengbowang-nv@users.noreply.github.com>
@pengbowang-nv
pengbowang-nv requested review from a team as code owners July 30, 2026 07:39
@pengbowang-nv pengbowang-nv changed the title [TRTLLM-14702][feat] Integrate kimi k3 kda decode kernel [TRTLLM-14702][feat] Integrate Kimi K3 KDA decode kernel Jul 30, 2026
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds a fused CUDA KDA single-token decode kernel with compact and many-head backends. Integrates it into the build and PyTorch custom-operator layers. Adds meta shape inference and parity tests against flash-linear-attention.

Changes

KDA decode

Layer / File(s) Summary
Kernel contract and build integration
cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.h, cpp/tensorrt_llm/kernels/*/CMakeLists.txt, cpp/tensorrt_llm/CMakeLists.txt
Defines KdaDecodeParams, dispatch-selection helpers, and invokeKdaDecode. Creates the CUDA object target, excludes its sources from aggregate kernel globbing, and links it into the shared library.
Fused CUDA implementation
cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu
Adds compact and many-head fused kernels with widened indexing, feature and layout dispatch, optional normalization, beta-sigmoid handling, convolution-cache updates, and state indexing.
PyTorch operator exposure
cpp/tensorrt_llm/thop/kdaDecodeOp.cpp, cpp/tensorrt_llm/thop/CMakeLists.txt, tensorrt_llm/_torch/custom_ops/cpp_custom_ops.py
Validates inputs, allocates outputs, dispatches the CUDA kernel, registers trtllm::kda_decode, and provides fake/meta shape inference.
Reference parity coverage
tests/unittest/_torch/thop/parallel/test_kda_decode.py, requirements-dev.txt
Adds a pinned reference dependency and parameterized tests for output parity, recurrent state updates, indexed storage, convolution-cache updates, normalization, and beta-sigmoid modes.

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

Possibly related PRs

  • NVIDIA/TensorRT-LLM#17077: Both PRs add KDA model support, but this PR adds the decode kernel and operator while that PR changes Kimi KDA warmup behavior and MNNVL cleanup.

Suggested labels: api-compatible

Suggested reviewers: qijune

Sequence Diagram(s)

sequenceDiagram
  participant Test
  participant KdaDecodeOperator
  participant invokeKdaDecode
  participant CUDADecodeKernel
  participant StateStorage
  Test->>KdaDecodeOperator: Submit tensors and decode options
  KdaDecodeOperator->>KdaDecodeOperator: Validate shapes, dtypes, strides, and alignment
  KdaDecodeOperator->>invokeKdaDecode: Pack KdaDecodeParams and launch
  invokeKdaDecode->>CUDADecodeKernel: Select compact or many-head backend
  CUDADecodeKernel->>StateStorage: Update recurrent and convolution state
  CUDADecodeKernel-->>KdaDecodeOperator: Produce decoded output
  KdaDecodeOperator-->>Test: Return output and mutated state
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the Kimi K3 KDA decode kernel integration as a new TensorRT-LLM feature.
Description check ✅ Passed The description explains the feature, tests, and dependency, but the Test Coverage section is empty and checklist items are not individually marked.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

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

🧹 Nitpick comments (6)
cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu (4)

1395-1399: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

cudaFuncSetAttribute runs on every launch.

This is a driver call on the per-token decode path; the attribute only needs to be set once per kernel instantiation. Hoist it behind a function-local static so repeated decodes skip it.

⚡ Set the attribute once per instantiation
+    auto* kernel = kda_decode_fusion_compact_heads_kernel<kApplyOnorm, true, kUseStaticDecodeLayout, kHeads, kHeads,
+        false, false, false, true, false, true, kUpdateConvState, kUseLowerBound, kApplyBetaSigmoid>;
+    static bool const smemConfigured = [&]
+    {
+        TLLM_CUDA_CHECK(
+            cudaFuncSetAttribute(kernel, cudaFuncAttributeMaxDynamicSharedMemorySize, kStageDynamicSmemBytes));
+        return true;
+    }();
+    (void) smemConfigured;
-    TLLM_CUDA_CHECK(cudaFuncSetAttribute(
-        kda_decode_fusion_compact_heads_kernel<kApplyOnorm, true, kUseStaticDecodeLayout, kHeads, kHeads, false, false,
-            false, true, false, true, kUpdateConvState, kUseLowerBound, kApplyBetaSigmoid>,
-        cudaFuncAttributeMaxDynamicSharedMemorySize, kStageDynamicSmemBytes));
🤖 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 `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu` around lines 1395 - 1399,
Update the setup around kStageDynamicSmemBytes and cudaFuncSetAttribute for
kda_decode_fusion_compact_heads_kernel to guard the attribute call with a
function-local static, ensuring it executes only once for each kernel
instantiation while preserving the existing CUDA error check.

122-136: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Dead code: cp_async_wait_oldest is never called; B is an unused kernel parameter.

cp_async_wait_oldest has no call site (both kernels inline their own wait_group_* selection), and int B at lines 374 and 911 is never read inside either kernel body — the batch size is only used for the grid dimensions in the launch wrappers. Dropping both shrinks the surface.

As per coding guidelines, "do not leave defined functions unused".

♻️ Remove the unused helper
-__device__ __forceinline__ void cp_async_wait_oldest(int outstanding_groups)
-{
-    if (outstanding_groups >= 3)
-    {
-        cp_async_wait_group_2();
-    }
-    else if (outstanding_groups == 2)
-    {
-        cp_async_wait_group_1();
-    }
-    else
-    {
-        cp_async_wait_group_0();
-    }
-}
-
🤖 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 `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu` around lines 122 - 136,
Remove the unused device helper cp_async_wait_oldest and delete the unused int B
parameters from both kernel definitions. Update all corresponding kernel launch
sites and argument lists to match, while preserving batch-size usage in the
launch wrapper grid dimensions.

Source: Coding guidelines


43-64: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Naming does not follow the repository C++ conventions.

The whole file uses snake_case for functions and locals (bf16_load, store_state_float4, cp_async_*, kda_decode_fusion_compact_heads_kernel, s_state, dot_hk_a, …). The C++ guidelines require lower camelCase for functions and local variables (k-prefixed camelCase constants are already correct here). Worth normalizing while the file is new, before it accumulates call sites.

As per coding guidelines, "Use lower-camel-case filenames, types in PascalCase, local variables/functions/namespaces in lower camelCase".

🤖 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 `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu` around lines 43 - 64,
Normalize function and local-variable naming throughout the new kdaDecode
implementation to lower camelCase, including bf16_load, bf16_store,
store_state_float4, and existing snake_case helpers, kernels, and locals such as
cp_async_*, kda_decode_fusion_compact_heads_kernel, s_state, and dot_hk_a.
Preserve behavior and keep k-prefixed constants in their existing camelCase
form.

Source: Coding guidelines


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

Optional: template fan-out cost, and case 2 is unreachable.

The 12 head values multiply with the layout/onorm/lower-bound/beta/conv-update booleans into ~384 instantiations of a large kernel, which shows up in build time and binary size; several of the boolean flags are currently pinned to one value at every call site and could be dropped. Also, invokeKdaDecode routes H == HV == 2 to the compact backend, so case 2 here can never be taken.

🤖 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 `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu` around lines 1625 - 1640,
The KDA decode dispatch in invokeKdaDecode includes unnecessary template fan-out
and an unreachable H == 2 specialization. Remove case 2 from
dispatch_kda_decode_layout, and reduce template boolean parameters that are
fixed at all call sites, including their corresponding dispatch arguments and
kernel signatures, while preserving the supported runtime combinations and
compact-backend routing.
tests/unittest/_torch/thop/parallel/test_kda_decode.py (1)

16-16: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Scale NUM_CACHE_SLOTS with head count to avoid multi-GB allocations.

Slot count is independent of num_heads, so the num_heads=96 indexed cases allocate 514 * 96 * 128 * 128 fp32 ≈ 3.2 GB of state, plus another ~3.2 GB for the state_before clone (line 367) — repeated across 3 batch sizes and 2 indexed configs. Indexing coverage does not need 514 slots for wide-head cases.

♻️ Cap the pool by total elements
-    num_cache_slots = NUM_CACHE_SLOTS if use_state_indices else batch_size
+    if use_state_indices:
+        # Keep the indexed pool a few slots wider than the batch without letting
+        # per-slot state (num_heads * 128 * 128 floats) blow up device memory.
+        num_cache_slots = min(NUM_CACHE_SLOTS, max(batch_size + 8, 8 * 1024 // num_heads))
+    else:
+        num_cache_slots = batch_size

Also applies to: 76-77, 99-103

🤖 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 `@tests/unittest/_torch/thop/parallel/test_kda_decode.py` at line 16, Scale
NUM_CACHE_SLOTS with num_heads in the test configurations, capping the cache
pool by a fixed total-element budget so wide-head cases use fewer slots while
preserving adequate coverage for smaller head counts. Apply the same calculation
consistently to the related NUM_CACHE_SLOTS definitions and keep the indexed
cases within a memory-safe allocation limit.
cpp/tensorrt_llm/thop/kdaDecodeOp.cpp (1)

39-43: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Take the tensor parameters by const&.

Both helpers copy 22 at::Tensor handles per call (44 atomic refcount ops per decode step) for read-only use.

♻️ Signature change
-void validate_kda_decode_fusion_inputs(at::Tensor x_q, at::Tensor x_k, at::Tensor x_v, at::Tensor w_q_t,
-    at::Tensor w_k_t, at::Tensor w_v_t, at::Tensor bias_q, at::Tensor bias_k, at::Tensor bias_v, at::Tensor cs_q,
-    at::Tensor cs_k, at::Tensor cs_v, at::Tensor a_log, at::Tensor g, at::Tensor dt_bias, at::Tensor beta,
-    at::Tensor onorm_g, at::Tensor onorm_weight, std::optional<at::Tensor> const& ssm_state_indices,
-    at::Tensor cu_seqlens, at::Tensor state, at::Tensor out, bool apply_onorm, bool update_conv_cache)
+void validate_kda_decode_fusion_inputs(at::Tensor const& x_q, at::Tensor const& x_k, at::Tensor const& x_v,
+    at::Tensor const& w_q_t, at::Tensor const& w_k_t, at::Tensor const& w_v_t, at::Tensor const& bias_q,
+    at::Tensor const& bias_k, at::Tensor const& bias_v, at::Tensor const& cs_q, at::Tensor const& cs_k,
+    at::Tensor const& cs_v, at::Tensor const& a_log, at::Tensor const& g, at::Tensor const& dt_bias,
+    at::Tensor const& beta, at::Tensor const& onorm_g, at::Tensor const& onorm_weight,
+    std::optional<at::Tensor> const& ssm_state_indices, at::Tensor const& cu_seqlens, at::Tensor const& state,
+    at::Tensor const& out, bool apply_onorm, bool update_conv_cache)

Apply the same to launch_selected_kernel.

Also applies to: 182-187

🤖 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 `@cpp/tensorrt_llm/thop/kdaDecodeOp.cpp` around lines 39 - 43, Update the
read-only tensor parameters in both validate_kda_decode_fusion_inputs and
launch_selected_kernel to accept const at::Tensor& instead of copying at::Tensor
handles; preserve the existing parameter order and behavior, including the
optional ssm_state_indices reference.
🤖 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 `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu`:
- Around line 654-701: Protect shared-memory state-stage reuse with block-wide
barriers: in cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu lines 654-701, add
__syncthreads() after consuming the current state_stage and before issuing the
chunk+2 prefetch; in lines 1288-1294, add __syncthreads() before the prefetch.
Keep the existing cp.async waits and __syncwarp() logic, ensuring both kernels
cannot overwrite a stage while another warp is still reading it.
- Around line 445-449: Widen convolution-state base offset calculations from int
to int64_t throughout the affected decode paths, including the kdaDecode offsets
near hk, hvv, and the many-heads equivalents. Ensure the full slot *
head-dimension * kConvStateWidth expression is evaluated in 64-bit arithmetic
before assignment, matching the existing recurrent-state offsets.
- Around line 91-95: Guard the cp_async_cg_16b device helper so the
cp.async.cg.shared.global assembly is only emitted when __CUDA_ARCH__ is at
least 800. Provide a compatible fallback for pre-SM80 architectures, or
otherwise ensure this target excludes those architectures while preserving the
existing 16-byte copy behavior.

In `@cpp/tensorrt_llm/thop/kdaDecodeOp.cpp`:
- Around line 202-204: In the KDA decode launch path, add a c10::cuda::CUDAGuard
using x_q.device() before obtaining the stream and calling invokeKdaDecode.
Ensure at::cuda::getCurrentCUDAStream() and the kernel launch execute on x_q’s
device.
- Around line 214-219: Move the rank validation for x_q and x_v ahead of the
x_q.size(1)/x_v.size(2) accesses and out allocation in the kda decode flow,
reusing validate_kda_decode_fusion_inputs or an equivalent rank-only pre-check.
Ensure rank-2/3 inputs produce the op’s “must be rank-4 tensors” validation
message before any dimension dereference, while retaining the existing full
validation before execution.

---

Nitpick comments:
In `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu`:
- Around line 1395-1399: Update the setup around kStageDynamicSmemBytes and
cudaFuncSetAttribute for kda_decode_fusion_compact_heads_kernel to guard the
attribute call with a function-local static, ensuring it executes only once for
each kernel instantiation while preserving the existing CUDA error check.
- Around line 122-136: Remove the unused device helper cp_async_wait_oldest and
delete the unused int B parameters from both kernel definitions. Update all
corresponding kernel launch sites and argument lists to match, while preserving
batch-size usage in the launch wrapper grid dimensions.
- Around line 43-64: Normalize function and local-variable naming throughout the
new kdaDecode implementation to lower camelCase, including bf16_load,
bf16_store, store_state_float4, and existing snake_case helpers, kernels, and
locals such as cp_async_*, kda_decode_fusion_compact_heads_kernel, s_state, and
dot_hk_a. Preserve behavior and keep k-prefixed constants in their existing
camelCase form.
- Around line 1625-1640: The KDA decode dispatch in invokeKdaDecode includes
unnecessary template fan-out and an unreachable H == 2 specialization. Remove
case 2 from dispatch_kda_decode_layout, and reduce template boolean parameters
that are fixed at all call sites, including their corresponding dispatch
arguments and kernel signatures, while preserving the supported runtime
combinations and compact-backend routing.

In `@cpp/tensorrt_llm/thop/kdaDecodeOp.cpp`:
- Around line 39-43: Update the read-only tensor parameters in both
validate_kda_decode_fusion_inputs and launch_selected_kernel to accept const
at::Tensor& instead of copying at::Tensor handles; preserve the existing
parameter order and behavior, including the optional ssm_state_indices
reference.

In `@tests/unittest/_torch/thop/parallel/test_kda_decode.py`:
- Line 16: Scale NUM_CACHE_SLOTS with num_heads in the test configurations,
capping the cache pool by a fixed total-element budget so wide-head cases use
fewer slots while preserving adequate coverage for smaller head counts. Apply
the same calculation consistently to the related NUM_CACHE_SLOTS definitions and
keep the indexed cases within a memory-safe allocation limit.
🪄 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: 86aaac3a-bf6f-4dad-94fc-45fcbeb7df1a

📥 Commits

Reviewing files that changed from the base of the PR and between da5b62f and dcfb5c9.

📒 Files selected for processing (10)
  • cpp/tensorrt_llm/CMakeLists.txt
  • cpp/tensorrt_llm/kernels/CMakeLists.txt
  • cpp/tensorrt_llm/kernels/kdaDecode/CMakeLists.txt
  • cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu
  • cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.h
  • cpp/tensorrt_llm/thop/CMakeLists.txt
  • cpp/tensorrt_llm/thop/kdaDecodeOp.cpp
  • requirements-dev.txt
  • tensorrt_llm/_torch/custom_ops/cpp_custom_ops.py
  • tests/unittest/_torch/thop/parallel/test_kda_decode.py

Comment thread cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu
Comment thread cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu Outdated
Comment thread cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu
Comment thread cpp/tensorrt_llm/thop/kdaDecodeOp.cpp
Comment thread cpp/tensorrt_llm/thop/kdaDecodeOp.cpp Outdated
Signed-off-by: Pengbo Wang <221450789+pengbowang-nv@users.noreply.github.com>
Signed-off-by: Pengbo Wang <221450789+pengbowang-nv@users.noreply.github.com>
Signed-off-by: Pengbo Wang <221450789+pengbowang-nv@users.noreply.github.com>
Signed-off-by: Pengbo Wang <221450789+pengbowang-nv@users.noreply.github.com>

@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 (2)
cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu (1)

1416-1422: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Annotate the positional boolean template packs. Eight/nine consecutive bare true/false template arguments select kernel behavior; inserting or reordering a flag in the kernel signature shifts them all with no compile error. Naming them makes the intent auditable.

As per coding guidelines: "document non-obvious call arguments with /*paramName=*/".

♻️ Example annotation
-    kda_decode_fusion_compact_heads_kernel<kApplyOnorm, true, kUseStaticDecodeLayout, kHeads, kHeads, false, false,
-        false, true, false, true, kUpdateConvState, kUseLowerBound, kApplyBetaSigmoid>
+    kda_decode_fusion_compact_heads_kernel<kApplyOnorm, /*kAccumulateOnormSumsq=*/true, kUseStaticDecodeLayout,
+        /*kFixedHeads=*/kHeads, /*kFixedValueHeads=*/kHeads, /*kUseHeadGrid=*/false, /*kUseCacheGlobalStore=*/false,
+        /*kComputeOutputBeforeStore=*/false, /*kPreloadOnormParams=*/true, /*kIssueThirdStatePrefetchEarly=*/false,
+        /*kUseActiveQkReduction=*/true, kUpdateConvState, kUseLowerBound, kApplyBetaSigmoid>

Also applies to: 1441-1443

🤖 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 `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu` around lines 1416 - 1422,
Annotate each positional boolean template argument in both the
cudaFuncSetAttribute and kernel launch instantiations of
kda_decode_fusion_compact_heads_kernel with /*paramName=*/ comments, using the
kernel template parameter names. Keep argument order and values unchanged while
making every boolean flag auditable.

Source: Coding guidelines

cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.h (1)

31-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Supported head counts have no single source of truth. The set {1,2,3,4,6,8,12,16,24,32,48,96} is now spelled out in the header predicate, in the CUDA dispatch switch, and again as supportedHeads in cpp/tensorrt_llm/thop/kdaDecodeOp.cpp (line 81). Adding a head count to one site without the others either aborts at the default branch or silently rejects a supported shape.

  • cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.h#L31-L35: make this the single source, e.g. a constexpr std::array of supported counts that isSupportedHeadCount scans.
  • cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu#L1544-L1557: generate the dispatch cases from that list (fold expression over the array) instead of restating the values, and reuse isSupportedHeadCount for the validation in cpp/tensorrt_llm/thop/kdaDecodeOp.cpp.
🤖 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 `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.h` around lines 31 - 35, Make
the supported head-count list in isSupportedHeadCount the single source of truth
by defining a shared constexpr array and scanning it for validation. In
cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu lines 1544-1557, generate
dispatch cases from that array via a fold expression instead of duplicating
values; update supportedHeads validation in
cpp/tensorrt_llm/thop/kdaDecodeOp.cpp line 81 to reuse isSupportedHeadCount.
🤖 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 `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu`:
- Around line 1416-1422: Annotate each positional boolean template argument in
both the cudaFuncSetAttribute and kernel launch instantiations of
kda_decode_fusion_compact_heads_kernel with /*paramName=*/ comments, using the
kernel template parameter names. Keep argument order and values unchanged while
making every boolean flag auditable.

In `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.h`:
- Around line 31-35: Make the supported head-count list in isSupportedHeadCount
the single source of truth by defining a shared constexpr array and scanning it
for validation. In cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu lines
1544-1557, generate dispatch cases from that array via a fold expression instead
of duplicating values; update supportedHeads validation in
cpp/tensorrt_llm/thop/kdaDecodeOp.cpp line 81 to reuse isSupportedHeadCount.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 1db00dcb-1c9c-4f6c-9594-f075ab1073e4

📥 Commits

Reviewing files that changed from the base of the PR and between dcfb5c9 and dbbaf62.

📒 Files selected for processing (3)
  • cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu
  • cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.h
  • cpp/tensorrt_llm/thop/kdaDecodeOp.cpp

@tburt-nv tburt-nv left a comment

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.

MIT licensed, no new transitive dependencies.
Confirmed tests/unittest/_torch/thop/parallel is scheduled in CI.

@pengbowang-nv

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #62932 [ run ] triggered by Bot. Commit: dbbaf62 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #62932 [ run ] completed with state SUCCESS. Commit: dbbaf62
/LLM/main/L0_MergeRequest_PR pipeline #51050 completed with status: 'SUCCESS'
Pipeline passed with automatic retried tests. Check the rerun report for details.

CI Report

Link to invocation

@mikeiovine
mikeiovine requested a review from Mgluhovskoi July 31, 2026 15:49
…-SM80 builds

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>

@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 (2)
cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu (2)

1557-1583: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Put each break inside a compound case.

The head dispatch uses one-line cases. The coding rule requires compound case braces with break inside the block.

Proposed structure
-case 1: dispatch_kda_decode_layout<kCompact, 1>(p); break;
+case 1:
+{
+    dispatch_kda_decode_layout<kCompact, 1>(p);
+    break;
+}

As per coding guidelines: “Structure switch statements clearly; ... place break inside compound case braces.”

🤖 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 `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu` around lines 1557 - 1583,
Update the switch cases in dispatch_kda_decode_heads so each supported
head-count case uses a compound brace block, with its dispatch_kda_decode_layout
call and break inside the block. Preserve the existing head mappings and default
error handling.

Source: Coding guidelines


43-100: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Align new declarations with the required C++ naming and const style.

bf16_load, bf16_store, cp_async_cg_16b, and related helpers use snake_case. smem_addr is unmodified but lacks const. Declarations such as const __nv_bfloat16 q_state and const Sum4 dot_hk violate east-const. Apply the required naming and declaration style consistently.

As per coding guidelines: “local variables/functions/namespaces in lower camel case”; “declare unmodified variables const”; and “use east-const style.”

Also applies to: 466-467, 481-482, 748-749

🤖 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 `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu` around lines 43 - 100,
Rename the affected helper functions and local variables to lower camel case,
including bf16_load, bf16_store, store_state_float4, sigmoid_fast, silu_fast,
softplus_fast, warp_reduce_sum, and cp_async_cg_16b. Apply the same naming style
to related declarations and uses, including q_state and smem_addr. Mark
unmodified locals such as smem_addr and the referenced reduction variables
const, using east-const syntax for declarations such as __nv_bfloat16 const
qState and Sum4 const dotHk.

Source: Coding guidelines

🤖 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 `@cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu`:
- Around line 1557-1583: Update the switch cases in dispatch_kda_decode_heads so
each supported head-count case uses a compound brace block, with its
dispatch_kda_decode_layout call and break inside the block. Preserve the
existing head mappings and default error handling.
- Around line 43-100: Rename the affected helper functions and local variables
to lower camel case, including bf16_load, bf16_store, store_state_float4,
sigmoid_fast, silu_fast, softplus_fast, warp_reduce_sum, and cp_async_cg_16b.
Apply the same naming style to related declarations and uses, including q_state
and smem_addr. Mark unmodified locals such as smem_addr and the referenced
reduction variables const, using east-const syntax for declarations such as
__nv_bfloat16 const qState and Sum4 const dotHk.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: cb1d1932-769b-4929-83d5-29fa8805f77f

📥 Commits

Reviewing files that changed from the base of the PR and between dbbaf62 and 5ba0c85.

📒 Files selected for processing (1)
  • cpp/tensorrt_llm/kernels/kdaDecode/kdaDecode.cu

Comment thread tests/unittest/_torch/thop/parallel/test_kda_decode.py Outdated
Comment thread cpp/tensorrt_llm/thop/kdaDecodeOp.cpp
Signed-off-by: Pengbo Wang <221450789+pengbowang-nv@users.noreply.github.com>
Signed-off-by: Pengbo Wang <221450789+pengbowang-nv@users.noreply.github.com>
@pengbowang-nv

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
cpp/tensorrt_llm/thop/kdaDecodeOp.cpp (3)

136-138: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Enforce the cu_seqlens value contract.

KdaDecodeParams requires cuSeqlens to equal arange(batchSize + 1), but this wrapper checks only dtype, layout, rank, and length. Invalid values reach invokeKdaDecode unchanged and can produce incorrect per-batch offsets or state updates.

Construct the required sequence internally, or validate its contents before launch. Add a negative test for non-arange values.

🤖 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 `@cpp/tensorrt_llm/thop/kdaDecodeOp.cpp` around lines 136 - 138, Update the
cu_seqlens validation in the KdaDecode wrapper to enforce that its values equal
arange(B + 1), not only its CUDA dtype, contiguity, rank, and length; validate
the contents before invoking invokeKdaDecode or construct the required sequence
internally, and add a negative test covering non-arange values.

39-64: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Enforce one CUDA device before launching KDA decode. Compare every tensor, including ssm_state_indices when present, with x_q.device() before output allocation and dispatch. Use a stream for that device instead of the implicit current-device stream.

🤖 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 `@cpp/tensorrt_llm/thop/kdaDecodeOp.cpp` around lines 39 - 64, Update
validate_kda_decode_fusion_inputs and the KDA decode dispatch to require every
tensor, including present ssm_state_indices, to be on x_q.device() before
allocating outputs or launching work. Select the CUDA stream associated with
x_q.device() rather than relying on the implicit current-device stream, and
preserve the existing dtype validation.

128-135: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Validate state-slot indices before launching the kernel.

Negative or out-of-range ssm_state_indices values cause invalid global-memory accesses to state and, when update_conv_cache is enabled, the convolution-cache pools. Add bounds validation against state.size(0) and negative tests. Reject duplicate indices only if the state-update contract requires unique slots.

🤖 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 `@cpp/tensorrt_llm/thop/kdaDecodeOp.cpp` around lines 128 - 135, Extend
validation in the ssm_state_indices checks before the kernel launch to verify
every index is nonnegative and less than state.size(0), rejecting invalid values
before any state or convolution-cache access. Preserve the existing CUDA, int32,
contiguous, one-dimensional, and [B] checks, and only add duplicate-index
rejection if the state-update contract requires unique slots.
🧹 Nitpick comments (3)
cpp/tensorrt_llm/thop/kdaDecodeOp.cpp (3)

123-127: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Name the alignment constants.

Replace the literal 4 and 16 values with named constants such as kFloat4Elements and kStateAlignmentBytes.

As per coding guidelines: avoid magic literals except 0, nullptr, true, and false; initialize named constants instead, using k-prefixed camelCase names.

🤖 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 `@cpp/tensorrt_llm/thop/kdaDecodeOp.cpp` around lines 123 - 127, In the
validation checks near the state alignment logic, replace the literal 4 and 16
values with locally defined k-prefixed camelCase constants such as
kFloat4Elements and kStateAlignmentBytes. Use those constants consistently for
the stride divisibility and data-pointer alignment checks while preserving the
existing error messages and behavior.

Source: Coding guidelines


189-196: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Annotate the KdaDecodeParams aggregate initialization.

This initializer passes many pointers, strides, dimensions, and flags positionally. A future field insertion or reordering can compile while binding the wrong value.

Add /*xQ=*/, /*logA=*/, /*stateSlotStride=*/, and equivalent comments for every field, as required by the C++ guidelines.

As per coding guidelines: document non-obvious call arguments with /*paramName=*/.

🤖 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 `@cpp/tensorrt_llm/thop/kdaDecodeOp.cpp` around lines 189 - 196, Annotate every
argument in the KdaDecodeParams aggregate initialization with inline
/*paramName=*/ comments, including pointers, dimensions, strides, and flags.
Update only the initializer for
tensorrt_llm::kernels::kdaDecode::KdaDecodeParams, using the exact corresponding
field names such as xQ, logA, and stateSlotStride, and ensure all positional
values are documented.

Source: Coding guidelines


39-43: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use lower-camel-case names for the new C++ identifiers.

Rename validate_kda_decode_fusion_inputs, launch_selected_kernel, kda_decode_fusion_forward, and their snake_case parameters to lower camel case, such as validateKdaDecodeFusionInputs, launchSelectedKernel, kdaDecodeFusionForward, xQ, and ssmStateIndices.

Keep the external PyTorch schema name unchanged if it is part of the public API.

As per coding guidelines: use lower-camel-case filenames, types in PascalCase, and local variables/functions/namespaces in lower camel case.

Also applies to: 178-183, 203-208

🤖 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 `@cpp/tensorrt_llm/thop/kdaDecodeOp.cpp` around lines 39 - 43, Rename the new
functions validate_kda_decode_fusion_inputs, launch_selected_kernel, and
kda_decode_fusion_forward to validateKdaDecodeFusionInputs,
launchSelectedKernel, and kdaDecodeFusionForward, and convert their snake_case
parameters and local identifiers to lower camel case such as xQ and
ssmStateIndices. Apply the same naming updates throughout their declarations,
definitions, and call sites while preserving any external PyTorch schema name
unchanged.

Source: Coding guidelines

🤖 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.

Outside diff comments:
In `@cpp/tensorrt_llm/thop/kdaDecodeOp.cpp`:
- Around line 136-138: Update the cu_seqlens validation in the KdaDecode wrapper
to enforce that its values equal arange(B + 1), not only its CUDA dtype,
contiguity, rank, and length; validate the contents before invoking
invokeKdaDecode or construct the required sequence internally, and add a
negative test covering non-arange values.
- Around line 39-64: Update validate_kda_decode_fusion_inputs and the KDA decode
dispatch to require every tensor, including present ssm_state_indices, to be on
x_q.device() before allocating outputs or launching work. Select the CUDA stream
associated with x_q.device() rather than relying on the implicit current-device
stream, and preserve the existing dtype validation.
- Around line 128-135: Extend validation in the ssm_state_indices checks before
the kernel launch to verify every index is nonnegative and less than
state.size(0), rejecting invalid values before any state or convolution-cache
access. Preserve the existing CUDA, int32, contiguous, one-dimensional, and [B]
checks, and only add duplicate-index rejection if the state-update contract
requires unique slots.

---

Nitpick comments:
In `@cpp/tensorrt_llm/thop/kdaDecodeOp.cpp`:
- Around line 123-127: In the validation checks near the state alignment logic,
replace the literal 4 and 16 values with locally defined k-prefixed camelCase
constants such as kFloat4Elements and kStateAlignmentBytes. Use those constants
consistently for the stride divisibility and data-pointer alignment checks while
preserving the existing error messages and behavior.
- Around line 189-196: Annotate every argument in the KdaDecodeParams aggregate
initialization with inline /*paramName=*/ comments, including pointers,
dimensions, strides, and flags. Update only the initializer for
tensorrt_llm::kernels::kdaDecode::KdaDecodeParams, using the exact corresponding
field names such as xQ, logA, and stateSlotStride, and ensure all positional
values are documented.
- Around line 39-43: Rename the new functions validate_kda_decode_fusion_inputs,
launch_selected_kernel, and kda_decode_fusion_forward to
validateKdaDecodeFusionInputs, launchSelectedKernel, and kdaDecodeFusionForward,
and convert their snake_case parameters and local identifiers to lower camel
case such as xQ and ssmStateIndices. Apply the same naming updates throughout
their declarations, definitions, and call sites while preserving any external
PyTorch schema name unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 1b8c607b-41be-4bf0-9de8-b2a9193682ee

📥 Commits

Reviewing files that changed from the base of the PR and between 5ba0c85 and 5ab47f8.

📒 Files selected for processing (2)
  • cpp/tensorrt_llm/thop/kdaDecodeOp.cpp
  • tests/unittest/_torch/thop/parallel/test_kda_decode.py
💤 Files with no reviewable changes (1)
  • tests/unittest/_torch/thop/parallel/test_kda_decode.py

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63679 [ run ] triggered by Bot. Commit: 5ab47f8 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63679 [ run ] completed with state SUCCESS. Commit: 5ab47f8
/LLM/main/L0_MergeRequest_PR pipeline #51630 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@Mgluhovskoi Mgluhovskoi left a comment

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.

LGTM. All concerns were addressed.

@brnguyen2

Copy link
Copy Markdown
Collaborator

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63850 [ run ] triggered by Bot. Commit: 5ab47f8 Link to invocation

@juney-nvidia
juney-nvidia requested a review from kris1025 August 4, 2026 22:55
@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63850 [ run ] completed with state SUCCESS. Commit: 5ab47f8
/LLM/main/L0_MergeRequest_PR pipeline #51791 completed with status: 'SUCCESS'
Pipeline passed with automatic retried tests. Check the rerun report for details.

CI Report

Link to invocation

@litaotju
litaotju merged commit 50edd73 into NVIDIA:main Aug 5, 2026
7 checks passed
brnguyen2 added a commit to brnguyen2/TensorRT-LLM that referenced this pull request Aug 5, 2026
Squash of the KimiLinear model integration on top of the kernel PRs
(NVIDIA#17190, NVIDIA#17054, NVIDIA#17266, NVIDIA#17225):

- KimiLinear model (modeling_kimi_k3) and KimiLinearConfig registration
- Kimi K3 support modules: KDA mixer, K3 MoE, K3 MLA, fused
  attention-residual wrapper
- K3 MLA module refactored onto the general MLA path (TRTLLM-14811)
- fused_moe: SiTu activation and communication_method support
- SiTu in the ActType_TrtllmGen python enum (python mirror of the C++
  enum from the MoE kernel drop)
- kda_decode: accept an optional out tensor (to be folded into NVIDIA#17054)
- KDA kernel/runtime unit tests

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
brnguyen2 added a commit to brnguyen2/TensorRT-LLM that referenced this pull request Aug 5, 2026
Squash of the KimiLinear model integration on top of the kernel PRs
(NVIDIA#17190, NVIDIA#17054, NVIDIA#17266, NVIDIA#17225):

- KimiLinear model (modeling_kimi_k3) and KimiLinearConfig registration
- Kimi K3 support modules: KDA mixer, K3 MoE, K3 MLA, fused
  attention-residual wrapper
- K3 MLA module refactored onto the general MLA path (TRTLLM-14811)
- fused_moe: SiTu activation and communication_method support
- SiTu in the ActType_TrtllmGen python enum (python mirror of the C++
  enum from the MoE kernel drop)
- kda_decode: accept an optional out tensor (to be folded into NVIDIA#17054)
- KDA kernel/runtime unit tests

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
brnguyen2 added a commit to brnguyen2/TensorRT-LLM that referenced this pull request Aug 5, 2026
Squash of the KimiLinear model integration on top of the kernel PRs
(NVIDIA#17190, NVIDIA#17054, NVIDIA#17266, NVIDIA#17225):

- KimiLinear model (modeling_kimi_k3) and KimiLinearConfig registration
- Kimi K3 support modules: KDA mixer, K3 MoE, K3 MLA, fused
  attention-residual wrapper
- K3 MLA module refactored onto the general MLA path (TRTLLM-14811)
- fused_moe: SiTu activation and communication_method support
- SiTu in the ActType_TrtllmGen python enum (python mirror of the C++
  enum from the MoE kernel drop)
- kda_decode: accept an optional out tensor (to be folded into NVIDIA#17054)
- KDA kernel/runtime unit tests

Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
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.

8 participants