@@ -496,17 +496,26 @@ __global__ void situ_and_mul_kernel(
496496 }
497497}
498498
499+ constexpr int kMaxMaskedTokenBlocks = 32 ;
500+
499501template <bool BATCHED_EXPERTS >
500502__device__ __forceinline__ bool get_masked_row_range (
501503 const int * __restrict__ valid_token_counts, const int max_num_tokens,
502- int64_t & first_row, int64_t & end_row) {
504+ int64_t & first_row, int64_t & end_row, int64_t & row_stride ) {
503505 if constexpr (BATCHED_EXPERTS ) {
504- // [E, T, *]: each block handles one expert's valid token prefix.
506+ // [E, T, *]: z lanes grid-stride over one expert's valid token prefix.
505507 const int expert = blockIdx .y ;
506508 const int num_tokens =
507509 max (0 , min (valid_token_counts[expert], max_num_tokens));
508- first_row = static_cast <int64_t >(expert) * max_num_tokens;
509- end_row = first_row + num_tokens;
510+ const int token_block = blockIdx .z ;
511+ if (token_block >= num_tokens) {
512+ return false ;
513+ }
514+ const int64_t expert_first_row =
515+ static_cast <int64_t >(expert) * max_num_tokens;
516+ first_row = expert_first_row + token_block;
517+ end_row = expert_first_row + num_tokens;
518+ row_stride = gridDim .z ;
510519 } else {
511520 // [T, *]: each block handles one row, masked by a single valid prefix.
512521 const int row = blockIdx .x ;
@@ -516,6 +525,7 @@ __device__ __forceinline__ bool get_masked_row_range(
516525 }
517526 first_row = row;
518527 end_row = row + 1 ;
528+ row_stride = 1 ;
519529 }
520530 return first_row < end_row;
521531}
@@ -535,17 +545,18 @@ __global__ void masked_situ_and_mul_kernel(
535545 scalar_t * __restrict__ out, const scalar_t * __restrict__ input,
536546 const int * __restrict__ valid_token_counts, const int max_num_tokens,
537547 const int d, const float beta, const float linear_beta) {
538- int64_t first_row, end_row;
548+ int64_t first_row, end_row, row_stride ;
539549 const int idx = get_masked_feature_index<BATCHED_EXPERTS >();
540- if (idx >= d || !get_masked_row_range<BATCHED_EXPERTS >(
541- valid_token_counts, max_num_tokens, first_row, end_row)) {
550+ if (idx >= d ||
551+ !get_masked_row_range<BATCHED_EXPERTS >(valid_token_counts, max_num_tokens,
552+ first_row, end_row, row_stride)) {
542553 return ;
543554 }
544555
545556 const bool clamp_up = linear_beta > 0 .0f ;
546557 const float inv_beta = 1 .0f / beta;
547558 const float inv_linear_beta = clamp_up ? 1 .0f / linear_beta : 0 .0f ;
548- for (int64_t row = first_row; row < end_row; ++ row) {
559+ for (int64_t row = first_row; row < end_row; row += row_stride ) {
549560 const scalar_t * gate_ptr = input + row * 2 * d;
550561 const scalar_t * up_ptr = gate_ptr + d;
551562 scalar_t * out_ptr = out + row * d;
@@ -564,14 +575,15 @@ __global__ void masked_act_and_mul_kernel(
564575 scalar_t * __restrict__ out, const scalar_t * __restrict__ input,
565576 const int * __restrict__ valid_token_counts, const int max_num_tokens,
566577 const int d, const float limit, const float alpha, const float beta) {
567- int64_t first_row, end_row;
578+ int64_t first_row, end_row, row_stride ;
568579 const int idx = get_masked_feature_index<BATCHED_EXPERTS >();
569- if (idx >= d || !get_masked_row_range<BATCHED_EXPERTS >(
570- valid_token_counts, max_num_tokens, first_row, end_row)) {
580+ if (idx >= d ||
581+ !get_masked_row_range<BATCHED_EXPERTS >(valid_token_counts, max_num_tokens,
582+ first_row, end_row, row_stride)) {
571583 return ;
572584 }
573585
574- for (int64_t row = first_row; row < end_row; ++ row) {
586+ for (int64_t row = first_row; row < end_row; row += row_stride ) {
575587 const scalar_t * x_ptr = input + row * 2 * d;
576588 const scalar_t * y_ptr = x_ptr + d;
577589 scalar_t * out_ptr = out + row * d;
@@ -587,14 +599,15 @@ __global__ void masked_swigluoai_and_mul_kernel(
587599 scalar_t * __restrict__ out, const scalar_t * __restrict__ input,
588600 const int * __restrict__ valid_token_counts, const int max_num_tokens,
589601 const int d, const float alpha, const float limit) {
590- int64_t first_row, end_row;
602+ int64_t first_row, end_row, row_stride ;
591603 const int idx = get_masked_feature_index<BATCHED_EXPERTS >();
592- if (idx >= d || !get_masked_row_range<BATCHED_EXPERTS >(
593- valid_token_counts, max_num_tokens, first_row, end_row)) {
604+ if (idx >= d ||
605+ !get_masked_row_range<BATCHED_EXPERTS >(valid_token_counts, max_num_tokens,
606+ first_row, end_row, row_stride)) {
594607 return ;
595608 }
596609
597- for (int64_t row = first_row; row < end_row; ++ row) {
610+ for (int64_t row = first_row; row < end_row; row += row_stride ) {
598611 const scalar_t * in_ptr = input + row * 2 * d;
599612 scalar_t * out_ptr = out + row * d;
600613 out_ptr[idx] =
@@ -607,14 +620,15 @@ __global__ void masked_swiglustep_and_mul_kernel(
607620 scalar_t * __restrict__ out, const scalar_t * __restrict__ input,
608621 const int * __restrict__ valid_token_counts, const int max_num_tokens,
609622 const int d, const float limit) {
610- int64_t first_row, end_row;
623+ int64_t first_row, end_row, row_stride ;
611624 const int idx = get_masked_feature_index<BATCHED_EXPERTS >();
612- if (idx >= d || !get_masked_row_range<BATCHED_EXPERTS >(
613- valid_token_counts, max_num_tokens, first_row, end_row)) {
625+ if (idx >= d ||
626+ !get_masked_row_range<BATCHED_EXPERTS >(valid_token_counts, max_num_tokens,
627+ first_row, end_row, row_stride)) {
614628 return ;
615629 }
616630
617- for (int64_t row = first_row; row < end_row; ++ row) {
631+ for (int64_t row = first_row; row < end_row; row += row_stride ) {
618632 const scalar_t * gate_ptr = input + row * 2 * d;
619633 const scalar_t * up_ptr = gate_ptr + d;
620634 scalar_t * out_ptr = out + row * d;
@@ -654,14 +668,15 @@ __global__ void masked_activation_kernel(
654668 scalar_t * __restrict__ out, const scalar_t * __restrict__ input,
655669 const int * __restrict__ valid_token_counts, const int max_num_tokens,
656670 const int d) {
657- int64_t first_row, end_row;
671+ int64_t first_row, end_row, row_stride ;
658672 const int idx = get_masked_feature_index<BATCHED_EXPERTS >();
659- if (idx >= d || !get_masked_row_range<BATCHED_EXPERTS >(
660- valid_token_counts, max_num_tokens, first_row, end_row)) {
673+ if (idx >= d ||
674+ !get_masked_row_range<BATCHED_EXPERTS >(valid_token_counts, max_num_tokens,
675+ first_row, end_row, row_stride)) {
661676 return ;
662677 }
663678
664- for (int64_t row = first_row; row < end_row; ++ row) {
679+ for (int64_t row = first_row; row < end_row; row += row_stride ) {
665680 const int64_t offset = row * d + idx;
666681 out[offset] = ACT_FN (VLLM_LDG (&input[offset]));
667682 }
@@ -787,11 +802,13 @@ void masked_situ_and_mul(torch::stable::Tensor& out, // [E, T, d]
787802 int num_experts = input.size (0 );
788803 int max_num_tokens = input.size (1 );
789804 int d = input.size (2 ) / 2 ;
790- if (num_experts == 0 || max_num_tokens == 0 ) {
805+ if (num_experts == 0 || max_num_tokens == 0 || d == 0 ) {
791806 return ;
792807 }
793808 constexpr int block_size = 256 ;
794- dim3 grid ((d + block_size - 1 ) / block_size, num_experts);
809+ const int token_blocks =
810+ std::min (max_num_tokens, vllm::kMaxMaskedTokenBlocks );
811+ dim3 grid ((d + block_size - 1 ) / block_size, num_experts, token_blocks);
795812 dim3 block (block_size);
796813 const torch::stable::accelerator::DeviceGuard device_guard (
797814 input.get_device_index ());
@@ -832,14 +849,17 @@ void masked_moe_activation(
832849 const int num_experts = batched_experts ? input.size (0 ) : 1 ;
833850 const int max_num_tokens = batched_experts ? input.size (1 ) : input.size (0 );
834851 const int d = out.size (-1 );
835- if (num_experts == 0 || max_num_tokens == 0 ) {
852+ if (num_experts == 0 || max_num_tokens == 0 || d == 0 ) {
836853 return ;
837854 }
838855
839856 constexpr int block_size = 256 ;
840857 const int feature_blocks = (d + block_size - 1 ) / block_size;
841- // Batched grid: (feature tile, expert); flat grid: (row, feature tile).
842- dim3 grid = batched_experts ? dim3 (feature_blocks, num_experts)
858+ const int token_blocks =
859+ std::min (max_num_tokens, vllm::kMaxMaskedTokenBlocks );
860+ // Batched grid: (feature tile, expert, token lane); flat grid: (row,
861+ // feature tile). Token lanes grid-stride the valid prefix.
862+ dim3 grid = batched_experts ? dim3 (feature_blocks, num_experts, token_blocks)
843863 : dim3 (max_num_tokens, feature_blocks);
844864 dim3 block (block_size);
845865 const torch::stable::accelerator::DeviceGuard device_guard (
0 commit comments