94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
206 lines
7.7 KiB
Plaintext
206 lines
7.7 KiB
Plaintext
#include <sgl_kernel/tensor.h>
|
|
#include <sgl_kernel/utils.h>
|
|
|
|
#include <sgl_kernel/math.cuh>
|
|
#include <sgl_kernel/type.cuh>
|
|
#include <sgl_kernel/utils.cuh>
|
|
#include <sgl_kernel/vec.cuh>
|
|
#include <sgl_kernel/warp.cuh>
|
|
|
|
#include <sgl_kernel/deepseek_v4/fp8_utils.cuh>
|
|
|
|
#include <dlpack/dlpack.h>
|
|
#include <tvm/ffi/container/tensor.h>
|
|
|
|
#include <bit>
|
|
#include <cstdint>
|
|
#include <cuda_fp8.h>
|
|
|
|
namespace {
|
|
|
|
using deepseek_v4::fp8::cast_to_ue8m0;
|
|
using deepseek_v4::fp8::inv_scale_ue8m0;
|
|
using deepseek_v4::fp8::pack_fp8;
|
|
|
|
struct FusedStoreCacheParam {
|
|
const void* __restrict__ input;
|
|
void* __restrict__ cache;
|
|
const void* __restrict__ indices;
|
|
uint32_t num_tokens;
|
|
};
|
|
|
|
template <typename Float, typename IndicesT, uint32_t kPageBits, bool kUsePDL>
|
|
__global__ void fused_store_flashmla_cache(const __grid_constant__ FusedStoreCacheParam param) {
|
|
using namespace device;
|
|
|
|
/// NOTE: 584 = 576 + 8
|
|
constexpr int64_t kPageBytes = host::div_ceil(584 << kPageBits, 576) * 576;
|
|
|
|
// each warp handles 64 elements, 8 warps, each block handles 1 row
|
|
const auto& [input, cache, indices, num_tokens] = param;
|
|
const uint32_t bid = blockIdx.x;
|
|
const uint32_t tid = threadIdx.x;
|
|
const uint32_t wid = tid / 32;
|
|
|
|
PDLWaitPrimary<kUsePDL>();
|
|
|
|
// prefetch the index
|
|
const auto index = static_cast<const IndicesT*>(indices)[bid];
|
|
// always load the value from input (don't store if invalid)
|
|
using Float2 = packed_t<Float>;
|
|
const auto elems = static_cast<const Float2*>(input)[tid + bid * 256];
|
|
if (wid != 7) {
|
|
const auto [x, y] = cast<fp32x2_t>(elems);
|
|
const auto abs_max = warp::reduce_max(fmaxf(fabs(x), fabs(y)));
|
|
const auto scale_raw = fmaxf(1e-4f, abs_max) / kFP8E4M3Max;
|
|
const auto scale_ue8m0 = cast_to_ue8m0(scale_raw);
|
|
const auto inv_scale = inv_scale_ue8m0(scale_ue8m0);
|
|
const auto result = pack_fp8(x * inv_scale, y * inv_scale);
|
|
const int32_t page = index >> kPageBits;
|
|
const int32_t offset = index & ((1 << kPageBits) - 1);
|
|
const auto page_ptr = pointer::offset(cache, page * kPageBytes);
|
|
const auto value_ptr = pointer::offset(page_ptr, offset * 576);
|
|
const auto scale_ptr = pointer::offset(page_ptr, 576 << kPageBits, offset * 8);
|
|
static_cast<fp8x2_e4m3_t*>(value_ptr)[tid] = result;
|
|
static_cast<uint8_t*>(scale_ptr)[wid] = scale_ue8m0;
|
|
} else {
|
|
const auto result = cast<bf16x2_t>(elems);
|
|
const int32_t page = index >> kPageBits;
|
|
const int32_t offset = index & ((1 << kPageBits) - 1);
|
|
const auto page_ptr = pointer::offset(cache, page * kPageBytes);
|
|
const auto value_ptr = pointer::offset(page_ptr, offset * 576, 448);
|
|
static_cast<bf16x2_t*>(value_ptr)[tid - 7 * 32] = result;
|
|
}
|
|
|
|
PDLTriggerSecondary<kUsePDL>();
|
|
}
|
|
|
|
template <typename Float, typename IndicesT, uint32_t kPageBits, bool kUsePDL>
|
|
__global__ void fused_store_indexer_cache(const __grid_constant__ FusedStoreCacheParam param) {
|
|
using namespace device;
|
|
|
|
/// NOTE: 132 = 128 + 4
|
|
constexpr int64_t kPageBytes = 132 << kPageBits;
|
|
|
|
// each warp handles 128 elements, 1 warp, each block handles multiple rows
|
|
const auto& [input, cache, indices, num_tokens] = param;
|
|
const auto global_tid = blockIdx.x * blockDim.x + threadIdx.x;
|
|
const auto global_wid = global_tid / 32;
|
|
const auto lane_id = threadIdx.x % 32;
|
|
|
|
if (global_wid >= num_tokens) return;
|
|
|
|
PDLWaitPrimary<kUsePDL>();
|
|
|
|
// prefetch the index
|
|
const auto index = static_cast<const IndicesT*>(indices)[global_wid];
|
|
// always load the value from input (don't store if invalid)
|
|
using Float2 = packed_t<Float>;
|
|
using InStorage = AlignedVector<Float2, 2>;
|
|
using OutStorage = AlignedVector<fp8x2_e4m3_t, 2>;
|
|
const auto elems = static_cast<const InStorage*>(input)[global_tid];
|
|
const auto [x0, x1] = cast<fp32x2_t>(elems[0]);
|
|
const auto [y0, y1] = cast<fp32x2_t>(elems[1]);
|
|
const auto local_max = fmaxf(fmaxf(fabs(x0), fabs(x1)), fmaxf(fabs(y0), fabs(y1)));
|
|
const auto abs_max = warp::reduce_max(local_max);
|
|
// use normal fp32 scale
|
|
const auto scale = fmaxf(1e-4f, abs_max) / kFP8E4M3Max;
|
|
const auto inv_scale = 1.0f / scale;
|
|
const int32_t page = index >> kPageBits;
|
|
const int32_t offset = index & ((1 << kPageBits) - 1);
|
|
const auto page_ptr = pointer::offset(cache, page * kPageBytes);
|
|
const auto value_ptr = pointer::offset(page_ptr, offset * 128);
|
|
const auto scale_ptr = pointer::offset(page_ptr, 128 << kPageBits, offset * 4);
|
|
OutStorage result;
|
|
result[0] = pack_fp8(x0 * inv_scale, x1 * inv_scale);
|
|
result[1] = pack_fp8(y0 * inv_scale, y1 * inv_scale);
|
|
static_cast<OutStorage*>(value_ptr)[lane_id] = result;
|
|
static_cast<float*>(scale_ptr)[0] = scale;
|
|
|
|
PDLTriggerSecondary<kUsePDL>();
|
|
}
|
|
|
|
template <typename Float, typename IndicesT, uint32_t kPageSize, bool kUsePDL>
|
|
struct FusedStoreCacheFlashMLAKernel {
|
|
static constexpr int32_t kLogSize = std::countr_zero(kPageSize);
|
|
static constexpr int64_t kPageBytes = host::div_ceil(584 * kPageSize, 576) * 576;
|
|
static constexpr auto kernel = fused_store_flashmla_cache<Float, IndicesT, kLogSize, kUsePDL>;
|
|
|
|
static_assert(std::has_single_bit(kPageSize), "kPageSize must be a power of 2");
|
|
static_assert(1 << kLogSize == kPageSize);
|
|
|
|
static void run(tvm::ffi::TensorView input, tvm::ffi::TensorView cache, tvm::ffi::TensorView indices) {
|
|
using namespace host;
|
|
|
|
auto N = SymbolicSize{"num_tokens"};
|
|
auto device_ = SymbolicDevice{};
|
|
device_.set_options<kDLCUDA>();
|
|
TensorMatcher({N, 512}) // input
|
|
.with_dtype<Float>()
|
|
.with_device(device_)
|
|
.verify(input);
|
|
TensorMatcher({-1, -1}) // cache
|
|
.with_strides({kPageBytes, 1})
|
|
.with_dtype<uint8_t>()
|
|
.with_device(device_)
|
|
.verify(cache);
|
|
TensorMatcher({N}) // indices
|
|
.with_dtype<IndicesT>()
|
|
.with_device(device_)
|
|
.verify(indices);
|
|
const auto num_tokens = static_cast<uint32_t>(N.unwrap());
|
|
const auto params = FusedStoreCacheParam{
|
|
.input = input.data_ptr(),
|
|
.cache = cache.data_ptr(),
|
|
.indices = indices.data_ptr(),
|
|
.num_tokens = num_tokens,
|
|
};
|
|
const auto kBlockSize = 256;
|
|
const auto num_blocks = num_tokens;
|
|
LaunchKernel(num_blocks, kBlockSize, device_.unwrap()).enable_pdl(kUsePDL)(kernel, params);
|
|
}
|
|
};
|
|
|
|
template <typename Float, typename IndicesT, uint32_t kPageSize, bool kUsePDL>
|
|
struct FusedStoreCacheIndexerKernel {
|
|
static constexpr int32_t kLogSize = std::countr_zero(kPageSize);
|
|
static constexpr int64_t kPageBytes = 132 * kPageSize;
|
|
static constexpr auto kernel = fused_store_indexer_cache<Float, IndicesT, kLogSize, kUsePDL>;
|
|
|
|
static_assert(std::has_single_bit(kPageSize), "kPageSize must be a power of 2");
|
|
static_assert(1 << kLogSize == kPageSize);
|
|
|
|
static void run(tvm::ffi::TensorView input, tvm::ffi::TensorView cache, tvm::ffi::TensorView indices) {
|
|
using namespace host;
|
|
|
|
auto N = SymbolicSize{"num_tokens"};
|
|
auto device_ = SymbolicDevice{};
|
|
device_.set_options<kDLCUDA>();
|
|
TensorMatcher({N, 128}) // input
|
|
.with_dtype<Float>()
|
|
.with_device(device_)
|
|
.verify(input);
|
|
TensorMatcher({-1, -1}) // cache
|
|
.with_strides({kPageBytes, 1})
|
|
.with_dtype<uint8_t>()
|
|
.with_device(device_)
|
|
.verify(cache);
|
|
TensorMatcher({N}) // indices
|
|
.with_dtype<IndicesT>()
|
|
.with_device(device_)
|
|
.verify(indices);
|
|
const auto num_tokens = static_cast<uint32_t>(N.unwrap());
|
|
const auto params = FusedStoreCacheParam{
|
|
.input = input.data_ptr(),
|
|
.cache = cache.data_ptr(),
|
|
.indices = indices.data_ptr(),
|
|
.num_tokens = num_tokens,
|
|
};
|
|
const auto kBlockSize = 128;
|
|
const auto num_blocks = div_ceil(num_tokens * 32, kBlockSize);
|
|
LaunchKernel(num_blocks, kBlockSize, device_.unwrap()).enable_pdl(kUsePDL)(kernel, params);
|
|
}
|
|
};
|
|
|
|
} // namespace
|