Files
sglang/python/sglang/kernels/jit/csrc/moe/align_single_token.cuh
T
+26 abddb1c7e9 [Kimi] Support kimi-k3 (#32541)
Co-authored-by: DarkSharpness <76582120+DarkSharpness@users.noreply.github.com>
Co-authored-by: Xiaoyu Zhang <1182563586@qq.com>
Co-authored-by: Mick <mickjagger19@icloud.com>
Co-authored-by: Yuhao Yang <47235274+yhyang201@users.noreply.github.com>
Co-authored-by: Cheng Wan <54331508+ch-wan@users.noreply.github.com>
Co-authored-by: Ke Bao <ispobaoke@gmail.com>
Co-authored-by: Baizhou Zhang <sobereddiezhang@gmail.com>
Co-authored-by: Chunan Zeng <zcnrex@gmail.com>
Co-authored-by: Khoa Pham <khoa.pham@radixark.ai>
Co-authored-by: Ziyi Xu <ziyi.xu@radixark.ai>
Co-authored-by: Zijie Xia <37504505+zijiexia@users.noreply.github.com>
Co-authored-by: Yuwei An <ayw.sirius19@gmail.com>
Co-authored-by: zhangxiaohao <1024393531@qq.com>
Co-authored-by: Yangmin Li <yangminl@nvidia.com>
Co-authored-by: Julien Lin <jullin@nvidia.com>
Co-authored-by: Hao Phan <htphan@nvidia.com>
Co-authored-by: Thomas Wang <1am9trash@gmail.com>
Co-authored-by: RolaoDenthu <xinyisong0111@gmail.com>
Co-authored-by: pigeonsoup <32922982+pigeonsoup@users.noreply.github.com>
Co-authored-by: HaiShaw <hixiao@gmail.com>
Co-authored-by: Xinyuan Tong <115166877+JustinTong0323@users.noreply.github.com>
Co-authored-by: Pranjal Shankhdhar <pranjal.ssh@gmail.com>
Co-authored-by: Lee Nau <lee.nau@gmail.com>
Co-authored-by: HMING <126185151+Hearum@users.noreply.github.com>
Co-authored-by: elvischenv <219235043+elvischenv@users.noreply.github.com>
Co-authored-by: Byron Hsu <byronhsu1230@gmail.com>
Co-authored-by: Byron Hsu <byron+per@periodiclabs.ai>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Thomas Wang <thomawan@amd.com>
Co-authored-by: Xinyi Song <86638975+RolaoDenthu@users.noreply.github.com>
Co-authored-by: Mohammad Miadh Angkad <176301910+mmangkad@users.noreply.github.com>
Co-authored-by: Cheng Wan <cheng.wan@radixark.ai>
Co-authored-by: BBuf <xiaoyu.zhang@radixark.ai>
Co-authored-by: Hanming Lu <hanminglu@meta.com>
Co-authored-by: Xinyi Song <xinyis10@illinois.edu>
2026-08-04 13:22:49 -07:00

108 lines
3.6 KiB
Plaintext

// Tiny moe_align_block_size for M == 1 decode: one warp replaces the
// moe_align_block_size + count_and_sort_expert_tokens kernel pair (~4.4us)
// with a single ~1.5us launch.
//
// For a single token the top-k expert ids are distinct, so the aligned
// layout is exactly: experts sorted ascending, one block per expert,
// slot i of block b = flat topk index for b's expert, remaining block
// slots padded with numel (= topk). num_tokens_post_padded = topk * block.
#include <sgl_kernel/tensor.h> // For TensorMatcher, SymbolicSize, SymbolicDevice
#include <sgl_kernel/utils.h> // For RuntimeCheck
#include <sgl_kernel/type.cuh> // For device::cast
#include <sgl_kernel/utils.cuh> // For LaunchKernel
#include <tvm/ffi/container/tensor.h>
#include <cstdint>
namespace {
struct AlignSingleTokenParams {
const int32_t* __restrict__ topk_ids; // [1, topk]
int32_t* __restrict__ sorted_ids; // [topk * block_size]
int32_t* __restrict__ expert_ids; // [topk]
int32_t* __restrict__ num_post; // [1]
uint32_t topk;
uint32_t block_size;
};
template <bool kUsePDL>
__global__ void align_single_token_kernel(const AlignSingleTokenParams __grid_constant__ params) {
using namespace device;
const uint32_t lane = threadIdx.x; // one warp
const uint32_t topk = params.topk;
const uint32_t bs = params.block_size;
PDLWaitPrimary<kUsePDL>();
int32_t my_id = (lane < topk) ? params.topk_ids[lane] : INT32_MAX;
// Rank of my expert id among the topk (ids are distinct for one token;
// tie-break on lane keeps this robust anyway).
uint32_t rank = 0;
for (uint32_t j = 0; j < topk; ++j) {
int32_t other = __shfl_sync(0xffffffff, my_id, j);
if (other < my_id || (other == my_id && j < lane)) {
rank++;
}
}
if (lane < topk) {
params.expert_ids[rank] = my_id;
// block `rank`: first slot is my flat index (token 0, slot `lane`),
// rest padded with numel (= topk).
params.sorted_ids[rank * bs] = static_cast<int32_t>(lane);
}
// Fill padding cooperatively: positions not equal to a block start.
for (uint32_t p = lane; p < topk * bs; p += 32) {
if (p % bs != 0) {
params.sorted_ids[p] = static_cast<int32_t>(topk);
}
}
if (lane == 0) {
params.num_post[0] = static_cast<int32_t>(topk * bs);
}
PDLTriggerSecondary<kUsePDL>();
}
template <bool kUsePDL>
struct AlignSingleTokenKernel {
static constexpr auto kernel = align_single_token_kernel<kUsePDL>;
static void
run(const tvm::ffi::TensorView topk_ids,
const tvm::ffi::TensorView sorted_ids,
const tvm::ffi::TensorView expert_ids,
const tvm::ffi::TensorView num_post,
int64_t block_size) {
using namespace host;
auto One_ = SymbolicSize{"one"};
auto K_ = SymbolicSize{"topk"};
auto device = SymbolicDevice{};
device.set_options<kDLCUDA>();
TensorMatcher({One_, K_}).with_dtype<int32_t>().with_device(device).verify(topk_ids);
const auto topk = static_cast<uint32_t>(K_.unwrap());
RuntimeCheck(One_.unwrap() == 1, "moe_align_single_token requires M == 1");
RuntimeCheck(topk <= 32, "moe_align_single_token requires topk <= 32");
const auto params = AlignSingleTokenParams{
.topk_ids = static_cast<const int32_t*>(topk_ids.data_ptr()),
.sorted_ids = static_cast<int32_t*>(sorted_ids.data_ptr()),
.expert_ids = static_cast<int32_t*>(expert_ids.data_ptr()),
.num_post = static_cast<int32_t*>(num_post.data_ptr()),
.topk = topk,
.block_size = static_cast<uint32_t>(block_size),
};
LaunchKernel(dim3(1), 32, device.unwrap()).enable_pdl(kUsePDL)(kernel, params);
}
};
} // namespace