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
98 lines
3.7 KiB
Python
98 lines
3.7 KiB
Python
"""
|
|
Copyright 2026 SGLang Team
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
Slot allocator for the Mamba state pool.
|
|
|
|
Mamba caches one whole state tensor per request, so the allocator hands out
|
|
fixed-size slots (1 per request) rather than paged token KV indices. The
|
|
underlying tensor storage lives in ``MambaPool``; this class owns only the
|
|
free-slot bookkeeping.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Iterator, Optional
|
|
|
|
import torch
|
|
|
|
|
|
class MambaSlotAllocator:
|
|
"""Manages the free-list of Mamba pool slot indices.
|
|
|
|
Unlike ``BaseTokenToKVPoolAllocator`` which is designed for per-token KV
|
|
pages, Mamba slots are request-level (typically 1 slot per request).
|
|
We keep the interface minimal and do NOT inherit the KV base class.
|
|
"""
|
|
|
|
def __init__(self, size: int, device: str):
|
|
self.size = size
|
|
self.device = device
|
|
# Active preallocated batch for `alloc_group_begin` / `alloc_group_end`.
|
|
# When non-None, `alloc(1)` consumes the next slot from this iterator
|
|
# instead of calling `_do_alloc(1)` per request. Reset to None outside
|
|
# a group window so `alloc` falls through to the per-call path.
|
|
self._alloc_iter: Optional[Iterator] = None
|
|
self.clear()
|
|
|
|
def available_size(self) -> int:
|
|
return len(self.free_slots)
|
|
|
|
def schedulable_available_size(self) -> int:
|
|
"""Planner-facing free count. Identity to ``available_size`` for the
|
|
static pool (slot-count and byte-coordinated views coincide); the shared
|
|
``UnifiedMambaSlotAllocator`` overrides it with the byte-coordinated view.
|
|
Lets ``alloc_req_slots`` call it uniformly without a getattr fallback."""
|
|
return self.available_size()
|
|
|
|
def alloc_group_begin(self, num_reqs: int):
|
|
"""Pre-allocate a batch of slots for match_prefix to amortize overhead."""
|
|
self._alloc_iter = None
|
|
if num_reqs > 0:
|
|
result = self._do_alloc(num_reqs)
|
|
if result is not None:
|
|
self._alloc_iter = iter(result.split(1))
|
|
|
|
def alloc_group_end(self):
|
|
"""Return any unused pre-allocated slots from the current group."""
|
|
if self._alloc_iter is not None:
|
|
remaining = list(self._alloc_iter)
|
|
if remaining:
|
|
self.free(torch.cat(remaining))
|
|
self._alloc_iter = None
|
|
|
|
def alloc(self, need_size: int) -> Optional[torch.Tensor]:
|
|
if self._alloc_iter is not None and need_size == 1:
|
|
slot = next(self._alloc_iter, None)
|
|
if slot is not None:
|
|
return slot
|
|
return self._do_alloc(need_size)
|
|
|
|
def _do_alloc(self, need_size: int) -> Optional[torch.Tensor]:
|
|
if need_size > len(self.free_slots):
|
|
return None
|
|
select_index = self.free_slots[:need_size]
|
|
self.free_slots = self.free_slots[need_size:]
|
|
return select_index
|
|
|
|
def free(self, free_index: torch.Tensor):
|
|
if free_index.numel() == 0:
|
|
return
|
|
self.free_slots = torch.cat((self.free_slots, free_index))
|
|
|
|
def clear(self):
|
|
# Slot 0 is reserved as a dummy write target for padded tokens.
|
|
self.free_slots = torch.arange(
|
|
1, self.size + 1, dtype=torch.int64, device=self.device
|
|
)
|