// DS4 ROCm routed-MoE quantization/device helpers and kernels. // // Included from the ROCm backend translation unit before // ds4_rocm_moe_launch.cuh so host policy/glue can keep using these static kernels directly. #if defined(__HIP_PLATFORM_AMD__) || defined(__HIPCC__) #include #endif __device__ static float dev_f16_to_f32(uint16_t v) { return __half2float(*reinterpret_cast(&v)); } __device__ __forceinline__ static uint32_t dev_pack_half2_bits(float x, float y) { const __half2 h = __floats2half2_rn(x, y); return *reinterpret_cast(&h); } __device__ __forceinline__ static uint32_t dev_unpack_iq2_signs(uint32_t v) { const uint32_t p = __popc(v) & 1u; const uint32_t s = v ^ (p << 7u); return s * 0x01010101u; } __device__ __forceinline__ static int32_t dev_iq2_dp4a_8(uint64_t grid, uint32_t sign, const int8_t *q8, int32_t acc) { const uint32_t signs = dev_unpack_iq2_signs(sign); const int32_t sm0 = __vcmpne4(signs & 0x08040201u, 0); const int32_t sm1 = __vcmpne4(signs & 0x80402010u, 0); const int32_t g0 = __vsub4((int32_t)(uint32_t)grid ^ sm0, sm0); const int32_t g1 = __vsub4((int32_t)(uint32_t)(grid >> 32) ^ sm1, sm1); acc = __dp4a(g0, *(const int32_t *)(q8 + 0), acc); acc = __dp4a(g1, *(const int32_t *)(q8 + 4), acc); return acc; } __device__ static int32_t dev_dot_q2_16(const uint8_t *q2, const int8_t *q8, int shift) { int32_t sum = 0; #pragma unroll for (uint32_t i = 0; i < 16; i += 4) { const int32_t v = (*(const int32_t *)(q2 + i) >> shift) & 0x03030303; sum = __dp4a(v, *(const int32_t *)(q8 + i), sum); } return sum; } __device__ static int32_t dev_dot_iq2_pair_16(uint8_t grid0, uint32_t sign0, uint8_t grid1, uint32_t sign1, const int8_t *q8) { int32_t sum = 0; sum = dev_iq2_dp4a_8(cuda_iq2xxs_grid[grid0], cuda_ksigns_iq2xs[sign0], q8, sum); sum = dev_iq2_dp4a_8(cuda_iq2xxs_grid[grid1], cuda_ksigns_iq2xs[sign1], q8 + 8, sum); return sum; } __device__ __forceinline__ static void dev_iq2_i8x8_lut( const uint64_t *grid, const uint8_t *signs, uint8_t grid_idx, uint32_t sign_idx, int32_t *w0, int32_t *w1) { const uint32_t s = dev_unpack_iq2_signs(signs[sign_idx]); const int32_t sm0 = __vcmpne4(s & 0x08040201u, 0); const int32_t sm1 = __vcmpne4(s & 0x80402010u, 0); const uint64_t g = grid[grid_idx]; *w0 = __vsub4((int32_t)(uint32_t)g ^ sm0, sm0); *w1 = __vsub4((int32_t)(uint32_t)(g >> 32) ^ sm1, sm1); } __device__ static float dev_dot_iq2_xxs_q8_K_block_lut( const cuda_block_iq2_xxs *x, const cuda_block_q8_K *y, const uint64_t *grid, const uint8_t *signs) { const float xd = dev_f16_to_f32(x->d); const uint16_t *q2 = x->qs; const int8_t *q8 = y->qs; int32_t bsum = 0; for (int ib32 = 0; ib32 < CUDA_QK_K / 32; ib32++) { const uint32_t aux0 = (uint32_t)q2[0] | ((uint32_t)q2[1] << 16); const uint32_t aux1 = (uint32_t)q2[2] | ((uint32_t)q2[3] << 16); q2 += 4; const int32_t ls = (int32_t)(2u * (aux1 >> 28) + 1u); int32_t w[8]; dev_iq2_i8x8_lut(grid, signs, (uint8_t)(aux0 & 0xffu), (aux1 >> 0) & 127u, &w[0], &w[1]); dev_iq2_i8x8_lut(grid, signs, (uint8_t)((aux0 >> 8) & 0xffu), (aux1 >> 7) & 127u, &w[2], &w[3]); dev_iq2_i8x8_lut(grid, signs, (uint8_t)((aux0 >> 16) & 0xffu), (aux1 >> 14) & 127u, &w[4], &w[5]); dev_iq2_i8x8_lut(grid, signs, (uint8_t)((aux0 >> 24) & 0xffu), (aux1 >> 21) & 127u, &w[6], &w[7]); int32_t sumi = 0; sumi = __dp4a(w[0], *(const int32_t *)(q8 + ib32 * 32u + 0), sumi); sumi = __dp4a(w[1], *(const int32_t *)(q8 + ib32 * 32u + 4), sumi); sumi = __dp4a(w[2], *(const int32_t *)(q8 + ib32 * 32u + 8), sumi); sumi = __dp4a(w[3], *(const int32_t *)(q8 + ib32 * 32u + 12), sumi); sumi = __dp4a(w[4], *(const int32_t *)(q8 + ib32 * 32u + 16), sumi); sumi = __dp4a(w[5], *(const int32_t *)(q8 + ib32 * 32u + 20), sumi); sumi = __dp4a(w[6], *(const int32_t *)(q8 + ib32 * 32u + 24), sumi); sumi = __dp4a(w[7], *(const int32_t *)(q8 + ib32 * 32u + 28), sumi); bsum += sumi * ls; } return 0.125f * xd * y->d * (float)bsum; } __device__ static float dev_dot_iq2_xxs_q8_K_block(const cuda_block_iq2_xxs *x, const cuda_block_q8_K *y) { const float d = dev_f16_to_f32(x->d) * y->d; const uint16_t *q2 = x->qs; const int8_t *q8 = y->qs; int32_t bsum = 0; for (int ib32 = 0; ib32 < CUDA_QK_K / 32; ib32++) { const uint32_t aux0 = (uint32_t)q2[0] | ((uint32_t)q2[1] << 16); const uint32_t aux1 = (uint32_t)q2[2] | ((uint32_t)q2[3] << 16); q2 += 4; const uint32_t ls = 2u * (aux1 >> 28) + 1u; const uint8_t a0 = (uint8_t)(aux0 & 0xffu); const uint8_t a1 = (uint8_t)((aux0 >> 8) & 0xffu); const uint8_t a2 = (uint8_t)((aux0 >> 16) & 0xffu); const uint8_t a3 = (uint8_t)((aux0 >> 24) & 0xffu); int32_t sumi = 0; sumi += dev_dot_iq2_pair_16(a0, (aux1 >> 0) & 127u, a1, (aux1 >> 7) & 127u, q8); q8 += 16; sumi += dev_dot_iq2_pair_16(a2, (aux1 >> 14) & 127u, a3, (aux1 >> 21) & 127u, q8); q8 += 16; bsum += sumi * (int32_t)ls; } return 0.125f * d * (float)bsum; } __device__ static void dev_dot_iq2_xxs_q8_K_block8_deq_lut( const cuda_block_iq2_xxs *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, const cuda_block_q8_K *y4, const cuda_block_q8_K *y5, const cuda_block_q8_K *y6, const cuda_block_q8_K *y7, uint32_t n, float acc[8], const uint64_t *grid, const uint8_t *signs) { const float xd = dev_f16_to_f32(x->d); const uint16_t *q2 = x->qs; int32_t bsum[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const int8_t *q8[8] = { y0 ? y0->qs : NULL, y1 ? y1->qs : NULL, y2 ? y2->qs : NULL, y3 ? y3->qs : NULL, y4 ? y4->qs : NULL, y5 ? y5->qs : NULL, y6 ? y6->qs : NULL, y7 ? y7->qs : NULL, }; for (int ib32 = 0; ib32 < CUDA_QK_K / 32; ib32++) { const uint32_t aux0 = (uint32_t)q2[0] | ((uint32_t)q2[1] << 16); const uint32_t aux1 = (uint32_t)q2[2] | ((uint32_t)q2[3] << 16); q2 += 4; const int32_t ls = (int32_t)(2u * (aux1 >> 28) + 1u); int32_t w[8]; dev_iq2_i8x8_lut(grid, signs, (uint8_t)(aux0 & 0xffu), (aux1 >> 0) & 127u, &w[0], &w[1]); dev_iq2_i8x8_lut(grid, signs, (uint8_t)((aux0 >> 8) & 0xffu), (aux1 >> 7) & 127u, &w[2], &w[3]); dev_iq2_i8x8_lut(grid, signs, (uint8_t)((aux0 >> 16) & 0xffu), (aux1 >> 14) & 127u, &w[4], &w[5]); dev_iq2_i8x8_lut(grid, signs, (uint8_t)((aux0 >> 24) & 0xffu), (aux1 >> 21) & 127u, &w[6], &w[7]); for (uint32_t p = 0; p < n; p++) { const int8_t *q = q8[p] + ib32 * 32; int32_t sumi = 0; sumi = __dp4a(w[0], *(const int32_t *)(q + 0), sumi); sumi = __dp4a(w[1], *(const int32_t *)(q + 4), sumi); sumi = __dp4a(w[2], *(const int32_t *)(q + 8), sumi); sumi = __dp4a(w[3], *(const int32_t *)(q + 12), sumi); sumi = __dp4a(w[4], *(const int32_t *)(q + 16), sumi); sumi = __dp4a(w[5], *(const int32_t *)(q + 20), sumi); sumi = __dp4a(w[6], *(const int32_t *)(q + 24), sumi); sumi = __dp4a(w[7], *(const int32_t *)(q + 28), sumi); bsum[p] += sumi * ls; } } const cuda_block_q8_K *ys[8] = { y0, y1, y2, y3, y4, y5, y6, y7 }; for (uint32_t p = 0; p < n; p++) acc[p] += 0.125f * xd * ys[p]->d * (float)bsum[p]; } __device__ static void dev_dot_iq2_xxs_q8_K_block4( const cuda_block_iq2_xxs *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, uint32_t n, float acc[4]) { const float xd = dev_f16_to_f32(x->d); const uint16_t *q2 = x->qs; int32_t bsum[4] = {0, 0, 0, 0}; const int8_t *q8[4] = { y0 ? y0->qs : NULL, y1 ? y1->qs : NULL, y2 ? y2->qs : NULL, y3 ? y3->qs : NULL, }; for (int ib32 = 0; ib32 < CUDA_QK_K / 32; ib32++) { const uint32_t aux0 = (uint32_t)q2[0] | ((uint32_t)q2[1] << 16); const uint32_t aux1 = (uint32_t)q2[2] | ((uint32_t)q2[3] << 16); q2 += 4; const uint32_t ls = 2u * (aux1 >> 28) + 1u; const uint8_t a0 = (uint8_t)(aux0 & 0xffu); const uint8_t a1 = (uint8_t)((aux0 >> 8) & 0xffu); const uint8_t a2 = (uint8_t)((aux0 >> 16) & 0xffu); const uint8_t a3 = (uint8_t)((aux0 >> 24) & 0xffu); for (uint32_t p = 0; p < n; p++) { int32_t sumi = 0; sumi += dev_dot_iq2_pair_16(a0, (aux1 >> 0) & 127u, a1, (aux1 >> 7) & 127u, q8[p] + ib32 * 32); sumi += dev_dot_iq2_pair_16(a2, (aux1 >> 14) & 127u, a3, (aux1 >> 21) & 127u, q8[p] + ib32 * 32 + 16); bsum[p] += sumi * (int32_t)ls; } } const cuda_block_q8_K *ys[4] = { y0, y1, y2, y3 }; for (uint32_t p = 0; p < n; p++) acc[p] += 0.125f * xd * ys[p]->d * (float)bsum[p]; } __device__ static DS4_ROCM_UNUSED void dev_dot_iq2_xxs_q8_K_block8( const cuda_block_iq2_xxs *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, const cuda_block_q8_K *y4, const cuda_block_q8_K *y5, const cuda_block_q8_K *y6, const cuda_block_q8_K *y7, uint32_t n, float acc[8]) { const float xd = dev_f16_to_f32(x->d); const uint16_t *q2 = x->qs; int32_t bsum[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const int8_t *q8[8] = { y0 ? y0->qs : NULL, y1 ? y1->qs : NULL, y2 ? y2->qs : NULL, y3 ? y3->qs : NULL, y4 ? y4->qs : NULL, y5 ? y5->qs : NULL, y6 ? y6->qs : NULL, y7 ? y7->qs : NULL, }; for (int ib32 = 0; ib32 < CUDA_QK_K / 32; ib32++) { const uint32_t aux0 = (uint32_t)q2[0] | ((uint32_t)q2[1] << 16); const uint32_t aux1 = (uint32_t)q2[2] | ((uint32_t)q2[3] << 16); q2 += 4; const uint32_t ls = 2u * (aux1 >> 28) + 1u; const uint8_t a0 = (uint8_t)(aux0 & 0xffu); const uint8_t a1 = (uint8_t)((aux0 >> 8) & 0xffu); const uint8_t a2 = (uint8_t)((aux0 >> 16) & 0xffu); const uint8_t a3 = (uint8_t)((aux0 >> 24) & 0xffu); for (uint32_t p = 0; p < n; p++) { int32_t sumi = 0; sumi += dev_dot_iq2_pair_16(a0, (aux1 >> 0) & 127u, a1, (aux1 >> 7) & 127u, q8[p] + ib32 * 32); sumi += dev_dot_iq2_pair_16(a2, (aux1 >> 14) & 127u, a3, (aux1 >> 21) & 127u, q8[p] + ib32 * 32 + 16); bsum[p] += sumi * (int32_t)ls; } } const cuda_block_q8_K *ys[8] = { y0, y1, y2, y3, y4, y5, y6, y7 }; for (uint32_t p = 0; p < n; p++) acc[p] += 0.125f * xd * ys[p]->d * (float)bsum[p]; } __device__ static void dev_q4_K_get_scale_min( uint32_t j, const uint8_t *scales, uint8_t *d_out, uint8_t *m_out) { if (j < 4u) { *d_out = scales[j] & 63u; *m_out = scales[j + 4u] & 63u; } else { *d_out = (scales[j + 4u] & 0x0fu) | ((scales[j - 4u] >> 6u) << 4u); *m_out = (scales[j + 4u] >> 4u) | ((scales[j] >> 6u) << 4u); } } __device__ __forceinline__ static int32_t dev_dot_q4_32(const uint8_t *qs, const int8_t *q8, int shift) { int32_t sum = 0; #pragma unroll for (uint32_t i = 0; i < 32u; i += 4u) { const int32_t v = (*(const int32_t *)(qs + i) >> shift) & 0x0f0f0f0f; sum = __dp4a(v, *(const int32_t *)(q8 + i), sum); } return sum; } __device__ static float dev_dot_q4_K_q8_K_block(const cuda_block_q4_K *x, const cuda_block_q8_K *y) { const float xd = dev_f16_to_f32(x->d); const float xmin = dev_f16_to_f32(x->dmin); int isum = 0; int summs = 0; #pragma unroll for (uint32_t j = 0; j < 8u; j++) { uint8_t sc, m; dev_q4_K_get_scale_min(j, x->scales, &sc, &m); summs += (int)m * (int)(y->bsums[2u * j] + y->bsums[2u * j + 1u]); const uint32_t byte_off = (j >> 1u) * 32u; const int shift = (j & 1u) ? 4 : 0; isum += (int)sc * dev_dot_q4_32(x->qs + byte_off, y->qs + j * 32u, shift); } return y->d * xd * (float)isum - y->d * xmin * (float)summs; } __device__ static void dev_dot_q4_K_q8_K_block4( const cuda_block_q4_K *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, uint32_t n, float acc[4]) { const cuda_block_q8_K *ys[4] = { y0, y1, y2, y3 }; const float xd = dev_f16_to_f32(x->d); const float xmin = dev_f16_to_f32(x->dmin); int isum[4] = {0, 0, 0, 0}; int summs[4] = {0, 0, 0, 0}; #pragma unroll for (uint32_t j = 0; j < 8u; j++) { uint8_t sc, m; dev_q4_K_get_scale_min(j, x->scales, &sc, &m); const uint32_t byte_off = (j >> 1u) * 32u; const int shift = (j & 1u) ? 4 : 0; for (uint32_t p = 0; p < n; p++) { if (!ys[p]) continue; summs[p] += (int)m * (int)(ys[p]->bsums[2u * j] + ys[p]->bsums[2u * j + 1u]); isum[p] += (int)sc * dev_dot_q4_32(x->qs + byte_off, ys[p]->qs + j * 32u, shift); } } for (uint32_t p = 0; p < n; p++) { if (ys[p]) acc[p] += ys[p]->d * xd * (float)isum[p] - ys[p]->d * xmin * (float)summs[p]; } } __device__ static void dev_dot_q4_K_q8_K_block8( const cuda_block_q4_K *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, const cuda_block_q8_K *y4, const cuda_block_q8_K *y5, const cuda_block_q8_K *y6, const cuda_block_q8_K *y7, uint32_t n, float acc[8]) { const cuda_block_q8_K *ys[8] = { y0, y1, y2, y3, y4, y5, y6, y7 }; const float xd = dev_f16_to_f32(x->d); const float xmin = dev_f16_to_f32(x->dmin); int isum[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int summs[8] = {0, 0, 0, 0, 0, 0, 0, 0}; #pragma unroll for (uint32_t j = 0; j < 8u; j++) { uint8_t sc, m; dev_q4_K_get_scale_min(j, x->scales, &sc, &m); const uint32_t byte_off = (j >> 1u) * 32u; const int shift = (j & 1u) ? 4 : 0; for (uint32_t p = 0; p < n; p++) { if (!ys[p]) continue; summs[p] += (int)m * (int)(ys[p]->bsums[2u * j] + ys[p]->bsums[2u * j + 1u]); isum[p] += (int)sc * dev_dot_q4_32(x->qs + byte_off, ys[p]->qs + j * 32u, shift); } } for (uint32_t p = 0; p < n; p++) { if (ys[p]) acc[p] += ys[p]->d * xd * (float)isum[p] - ys[p]->d * xmin * (float)summs[p]; } } __device__ static float dev_dot_q2_K_q8_K_block(const cuda_block_q2_K *x, const cuda_block_q8_K *y) { const uint8_t *q2 = x->qs; const int8_t *q8 = y->qs; const uint8_t *sc = x->scales; int summs = 0; for (int j = 0; j < 16; j++) summs += y->bsums[j] * (sc[j] >> 4); const float dall = y->d * dev_f16_to_f32(x->d); const float dmin = y->d * dev_f16_to_f32(x->dmin); int isum = 0; int is = 0; for (int k = 0; k < CUDA_QK_K / 128; k++) { int shift = 0; for (int j = 0; j < 4; j++) { int d = sc[is++] & 0x0f; isum += d * dev_dot_q2_16(q2, q8, shift); d = sc[is++] & 0x0f; isum += d * dev_dot_q2_16(q2 + 16, q8 + 16, shift); shift += 2; q8 += 32; } q2 += 32; } return dall * (float)isum - dmin * (float)summs; } __device__ static void dev_dot_q2_K_q8_K_block4( const cuda_block_q2_K *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, uint32_t n, float acc[4]) { const uint8_t *sc = x->scales; const float xd = dev_f16_to_f32(x->d); const float xmin = dev_f16_to_f32(x->dmin); const cuda_block_q8_K *ys[4] = { y0, y1, y2, y3 }; int isum[4] = {0, 0, 0, 0}; int summs[4] = {0, 0, 0, 0}; for (uint32_t p = 0; p < n; p++) { for (int j = 0; j < 16; j++) summs[p] += ys[p]->bsums[j] * (sc[j] >> 4); } for (uint32_t p = 0; p < n; p++) { const uint8_t *q2 = x->qs; const int8_t *q8 = ys[p]->qs; int is = 0; for (int k = 0; k < CUDA_QK_K / 128; k++) { int shift = 0; for (int j = 0; j < 4; j++) { int d = sc[is++] & 0x0f; isum[p] += d * dev_dot_q2_16(q2, q8, shift); d = sc[is++] & 0x0f; isum[p] += d * dev_dot_q2_16(q2 + 16, q8 + 16, shift); shift += 2; q8 += 32; } q2 += 32; } } for (uint32_t p = 0; p < n; p++) { const float yd = ys[p]->d; acc[p] += yd * xd * (float)isum[p] - yd * xmin * (float)summs[p]; } } __device__ static void dev_dot_q2_K_q8_K_block8( const cuda_block_q2_K *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, const cuda_block_q8_K *y4, const cuda_block_q8_K *y5, const cuda_block_q8_K *y6, const cuda_block_q8_K *y7, uint32_t n, float acc[8]) { const uint8_t *sc = x->scales; const float xd = dev_f16_to_f32(x->d); const float xmin = dev_f16_to_f32(x->dmin); const cuda_block_q8_K *ys[8] = { y0, y1, y2, y3, y4, y5, y6, y7 }; int isum[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int summs[8] = {0, 0, 0, 0, 0, 0, 0, 0}; for (uint32_t p = 0; p < n; p++) { for (int j = 0; j < 16; j++) summs[p] += ys[p]->bsums[j] * (sc[j] >> 4); } for (uint32_t p = 0; p < n; p++) { const uint8_t *q2 = x->qs; const int8_t *q8 = ys[p]->qs; int is = 0; for (int k = 0; k < CUDA_QK_K / 128; k++) { int shift = 0; for (int j = 0; j < 4; j++) { int d = sc[is++] & 0x0f; isum[p] += d * dev_dot_q2_16(q2, q8, shift); d = sc[is++] & 0x0f; isum[p] += d * dev_dot_q2_16(q2 + 16, q8 + 16, shift); shift += 2; q8 += 32; } q2 += 32; } } for (uint32_t p = 0; p < n; p++) { const float yd = ys[p]->d; acc[p] += yd * xd * (float)isum[p] - yd * xmin * (float)summs[p]; } } __device__ static float half_warp_sum_f32(float v, uint32_t lane16) { uint32_t mask = 0xffffu << (threadIdx.x & 16u); for (int offset = 8; offset > 0; offset >>= 1) { v += __shfl_down_sync(static_cast(mask), v, offset, 16); } (void)lane16; return v; } __device__ static float quarter_warp_sum_f32(float v, uint32_t lane8) { uint32_t mask = 0xffu << (threadIdx.x & 24u); for (int offset = 4; offset > 0; offset >>= 1) { v += __shfl_down_sync(static_cast(mask), v, offset, 8); } (void)lane8; return v; } __global__ static void q8_K_quantize_kernel(cuda_block_q8_K *out, const float *x, uint32_t in_dim, uint32_t n_rows) { uint32_t b = blockIdx.x; uint32_t row = blockIdx.y; if (row >= n_rows || b >= in_dim / CUDA_QK_K) return; const float *xr = x + (uint64_t)row * in_dim + (uint64_t)b * CUDA_QK_K; cuda_block_q8_K *yb = out + (uint64_t)row * (in_dim / CUDA_QK_K) + b; __shared__ float abs_part[256]; __shared__ float val_part[256]; __shared__ float maxv_s; __shared__ float iscale_s; uint32_t tid = threadIdx.x; float v = tid < CUDA_QK_K ? xr[tid] : 0.0f; abs_part[tid] = tid < CUDA_QK_K ? fabsf(v) : 0.0f; val_part[tid] = v; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (tid < stride && abs_part[tid + stride] > abs_part[tid]) { abs_part[tid] = abs_part[tid + stride]; val_part[tid] = val_part[tid + stride]; } __syncthreads(); } float amax = abs_part[0]; if (amax == 0.0f) { if (tid == 0) yb->d = 0.0f; if (tid < CUDA_QK_K) yb->qs[tid] = 0; if (tid < CUDA_QK_K / 16) yb->bsums[tid] = 0; return; } if (tid == 0) { maxv_s = val_part[0]; iscale_s = -127.0f / maxv_s; } __syncthreads(); if (tid < CUDA_QK_K) { int qv = (int)lrintf(iscale_s * xr[tid]); if (qv > 127) qv = 127; if (qv < -128) qv = -128; yb->qs[tid] = (int8_t)qv; } __syncthreads(); if (tid < CUDA_QK_K / 16) { int sum = 0; for (int i = 0; i < 16; i++) sum += yb->qs[tid * 16 + i]; yb->bsums[tid] = (int16_t)sum; } if (tid == 0) yb->d = 1.0f / iscale_s; } __global__ static DS4_ROCM_UNUSED void moe_gate_up_mid_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t row = blockIdx.x; uint32_t pair = blockIdx.y; if (row >= expert_mid_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; float gate = 0.0f; float up = 0.0f; for (uint32_t b = threadIdx.x; b < xq_blocks; b += blockDim.x) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } __shared__ float partial_gate[256]; __shared__ float partial_up[256]; partial_gate[threadIdx.x] = gate; partial_up[threadIdx.x] = up; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) { partial_gate[threadIdx.x] += partial_gate[threadIdx.x + stride]; partial_up[threadIdx.x] += partial_up[threadIdx.x + stride]; } __syncthreads(); } if (threadIdx.x == 0) { gate = partial_gate[0]; up = partial_up[0]; if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static DS4_ROCM_UNUSED void moe_gate_up_mid_warp8_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t lane = threadIdx.x & 31u; uint32_t warp = threadIdx.x >> 5u; uint32_t row = blockIdx.x * 8u + warp; uint32_t pair = blockIdx.y; if (row >= expert_mid_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 32u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = warp_sum_f32(gate); up = warp_sum_f32(up); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static DS4_ROCM_UNUSED void moe_gate_up_mid_hwarp16_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t lane = threadIdx.x & 15u; uint32_t row = blockIdx.x * 16u + (threadIdx.x >> 4u); uint32_t pair = blockIdx.y; if (row >= expert_mid_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 16u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = half_warp_sum_f32(gate, lane); up = half_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static void moe_gate_up_mid_qwarp32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t active_mask, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t pair = blockIdx.y; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; if ((active_mask & (1u << slot)) == 0) return; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; for (uint32_t rr = 0; rr < 4u; rr++) { uint32_t row = blockIdx.x * 128u + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } } __global__ static void moe_gate_up_mid_qwarp32_ptrs_kernel( float *gate_out, float *up_out, float *mid_out, const char * const *gate_slots, const char * const *up_slots, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t active_mask, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t pair = blockIdx.y; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; if ((active_mask & (1u << slot)) == 0) return; int32_t slot_i = selected[(uint64_t)tok * n_expert + slot]; if (slot_i < 0) slot_i = 0; const uint32_t compact_slot = (uint32_t)slot_i; const char *gate_base = gate_slots[compact_slot]; const char *up_base = up_slots[compact_slot]; if (!gate_base || !up_base) return; const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; for (uint32_t rr = 0; rr < 4u; rr++) { uint32_t row = blockIdx.x * 128u + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)row * gate_row_bytes); float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } } __global__ static void moe_gate_up_mid_qwarp32_ptrs_split_kernel( float *gate_out, float *up_out, float *mid_out, const char * const *gate_slots, const char * const *up_slots, const uint8_t *pair_missing, uint32_t want_missing, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t active_mask, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t pair = blockIdx.y; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; if ((active_mask & (1u << slot)) == 0) return; if (!pair_missing || ((uint32_t)(pair_missing[pair] != 0) != want_missing)) return; int32_t slot_i = selected[(uint64_t)tok * n_expert + slot]; if (slot_i < 0) slot_i = 0; const uint32_t compact_slot = (uint32_t)slot_i; const char *gate_base = gate_slots[compact_slot]; const char *up_base = up_slots[compact_slot]; if (!gate_base || !up_base) return; const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; for (uint32_t rr = 0; rr < 4u; rr++) { uint32_t row = blockIdx.x * 128u + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)row * gate_row_bytes); float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } } __global__ static void moe_gate_up_mid_decode_lut_qwarp32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t write_aux, uint32_t active_mask, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t pair = blockIdx.y; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; if ((active_mask & (1u << slot)) == 0) return; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; __shared__ cuda_block_q8_K sxq[16]; __shared__ uint64_t s_iq2_grid[256]; __shared__ uint8_t s_iq2_signs[128]; if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < xq_blocks; i += blockDim.x) sxq[i] = xqb[i]; for (uint32_t i = threadIdx.x; i < 256u; i += blockDim.x) s_iq2_grid[i] = cuda_iq2xxs_grid[i]; for (uint32_t i = threadIdx.x; i < 128u; i += blockDim.x) s_iq2_signs[i] = cuda_ksigns_iq2xs[i]; __syncthreads(); xqb = sxq; } for (uint32_t rr = 0; rr < 4u; rr++) { uint32_t row = blockIdx.x * 128u + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block_lut(gr + b, xqb + b, s_iq2_grid, s_iq2_signs); up += dev_dot_iq2_xxs_q8_K_block_lut(ur + b, xqb + b, s_iq2_grid, s_iq2_signs); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate; up_out[off] = up; } mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } } __global__ static void moe_gate_up_mid_decode_lut_qwarp32_ptrs_kernel( float *gate_out, float *up_out, float *mid_out, const char * const *gate_slots, const char * const *up_slots, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t write_aux, uint32_t active_mask, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t pair = blockIdx.y; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; if ((active_mask & (1u << slot)) == 0) return; int32_t slot_i = selected[(uint64_t)tok * n_expert + slot]; if (slot_i < 0) slot_i = 0; const uint32_t compact_slot = (uint32_t)slot_i; const char *gate_base = gate_slots[compact_slot]; const char *up_base = up_slots[compact_slot]; if (!gate_base || !up_base) return; const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; __shared__ cuda_block_q8_K sxq[16]; __shared__ uint64_t s_iq2_grid[256]; __shared__ uint8_t s_iq2_signs[128]; if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < xq_blocks; i += blockDim.x) sxq[i] = xqb[i]; for (uint32_t i = threadIdx.x; i < 256u; i += blockDim.x) s_iq2_grid[i] = cuda_iq2xxs_grid[i]; for (uint32_t i = threadIdx.x; i < 128u; i += blockDim.x) s_iq2_signs[i] = cuda_ksigns_iq2xs[i]; __syncthreads(); xqb = sxq; } for (uint32_t rr = 0; rr < 4u; rr++) { uint32_t row = blockIdx.x * 128u + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)row * gate_row_bytes); float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block_lut(gr + b, xqb + b, s_iq2_grid, s_iq2_signs); up += dev_dot_iq2_xxs_q8_K_block_lut(ur + b, xqb + b, s_iq2_grid, s_iq2_signs); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate; up_out[off] = up; } mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } } __global__ static void moe_count_sorted_pairs_kernel( uint32_t *counts, const int32_t *selected, uint32_t pair_count, uint32_t n_total_expert) { uint32_t pair = (uint32_t)((uint64_t)blockIdx.x * blockDim.x + threadIdx.x); if (pair >= pair_count) return; int32_t expert_i = selected[pair]; if (expert_i < 0) expert_i = 0; if ((uint32_t)expert_i >= n_total_expert) return; atomicAdd(counts + (uint32_t)expert_i, 1u); } __global__ static void moe_prefix_sorted_pairs_kernel( uint32_t *offsets, uint32_t *cursors, const uint32_t *counts, uint32_t n_total_expert) { if (threadIdx.x == 0) { uint32_t sum = 0; for (uint32_t e = 0; e < n_total_expert; e++) { offsets[e] = sum; cursors[e] = sum; sum += counts[e]; } offsets[n_total_expert] = sum; } } __global__ static void moe_scatter_sorted_pairs_kernel( uint32_t *sorted_pairs, uint32_t *cursors, const int32_t *selected, uint32_t pair_count, uint32_t n_total_expert) { uint32_t pair = (uint32_t)((uint64_t)blockIdx.x * blockDim.x + threadIdx.x); if (pair >= pair_count) return; int32_t expert_i = selected[pair]; if (expert_i < 0) expert_i = 0; if ((uint32_t)expert_i >= n_total_expert) return; uint32_t pos = atomicAdd(cursors + (uint32_t)expert_i, 1u); sorted_pairs[pos] = pair; } /* Keep pair order stable inside each expert bucket. The MoE WMMA kernels are * row-position sensitive enough that atomic append order changes logits. */ __global__ static void moe_scatter_sorted_pairs_deterministic_kernel( uint32_t *sorted_pairs, const uint32_t *offsets, const int32_t *selected, uint32_t pair_count, uint32_t n_total_expert) { const uint32_t expert = (uint32_t)blockIdx.x; if (expert >= n_total_expert || threadIdx.x != 0u) return; uint32_t pos = offsets[expert]; for (uint32_t pair = 0; pair < pair_count; pair++) { int32_t expert_i = selected[pair]; if (expert_i < 0) expert_i = 0; if ((uint32_t)expert_i == expert) sorted_pairs[pos++] = pair; } } __global__ static void moe_build_expert_tile_offsets_kernel( uint32_t *tile_offsets, uint32_t *tile_total, const uint32_t *counts, uint32_t block_m, uint32_t n_total_expert) { if (threadIdx.x == 0) { uint32_t sum = 0; for (uint32_t e = 0; e < n_total_expert; e++) { tile_offsets[e] = sum; sum += (counts[e] + block_m - 1u) / block_m; } tile_offsets[n_total_expert] = sum; *tile_total = sum; } } __global__ static void moe_build_expert_tiles_kernel( uint32_t *tile_experts, uint32_t *tile_starts, const uint32_t *tile_offsets, const uint32_t *counts, uint32_t block_m, uint32_t n_total_expert) { uint32_t e = (uint32_t)((uint64_t)blockIdx.x * blockDim.x + threadIdx.x); if (e >= n_total_expert) return; uint32_t ntiles = (counts[e] + block_m - 1u) / block_m; uint32_t off = tile_offsets[e]; for (uint32_t t = 0; t < ntiles; t++) { tile_experts[off + t] = e; tile_starts[off + t] = t * block_m; } } __global__ static void moe_gate_up_mid_sorted_qwarp32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t pair = sorted_pairs[blockIdx.y]; if (row >= expert_mid_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static DS4_ROCM_UNUSED void moe_gate_up_mid_expert_tile8_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t group = threadIdx.x >> 3u; uint32_t lane = threadIdx.x & 7u; uint32_t pair_slot = group & 7u; uint32_t row_lane = group >> 3u; uint32_t expert = tile_experts[tile]; uint32_t local_pair = tile_starts[tile] + pair_slot; if (local_pair >= counts[expert]) return; uint32_t sorted_idx = offsets[expert] + local_pair; uint32_t pair = sorted_pairs[sorted_idx]; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; for (uint32_t rr = 0; rr < 2u; rr++) { uint32_t row = blockIdx.x * 8u + row_lane + rr * 4u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } } __global__ static void moe_gate_up_mid_expert_tile4_row32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t max_count, uint32_t write_aux, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; uint32_t count = counts[expert]; if (max_count != 0u && count >= max_count) return; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[4][16]; uint32_t pair[4] = {0, 0, 0, 0}; uint32_t tok[4] = {0, 0, 0, 0}; uint32_t slot[4] = {0, 0, 0, 0}; const cuda_block_q8_K *xqb[4] = {NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 4u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= count) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; tok[np] = pair[np] / n_expert; slot[np] = pair[np] - tok[np] * n_expert; xqb[np] = xq + (uint64_t)tok[np] * xq_blocks; } if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < np * xq_blocks; i += blockDim.x) { uint32_t p = i / xq_blocks; uint32_t b = i - p * xq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= expert_mid_dim) return; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate[4] = {0.0f, 0.0f, 0.0f, 0.0f}; float up[4] = {0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < xq_blocks; b += 8u) { dev_dot_iq2_xxs_q8_K_block4(gr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, np, gate); dev_dot_iq2_xxs_q8_K_block4(ur + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, np, up); } for (uint32_t p = 0; p < np; p++) { gate[p] = quarter_warp_sum_f32(gate[p], lane); up[p] = quarter_warp_sum_f32(up[p], lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate[p] > clamp) gate[p] = clamp; if (up[p] > clamp) up[p] = clamp; if (up[p] < -clamp) up[p] = -clamp; } const uint64_t off = (uint64_t)pair[p] * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate[p]; up_out[off] = up[p]; } mid_out[off] = (gate[p] / (1.0f + expf(-gate[p]))) * up[p] * weights[(uint64_t)tok[p] * n_expert + slot[p]]; } } } __global__ static void moe_gate_up_mid_expert_tile8_row32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t max_count, uint32_t write_aux, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; uint32_t count = counts[expert]; if (max_count != 0u && count >= max_count) return; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[8][16]; __shared__ uint64_t s_iq2_grid[256]; __shared__ uint8_t s_iq2_signs[128]; uint32_t pair[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t tok[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t slot[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const cuda_block_q8_K *xqb[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 8u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= count) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; tok[np] = pair[np] / n_expert; slot[np] = pair[np] - tok[np] * n_expert; xqb[np] = xq + (uint64_t)tok[np] * xq_blocks; } if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < np * xq_blocks; i += blockDim.x) { uint32_t p = i / xq_blocks; uint32_t b = i - p * xq_blocks; sxq[p][b] = xqb[p][b]; } for (uint32_t i = threadIdx.x; i < 256u; i += blockDim.x) s_iq2_grid[i] = cuda_iq2xxs_grid[i]; for (uint32_t i = threadIdx.x; i < 128u; i += blockDim.x) s_iq2_signs[i] = cuda_ksigns_iq2xs[i]; __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= expert_mid_dim) return; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; float up[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < xq_blocks; b += 8u) { dev_dot_iq2_xxs_q8_K_block8_deq_lut(gr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, gate, s_iq2_grid, s_iq2_signs); dev_dot_iq2_xxs_q8_K_block8_deq_lut(ur + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, up, s_iq2_grid, s_iq2_signs); } for (uint32_t p = 0; p < np; p++) { gate[p] = quarter_warp_sum_f32(gate[p], lane); up[p] = quarter_warp_sum_f32(up[p], lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate[p] > clamp) gate[p] = clamp; if (up[p] > clamp) up[p] = clamp; if (up[p] < -clamp) up[p] = -clamp; } const uint64_t off = (uint64_t)pair[p] * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate[p]; up_out[off] = up[p]; } mid_out[off] = (gate[p] / (1.0f + expf(-gate[p]))) * up[p] * weights[(uint64_t)tok[p] * n_expert + slot[p]]; } } } __global__ static void moe_gate_up_mid_expert_tile8_row2048_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t max_count, uint32_t write_aux, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t expert = tile_experts[tile]; uint32_t count = counts[expert]; if (max_count != 0u && count >= max_count) return; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[8][16]; __shared__ uint64_t s_iq2_grid[256]; __shared__ uint8_t s_iq2_signs[128]; uint32_t pair[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t tok[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t slot[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const cuda_block_q8_K *xqb[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 8u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= count) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; tok[np] = pair[np] / n_expert; slot[np] = pair[np] - tok[np] * n_expert; xqb[np] = xq + (uint64_t)tok[np] * xq_blocks; } if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < np * xq_blocks; i += blockDim.x) { uint32_t p = i / xq_blocks; uint32_t b = i - p * xq_blocks; sxq[p][b] = xqb[p][b]; } for (uint32_t i = threadIdx.x; i < 256u; i += blockDim.x) s_iq2_grid[i] = cuda_iq2xxs_grid[i]; for (uint32_t i = threadIdx.x; i < 128u; i += blockDim.x) s_iq2_signs[i] = cuda_ksigns_iq2xs[i]; __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } for (uint32_t rr = 0; rr < 64u; rr++) { uint32_t row = blockIdx.x * 2048u + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; float up[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < xq_blocks; b += 8u) { dev_dot_iq2_xxs_q8_K_block8_deq_lut(gr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, gate, s_iq2_grid, s_iq2_signs); dev_dot_iq2_xxs_q8_K_block8_deq_lut(ur + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, up, s_iq2_grid, s_iq2_signs); } for (uint32_t p = 0; p < np; p++) { gate[p] = quarter_warp_sum_f32(gate[p], lane); up[p] = quarter_warp_sum_f32(up[p], lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate[p] > clamp) gate[p] = clamp; if (up[p] > clamp) up[p] = clamp; if (up[p] < -clamp) up[p] = -clamp; } const uint64_t off = (uint64_t)pair[p] * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate[p]; up_out[off] = up[p]; } mid_out[off] = (gate[p] / (1.0f + expf(-gate[p]))) * up[p] * weights[(uint64_t)tok[p] * n_expert + slot[p]]; } } } } template __global__ static void moe_gate_up_mid_expert_tile8_rowspan_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t max_count, uint32_t write_aux, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t expert = tile_experts[tile]; uint32_t count = counts[expert]; if (max_count != 0u && count >= max_count) return; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[8][16]; __shared__ uint64_t s_iq2_grid[256]; __shared__ uint8_t s_iq2_signs[128]; uint32_t pair[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t tok[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t slot[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const cuda_block_q8_K *xqb[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 8u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= count) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; tok[np] = pair[np] / n_expert; slot[np] = pair[np] - tok[np] * n_expert; xqb[np] = xq + (uint64_t)tok[np] * xq_blocks; } if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < np * xq_blocks; i += blockDim.x) { uint32_t p = i / xq_blocks; uint32_t b = i - p * xq_blocks; sxq[p][b] = xqb[p][b]; } for (uint32_t i = threadIdx.x; i < 256u; i += blockDim.x) s_iq2_grid[i] = cuda_iq2xxs_grid[i]; for (uint32_t i = threadIdx.x; i < 128u; i += blockDim.x) s_iq2_signs[i] = cuda_ksigns_iq2xs[i]; __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } for (uint32_t rr = 0; rr < ROW_SPAN / 32u; rr++) { uint32_t row = blockIdx.x * ROW_SPAN + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; float up[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < xq_blocks; b += 8u) { dev_dot_iq2_xxs_q8_K_block8_deq_lut(gr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, gate, s_iq2_grid, s_iq2_signs); dev_dot_iq2_xxs_q8_K_block8_deq_lut(ur + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, up, s_iq2_grid, s_iq2_signs); } for (uint32_t p = 0; p < np; p++) { gate[p] = quarter_warp_sum_f32(gate[p], lane); up[p] = quarter_warp_sum_f32(up[p], lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate[p] > clamp) gate[p] = clamp; if (up[p] > clamp) up[p] = clamp; if (up[p] < -clamp) up[p] = -clamp; } const uint64_t off = (uint64_t)pair[p] * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate[p]; up_out[off] = up[p]; } mid_out[off] = (gate[p] / (1.0f + expf(-gate[p]))) * up[p] * weights[(uint64_t)tok[p] * n_expert + slot[p]]; } } } } __global__ static void moe_gate_up_mid_sorted_p2_qwarp32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t pair_count, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t pair_lane = (threadIdx.x >> 3u) & 1u; uint32_t row = blockIdx.x * 16u + (threadIdx.x >> 4u); uint32_t sorted_idx = blockIdx.y * 2u + pair_lane; if (row >= expert_mid_dim || sorted_idx >= pair_count) return; uint32_t pair = sorted_pairs[sorted_idx]; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static void moe_gate_up_mid_q4K_sorted_qwarp32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t pair = sorted_pairs[blockIdx.y]; if (row >= expert_mid_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_q4_K *gr = (const cuda_block_q4_K *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q4_K *ur = (const cuda_block_q4_K *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_q4_K_q8_K_block(gr + b, xqb + b); up += dev_dot_q4_K_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static void moe_gate_up_mid_q4K_expert_tile4_row32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t max_count, uint32_t write_aux, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; uint32_t count = counts[expert]; if (max_count != 0u && count >= max_count) return; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[4][16]; uint32_t pair[4] = {0, 0, 0, 0}; uint32_t tok[4] = {0, 0, 0, 0}; uint32_t slot[4] = {0, 0, 0, 0}; const cuda_block_q8_K *xqb[4] = {NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 4u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= count) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; tok[np] = pair[np] / n_expert; slot[np] = pair[np] - tok[np] * n_expert; xqb[np] = xq + (uint64_t)tok[np] * xq_blocks; } if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < np * xq_blocks; i += blockDim.x) { uint32_t p = i / xq_blocks; uint32_t b = i - p * xq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= expert_mid_dim) return; const cuda_block_q4_K *gr = (const cuda_block_q4_K *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q4_K *ur = (const cuda_block_q4_K *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate[4] = {0.0f, 0.0f, 0.0f, 0.0f}; float up[4] = {0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < xq_blocks; b += 8u) { dev_dot_q4_K_q8_K_block4(gr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, np, gate); dev_dot_q4_K_q8_K_block4(ur + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, np, up); } for (uint32_t p = 0; p < np; p++) { gate[p] = quarter_warp_sum_f32(gate[p], lane); up[p] = quarter_warp_sum_f32(up[p], lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate[p] > clamp) gate[p] = clamp; if (up[p] > clamp) up[p] = clamp; if (up[p] < -clamp) up[p] = -clamp; } const uint64_t off = (uint64_t)pair[p] * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate[p]; up_out[off] = up[p]; } mid_out[off] = (gate[p] / (1.0f + expf(-gate[p]))) * up[p] * weights[(uint64_t)tok[p] * n_expert + slot[p]]; } } } __global__ static void moe_gate_up_mid_q4K_expert_tile8_row32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t max_count, uint32_t write_aux, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; uint32_t count = counts[expert]; if (max_count != 0u && count >= max_count) return; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[8][16]; uint32_t pair[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t tok[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t slot[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const cuda_block_q8_K *xqb[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 8u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= count) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; tok[np] = pair[np] / n_expert; slot[np] = pair[np] - tok[np] * n_expert; xqb[np] = xq + (uint64_t)tok[np] * xq_blocks; } if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < np * xq_blocks; i += blockDim.x) { uint32_t p = i / xq_blocks; uint32_t b = i - p * xq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= expert_mid_dim) return; const cuda_block_q4_K *gr = (const cuda_block_q4_K *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q4_K *ur = (const cuda_block_q4_K *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; float up[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < xq_blocks; b += 8u) { dev_dot_q4_K_q8_K_block8(gr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, gate); dev_dot_q4_K_q8_K_block8(ur + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, up); } for (uint32_t p = 0; p < np; p++) { gate[p] = quarter_warp_sum_f32(gate[p], lane); up[p] = quarter_warp_sum_f32(up[p], lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate[p] > clamp) gate[p] = clamp; if (up[p] > clamp) up[p] = clamp; if (up[p] < -clamp) up[p] = -clamp; } const uint64_t off = (uint64_t)pair[p] * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate[p]; up_out[off] = up[p]; } mid_out[off] = (gate[p] / (1.0f + expf(-gate[p]))) * up[p] * weights[(uint64_t)tok[p] * n_expert + slot[p]]; } } } __global__ static DS4_ROCM_UNUSED void moe_down_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t row = blockIdx.x; uint32_t pair = blockIdx.y; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = threadIdx.x; b < midq_blocks; b += blockDim.x) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); __shared__ float partial[256]; partial[threadIdx.x] = acc; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) down_out[(uint64_t)pair * out_dim + row] = partial[0]; } __global__ static DS4_ROCM_UNUSED void moe_down_warp8_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t lane = threadIdx.x & 31u; uint32_t warp = threadIdx.x >> 5u; uint32_t row = blockIdx.x * 8u + warp; uint32_t pair = blockIdx.y; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 32u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = warp_sum_f32(acc); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } __global__ static DS4_ROCM_UNUSED void moe_down_hwarp16_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t lane = threadIdx.x & 15u; uint32_t row = blockIdx.x * 16u + (threadIdx.x >> 4u); uint32_t pair = blockIdx.y; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 16u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = half_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } __global__ static void moe_down_qwarp32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t pair = blockIdx.y; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } __global__ static void moe_gate_up_mid_decode_q4K_qwarp32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t write_aux, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t pair = blockIdx.y; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; for (uint32_t rr = 0; rr < 4u; rr++) { uint32_t row = blockIdx.x * 128u + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_q4_K *gr = (const cuda_block_q4_K *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q4_K *ur = (const cuda_block_q4_K *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_q4_K_q8_K_block(gr + b, xqb + b); up += dev_dot_q4_K_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate; up_out[off] = up; } mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } } __global__ static void moe_gate_up_mid_q2K_decode_q8_qwarp32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t write_aux, float clamp) { const uint32_t lane = threadIdx.x & 15u; const uint32_t row_lane = threadIdx.x >> 4u; const uint32_t pair = blockIdx.y; const uint32_t tok = pair / n_expert; const uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const uint32_t expert = (uint32_t)expert_i; const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; __shared__ cuda_block_q8_K sxq[16]; if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < xq_blocks; i += blockDim.x) sxq[i] = xqb[i]; __syncthreads(); xqb = sxq; } for (uint32_t rr = 0; rr < 16u; rr++) { const uint32_t row = blockIdx.x * 256u + row_lane + rr * 16u; if (row >= expert_mid_dim) continue; const cuda_block_q2_K *gr = (const cuda_block_q2_K *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q2_K *ur = (const cuda_block_q2_K *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 16u) { gate += dev_dot_q2_K_q8_K_block(gr + b, xqb + b); up += dev_dot_q2_K_q8_K_block(ur + b, xqb + b); } gate = half_warp_sum_f32(gate, lane); up = half_warp_sum_f32(up, lane); if (lane == 0u) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate; up_out[off] = up; } mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } } __global__ static void moe_down_sum6_qwarp32_kernel( float *out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); if (row >= out_dim) return; float total = 0.0f; #pragma unroll for (uint32_t slot = 0; slot < 6u; slot++) { int32_t expert_i = selected[slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)slot * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) total += acc; } if (lane == 0) out[row] = total; } __global__ static void moe_down_sum6_qwarp32_ptrs_kernel( float *out, const char * const *down_slots, const cuda_block_q8_K *midq, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); if (row >= out_dim) return; float total = 0.0f; #pragma unroll for (uint32_t slot = 0; slot < 6u; slot++) { const char *down_base = down_slots[slot]; if (!down_base) continue; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)slot * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) total += acc; } if (lane == 0) out[row] = total; } __global__ static void moe_down_sum6_qwarp32_ptrs_batch_kernel( float *out, const char * const *down_slots, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t n_tokens) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t tok = blockIdx.y; if (row >= out_dim || tok >= n_tokens) return; float total = 0.0f; #pragma unroll for (uint32_t slot = 0; slot < 6u; slot++) { int32_t compact_i = selected[(uint64_t)tok * n_expert + slot]; if (compact_i < 0) compact_i = 0; const char *down_base = down_slots[(uint32_t)compact_i]; if (!down_base) continue; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + ((uint64_t)tok * n_expert + slot) * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) total += acc; } if (lane == 0) out[(uint64_t)tok * out_dim + row] = total; } __global__ static void moe_down_q4K_sum6_qwarp32_kernel( float *out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); if (row >= out_dim) return; float total = 0.0f; #pragma unroll for (uint32_t slot = 0; slot < 6u; slot++) { int32_t expert_i = selected[slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q4_K *wr = (const cuda_block_q4_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)slot * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q4_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) total += acc; } if (lane == 0) out[row] = total; } __global__ static void moe_down_q4K_qwarp32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t pair = blockIdx.y; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q4_K *wr = (const cuda_block_q4_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q4_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } __global__ static void moe_down_q4K_sorted_qwarp32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t pair = sorted_pairs[blockIdx.y]; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q4_K *wr = (const cuda_block_q4_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q4_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } __global__ static void moe_down_q4K_expert_tile4_row32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[4][8]; uint32_t pair[4] = {0, 0, 0, 0}; const cuda_block_q8_K *xqb[4] = {NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 4u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= out_dim) return; const cuda_block_q4_K *wr = (const cuda_block_q4_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[4] = {0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { dev_dot_q4_K_q8_K_block4(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, np, acc); } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } __global__ static void moe_down_q4K_expert_tile8_row32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[8][8]; uint32_t pair[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const cuda_block_q8_K *xqb[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 8u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= out_dim) return; const cuda_block_q4_K *wr = (const cuda_block_q4_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { dev_dot_q4_K_q8_K_block8(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, acc); } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } __global__ static void moe_down_sorted_qwarp32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t pair = sorted_pairs[blockIdx.y]; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } __global__ static DS4_ROCM_UNUSED void moe_down_expert_tile8_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t group = threadIdx.x >> 3u; uint32_t lane = threadIdx.x & 7u; uint32_t pair_slot = group & 7u; uint32_t row_lane = group >> 3u; uint32_t expert = tile_experts[tile]; uint32_t local_pair = tile_starts[tile] + pair_slot; if (local_pair >= counts[expert]) return; uint32_t sorted_idx = offsets[expert] + local_pair; uint32_t pair = sorted_pairs[sorted_idx]; const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; for (uint32_t rr = 0; rr < 2u; rr++) { uint32_t row = blockIdx.x * 8u + row_lane + rr * 4u; if (row >= out_dim) continue; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } } __global__ static void moe_down_expert_tile4_row32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[4][8]; uint32_t pair[4] = {0, 0, 0, 0}; const cuda_block_q8_K *xqb[4] = {NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 4u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= out_dim) return; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[4] = {0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { dev_dot_q2_K_q8_K_block4(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, np, acc); } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } __global__ static void moe_down_expert_tile8_row32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[8][8]; uint32_t pair[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const cuda_block_q8_K *xqb[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 8u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= out_dim) return; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, acc); } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } __global__ static void moe_down_expert_tile16_row32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t local_start = tile_starts[tile]; if (local_start & 8u) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; __shared__ cuda_block_q8_K sxq[16][8]; uint32_t pair[16] = {0}; const cuda_block_q8_K *xqb[16] = {NULL}; uint32_t np = 0; for (; np < 16u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= out_dim) return; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[16] = {0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np < 8u ? np : 8u, acc); if (np > 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[8] ? xqb[8] + b : NULL, xqb[9] ? xqb[9] + b : NULL, xqb[10] ? xqb[10] + b : NULL, xqb[11] ? xqb[11] + b : NULL, xqb[12] ? xqb[12] + b : NULL, xqb[13] ? xqb[13] + b : NULL, xqb[14] ? xqb[14] + b : NULL, xqb[15] ? xqb[15] + b : NULL, np - 8u, acc + 8); } } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } __global__ static void moe_down_expert_tile16_row2048_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t local_start = tile_starts[tile]; if (local_start & 8u) return; uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t expert = tile_experts[tile]; __shared__ cuda_block_q8_K sxq[16][8]; uint32_t pair[16] = {0}; const cuda_block_q8_K *xqb[16] = {NULL}; uint32_t np = 0; for (; np < 16u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } for (uint32_t rr = 0; rr < 64u; rr++) { uint32_t row = blockIdx.x * 2048u + row_lane + rr * 32u; if (row >= out_dim) continue; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[16] = {0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np < 8u ? np : 8u, acc); if (np > 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[8] ? xqb[8] + b : NULL, xqb[9] ? xqb[9] + b : NULL, xqb[10] ? xqb[10] + b : NULL, xqb[11] ? xqb[11] + b : NULL, xqb[12] ? xqb[12] + b : NULL, xqb[13] ? xqb[13] + b : NULL, xqb[14] ? xqb[14] + b : NULL, xqb[15] ? xqb[15] + b : NULL, np - 8u, acc + 8); } } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } } template __global__ static void moe_down_expert_tile16_rowspan_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t local_start = tile_starts[tile]; if (local_start & 8u) return; uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t expert = tile_experts[tile]; __shared__ cuda_block_q8_K sxq[16][8]; uint32_t pair[16] = {0}; const cuda_block_q8_K *xqb[16] = {NULL}; uint32_t np = 0; for (; np < 16u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } for (uint32_t rr = 0; rr < ROW_SPAN / 32u; rr++) { uint32_t row = blockIdx.x * ROW_SPAN + row_lane + rr * 32u; if (row >= out_dim) continue; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[16] = {0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np < 8u ? np : 8u, acc); if (np > 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[8] ? xqb[8] + b : NULL, xqb[9] ? xqb[9] + b : NULL, xqb[10] ? xqb[10] + b : NULL, xqb[11] ? xqb[11] + b : NULL, xqb[12] ? xqb[12] + b : NULL, xqb[13] ? xqb[13] + b : NULL, xqb[14] ? xqb[14] + b : NULL, xqb[15] ? xqb[15] + b : NULL, np - 8u, acc + 8); } } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } } __global__ static void moe_down_sorted_p2_qwarp32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t pair_count) { uint32_t lane = threadIdx.x & 7u; uint32_t pair_lane = (threadIdx.x >> 3u) & 1u; uint32_t row = blockIdx.x * 16u + (threadIdx.x >> 4u); uint32_t sorted_idx = blockIdx.y * 2u + pair_lane; if (row >= out_dim || sorted_idx >= pair_count) return; uint32_t pair = sorted_pairs[sorted_idx]; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } __global__ static void moe_sum_kernel(float *out, const float *down, uint32_t out_dim, uint32_t n_expert, uint32_t n_tokens) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)n_tokens * out_dim; if (gid >= n) return; uint32_t tok = gid / out_dim; uint32_t row = gid - (uint64_t)tok * out_dim; float acc = 0.0f; for (uint32_t e = 0; e < n_expert; e++) acc += down[((uint64_t)tok * n_expert + e) * out_dim + row]; out[gid] = acc; } __global__ static void moe_sum_f16_kernel(float *out, const half *down_h, uint32_t out_dim, uint32_t n_expert, uint32_t n_tokens) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)n_tokens * out_dim; if (gid >= n) return; uint32_t tok = gid / out_dim; uint32_t row = gid - (uint64_t)tok * out_dim; float acc = 0.0f; for (uint32_t e = 0; e < n_expert; e++) acc += __half2float(down_h[((uint64_t)tok * n_expert + e) * out_dim + row]); out[gid] = acc; } __global__ static void moe_sum_f16x2_kernel(float *out, const half *down_h, uint32_t out_dim, uint32_t n_expert, uint32_t n_tokens) { const uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; const uint32_t out_dim2 = out_dim >> 1u; const uint64_t n2 = (uint64_t)n_tokens * out_dim2; if (gid >= n2) return; const uint32_t tok = gid / out_dim2; const uint32_t row = (uint32_t)(gid - (uint64_t)tok * out_dim2) << 1u; float acc0 = 0.0f; float acc1 = 0.0f; for (uint32_t e = 0; e < n_expert; e++) { const uint64_t off = ((uint64_t)tok * n_expert + e) * out_dim + row; const float2 v = __half22float2(*reinterpret_cast(down_h + off)); acc0 += v.x; acc1 += v.y; } const uint64_t out_off = (uint64_t)tok * out_dim + row; out[out_off] = acc0; out[out_off + 1u] = acc1; } __device__ __forceinline__ static void q2_K_scale_broadcast_w32(const unsigned char *blk, float *d, float *dmin) { float vd = 0.0f; float vm = 0.0f; if ((threadIdx.x & 31u) == 0u) { const uint16_t d_bits = (uint16_t)blk[80] | ((uint16_t)blk[81] << 8); const uint16_t dmin_bits = (uint16_t)blk[82] | ((uint16_t)blk[83] << 8); vd = dev_f16_to_f32(d_bits); vm = dev_f16_to_f32(dmin_bits); } #if defined(__HIP_PLATFORM_AMD__) || defined(__HIPCC__) *d = __shfl(vd, 0, 32); *dmin = __shfl(vm, 0, 32); #else *d = __shfl_sync(FULL_WARP_MASK, vd, 0, 32); *dmin = __shfl_sync(FULL_WARP_MASK, vm, 0, 32); #endif } __device__ __forceinline__ static float q2_K_dequant_256_scaled_w32( const unsigned char *blk, uint32_t lane, uint32_t kk, float d, float dmin) { const unsigned char *sc = blk; const unsigned char *qs = blk + 16u; const uint32_t g = (lane >> 4u) + (kk << 1u); const uint32_t within = g & 7u; const uint32_t qi = (g >> 3u) * 32u + (within & 1u) * 16u + (lane & 15u); const uint32_t shift = (within >> 1u) * 2u; const float q = (float)((qs[qi] >> shift) & 3u); const float scale = (float)(sc[g] & 0x0fu); const float mn = (float)(sc[g] >> 4u); return d * scale * q - dmin * mn; } __device__ __forceinline__ static float q2_K_dequant_256_direct(const unsigned char *blk, uint32_t i) { const uint16_t d_bits = (uint16_t)blk[80] | ((uint16_t)blk[81] << 8); const uint16_t dmin_bits = (uint16_t)blk[82] | ((uint16_t)blk[83] << 8); const unsigned char *sc = blk; const unsigned char *qs = blk + 16u; const uint32_t g = i >> 4u; const uint32_t within = g & 7u; const uint32_t qi = (g >> 3u) * 32u + (within & 1u) * 16u + (i & 15u); const uint32_t shift = (within >> 1u) * 2u; const float q = (float)((qs[qi] >> shift) & 3u); const float scale = (float)(sc[g] & 0x0fu); const float mn = (float)(sc[g] >> 4u); return dev_f16_to_f32(d_bits) * scale * q - dev_f16_to_f32(dmin_bits) * mn; } template __device__ __forceinline__ static void q2_K_dequant_tile_half_rowwise( half *shB, const unsigned char *base, uint64_t row_bytes, uint32_t n0, uint32_t k0, uint32_t out_dim, uint32_t tid) { const uint32_t g = (k0 & 255u) >> 4u; const uint32_t within = g & 7u; const uint32_t qbase = (g >> 3u) * 32u + (within & 1u) * 16u; const uint32_t shift = (within >> 1u) * 2u; constexpr uint32_t KG = 2u; for (uint32_t j = tid; j < (uint32_t)(BN * (BK / KG)); j += blockDim.x) { const uint32_t nn = j / (uint32_t)(BK / KG); const uint32_t kk0 = (j - nn * (uint32_t)(BK / KG)) * KG; const uint32_t row = n0 + nn; if (row < out_dim) { const unsigned char *blk = base + (uint64_t)row * row_bytes + (uint64_t)(k0 >> 8u) * 84u; const float d = dev_f16_to_f32((uint16_t)blk[80] | ((uint16_t)blk[81] << 8)); const float dm = dev_f16_to_f32((uint16_t)blk[82] | ((uint16_t)blk[83] << 8)); const float s = (float)(blk[g] & 0x0fu); const float m = (float)(blk[g] >> 4u); #pragma unroll for (uint32_t u = 0; u < KG; u++) { const uint32_t kk = kk0 + u; const float q = (float)((blk[16u + qbase + kk] >> shift) & 3u); shB[kk * (uint32_t)BN + nn] = __float2half(d * s * q - dm * m); } } else { #pragma unroll for (uint32_t u = 0; u < KG; u++) { const uint32_t kk = kk0 + u; shB[kk * (uint32_t)BN + nn] = __float2half(0.0f); } } } } template __device__ __forceinline__ static void q2_K_dequant_dual_tile_half_rowwise( half *shB0, half *shB1, const unsigned char *base0, const unsigned char *base1, uint64_t row_bytes, uint32_t n0, uint32_t k0, uint32_t out_dim, uint32_t tid) { const uint32_t g = (k0 & 255u) >> 4u; const uint32_t within = g & 7u; const uint32_t qbase = (g >> 3u) * 32u + (within & 1u) * 16u; const uint32_t shift = (within >> 1u) * 2u; constexpr uint32_t KG = 2u; for (uint32_t j = tid; j < (uint32_t)(BN * (BK / KG)); j += blockDim.x) { const uint32_t nn = j / (uint32_t)(BK / KG); const uint32_t kk0 = (j - nn * (uint32_t)(BK / KG)) * KG; const uint32_t row = n0 + nn; if (row < out_dim) { const unsigned char *blk0 = base0 + (uint64_t)row * row_bytes + (uint64_t)(k0 >> 8u) * 84u; const unsigned char *blk1 = base1 + (uint64_t)row * row_bytes + (uint64_t)(k0 >> 8u) * 84u; const float d0 = dev_f16_to_f32((uint16_t)blk0[80] | ((uint16_t)blk0[81] << 8)); const float dm0 = dev_f16_to_f32((uint16_t)blk0[82] | ((uint16_t)blk0[83] << 8)); const float d1 = dev_f16_to_f32((uint16_t)blk1[80] | ((uint16_t)blk1[81] << 8)); const float dm1 = dev_f16_to_f32((uint16_t)blk1[82] | ((uint16_t)blk1[83] << 8)); const float s0 = (float)(blk0[g] & 0x0fu); const float m0 = (float)(blk0[g] >> 4u); const float s1 = (float)(blk1[g] & 0x0fu); const float m1 = (float)(blk1[g] >> 4u); #pragma unroll for (uint32_t u = 0; u < KG; u++) { const uint32_t kk = kk0 + u; const float q0 = (float)((blk0[16u + qbase + kk] >> shift) & 3u); const float q1 = (float)((blk1[16u + qbase + kk] >> shift) & 3u); const uint32_t sj = kk * (uint32_t)BN + nn; shB0[sj] = __float2half(d0 * s0 * q0 - dm0 * m0); shB1[sj] = __float2half(d1 * s1 * q1 - dm1 * m1); } } else { #pragma unroll for (uint32_t u = 0; u < KG; u++) { const uint32_t kk = kk0 + u; const uint32_t sj = kk * (uint32_t)BN + nn; shB0[sj] = __float2half(0.0f); shB1[sj] = __float2half(0.0f); } } } } template __device__ __forceinline__ static void q2_K_dequant_pair_tile_half_rowwise( half *shB0, half *shB1, const unsigned char *base, uint64_t row_bytes, uint32_t n0, uint32_t k0, uint32_t out_dim, uint32_t tid) { const uint32_t g = (k0 & 255u) >> 4u; const uint32_t within = g & 7u; const uint32_t qbase = (g >> 3u) * 32u + (within & 1u) * 16u; const uint32_t shift = (within >> 1u) * 2u; constexpr uint32_t KG = 4u; constexpr uint32_t UNITS_PER_TILE = (uint32_t)(BN * (BK / KG)); for (uint32_t j = tid; j < 2u * UNITS_PER_TILE; j += blockDim.x) { const uint32_t tile = j / UNITS_PER_TILE; const uint32_t rem = j - tile * UNITS_PER_TILE; const uint32_t nn = rem / (uint32_t)(BK / KG); const uint32_t kk0 = (rem - nn * (uint32_t)(BK / KG)) * KG; const uint32_t row = n0 + tile * (uint32_t)BN + nn; half *shB = tile == 0u ? shB0 : shB1; uint32_t v0 = 0u; uint32_t v1 = 0u; if (row < out_dim) { const unsigned char *blk = base + (uint64_t)row * row_bytes + (uint64_t)(k0 >> 8u) * 84u; const float d = dev_f16_to_f32((uint16_t)blk[80] | ((uint16_t)blk[81] << 8)); const float dm = dev_f16_to_f32((uint16_t)blk[82] | ((uint16_t)blk[83] << 8)); const float s = (float)(blk[g] & 0x0fu); const float m = (float)(blk[g] >> 4u); const uint32_t qbits = *reinterpret_cast(blk + 16u + qbase + kk0); const uint32_t q0 = (qbits >> shift) & 3u; const uint32_t q1 = (qbits >> (8u + shift)) & 3u; const uint32_t q2 = (qbits >> (16u + shift)) & 3u; const uint32_t q3 = (qbits >> (24u + shift)) & 3u; const float ds = d * s; const float dmm = dm * m; v0 = dev_pack_half2_bits(ds * (float)q0 - dmm, ds * (float)q1 - dmm); v1 = dev_pack_half2_bits(ds * (float)q2 - dmm, ds * (float)q3 - dmm); } half *dst = shB + nn * (uint32_t)BK + kk0; *reinterpret_cast(dst) = v0; *reinterpret_cast(dst + 2u) = v1; } } template __device__ __forceinline__ static void q2_K_dequant_dual_pair_tile_half_rowwise( half *shB0g, half *shB0u, half *shB1g, half *shB1u, const unsigned char *gate_base, const unsigned char *up_base, uint64_t row_bytes, uint32_t n0, uint32_t k0, uint32_t out_dim, uint32_t tid) { const uint32_t g = (k0 & 255u) >> 4u; const uint32_t within = g & 7u; const uint32_t qbase = (g >> 3u) * 32u + (within & 1u) * 16u; const uint32_t shift = (within >> 1u) * 2u; constexpr uint32_t KG = 4u; constexpr uint32_t UNITS_PER_TILE = (uint32_t)(BN * (BK / KG)); for (uint32_t j = tid; j < 2u * UNITS_PER_TILE; j += blockDim.x) { const uint32_t tile = j / UNITS_PER_TILE; const uint32_t rem = j - tile * UNITS_PER_TILE; const uint32_t nn = rem / (uint32_t)(BK / KG); const uint32_t kk0 = (rem - nn * (uint32_t)(BK / KG)) * KG; const uint32_t row = n0 + tile * (uint32_t)BN + nn; half *shBg = tile == 0u ? shB0g : shB1g; half *shBu = tile == 0u ? shB0u : shB1u; uint32_t gv0 = 0u; uint32_t gv1 = 0u; uint32_t uv0 = 0u; uint32_t uv1 = 0u; if (row < out_dim) { const unsigned char *gb = gate_base + (uint64_t)row * row_bytes + (uint64_t)(k0 >> 8u) * 84u; const unsigned char *ub = up_base + (uint64_t)row * row_bytes + (uint64_t)(k0 >> 8u) * 84u; const float gd = dev_f16_to_f32((uint16_t)gb[80] | ((uint16_t)gb[81] << 8)); const float gm = dev_f16_to_f32((uint16_t)gb[82] | ((uint16_t)gb[83] << 8)); const float ud = dev_f16_to_f32((uint16_t)ub[80] | ((uint16_t)ub[81] << 8)); const float um = dev_f16_to_f32((uint16_t)ub[82] | ((uint16_t)ub[83] << 8)); const float gs = (float)(gb[g] & 0x0fu); const float gmn = (float)(gb[g] >> 4u); const float us = (float)(ub[g] & 0x0fu); const float umn = (float)(ub[g] >> 4u); const uint32_t gqbits = *reinterpret_cast(gb + 16u + qbase + kk0); const uint32_t uqbits = *reinterpret_cast(ub + 16u + qbase + kk0); const uint32_t gq0 = (gqbits >> shift) & 3u; const uint32_t gq1 = (gqbits >> (8u + shift)) & 3u; const uint32_t gq2 = (gqbits >> (16u + shift)) & 3u; const uint32_t gq3 = (gqbits >> (24u + shift)) & 3u; const uint32_t uq0 = (uqbits >> shift) & 3u; const uint32_t uq1 = (uqbits >> (8u + shift)) & 3u; const uint32_t uq2 = (uqbits >> (16u + shift)) & 3u; const uint32_t uq3 = (uqbits >> (24u + shift)) & 3u; const float gds = gd * gs; const float gmm = gm * gmn; const float uds = ud * us; const float umm = um * umn; gv0 = dev_pack_half2_bits(gds * (float)gq0 - gmm, gds * (float)gq1 - gmm); gv1 = dev_pack_half2_bits(gds * (float)gq2 - gmm, gds * (float)gq3 - gmm); uv0 = dev_pack_half2_bits(uds * (float)uq0 - umm, uds * (float)uq1 - umm); uv1 = dev_pack_half2_bits(uds * (float)uq2 - umm, uds * (float)uq3 - umm); } const uint32_t sj = nn * (uint32_t)BK + kk0; *reinterpret_cast(shBg + sj) = gv0; *reinterpret_cast(shBg + sj + 2u) = gv1; *reinterpret_cast(shBu + sj) = uv0; *reinterpret_cast(shBu + sj + 2u) = uv1; } } __device__ __forceinline__ static float moe_silu_oldhip(float x) { return x * (1.0f / (1.0f + expf(-x))); } __global__ __launch_bounds__(32) static void moe_gate_up_mid_q2K_rows_rpb1_w32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const float *x, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t expert_in_dim, uint32_t expert_mid_dim, uint32_t n_expert, float clamp, int store_gate_up) { const uint32_t lane = threadIdx.x; const uint32_t row = blockIdx.x; const uint32_t pair = blockIdx.y; if (row >= expert_mid_dim || lane >= 32u) return; const uint32_t tok = pair / n_expert; const uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const uint32_t expert = (uint32_t)expert_i; const float *xr = x + (uint64_t)tok * expert_in_dim; const unsigned char *gr = (const unsigned char *)gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes; const unsigned char *ur = (const unsigned char *)up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes; float gate = 0.0f; float up = 0.0f; const uint32_t nb = expert_in_dim >> 8u; for (uint32_t b = 0; b < nb; b++) { const unsigned char *gb = gr + (uint64_t)b * 84u; const unsigned char *ub = ur + (uint64_t)b * 84u; float gd, gdmin, ud, udmin; q2_K_scale_broadcast_w32(gb, &gd, &gdmin); q2_K_scale_broadcast_w32(ub, &ud, &udmin); const uint64_t xbase = (uint64_t)b * 256u; #pragma unroll for (uint32_t kk = 0; kk < 8u; kk++) { const uint32_t i = lane + (kk << 5u); const float xv = xr[xbase + i]; gate += q2_K_dequant_256_scaled_w32(gb, lane, kk, gd, gdmin) * xv; up += q2_K_dequant_256_scaled_w32(ub, lane, kk, ud, udmin) * xv; } } gate = warp_sum_f32(gate); up = warp_sum_f32(up); if (lane == 0u) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; if (store_gate_up) { gate_out[off] = gate; up_out[off] = up; } mid_out[off] = moe_silu_oldhip(gate) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static void moe_gate_up_mid_q2K_rows_w32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const float *x, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t expert_in_dim, uint32_t expert_mid_dim, uint32_t n_expert, float clamp, int store_gate_up) { const uint32_t tid = threadIdx.x; const uint32_t lane = tid & 31u; const uint32_t wave = tid >> 5u; const uint32_t rows_per_block = blockDim.x >> 5u; const uint32_t row = blockIdx.x * rows_per_block + wave; const uint32_t pair = blockIdx.y; if (row >= expert_mid_dim) return; const uint32_t tok = pair / n_expert; const uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const uint32_t expert = (uint32_t)expert_i; const float *xr = x + (uint64_t)tok * expert_in_dim; const unsigned char *gr = (const unsigned char *)gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes; const unsigned char *ur = (const unsigned char *)up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes; float gate = 0.0f; float up = 0.0f; const uint32_t nb = expert_in_dim >> 8u; for (uint32_t b = 0; b < nb; b++) { const unsigned char *gb = gr + (uint64_t)b * 84u; const unsigned char *ub = ur + (uint64_t)b * 84u; float gd, gdmin, ud, udmin; q2_K_scale_broadcast_w32(gb, &gd, &gdmin); q2_K_scale_broadcast_w32(ub, &ud, &udmin); const uint64_t xbase = (uint64_t)b * 256u; #pragma unroll for (uint32_t kk = 0; kk < 8u; kk++) { const uint32_t i = lane + (kk << 5u); const float xv = xr[xbase + i]; gate += q2_K_dequant_256_scaled_w32(gb, lane, kk, gd, gdmin) * xv; up += q2_K_dequant_256_scaled_w32(ub, lane, kk, ud, udmin) * xv; } } gate = warp_sum_f32(gate); up = warp_sum_f32(up); if (lane == 0u) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; if (store_gate_up) { gate_out[off] = gate; up_out[off] = up; } mid_out[off] = moe_silu_oldhip(gate) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static void moe_down_q2K_sum_rows_w32_kernel( float *out, const char *down_base, const float *mid, const int32_t *selected, uint32_t n_tokens, uint32_t expert_mid_dim, uint32_t out_dim, uint64_t down_expert_bytes, uint64_t down_row_bytes) { const uint32_t tid = threadIdx.x; const uint32_t lane = tid & 31u; const uint32_t wave = tid >> 5u; const uint32_t rows_per_block = blockDim.x >> 5u; const uint32_t row = blockIdx.x * rows_per_block + wave; const uint32_t tok = blockIdx.y; if (row >= out_dim || tok >= n_tokens) return; float acc = 0.0f; const uint32_t nb = expert_mid_dim >> 8u; #pragma unroll for (uint32_t slot = 0; slot < 6u; slot++) { int32_t expert_i = selected[(uint64_t)tok * 6u + slot]; if (expert_i < 0) expert_i = 0; const unsigned char *dr = (const unsigned char *)down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes; const float *mr = mid + ((uint64_t)tok * 6u + slot) * expert_mid_dim; for (uint32_t b = 0; b < nb; b++) { const unsigned char *db = dr + (uint64_t)b * 84u; float d, dmin; q2_K_scale_broadcast_w32(db, &d, &dmin); const uint64_t mbase = (uint64_t)b * 256u; #pragma unroll for (uint32_t kk = 0; kk < 8u; kk++) { const uint32_t i = lane + (kk << 5u); acc += q2_K_dequant_256_scaled_w32(db, lane, kk, d, dmin) * mr[mbase + i]; } } } acc = warp_sum_f32(acc); if (lane == 0u) out[(uint64_t)tok * out_dim + row] = acc; } template __global__ static void moe_gate_up_mid_q2K_expert_batch_sharedx_kernel( float *mid_out, half *mid_out_h, const char *gate_base, const char *up_base, const float *x, const float *weights, const uint32_t *counts, const uint32_t *offsets, const uint32_t *pairs, uint32_t min_count, uint32_t max_count, uint32_t expert_in_dim, uint32_t expert_mid_dim, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, float clamp) { extern __shared__ float shx[]; const uint32_t tid = threadIdx.x; const uint32_t lane = tid & 31u; const uint32_t wave = tid >> 5u; const uint32_t rows_per_block = blockDim.x >> 5u; const uint32_t row = blockIdx.x * rows_per_block + wave; const uint32_t expert = blockIdx.y; const bool row_valid = row < expert_mid_dim; const uint32_t count = counts[expert]; if (count == 0u || count < min_count || (max_count != 0u && count >= max_count)) return; const uint32_t first = offsets[expert]; const unsigned char *grow = (const unsigned char *)gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)(row_valid ? row : 0u) * gate_row_bytes; const unsigned char *urow = (const unsigned char *)up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)(row_valid ? row : 0u) * gate_row_bytes; const uint32_t nb = expert_in_dim >> 8u; for (uint32_t p0 = 0; p0 < count; p0 += PAIR_TILE) { uint32_t pair[PAIR_TILE]; float g_acc[PAIR_TILE]; float u_acc[PAIR_TILE]; #pragma unroll for (uint32_t u = 0; u < PAIR_TILE; u++) { pair[u] = (p0 + u < count) ? pairs[first + p0 + u] : UINT32_MAX; g_acc[u] = 0.0f; u_acc[u] = 0.0f; } for (uint32_t b = 0; b < nb; b++) { const uint64_t xbase = (uint64_t)b * 256u; for (uint32_t j = tid; j < PAIR_TILE * 256u; j += blockDim.x) { const uint32_t u = j >> 8u; const uint32_t k = j & 255u; if (pair[u] != UINT32_MAX) { const uint32_t tok = pair[u] / 6u; shx[j] = x[(uint64_t)tok * expert_in_dim + xbase + k]; } else { shx[j] = 0.0f; } } __syncthreads(); if (row_valid) { const unsigned char *gb = grow + (uint64_t)b * 84u; const unsigned char *ub = urow + (uint64_t)b * 84u; float gd, gdmin, ud, udmin; q2_K_scale_broadcast_w32(gb, &gd, &gdmin); q2_K_scale_broadcast_w32(ub, &ud, &udmin); #pragma unroll for (uint32_t kk = 0; kk < 8u; kk++) { const uint32_t i = lane + (kk << 5u); const float gwv = q2_K_dequant_256_scaled_w32(gb, lane, kk, gd, gdmin); const float uwv = q2_K_dequant_256_scaled_w32(ub, lane, kk, ud, udmin); #pragma unroll for (uint32_t u = 0; u < PAIR_TILE; u++) { const float xv = shx[(u << 8u) + i]; g_acc[u] += gwv * xv; u_acc[u] += uwv * xv; } } } __syncthreads(); } #pragma unroll for (uint32_t u = 0; u < PAIR_TILE; u++) { g_acc[u] = warp_sum_f32(g_acc[u]); u_acc[u] = warp_sum_f32(u_acc[u]); } if (lane == 0u && row_valid) { #pragma unroll for (uint32_t u = 0; u < PAIR_TILE; u++) { if (pair[u] != UINT32_MAX) { float g = g_acc[u]; float upv = u_acc[u]; if (clamp > 1.0e-6f) { if (g > clamp) g = clamp; if (upv > clamp) upv = clamp; if (upv < -clamp) upv = -clamp; } const float v = moe_silu_oldhip(g) * upv * weights[pair[u]]; if (OUT_F16) mid_out_h[(uint64_t)pair[u] * expert_mid_dim + row] = __float2half(v); else mid_out[(uint64_t)pair[u] * expert_mid_dim + row] = v; } } } } } template __global__ static void moe_down_q2K_expert_batch_sharedmid_kernel( float *down_out, half *down_out_h, const char *down_base, const float *mid, const half *mid_h, const uint32_t *counts, const uint32_t *offsets, const uint32_t *pairs, uint32_t min_count, uint32_t max_count, uint32_t expert_mid_dim, uint32_t out_dim, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t n_tokens = 0u) { extern __shared__ float shmid[]; const uint32_t tid = threadIdx.x; const uint32_t lane = tid & 31u; const uint32_t wave = tid >> 5u; const uint32_t rows_per_block = blockDim.x >> 5u; const uint32_t row = blockIdx.x * rows_per_block + wave; const uint32_t expert = blockIdx.y; const bool row_valid = row < out_dim; const uint32_t count = counts[expert]; if (count == 0u || count < min_count || (max_count != 0u && count >= max_count)) return; const uint32_t first = offsets[expert]; const unsigned char *drow = (const unsigned char *)down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)(row_valid ? row : 0u) * down_row_bytes; const uint32_t nb = expert_mid_dim >> 8u; for (uint32_t p0 = 0; p0 < count; p0 += PAIR_TILE) { uint32_t pair[PAIR_TILE]; float acc[PAIR_TILE]; #pragma unroll for (uint32_t u = 0; u < PAIR_TILE; u++) { pair[u] = (p0 + u < count) ? pairs[first + p0 + u] : UINT32_MAX; acc[u] = 0.0f; } for (uint32_t b = 0; b < nb; b++) { const uint64_t mbase = (uint64_t)b * 256u; for (uint32_t j = tid; j < PAIR_TILE * 256u; j += blockDim.x) { const uint32_t u = j >> 8u; const uint32_t k = j & 255u; if (pair[u] != UINT32_MAX) { const uint64_t moff = (uint64_t)pair[u] * expert_mid_dim + mbase + k; shmid[j] = MID_F16 ? __half2float(mid_h[moff]) : mid[moff]; } else { shmid[j] = 0.0f; } } __syncthreads(); if (row_valid) { const unsigned char *db = drow + (uint64_t)b * 84u; float d, dmin; q2_K_scale_broadcast_w32(db, &d, &dmin); #pragma unroll for (uint32_t kk = 0; kk < 8u; kk++) { const uint32_t i = lane + (kk << 5u); const float wv = q2_K_dequant_256_scaled_w32(db, lane, kk, d, dmin); #pragma unroll for (uint32_t u = 0; u < PAIR_TILE; u++) acc[u] += wv * shmid[(u << 8u) + i]; } } __syncthreads(); } #pragma unroll for (uint32_t u = 0; u < PAIR_TILE; u++) acc[u] = warp_sum_f32(acc[u]); if (lane == 0u && row_valid) { #pragma unroll for (uint32_t u = 0; u < PAIR_TILE; u++) { if (pair[u] != UINT32_MAX) { if (OUT_F16) { uint64_t dst = (uint64_t)pair[u] * out_dim + row; if (SLOT_MAJOR) { const uint32_t tok = pair[u] / 6u; const uint32_t slot = pair[u] - tok * 6u; dst = ((uint64_t)slot * n_tokens + tok) * out_dim + row; } down_out_h[dst] = __float2half(acc[u]); } else { uint64_t dst = (uint64_t)pair[u] * out_dim + row; if (SLOT_MAJOR) { const uint32_t tok = pair[u] / 6u; const uint32_t slot = pair[u] - tok * 6u; dst = ((uint64_t)slot * n_tokens + tok) * out_dim + row; } down_out[dst] = acc[u]; } } } } } } #if defined(__HIP_PLATFORM_AMD__) || defined(__HIPCC__) __device__ __forceinline__ static float iq2_xxs_dequant_256_direct(const unsigned char *blk, uint32_t i) { const uint16_t d_bits = (uint16_t)blk[0] | ((uint16_t)blk[1] << 8); const uint16_t *q2 = reinterpret_cast(blk + 2u); const uint32_t ib32 = i >> 5u; const uint32_t j = i & 31u; const uint32_t aux_g = (uint32_t)q2[ib32 * 4u + 0u] | ((uint32_t)q2[ib32 * 4u + 1u] << 16); const uint32_t aux_s = (uint32_t)q2[ib32 * 4u + 2u] | ((uint32_t)q2[ib32 * 4u + 3u] << 16); const uint32_t half = j >> 4u; const uint32_t g = (j >> 3u) & 1u; const uint32_t ii = j & 7u; const uint32_t grid_idx = (aux_g >> (8u * ((half << 1u) + g))) & 0xffu; const uint32_t sign_idx = (aux_s >> (14u * half + 7u * g)) & 127u; const uint64_t grid = cuda_iq2xxs_grid[grid_idx]; const uint32_t signs = dev_unpack_iq2_signs(cuda_ksigns_iq2xs[sign_idx]); float w = (float)((grid >> (8u * ii)) & 0xffu); if (signs & (1u << ii)) w = -w; return dev_f16_to_f32(d_bits) * (0.125f + 0.25f * (float)(aux_s >> 28u)) * w; } template __device__ __forceinline__ static void iq2_xxs_dequant_dual_pair_tile_half_rowwise( half *shB0g, half *shB0u, half *shB1g, half *shB1u, const unsigned char *gate_base, const unsigned char *up_base, uint64_t row_bytes, uint32_t n0, uint32_t k0, uint32_t out_dim, uint32_t tid) { constexpr uint32_t KG = 4u; constexpr uint32_t UNITS_PER_TILE = (uint32_t)(BN * (BK / KG)); for (uint32_t j = tid; j < 2u * UNITS_PER_TILE; j += blockDim.x) { const uint32_t tile = j / UNITS_PER_TILE; const uint32_t rem = j - tile * UNITS_PER_TILE; const uint32_t nn = rem / (uint32_t)(BK / KG); const uint32_t kk0 = (rem - nn * (uint32_t)(BK / KG)) * KG; const uint32_t row = n0 + tile * (uint32_t)BN + nn; half *shBg = tile == 0u ? shB0g : shB1g; half *shBu = tile == 0u ? shB0u : shB1u; uint32_t gv0 = 0u, gv1 = 0u, uv0 = 0u, uv1 = 0u; if (row < out_dim) { const unsigned char *gb = gate_base + (uint64_t)row * row_bytes + (uint64_t)(k0 >> 8u) * 66u; const unsigned char *ub = up_base + (uint64_t)row * row_bytes + (uint64_t)(k0 >> 8u) * 66u; const uint32_t kk_base = k0 & 255u; const float g0 = iq2_xxs_dequant_256_direct(gb, kk_base + kk0 + 0u); const float g1 = iq2_xxs_dequant_256_direct(gb, kk_base + kk0 + 1u); const float g2 = iq2_xxs_dequant_256_direct(gb, kk_base + kk0 + 2u); const float g3 = iq2_xxs_dequant_256_direct(gb, kk_base + kk0 + 3u); const float u0 = iq2_xxs_dequant_256_direct(ub, kk_base + kk0 + 0u); const float u1 = iq2_xxs_dequant_256_direct(ub, kk_base + kk0 + 1u); const float u2 = iq2_xxs_dequant_256_direct(ub, kk_base + kk0 + 2u); const float u3 = iq2_xxs_dequant_256_direct(ub, kk_base + kk0 + 3u); gv0 = dev_pack_half2_bits(g0, g1); gv1 = dev_pack_half2_bits(g2, g3); uv0 = dev_pack_half2_bits(u0, u1); uv1 = dev_pack_half2_bits(u2, u3); } const uint32_t sj = nn * (uint32_t)BK + kk0; *reinterpret_cast(shBg + sj) = gv0; *reinterpret_cast(shBg + sj + 2u) = gv1; *reinterpret_cast(shBu + sj) = uv0; *reinterpret_cast(shBu + sj + 2u) = uv1; } } template __global__ static void moe_gate_up_mid_iq2_hotlist_wmma_n2_kernel( float *mid_out, half *mid_out_h, const char *gate_base, const char *up_base, const float *x, const half *x_h, const float *weights, const uint32_t *counts, const uint32_t *offsets, const uint32_t *pairs, const uint32_t *hot_experts, uint32_t hot_count, uint32_t expert_in_dim, uint32_t expert_mid_dim, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, float clamp) { extern __shared__ unsigned char raw_sh[]; half *shA = reinterpret_cast(raw_sh); half *shBg0 = shA + MTILES * BM * BK; half *shBu0 = shBg0 + BK * BN; half *shBg1 = shBu0 + BK * BN; half *shBu1 = shBg1 + BK * BN; float *shCg0 = reinterpret_cast(shBu1 + BK * BN); float *shCu0 = shCg0 + MTILES * BM * BN; float *shCg1 = shCu0 + MTILES * BM * BN; float *shCu1 = shCg1 + MTILES * BM * BN; const uint32_t hot_idx = (uint32_t)blockIdx.z; if (hot_idx >= hot_count) return; const uint32_t expert = hot_experts[hot_idx]; const uint32_t count = counts[expert]; const uint32_t m_group0 = (uint32_t)blockIdx.y * MTILES * BM; if (m_group0 >= count) return; const uint32_t n0 = (uint32_t)blockIdx.x * (2u * BN); const uint32_t tid = threadIdx.x; const uint32_t wave = tid >> 5u; const uint32_t first = offsets[expert]; __shared__ uint32_t shPair[MTILES * BM]; for (uint32_t j = tid; j < MTILES * BM; j += blockDim.x) { const uint32_t bucket_row = m_group0 + j; shPair[j] = (bucket_row < count) ? pairs[first + bucket_row] : UINT32_MAX; } __syncthreads(); using frag_a = rocwmma::fragment; using frag_b = rocwmma::fragment; using frag_c = rocwmma::fragment; frag_a a; frag_b bg0, bu0, bg1, bu1; frag_c accg0, accu0, accg1, accu1; if (wave < MTILES) { rocwmma::fill_fragment(accg0, 0.0f); rocwmma::fill_fragment(accu0, 0.0f); rocwmma::fill_fragment(accg1, 0.0f); rocwmma::fill_fragment(accu1, 0.0f); } const unsigned char *gew = (const unsigned char *)gate_base + (uint64_t)expert * gate_expert_bytes; const unsigned char *uew = (const unsigned char *)up_base + (uint64_t)expert * gate_expert_bytes; for (uint32_t k0 = 0; k0 < expert_in_dim; k0 += BK) { if (X_F16) { for (uint32_t j = tid; j < MTILES * BM * (BK / 2); j += blockDim.x) { const uint32_t pair_row = j / (BK / 2); const uint32_t kk2 = j - pair_row * (BK / 2); const uint32_t pair = shPair[pair_row]; uint32_t v = 0u; if (pair != UINT32_MAX) { const uint32_t token = pair / 6u; const uint64_t xoff = (uint64_t)token * expert_in_dim + k0 + kk2 * 2u; v = *reinterpret_cast(x_h + xoff); } *reinterpret_cast(shA + pair_row * BK + kk2 * 2u) = v; } } else { for (uint32_t j = tid; j < MTILES * BM * BK; j += blockDim.x) { const uint32_t pair_row = j / BK; const uint32_t kk = j - pair_row * BK; const uint32_t pair = shPair[pair_row]; shA[j] = pair != UINT32_MAX ? __float2half(x[(uint64_t)(pair / 6u) * expert_in_dim + k0 + kk]) : __float2half(0.0f); } } iq2_xxs_dequant_dual_pair_tile_half_rowwise( shBg0, shBu0, shBg1, shBu1, gew, uew, gate_row_bytes, n0, k0, expert_mid_dim, tid); __syncthreads(); if (wave < MTILES) { rocwmma::load_matrix_sync(a, shA + wave * BM * BK, BK); rocwmma::load_matrix_sync(bg0, shBg0, BN); rocwmma::load_matrix_sync(bu0, shBu0, BN); rocwmma::load_matrix_sync(bg1, shBg1, BN); rocwmma::load_matrix_sync(bu1, shBu1, BN); rocwmma::mma_sync(accg0, a, bg0, accg0); rocwmma::mma_sync(accu0, a, bu0, accu0); rocwmma::mma_sync(accg1, a, bg1, accg1); rocwmma::mma_sync(accu1, a, bu1, accu1); } __syncthreads(); } if (wave < MTILES) { rocwmma::store_matrix_sync(shCg0 + wave * BM * BN, accg0, BN, rocwmma::mem_row_major); rocwmma::store_matrix_sync(shCu0 + wave * BM * BN, accu0, BN, rocwmma::mem_row_major); rocwmma::store_matrix_sync(shCg1 + wave * BM * BN, accg1, BN, rocwmma::mem_row_major); rocwmma::store_matrix_sync(shCu1 + wave * BM * BN, accu1, BN, rocwmma::mem_row_major); } __syncthreads(); for (uint32_t j = tid; j < MTILES * BM * BN; j += blockDim.x) { const uint32_t mt = j / (BM * BN); const uint32_t rem = j - mt * BM * BN; const uint32_t mm = rem / BN; const uint32_t nn = rem - mm * BN; const uint32_t pair = shPair[mt * BM + mm]; if (pair != UINT32_MAX) { const uint32_t row0 = n0 + nn; const uint32_t row1 = n0 + BN + nn; const float wt = weights[pair]; if (row0 < expert_mid_dim) { float g = shCg0[j], u = shCu0[j]; if (clamp > 1.0e-6f) { if (g > clamp) g = clamp; if (u > clamp) u = clamp; if (u < -clamp) u = -clamp; } const float v = moe_silu_oldhip(g) * u * wt; if (OUT_F16) mid_out_h[(uint64_t)pair * expert_mid_dim + row0] = __float2half(v); else mid_out[(uint64_t)pair * expert_mid_dim + row0] = v; } if (row1 < expert_mid_dim) { float g = shCg1[j], u = shCu1[j]; if (clamp > 1.0e-6f) { if (g > clamp) g = clamp; if (u > clamp) u = clamp; if (u < -clamp) u = -clamp; } const float v = moe_silu_oldhip(g) * u * wt; if (OUT_F16) mid_out_h[(uint64_t)pair * expert_mid_dim + row1] = __float2half(v); else mid_out[(uint64_t)pair * expert_mid_dim + row1] = v; } } } } template __global__ static void moe_gate_up_mid_q2K_hotlist_wmma_n2_kernel( float *mid_out, half *mid_out_h, const char *gate_base, const char *up_base, const float *x, const half *x_h, const float *weights, const uint32_t *counts, const uint32_t *offsets, const uint32_t *pairs, const uint32_t *hot_experts, uint32_t hot_count, uint32_t expert_in_dim, uint32_t expert_mid_dim, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, float clamp) { extern __shared__ unsigned char raw_sh[]; half *shA = reinterpret_cast(raw_sh); half *shBg0 = shA + MTILES * BM * BK; half *shBu0 = shBg0 + BK * BN; half *shBg1 = shBu0 + BK * BN; half *shBu1 = shBg1 + BK * BN; float *shCg0 = reinterpret_cast(shBu1 + BK * BN); float *shCu0 = shCg0 + MTILES * BM * BN; float *shCg1 = shCu0 + MTILES * BM * BN; float *shCu1 = shCg1 + MTILES * BM * BN; const uint32_t hot_idx = (uint32_t)blockIdx.z; if (hot_idx >= hot_count) return; const uint32_t expert = hot_experts[hot_idx]; const uint32_t count = counts[expert]; const uint32_t m_group0 = (uint32_t)blockIdx.y * MTILES * BM; if (m_group0 >= count) return; const uint32_t n0 = (uint32_t)blockIdx.x * (2u * BN); const uint32_t tid = threadIdx.x; const uint32_t wave = tid >> 5u; const uint32_t first = offsets[expert]; __shared__ uint32_t shPair[MTILES * BM]; for (uint32_t j = tid; j < MTILES * BM; j += blockDim.x) { const uint32_t bucket_row = m_group0 + j; shPair[j] = (bucket_row < count) ? pairs[first + bucket_row] : UINT32_MAX; } __syncthreads(); using frag_a = rocwmma::fragment; using frag_b = rocwmma::fragment; using frag_c = rocwmma::fragment; frag_a a; frag_b bg0; frag_b bu0; frag_b bg1; frag_b bu1; frag_c accg0; frag_c accu0; frag_c accg1; frag_c accu1; if (wave < MTILES) { rocwmma::fill_fragment(accg0, 0.0f); rocwmma::fill_fragment(accu0, 0.0f); rocwmma::fill_fragment(accg1, 0.0f); rocwmma::fill_fragment(accu1, 0.0f); } const unsigned char *gew = (const unsigned char *)gate_base + (uint64_t)expert * gate_expert_bytes; const unsigned char *uew = (const unsigned char *)up_base + (uint64_t)expert * gate_expert_bytes; for (uint32_t k0 = 0; k0 < expert_in_dim; k0 += BK) { if (X_F16) { for (uint32_t j = tid; j < MTILES * BM * (BK / 2); j += blockDim.x) { const uint32_t pair_row = j / (BK / 2); const uint32_t kk2 = j - pair_row * (BK / 2); const uint32_t pair = shPair[pair_row]; uint32_t v = 0u; if (pair != UINT32_MAX) { const uint32_t token = pair / 6u; const uint64_t xoff = (uint64_t)token * expert_in_dim + k0 + kk2 * 2u; v = *reinterpret_cast(x_h + xoff); } *reinterpret_cast(shA + pair_row * BK + kk2 * 2u) = v; } } else { for (uint32_t j = tid; j < MTILES * BM * BK; j += blockDim.x) { const uint32_t mt = j / (BM * BK); const uint32_t rem = j - mt * BM * BK; const uint32_t mm = rem / BK; const uint32_t kk = rem - mm * BK; const uint32_t pair = shPair[mt * BM + mm]; if (pair != UINT32_MAX) { const uint32_t token = pair / 6u; shA[j] = __float2half(x[(uint64_t)token * expert_in_dim + k0 + kk]); } else { shA[j] = __float2half(0.0f); } } } q2_K_dequant_dual_pair_tile_half_rowwise( shBg0, shBu0, shBg1, shBu1, gew, uew, gate_row_bytes, n0, k0, expert_mid_dim, tid); __syncthreads(); if (wave < MTILES) { rocwmma::load_matrix_sync(a, shA + wave * BM * BK, BK); rocwmma::load_matrix_sync(bg0, shBg0, BN); rocwmma::load_matrix_sync(bu0, shBu0, BN); rocwmma::load_matrix_sync(bg1, shBg1, BN); rocwmma::load_matrix_sync(bu1, shBu1, BN); rocwmma::mma_sync(accg0, a, bg0, accg0); rocwmma::mma_sync(accu0, a, bu0, accu0); rocwmma::mma_sync(accg1, a, bg1, accg1); rocwmma::mma_sync(accu1, a, bu1, accu1); } __syncthreads(); } if (wave < MTILES) { rocwmma::store_matrix_sync(shCg0 + wave * BM * BN, accg0, BN, rocwmma::mem_row_major); rocwmma::store_matrix_sync(shCu0 + wave * BM * BN, accu0, BN, rocwmma::mem_row_major); rocwmma::store_matrix_sync(shCg1 + wave * BM * BN, accg1, BN, rocwmma::mem_row_major); rocwmma::store_matrix_sync(shCu1 + wave * BM * BN, accu1, BN, rocwmma::mem_row_major); } __syncthreads(); for (uint32_t j = tid; j < MTILES * BM * BN; j += blockDim.x) { const uint32_t mt = j / (BM * BN); const uint32_t rem = j - mt * BM * BN; const uint32_t mm = rem / BN; const uint32_t nn = rem - mm * BN; const uint32_t pair = shPair[mt * BM + mm]; if (pair != UINT32_MAX) { const uint32_t row0 = n0 + nn; const uint32_t row1 = n0 + BN + nn; const float wt = weights[pair]; if (row0 < expert_mid_dim) { float g = shCg0[j]; float u = shCu0[j]; if (clamp > 1.0e-6f) { if (g > clamp) g = clamp; if (u > clamp) u = clamp; if (u < -clamp) u = -clamp; } const float v = moe_silu_oldhip(g) * u * wt; if (OUT_F16) mid_out_h[(uint64_t)pair * expert_mid_dim + row0] = __float2half(v); else mid_out[(uint64_t)pair * expert_mid_dim + row0] = v; } if (row1 < expert_mid_dim) { float g = shCg1[j]; float u = shCu1[j]; if (clamp > 1.0e-6f) { if (g > clamp) g = clamp; if (u > clamp) u = clamp; if (u < -clamp) u = -clamp; } const float v = moe_silu_oldhip(g) * u * wt; if (OUT_F16) mid_out_h[(uint64_t)pair * expert_mid_dim + row1] = __float2half(v); else mid_out[(uint64_t)pair * expert_mid_dim + row1] = v; } } } } template __global__ static void moe_down_q2K_hotlist_wmma_kernel( float *down_out, const char *down_base, const float *mid, const uint32_t *counts, const uint32_t *offsets, const uint32_t *pairs, const uint32_t *hot_experts, uint32_t hot_count, uint32_t expert_mid_dim, uint32_t out_dim, uint64_t down_expert_bytes, uint64_t down_row_bytes) { extern __shared__ unsigned char raw_sh[]; half *shA = reinterpret_cast(raw_sh); half *shB = shA + MTILES * BM * BK; float *shC = reinterpret_cast(shB + BK * BN); const uint32_t hot_idx = (uint32_t)blockIdx.z; if (hot_idx >= hot_count) return; const uint32_t expert = hot_experts[hot_idx]; const uint32_t count = counts[expert]; const uint32_t m_group0 = (uint32_t)blockIdx.y * MTILES * BM; if (m_group0 >= count) return; const uint32_t n0 = (uint32_t)blockIdx.x * BN; const uint32_t tid = threadIdx.x; const uint32_t wave = tid >> 5u; const uint32_t first = offsets[expert]; using frag_a = rocwmma::fragment; using frag_b = rocwmma::fragment; using frag_c = rocwmma::fragment; frag_a a; frag_b b; frag_c acc; if (wave < MTILES) rocwmma::fill_fragment(acc, 0.0f); const unsigned char *dew = (const unsigned char *)down_base + (uint64_t)expert * down_expert_bytes; for (uint32_t k0 = 0; k0 < expert_mid_dim; k0 += BK) { for (uint32_t j = tid; j < MTILES * BM * BK; j += blockDim.x) { const uint32_t mt = j / (BM * BK); const uint32_t rem = j - mt * BM * BK; const uint32_t mm = rem / BK; const uint32_t kk = rem - mm * BK; const uint32_t bucket_row = m_group0 + mt * BM + mm; if (bucket_row < count) { const uint32_t pair = pairs[first + bucket_row]; shA[j] = __float2half(mid[(uint64_t)pair * expert_mid_dim + k0 + kk]); } else { shA[j] = __float2half(0.0f); } } q2_K_dequant_tile_half_rowwise( shB, dew, down_row_bytes, n0, k0, out_dim, tid); __syncthreads(); if (wave < MTILES) { rocwmma::load_matrix_sync(a, shA + wave * BM * BK, BK); rocwmma::load_matrix_sync(b, shB, BN); rocwmma::mma_sync(acc, a, b, acc); } __syncthreads(); } if (wave < MTILES) rocwmma::store_matrix_sync(shC + wave * BM * BN, acc, BN, rocwmma::mem_row_major); __syncthreads(); for (uint32_t j = tid; j < MTILES * BM * BN; j += blockDim.x) { const uint32_t mt = j / (BM * BN); const uint32_t rem = j - mt * BM * BN; const uint32_t mm = rem / BN; const uint32_t nn = rem - mm * BN; const uint32_t bucket_row = m_group0 + mt * BM + mm; const uint32_t row = n0 + nn; if (bucket_row < count && row < out_dim) { const uint32_t pair = pairs[first + bucket_row]; down_out[(uint64_t)pair * out_dim + row] = shC[j]; } } } template __global__ static void moe_down_q2K_hotlist_wmma_n2_kernel( float *down_out, half *down_out_h, const char *down_base, const float *mid, const half *mid_h, const uint32_t *counts, const uint32_t *offsets, const uint32_t *pairs, const uint32_t *hot_experts, uint32_t hot_count, uint32_t expert_mid_dim, uint32_t out_dim, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t n_tokens = 0u) { extern __shared__ unsigned char raw_sh[]; half *shA = reinterpret_cast(raw_sh); half *shB0 = shA + MTILES * BM * BK; half *shB1 = shB0 + BK * BN; float *shC0 = reinterpret_cast(shB1 + BK * BN); float *shC1 = shC0 + MTILES * BM * BN; const uint32_t hot_idx = (uint32_t)blockIdx.z; if (hot_idx >= hot_count) return; const uint32_t expert = hot_experts[hot_idx]; const uint32_t count = counts[expert]; const uint32_t m_group0 = (uint32_t)blockIdx.y * MTILES * BM; if (m_group0 >= count) return; const uint32_t n0 = (uint32_t)blockIdx.x * (2u * BN); const uint32_t tid = threadIdx.x; const uint32_t wave = tid >> 5u; const uint32_t first = offsets[expert]; __shared__ uint32_t shPair[MTILES * BM]; for (uint32_t j = tid; j < MTILES * BM; j += blockDim.x) { const uint32_t bucket_row = m_group0 + j; shPair[j] = (bucket_row < count) ? pairs[first + bucket_row] : UINT32_MAX; } __syncthreads(); using frag_a = rocwmma::fragment; using frag_b = rocwmma::fragment; using frag_c = rocwmma::fragment; frag_a a; frag_b b0; frag_b b1; frag_c acc0; frag_c acc1; if (wave < MTILES) { rocwmma::fill_fragment(acc0, 0.0f); rocwmma::fill_fragment(acc1, 0.0f); } const unsigned char *dew = (const unsigned char *)down_base + (uint64_t)expert * down_expert_bytes; for (uint32_t k0 = 0; k0 < expert_mid_dim; k0 += BK) { if (MID_F16) { for (uint32_t j = tid; j < MTILES * BM * (BK / 2); j += blockDim.x) { const uint32_t pair_row = j / (BK / 2); const uint32_t kk2 = j - pair_row * (BK / 2); const uint32_t pair = shPair[pair_row]; uint32_t v = 0u; if (pair != UINT32_MAX) { const uint64_t moff = (uint64_t)pair * expert_mid_dim + k0 + kk2 * 2u; v = *reinterpret_cast(mid_h + moff); } *reinterpret_cast(shA + pair_row * BK + kk2 * 2u) = v; } } else { for (uint32_t j = tid; j < MTILES * BM * BK; j += blockDim.x) { const uint32_t mt = j / (BM * BK); const uint32_t rem = j - mt * BM * BK; const uint32_t mm = rem / BK; const uint32_t kk = rem - mm * BK; const uint32_t pair = shPair[mt * BM + mm]; if (pair != UINT32_MAX) { shA[j] = __float2half(mid[(uint64_t)pair * expert_mid_dim + k0 + kk]); } else { shA[j] = __float2half(0.0f); } } } q2_K_dequant_pair_tile_half_rowwise( shB0, shB1, dew, down_row_bytes, n0, k0, out_dim, tid); __syncthreads(); if (wave < MTILES) { rocwmma::load_matrix_sync(a, shA + wave * BM * BK, BK); rocwmma::load_matrix_sync(b0, shB0, BN); rocwmma::load_matrix_sync(b1, shB1, BN); rocwmma::mma_sync(acc0, a, b0, acc0); rocwmma::mma_sync(acc1, a, b1, acc1); } __syncthreads(); } if (wave < MTILES) { rocwmma::store_matrix_sync(shC0 + wave * BM * BN, acc0, BN, rocwmma::mem_row_major); rocwmma::store_matrix_sync(shC1 + wave * BM * BN, acc1, BN, rocwmma::mem_row_major); } __syncthreads(); for (uint32_t j = tid; j < MTILES * BM * BN; j += blockDim.x) { const uint32_t mt = j / (BM * BN); const uint32_t rem = j - mt * BM * BN; const uint32_t mm = rem / BN; const uint32_t nn = rem - mm * BN; const uint32_t pair = shPair[mt * BM + mm]; if (pair != UINT32_MAX) { const uint32_t row0 = n0 + nn; const uint32_t row1 = n0 + BN + nn; const uint32_t tok = pair / 6u; const uint32_t slot = pair - tok * 6u; if (row0 < out_dim) { if (OUT_F16) { uint64_t dst = (uint64_t)pair * out_dim + row0; if (SLOT_MAJOR) dst = ((uint64_t)slot * n_tokens + tok) * out_dim + row0; down_out_h[dst] = __float2half(shC0[j]); } else { uint64_t dst = (uint64_t)pair * out_dim + row0; if (SLOT_MAJOR) dst = ((uint64_t)slot * n_tokens + tok) * out_dim + row0; down_out[dst] = shC0[j]; } } if (row1 < out_dim) { if (OUT_F16) { uint64_t dst = (uint64_t)pair * out_dim + row1; if (SLOT_MAJOR) dst = ((uint64_t)slot * n_tokens + tok) * out_dim + row1; down_out_h[dst] = __float2half(shC1[j]); } else { uint64_t dst = (uint64_t)pair * out_dim + row1; if (SLOT_MAJOR) dst = ((uint64_t)slot * n_tokens + tok) * out_dim + row1; down_out[dst] = shC1[j]; } } } } } #endif __device__ static float dev_iq2_xxs_dot_f32(const cuda_block_iq2_xxs *row, const float *x, uint32_t nb) { float acc = 0.0f; for (uint32_t b = 0; b < nb; b++) { const cuda_block_iq2_xxs *xb = row + b; const float d = dev_f16_to_f32(xb->d); const uint16_t *q2 = xb->qs; const float *xf = x + (uint64_t)b * CUDA_QK_K; for (uint32_t ib32 = 0; ib32 < CUDA_QK_K / 32; ib32++) { const uint32_t aux_g = (uint32_t)q2[0] | ((uint32_t)q2[1] << 16); const uint32_t aux_s = (uint32_t)q2[2] | ((uint32_t)q2[3] << 16); q2 += 4; const float dl = d * (0.5f + (float)(aux_s >> 28)) * 0.25f; const uint8_t grids[4] = { (uint8_t)(aux_g & 0xffu), (uint8_t)((aux_g >> 8) & 0xffu), (uint8_t)((aux_g >> 16) & 0xffu), (uint8_t)((aux_g >> 24) & 0xffu), }; for (uint32_t half = 0; half < 2; half++) { for (uint32_t g = 0; g < 2; g++) { const uint32_t gi = half * 2 + g; const uint64_t grid = cuda_iq2xxs_grid[grids[gi]]; const uint8_t signs = cuda_ksigns_iq2xs[(aux_s >> (14u * half + 7u * g)) & 127u]; for (uint32_t i = 0; i < 8; i++) { float w = (float)((grid >> (8u * i)) & 0xffu); if (signs & (1u << i)) w = -w; acc += dl * w * xf[ib32 * 32u + half * 16u + g * 8u + i]; } } } } } return acc; } __device__ static float dev_q2_K_dot_f32(const cuda_block_q2_K *row, const float *x, uint32_t nb) { float acc = 0.0f; for (uint32_t b = 0; b < nb; b++) { const cuda_block_q2_K *xb = row + b; const float d = dev_f16_to_f32(xb->d); const float dmin = dev_f16_to_f32(xb->dmin); for (uint32_t il = 0; il < 16; il++) { const uint32_t chunk = il / 8u; const uint32_t pair = il & 1u; const uint32_t shift = ((il / 2u) & 3u) * 2u; const uint8_t sc = xb->scales[il]; const float dl = d * (float)(sc & 0x0fu); const float ml = dmin * (float)(sc >> 4); const uint8_t *q = xb->qs + 32u * chunk + 16u * pair; const float *xf = x + (uint64_t)b * CUDA_QK_K + chunk * 128u + ((il % 8u) / 2u) * 32u + pair * 16u; for (uint32_t i = 0; i < 16; i++) { const float w = dl * (float)((q[i] >> shift) & 3u) - ml; acc += w * xf[i]; } } } return acc; } __global__ static void moe_gate_up_mid_f32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const float *x, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t expert_in_dim, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t row = blockIdx.x; uint32_t pair = blockIdx.y; if (row >= expert_mid_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const uint32_t nb = expert_in_dim / CUDA_QK_K; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const float *xr = x + (uint64_t)tok * expert_in_dim; float gate = 0.0f; float up = 0.0f; for (uint32_t b = threadIdx.x; b < nb; b += blockDim.x) { gate += dev_iq2_xxs_dot_f32(gr + b, xr + (uint64_t)b * CUDA_QK_K, 1); up += dev_iq2_xxs_dot_f32(ur + b, xr + (uint64_t)b * CUDA_QK_K, 1); } __shared__ float partial_gate[256]; __shared__ float partial_up[256]; partial_gate[threadIdx.x] = gate; partial_up[threadIdx.x] = up; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) { partial_gate[threadIdx.x] += partial_gate[threadIdx.x + stride]; partial_up[threadIdx.x] += partial_up[threadIdx.x + stride]; } __syncthreads(); } if (threadIdx.x == 0) { gate = partial_gate[0]; up = partial_up[0]; if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static void moe_gate_up_mid_q2K_f32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const float *x, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t expert_in_dim, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t row = blockIdx.x; uint32_t pair = blockIdx.y; if (row >= expert_mid_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const uint32_t nb = expert_in_dim / CUDA_QK_K; const cuda_block_q2_K *gr = (const cuda_block_q2_K *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q2_K *ur = (const cuda_block_q2_K *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const float *xr = x + (uint64_t)tok * expert_in_dim; float gate = 0.0f; float up = 0.0f; for (uint32_t b = threadIdx.x; b < nb; b += blockDim.x) { gate += dev_q2_K_dot_f32(gr + b, xr + (uint64_t)b * CUDA_QK_K, 1); up += dev_q2_K_dot_f32(ur + b, xr + (uint64_t)b * CUDA_QK_K, 1); } __shared__ float partial_gate[256]; __shared__ float partial_up[256]; partial_gate[threadIdx.x] = gate; partial_up[threadIdx.x] = up; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) { partial_gate[threadIdx.x] += partial_gate[threadIdx.x + stride]; partial_up[threadIdx.x] += partial_up[threadIdx.x + stride]; } __syncthreads(); } if (threadIdx.x == 0) { gate = partial_gate[0]; up = partial_up[0]; if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static void moe_down_f32_kernel( float *down_out, const char *down_base, const float *mid, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t expert_mid_dim, uint32_t out_dim, uint32_t n_expert) { uint32_t row = blockIdx.x; uint32_t pair = blockIdx.y; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const uint32_t nb = expert_mid_dim / CUDA_QK_K; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const float *xr = mid + (uint64_t)pair * expert_mid_dim; float acc = 0.0f; for (uint32_t b = threadIdx.x; b < nb; b += blockDim.x) acc += dev_q2_K_dot_f32(wr + b, xr + (uint64_t)b * CUDA_QK_K, 1); __shared__ float partial[256]; partial[threadIdx.x] = acc; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) down_out[(uint64_t)pair * out_dim + row] = partial[0]; }