[unified-memory] Stop eviction when shared allocation capacity is sufficient (#33091)
Co-authored-by: seokwoosong <seokwoosong@users.noreply.github.com>
This commit is contained in:
@@ -877,6 +877,17 @@ class TestMlxAuxiliaryStateRunnerCache(unittest.TestCase):
|
||||
self.assertEqual(forked.tolist(), [3])
|
||||
self.assertEqual(restored[0].state[0].tolist(), [1.0])
|
||||
self.assertEqual(pool.available_size(), 3)
|
||||
self.assertEqual(pool.schedulable_available_size(), 3)
|
||||
|
||||
def test_auxiliary_state_pool_returns_unused_group_slots(self):
|
||||
pool = MlxAuxiliaryStatePool(size=4, device="cpu")
|
||||
|
||||
pool.alloc_group_begin(3)
|
||||
allocated = pool.alloc(1)
|
||||
pool.alloc_group_end()
|
||||
|
||||
self.assertEqual(allocated.tolist(), [1])
|
||||
self.assertEqual(pool.available_size(), 3)
|
||||
|
||||
def test_auxiliary_state_pool_restores_instance_meta_state(self):
|
||||
pool = MlxAuxiliaryStatePool(size=2, device="cpu")
|
||||
@@ -916,6 +927,7 @@ class TestMlxAuxiliaryStateRunnerCache(unittest.TestCase):
|
||||
self.assertIsNotNone(auxiliary_state_idx)
|
||||
self.assertIsNone(req.req_pool_idx)
|
||||
self.assertIsNotNone(req.mamba_pool_idx)
|
||||
self.assertIs(pool.mamba_allocator, pool.mamba_pool)
|
||||
self.assertEqual(pool.auxiliary_state_pool.available_size(), 3)
|
||||
pool.free_auxiliary_state_cache(req)
|
||||
self.assertIsNone(req.mamba_pool_idx)
|
||||
|
||||
@@ -144,7 +144,7 @@ class TestDecodeLockRefScenarios(unittest.TestCase):
|
||||
error = queue._reclaim_swa_tail_capacity(129, "req-1")
|
||||
|
||||
self.assertIsNone(error)
|
||||
params = queue.tree_cache.evict.call_args.args[0]
|
||||
params = queue.tree_cache.evict_for_alloc.call_args.args[0]
|
||||
self.assertEqual(params.num_tokens, 0)
|
||||
self.assertEqual(params.swa_num_tokens, 128)
|
||||
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from sglang.srt.mem_cache.base_prefix_cache import EvictParams
|
||||
from sglang.srt.mem_cache.hybrid_cache.hybrid_pool_assembler import (
|
||||
_evict_mamba_for_device_alloc,
|
||||
_evict_swa_for_device_alloc,
|
||||
_split_hicache_size,
|
||||
build_full_draft_pools,
|
||||
)
|
||||
@@ -23,6 +26,40 @@ class _Pool:
|
||||
return self._kv_bytes
|
||||
|
||||
|
||||
class TestDeviceAllocEviction(CustomTestCase):
|
||||
def test_swa_evicts_only_allocation_shortfall(self):
|
||||
cache = MagicMock()
|
||||
cache.token_to_kv_pool_allocator.swa_available_size.return_value = 8
|
||||
|
||||
_evict_swa_for_device_alloc(cache, required_size=10)
|
||||
|
||||
cache.evict_for_alloc.assert_called_once_with(EvictParams(swa_num_tokens=2))
|
||||
cache.evict.assert_not_called()
|
||||
|
||||
def test_mamba_evicts_only_allocation_shortfall(self):
|
||||
cache = MagicMock()
|
||||
allocator = cache.req_to_token_pool.mamba_allocator
|
||||
allocator.schedulable_available_size.return_value = 8
|
||||
|
||||
_evict_mamba_for_device_alloc(cache, required_size=10)
|
||||
|
||||
cache.evict_for_alloc.assert_called_once_with(EvictParams(mamba_num=2))
|
||||
cache.evict.assert_not_called()
|
||||
|
||||
def test_sufficient_capacity_skips_eviction(self):
|
||||
cache = MagicMock()
|
||||
cache.token_to_kv_pool_allocator.swa_available_size.return_value = 10
|
||||
cache.req_to_token_pool.mamba_allocator.schedulable_available_size.return_value = (
|
||||
10
|
||||
)
|
||||
|
||||
_evict_swa_for_device_alloc(cache, required_size=10)
|
||||
_evict_mamba_for_device_alloc(cache, required_size=10)
|
||||
|
||||
cache.evict_for_alloc.assert_not_called()
|
||||
cache.evict.assert_not_called()
|
||||
|
||||
|
||||
class TestSplitHicacheSize(CustomTestCase):
|
||||
def test_splits_total_budget_by_device_bytes(self):
|
||||
# scalar and (k, v) tuple return shapes both supported
|
||||
|
||||
@@ -55,10 +55,10 @@ class _RatioCache:
|
||||
self.component_evictable_size_ = {ComponentType.MAMBA: 0}
|
||||
self.component_protected_size_ = {ComponentType.MAMBA: 0}
|
||||
self.prefix_nodes = []
|
||||
self.alloc_evict_params = []
|
||||
|
||||
def evict(self, params: EvictParams):
|
||||
# Reclaim up to mamba_num evictable (unlocked) prefix snapshots, mirroring
|
||||
# what the real tree eviction can hand back under mamba pressure.
|
||||
def evict_for_alloc(self, params: EvictParams):
|
||||
self.alloc_evict_params.append(params)
|
||||
need = params.mamba_num
|
||||
for node in list(self.prefix_nodes):
|
||||
if need <= 0:
|
||||
@@ -130,7 +130,9 @@ class TestMambaRatioEnvGate(unittest.TestCase):
|
||||
return KVCacheConfigurator._calculate_mamba_ratio(fake)
|
||||
|
||||
def test_flag_off_restores_original_ratios(self):
|
||||
r = lambda **kw: self._ratio(skip=False, **kw)
|
||||
def r(**kwargs):
|
||||
return self._ratio(skip=False, **kwargs)
|
||||
|
||||
self.assertEqual(
|
||||
r(extra_buffer=False, lazy=False, disable_overlap=True), 3
|
||||
) # no_buffer
|
||||
@@ -142,7 +144,9 @@ class TestMambaRatioEnvGate(unittest.TestCase):
|
||||
) # overlap
|
||||
|
||||
def test_flag_on_drops_base_but_keeps_no_buffer(self):
|
||||
r = lambda **kw: self._ratio(skip=True, **kw)
|
||||
def r(**kwargs):
|
||||
return self._ratio(skip=True, **kwargs)
|
||||
|
||||
self.assertEqual(
|
||||
r(extra_buffer=False, lazy=False, disable_overlap=True), 3
|
||||
) # no_buffer
|
||||
@@ -212,9 +216,12 @@ class TestDecSwaLockSkip(unittest.TestCase):
|
||||
class TestMambaDonatedAllocRatio(unittest.TestCase):
|
||||
def test_prefill_peak_ratio2_exhausts_pool(self):
|
||||
# pool = 2N, all N prefixes admission-locked: no evictable victim.
|
||||
component, _, _ = _build_peak(pool_size=2 * N, lock_prefixes=True)
|
||||
component, cache, _ = _build_peak(pool_size=2 * N, lock_prefixes=True)
|
||||
with self.assertRaisesRegex(AssertionError, "Can not alloc mamba cache"):
|
||||
component._alloc_mamba_slot()
|
||||
self.assertEqual(
|
||||
cache.alloc_evict_params, [EvictParams(num_tokens=0, mamba_num=1)]
|
||||
)
|
||||
|
||||
def test_prefill_peak_ratio3_has_headroom(self):
|
||||
# pool = 3N: N free slots remain after own + locked prefix.
|
||||
@@ -230,6 +237,9 @@ class TestMambaDonatedAllocRatio(unittest.TestCase):
|
||||
slot = component._alloc_mamba_slot()
|
||||
self.assertIsNotNone(slot)
|
||||
self.assertEqual(len(cache.prefix_nodes), N - 1)
|
||||
self.assertEqual(
|
||||
cache.alloc_evict_params, [EvictParams(num_tokens=0, mamba_num=1)]
|
||||
)
|
||||
|
||||
|
||||
class TestPPMambaPoolSizing(unittest.TestCase):
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
"""CPU-only tests for allocation-aware UnifiedRadixCache eviction."""
|
||||
|
||||
import unittest
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from sglang.srt.mem_cache.base_prefix_cache import EvictParams
|
||||
from sglang.srt.mem_cache.common import evict_from_tree_cache
|
||||
from sglang.srt.mem_cache.unified_cache.components import ComponentType
|
||||
from sglang.srt.mem_cache.unified_radix_cache import UnifiedRadixCache
|
||||
from sglang.test.ci.ci_register import register_cpu_ci
|
||||
from sglang.test.test_utils import CustomTestCase
|
||||
|
||||
register_cpu_ci(est_time=2, suite="base-a-test-cpu")
|
||||
|
||||
|
||||
class TestUnifiedRadixAllocationEviction(CustomTestCase):
|
||||
@staticmethod
|
||||
def _build_cache(*, collateral_capacity_gain: int):
|
||||
cache = object.__new__(UnifiedRadixCache)
|
||||
cache.disable = False
|
||||
cache.tree_components = (ComponentType.FULL, ComponentType.MAMBA)
|
||||
cache.is_swa_enabled = False
|
||||
cache.cache_controller = None
|
||||
cache.metrics_collector = None
|
||||
cache.tree_core = MagicMock()
|
||||
|
||||
capacity = {"available": 30}
|
||||
allocator = MagicMock()
|
||||
allocator.available_size.side_effect = lambda: capacity["available"]
|
||||
cache.token_to_kv_pool_allocator = allocator
|
||||
cache.req_to_token_pool = MagicMock()
|
||||
|
||||
leaf_count = {"value": 0}
|
||||
|
||||
def next_node(component_type, tracker):
|
||||
if tracker[component_type] >= 70:
|
||||
return None, False
|
||||
return leaf_count["value"] + 1, True
|
||||
|
||||
def evict_leaf(_node_id, tracker):
|
||||
leaf_count["value"] += 1
|
||||
tracker[ComponentType.FULL] += 20
|
||||
tracker[ComponentType.MAMBA] += 1
|
||||
capacity["available"] += (
|
||||
collateral_capacity_gain if leaf_count["value"] == 1 else 20
|
||||
)
|
||||
return None
|
||||
|
||||
cache._evict_device_next_node = MagicMock(side_effect=next_node)
|
||||
cache._evict_device_leaf = MagicMock(side_effect=evict_leaf)
|
||||
return cache, capacity, leaf_count
|
||||
|
||||
def test_allocation_eviction_stops_when_shared_capacity_is_sufficient(self):
|
||||
cache, capacity, leaf_count = self._build_cache(collateral_capacity_gain=70)
|
||||
|
||||
result = cache.evict_for_alloc(EvictParams(num_tokens=70))
|
||||
|
||||
self.assertEqual(capacity["available"], 100)
|
||||
self.assertEqual(leaf_count["value"], 1)
|
||||
self.assertEqual(result.num_tokens_evicted, 20)
|
||||
self.assertEqual(result.mamba_num_evicted, 1)
|
||||
|
||||
def test_explicit_evict_preserves_component_count_semantics(self):
|
||||
cache, _, leaf_count = self._build_cache(collateral_capacity_gain=70)
|
||||
|
||||
result = cache.evict(EvictParams(num_tokens=70))
|
||||
|
||||
self.assertEqual(leaf_count["value"], 4)
|
||||
self.assertEqual(result.num_tokens_evicted, 80)
|
||||
self.assertEqual(result.mamba_num_evicted, 4)
|
||||
|
||||
def test_c128_component_keeps_zero_quota(self):
|
||||
cache, _, _ = self._build_cache(collateral_capacity_gain=70)
|
||||
cache.tree_components = (ComponentType.FULL, ComponentType.C128)
|
||||
cache._evict_device_next_node.side_effect = None
|
||||
cache._evict_device_next_node.return_value = (None, False)
|
||||
|
||||
result = cache.evict(EvictParams(num_tokens=1))
|
||||
|
||||
self.assertEqual(result.num_tokens_evicted, 0)
|
||||
cache.tree_core.evict_device_start.assert_called_once_with(
|
||||
ComponentType.FULL, 1
|
||||
)
|
||||
|
||||
def test_mamba_allocation_counts_collateral_full_capacity(self):
|
||||
cache = object.__new__(UnifiedRadixCache)
|
||||
cache.disable = False
|
||||
cache.tree_components = (ComponentType.FULL, ComponentType.MAMBA)
|
||||
cache.is_swa_enabled = False
|
||||
cache.cache_controller = None
|
||||
cache.metrics_collector = None
|
||||
cache.tree_core = MagicMock()
|
||||
cache.token_to_kv_pool_allocator = MagicMock()
|
||||
|
||||
capacity = {"available": 0}
|
||||
mamba_allocator = MagicMock()
|
||||
mamba_allocator.schedulable_available_size.side_effect = lambda: capacity[
|
||||
"available"
|
||||
]
|
||||
cache.req_to_token_pool = MagicMock(mamba_allocator=mamba_allocator)
|
||||
|
||||
def next_node(component_type, tracker):
|
||||
return (None, False) if tracker[component_type] >= 3 else (1, True)
|
||||
|
||||
def evict_leaf(_node_id, tracker):
|
||||
tracker[ComponentType.FULL] += 20
|
||||
tracker[ComponentType.MAMBA] += 1
|
||||
capacity["available"] += 3
|
||||
return None
|
||||
|
||||
cache._evict_device_next_node = MagicMock(side_effect=next_node)
|
||||
cache._evict_device_leaf = MagicMock(side_effect=evict_leaf)
|
||||
|
||||
result = cache.evict_for_alloc(EvictParams(mamba_num=3))
|
||||
|
||||
self.assertEqual(capacity["available"], 3)
|
||||
self.assertEqual(result.num_tokens_evicted, 20)
|
||||
self.assertEqual(result.mamba_num_evicted, 1)
|
||||
|
||||
def test_common_helper_uses_allocation_aware_entry_point(self):
|
||||
tree_cache = MagicMock()
|
||||
tree_cache.is_chunk_cache.return_value = False
|
||||
tree_cache.token_to_kv_pool_allocator.available_size.return_value = 30
|
||||
|
||||
evict_from_tree_cache(tree_cache, num_tokens=100)
|
||||
|
||||
tree_cache.evict_for_alloc.assert_called_once_with(EvictParams(num_tokens=70))
|
||||
tree_cache.evict.assert_not_called()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -343,6 +343,7 @@ def build_fixture(
|
||||
cfg: CacheConfig,
|
||||
*,
|
||||
enable_kv_cache_events: bool = False,
|
||||
enable_session_radix_cache: bool = False,
|
||||
tree_page_size: Optional[int] = None,
|
||||
mamba_cache_chunk_size: Optional[int] = None,
|
||||
):
|
||||
@@ -472,6 +473,7 @@ def build_fixture(
|
||||
tree_components=cfg.components,
|
||||
enable_mamba_extra_buffer=cfg.enable_mamba_extra_buffer,
|
||||
enable_kv_cache_events=enable_kv_cache_events,
|
||||
enable_session_radix_cache=enable_session_radix_cache,
|
||||
eviction_policy=cfg.eviction_policy,
|
||||
is_eagle=cfg.is_eagle,
|
||||
)
|
||||
@@ -481,6 +483,162 @@ def build_fixture(
|
||||
return cache, allocator, req_to_token_pool
|
||||
|
||||
|
||||
@unittest.skipUnless(torch.cuda.is_available(), "cache fixtures need CUDA")
|
||||
class TestUnifiedRadixAllocationEvictionRealComponents(CustomTestCase):
|
||||
"""Allocation targets are observed between real auxiliary-tree steps."""
|
||||
|
||||
_SHORTFALL = 100
|
||||
|
||||
def _insert(self, cache, allocator, req_to_token_pool, tokens) -> None:
|
||||
value = allocator.alloc(len(tokens))
|
||||
self.assertIsNotNone(value)
|
||||
params = InsertParams(
|
||||
key=RadixKey(array("q", tokens)),
|
||||
value=value[: len(tokens)],
|
||||
)
|
||||
if cache.supports_mamba():
|
||||
req = Req(
|
||||
rid=f"mamba-{len(tokens)}",
|
||||
origin_input_text="",
|
||||
origin_input_ids=array("q"),
|
||||
sampling_params=SamplingParams(temperature=0, max_new_tokens=1),
|
||||
)
|
||||
req_to_token_pool.alloc([req])
|
||||
params.mamba_value = req.mamba_pool_idx.unsqueeze(0)
|
||||
cache.insert(params)
|
||||
|
||||
def _build_internal_chain(self, component_type, enable_session_radix_cache):
|
||||
cfg = (
|
||||
CacheConfig(
|
||||
components=(ComponentType.FULL, ComponentType.SWA),
|
||||
sliding_window_size=128,
|
||||
)
|
||||
if component_type is ComponentType.SWA
|
||||
else CacheConfig(
|
||||
components=(ComponentType.FULL, ComponentType.MAMBA),
|
||||
mamba_cache_size=8,
|
||||
)
|
||||
)
|
||||
cache, allocator, req_to_token_pool = build_fixture(
|
||||
cfg, enable_session_radix_cache=enable_session_radix_cache
|
||||
)
|
||||
for length in (2, 4, 6):
|
||||
self._insert(
|
||||
cache,
|
||||
allocator,
|
||||
req_to_token_pool,
|
||||
list(range(1, length + 1)),
|
||||
)
|
||||
|
||||
lru = cache.tree_core.lru_lists[component_type]
|
||||
first = lru.get_lru_no_lock()
|
||||
second = lru.get_prev_no_lock(first)
|
||||
leaf = lru.get_prev_no_lock(second)
|
||||
self.assertNotIn(first, cache.tree_core.evictable_device_leaves)
|
||||
self.assertNotIn(second, cache.tree_core.evictable_device_leaves)
|
||||
self.assertIn(leaf, cache.tree_core.evictable_device_leaves)
|
||||
for node in (first, second, leaf):
|
||||
self.assertIsNotNone(node.component_data[component_type].value)
|
||||
self.assertIsNotNone(node.component_data[ComponentType.FULL].value)
|
||||
return cache, first, second, leaf
|
||||
|
||||
def _evict_for_alloc_after_first_drain(self, cache, component_type):
|
||||
capacity = {"available": 0}
|
||||
auxiliary_drains = {"count": 0}
|
||||
real_available_size = cache._component_available_size
|
||||
real_free_values = cache._free_values
|
||||
|
||||
def available_size(requested_type):
|
||||
if requested_type is component_type:
|
||||
return capacity["available"]
|
||||
return real_available_size(requested_type)
|
||||
|
||||
def free_values(device_frees, host_frees):
|
||||
freed_auxiliary = bool(device_frees.get(component_type))
|
||||
real_free_values(device_frees, host_frees)
|
||||
if freed_auxiliary:
|
||||
auxiliary_drains["count"] += 1
|
||||
capacity["available"] = self._SHORTFALL
|
||||
|
||||
params = (
|
||||
EvictParams(swa_num_tokens=self._SHORTFALL)
|
||||
if component_type is ComponentType.SWA
|
||||
else EvictParams(mamba_num=self._SHORTFALL)
|
||||
)
|
||||
with (
|
||||
mock.patch.object(
|
||||
cache, "_component_available_size", side_effect=available_size
|
||||
),
|
||||
mock.patch.object(cache, "_free_values", side_effect=free_values),
|
||||
):
|
||||
result = cache.evict_for_alloc(params)
|
||||
return result, auxiliary_drains["count"]
|
||||
|
||||
def test_allocation_target_stops_after_one_internal_tombstone(self):
|
||||
for component_type in (ComponentType.SWA, ComponentType.MAMBA):
|
||||
for enable_session_radix_cache in (False, True):
|
||||
with self.subTest(
|
||||
component_type=component_type,
|
||||
enable_session_radix_cache=enable_session_radix_cache,
|
||||
):
|
||||
cache, first, second, leaf = self._build_internal_chain(
|
||||
component_type, enable_session_radix_cache
|
||||
)
|
||||
first_size = len(first.component_data[component_type].value)
|
||||
|
||||
result, drain_count = self._evict_for_alloc_after_first_drain(
|
||||
cache, component_type
|
||||
)
|
||||
|
||||
self.assertIsNone(first.component_data[component_type].value)
|
||||
self.assertIsNotNone(second.component_data[component_type].value)
|
||||
self.assertIsNotNone(leaf.component_data[component_type].value)
|
||||
self.assertIsNotNone(leaf.component_data[ComponentType.FULL].value)
|
||||
self.assertEqual(result.num_tokens_evicted, 0)
|
||||
self.assertEqual(drain_count, 1)
|
||||
evicted = (
|
||||
result.swa_num_tokens_evicted
|
||||
if component_type is ComponentType.SWA
|
||||
else result.mamba_num_evicted
|
||||
)
|
||||
self.assertEqual(evicted, first_size)
|
||||
cache.sanity_check()
|
||||
|
||||
def test_explicit_evict_continues_across_internal_steps(self):
|
||||
for component_type in (ComponentType.SWA, ComponentType.MAMBA):
|
||||
for enable_session_radix_cache in (False, True):
|
||||
with self.subTest(
|
||||
component_type=component_type,
|
||||
enable_session_radix_cache=enable_session_radix_cache,
|
||||
):
|
||||
cache, first, second, leaf = self._build_internal_chain(
|
||||
component_type, enable_session_radix_cache
|
||||
)
|
||||
request_count = sum(
|
||||
len(node.component_data[component_type].value)
|
||||
for node in (first, second)
|
||||
)
|
||||
params = (
|
||||
EvictParams(swa_num_tokens=request_count)
|
||||
if component_type is ComponentType.SWA
|
||||
else EvictParams(mamba_num=request_count)
|
||||
)
|
||||
|
||||
result = cache.evict(params)
|
||||
|
||||
self.assertIsNone(first.component_data[component_type].value)
|
||||
self.assertIsNone(second.component_data[component_type].value)
|
||||
self.assertIsNotNone(leaf.component_data[component_type].value)
|
||||
self.assertIsNotNone(leaf.component_data[ComponentType.FULL].value)
|
||||
evicted = (
|
||||
result.swa_num_tokens_evicted
|
||||
if component_type is ComponentType.SWA
|
||||
else result.mamba_num_evicted
|
||||
)
|
||||
self.assertEqual(evicted, request_count)
|
||||
cache.sanity_check()
|
||||
|
||||
|
||||
class TestUnifiedRadixCacheEagleHiCacheStorageKey(CustomTestCase):
|
||||
cfg = CacheConfig(
|
||||
page_size=4,
|
||||
@@ -5363,10 +5521,12 @@ class UnifiedRadixCacheSuite:
|
||||
"alloc",
|
||||
side_effect=[None, retry_slot],
|
||||
),
|
||||
mock.patch.object(cache, "evict", autospec=True) as evict,
|
||||
mock.patch.object(
|
||||
cache, "evict_for_alloc", autospec=True
|
||||
) as evict_for_alloc,
|
||||
):
|
||||
prep = comp.prepare_load_back(leaf.id, req=req)
|
||||
evict.assert_called_once_with(EvictParams(num_tokens=0, mamba_num=1))
|
||||
evict_for_alloc.assert_called_once_with(EvictParams(num_tokens=0, mamba_num=1))
|
||||
self.assertIs(prep.allocated_mamba_slot, retry_slot)
|
||||
self.assertEqual(int(req.mamba_pool_idx), int(retry_slot[0]))
|
||||
|
||||
@@ -5790,13 +5950,15 @@ class UnifiedRadixCacheSuite:
|
||||
int(swa_xfer.host_indices.numel()),
|
||||
)
|
||||
|
||||
with mock.patch.object(cache, "evict", wraps=cache.evict) as evict_mock:
|
||||
with mock.patch.object(
|
||||
cache, "evict_for_alloc", wraps=cache.evict_for_alloc
|
||||
) as evict_for_alloc_mock:
|
||||
self.assertTrue(cache.load_back(leaf.id))
|
||||
|
||||
# Full pre-eviction must not be triggered by SWA pool pressure.
|
||||
full_pre_evict_calls = [
|
||||
call
|
||||
for call in evict_mock.call_args_list
|
||||
for call in evict_for_alloc_mock.call_args_list
|
||||
if call.args and call.args[0].num_tokens > 0
|
||||
]
|
||||
self.assertEqual(full_pre_evict_calls, [])
|
||||
@@ -5807,7 +5969,7 @@ class UnifiedRadixCacheSuite:
|
||||
call.args
|
||||
and call.args[0].num_tokens == 0
|
||||
and call.args[0].swa_num_tokens > 0
|
||||
for call in evict_mock.call_args_list
|
||||
for call in evict_for_alloc_mock.call_args_list
|
||||
)
|
||||
)
|
||||
|
||||
@@ -7026,9 +7188,13 @@ class TestReturnedValuesDrain(_InsertWalkSuite):
|
||||
cases = [
|
||||
(
|
||||
"evict_device_next_node",
|
||||
lambda: make(EvictDeviceNextNodeResult, node_id=node.id),
|
||||
lambda: make(
|
||||
EvictDeviceNextNodeResult,
|
||||
node_id=node.id,
|
||||
made_progress=True,
|
||||
),
|
||||
lambda: cache._evict_device_next_node(ComponentType.FULL, tracker),
|
||||
node.id,
|
||||
(node.id, True),
|
||||
),
|
||||
(
|
||||
"evict_device_leaf",
|
||||
|
||||
Reference in New Issue
Block a user