Files
lightseekorg--tokenspeed/test/runtime/test_flat_block_tables_bridge.py
wehub-resource-sync 59a0a3844c
PR Test AMD / cancel-on-close (push) Has been skipped
PR Test NVIDIA ARM / scan (push) Has been skipped
PR Test NVIDIA / cancel-on-close (push) Has been skipped
PR Test AMD / scan (push) Has been skipped
PR Test NVIDIA ARM / cancel-on-close (push) Has been skipped
PR Test NVIDIA / scan (push) Has been skipped
Release Docker Images / build (cu129-torch-2.11.0) (push) Has been skipped
Release Docker Images / build (cu130-torch-2.11.0) (push) Has been skipped
Release PyPI / publish (push) Has been skipped
Scheduler Python Test / test (push) Successful in 27m19s
Docs / build (push) Successful in 28m8s
Scheduler C++ Test / test (push) Successful in 28m19s
Scheduler C++ Test / test-flat (push) Successful in 28m18s
Docs / deploy (push) Has been cancelled
PR Test AMD / finish (push) Has been cancelled
PR Test NVIDIA / finish (push) Has been cancelled
PR Test NVIDIA ARM / finish (push) Has been cancelled
PR Test NVIDIA ARM / ${{ matrix.name }} (${{ matrix.runner }}) (push) Has been cancelled
PR Test AMD / ${{ matrix.name }} (${{ matrix.runner }}) (push) Has been cancelled
PR Test NVIDIA / ${{ matrix.name }} (${{ matrix.runner }}) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:32:31 +08:00

120 lines
4.2 KiB
Python

from __future__ import annotations
import os
import sys
import unittest
# CI Registration (parsed via AST, runtime no-op)
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from ci_system.ci_register import register_cuda_ci
register_cuda_ci(est_time=10, suite="runtime-1gpu")
def _import_bridge():
"""Import the bridge; skip if torch / tokenspeed_scheduler ext absent."""
from tokenspeed.runtime.engine.scheduler_utils import (
flat_block_tables_from_forward_op,
)
return flat_block_tables_from_forward_op
class FlatBlockTablesBridgeTest(unittest.TestCase):
def setUp(self):
try:
self.bridge = _import_bridge()
except (ImportError, ModuleNotFoundError) as exc:
self.skipTest(
f"flat bridge unavailable (needs torch + tokenspeed_scheduler "
f"ext): {exc}"
)
import torch
self.torch = torch
def _make_op(self, flat_block_tables):
from types import SimpleNamespace
return SimpleNamespace(flat_block_tables=flat_block_tables)
def test_two_groups_shape_and_null_hole_preserved(self):
op = self._make_op(
{
"full": [[11, 12], [13, 0]],
"swa": [[21], [0]],
}
)
out = self.bridge(op, device="cpu", num_reqs=2)
self.assertEqual(set(out.keys()), {"full", "swa"})
full = out["full"]
self.assertEqual(tuple(full.shape), (2, 2))
self.assertEqual(full.dtype, self.torch.int32)
self.assertEqual(full.tolist(), [[11, 12], [13, 0]])
swa = out["swa"]
self.assertEqual(tuple(swa.shape), (2, 1))
self.assertEqual(swa.tolist(), [[21], [0]])
def test_ragged_rows_padded_with_minus_one(self):
op = self._make_op({"full": [[1, 2, 3], [9]]})
out = self.bridge(op, device="cpu", num_reqs=2)
self.assertEqual(out["full"].tolist(), [[1, 2, 3], [9, -1, -1]])
def test_missing_attribute_returns_empty(self):
from types import SimpleNamespace
op = SimpleNamespace()
self.assertEqual(self.bridge(op, device="cpu"), {})
def test_attribute_name_is_pinned(self):
# The bridge reads exactly `flat_block_tables`; a renamed payload
# yields {} like a radix op, so a rename must be caught here.
from types import SimpleNamespace
renamed = SimpleNamespace(flat_page_tables={"full": [[1]]})
self.assertEqual(self.bridge(renamed, device="cpu", num_reqs=1), {})
op = self._make_op({"full": [[1]]})
out = self.bridge(op, device="cpu", num_reqs=1)
self.assertEqual(out["full"].tolist(), [[1]])
def test_row_count_mismatch_raises(self):
op = self._make_op({"full": [[1, 2]]})
with self.assertRaises(ValueError):
self.bridge(op, device="cpu", num_reqs=2)
def test_empty_rows_group_on_live_batch_raises(self):
# An empty row list may not silently vanish on a live op: downstream
# replay would see a per-group hole over stale pages.
op = self._make_op({"full": [[1, 2], [3, 4]], "swa": []})
with self.assertRaisesRegex(ValueError, r"swa.*0 rows"):
self.bridge(op, device="cpu", num_reqs=2)
def test_empty_rows_group_on_zero_req_op_dropped(self):
# bs==0 replay/idle paths treat the resulting {} as "no tables".
op = self._make_op({"full": [], "swa": []})
self.assertEqual(self.bridge(op, device="cpu", num_reqs=0), {})
self.assertEqual(self.bridge(op, device="cpu"), {})
class FlatFlagGatingTest(unittest.TestCase):
"""uses_flat_cache_groups must default to False so every existing
backend stays on today's path; needs torch, skips otherwise."""
def setUp(self):
try:
from tokenspeed.runtime.layers.attention.backends.base import (
AttentionBackend,
)
except (ImportError, ModuleNotFoundError) as exc:
self.skipTest(f"needs torch + backend base: {exc}")
self.AttentionBackend = AttentionBackend
def test_default_backend_does_not_use_flat_groups(self):
self.assertFalse(self.AttentionBackend.uses_flat_cache_groups)
if __name__ == "__main__":
unittest.main()