-
Notifications
You must be signed in to change notification settings - Fork 1.2k
perf: optimize MXFP4xBF16 & INT4xFP8 CUTLASS MoE backend for SM90 #3084
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 23 commits
4c2372b
ac0e82e
931b87a
9c4d204
31f80e2
1687648
e43b3e6
be83fd0
f1ae825
50de6f8
9c251a4
7446660
f57bf38
1461814
4ed56ff
c4002f1
31ff00e
e355831
2fac475
4223e45
eabea6d
0e4ba76
dcafd6a
efd9aff
21b5d44
d3a6190
fc3bb6d
77746b8
cb90611
335345b
17a9c54
7c2ab34
1a5b242
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| /* | ||
| * Copyright (c) 2020-2025, NVIDIA CORPORATION. All rights reserved. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| #include "moe_gemm_mixed_utils.h" | ||
|
|
||
| namespace tensorrt_llm { | ||
| namespace kernels { | ||
| namespace cutlass_kernels { | ||
|
|
||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| __global__ void interleave_fp4_weights_for_Hopper_mixed_gemm_kernel(uint8_t* fp4_weight, | ||
|
samuellees marked this conversation as resolved.
Outdated
|
||
| uint8_t* fp4_weight_interleaved, | ||
| int const rows, | ||
| int const cols) { | ||
| for (int block_id = blockIdx.x; block_id < rows / 2; block_id += gridDim.x) { | ||
| for (int partition_id = threadIdx.y; partition_id < cols / 64; partition_id += blockDim.y) { | ||
|
Comment on lines
+28
to
+29
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fail fast on unsupported matrix shapes. These kernels only work when Also applies to: 41-56, 66-67, 79-88, 95-108 🤖 Prompt for AI Agents |
||
| int lane_id = threadIdx.x; | ||
| int row_id = block_id / 8 * 16 + block_id % 8; | ||
|
|
||
| int mma_id = lane_id / 8; | ||
| int dst_row_id = row_id + (mma_id % 2) * 8; | ||
|
|
||
| int interleaved_lane_id = lane_id / 16 * 16 + (lane_id % 4) * 4 + (lane_id % 8) / 4 * 2; | ||
|
|
||
| int col_id = partition_id * 32 + lane_id; | ||
| int dst_col_id = partition_id * 32 + interleaved_lane_id; | ||
|
|
||
| int index_a = row_id * cols / 2 + col_id; | ||
| int index_b = (row_id + 8) * cols / 2 + col_id; | ||
|
|
||
| uint8_t fp4x2_a = fp4_weight[index_a]; | ||
| uint8_t fp4x2_b = fp4_weight[index_b]; | ||
|
|
||
| uint8_t fp4_temp_a = (fp4x2_a & 0xF0U) >> 4; | ||
| uint8_t fp4_temp_b = (fp4x2_b & 0x0FU) << 4; | ||
|
|
||
| fp4x2_a = (fp4x2_a & 0x0FU) | fp4_temp_b; | ||
| fp4x2_b = (fp4x2_b & 0xF0U) | fp4_temp_a; | ||
|
|
||
| int dst_id = dst_row_id * cols / 2 + dst_col_id; | ||
|
|
||
| fp4_weight_interleaved[dst_id] = fp4x2_a; | ||
| fp4_weight_interleaved[dst_id + 1] = fp4x2_b; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| __global__ void interleave_int4_weights_for_Hopper_mixed_gemm_kernel( | ||
| uint8_t* int4_weight, uint8_t* int4_weight_interleaved, int const rows, int const cols) { | ||
| uint16_t* uint16_ptr = reinterpret_cast<uint16_t*>(int4_weight); | ||
| uint16_t* uint16_interleaved_ptr = reinterpret_cast<uint16_t*>(int4_weight_interleaved); | ||
|
|
||
| for (int block_id = blockIdx.x; block_id < rows / 2; block_id += gridDim.x) { | ||
| for (int partition_id = threadIdx.y; partition_id < cols / 64; partition_id += blockDim.y) { | ||
| int lane_id = threadIdx.x; | ||
|
|
||
| int row_id = block_id / 8 * 16 + block_id % 8; | ||
| int dst_row_id = row_id + (lane_id % 8) / 4 * 8; | ||
|
|
||
| int mma_id = lane_id / 8; | ||
| int interleaved_lane_id = mma_id * 8 + lane_id % 4 * 2; | ||
|
|
||
| int col_id = partition_id * 16 + lane_id; | ||
| int dst_col_id = partition_id * 16 + interleaved_lane_id; | ||
|
|
||
| int src_id_a = row_id * cols / 4 + col_id; | ||
| int src_id_b = (row_id + 8) * cols / 4 + col_id; | ||
|
|
||
| uint16_t int4x2_a = uint16_ptr[src_id_a]; | ||
| uint16_t int4x2_b = uint16_ptr[src_id_b]; | ||
|
|
||
| int dst_id = dst_row_id * cols / 4 + dst_col_id; | ||
|
|
||
| uint16_interleaved_ptr[dst_id] = int4x2_a; | ||
| uint16_interleaved_ptr[dst_id + 1] = int4x2_b; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| void interleave_fp4_weights_for_Hopper_mixed_gemm(uint8_t* fp4_weight, | ||
| uint8_t* fp4_weight_interleaved, int const rows, | ||
| int const cols, cudaStream_t stream) { | ||
| dim3 block(32, 32); | ||
| interleave_fp4_weights_for_Hopper_mixed_gemm_kernel<<<1024, block, 0, stream>>>( | ||
| fp4_weight, fp4_weight_interleaved, rows, cols); | ||
| } | ||
|
|
||
| void interleave_int4_weights_for_Hopper_mixed_gemm(uint8_t* int4_weight, | ||
| uint8_t* int4_weight_interleaved, int const rows, | ||
| int const cols, cudaStream_t stream) { | ||
| dim3 block(16, 32); | ||
| interleave_int4_weights_for_Hopper_mixed_gemm_kernel<<<1024, block, 0, stream>>>( | ||
| int4_weight, int4_weight_interleaved, rows, cols); | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| } // namespace cutlass_kernels | ||
| } // namespace kernels | ||
| } // namespace tensorrt_llm | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| /* | ||
| * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <cuda_runtime.h> | ||
|
|
||
| #include <cstdint> | ||
|
|
||
| namespace tensorrt_llm { | ||
| namespace kernels { | ||
| namespace cutlass_kernels { | ||
|
|
||
| void interleave_fp4_weights_for_Hopper_mixed_gemm(uint8_t* weight, uint8_t* weight_interleaved, | ||
| int rows, int cols, cudaStream_t stream = 0); | ||
|
|
||
| void interleave_int4_weights_for_Hopper_mixed_gemm(uint8_t* weight, uint8_t* weight_interleaved, | ||
| int rows, int cols, cudaStream_t stream = 0); | ||
|
|
||
| } // namespace cutlass_kernels | ||
| } // namespace kernels | ||
| } // namespace tensorrt_llm |
Uh oh!
There was an error while loading. Please reload this page.