+26









Liangsheng Yin
DarkSharpness
Xiaoyu Zhang
Mick
Yuhao Yang
Cheng Wan
Ke Bao
Baizhou Zhang
Chunan Zeng
Khoa Pham
Ziyi Xu
Zijie Xia
Yuwei An
zhangxiaohao
Yangmin Li
Julien Lin
Hao Phan
Thomas Wang
RolaoDenthu
pigeonsoup
HaiShaw
Xinyuan Tong
Pranjal Shankhdhar
Lee Nau
HMING
elvischenv
Byron Hsu
Byron Hsu
Claude Opus 5
Thomas Wang
Xinyi Song
Mohammad Miadh Angkad
Cheng Wan
BBuf
Hanming Lu
Xinyi Song
abddb1c7e9
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>
108 lines
3.6 KiB
Plaintext
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
|