Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ def build_tensorcast_session_options(
from sglang.srt.runtime_context import get_parallel

parallel = get_parallel()
world_rank = parallel.world_rank
world_size = parallel.world_size
world_rank = parallel.launch_world_rank
world_size = parallel.launch_world_size

rank_label = format_tensorcast_rank_label(world_rank, cast(int, world_size))
if config.transfer_mode == TensorcastTransferMode.ALLOCATOR:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ def test_store_close_lifecycle_is_terminal_and_retains_allocator_roots_in_subpro
)

runtime_context.get_parallel = lambda: SimpleNamespace(
world_rank=0,
world_size=1,
launch_world_rank=0,
launch_world_size=1,
)

class FakeSession:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ def test_registration_constructor_claim_is_final_local_step(
monkeypatch.setattr(
runtime_context,
"get_parallel",
lambda: SimpleNamespace(world_rank=0, world_size=1),
lambda: SimpleNamespace(launch_world_rank=0, launch_world_size=1),
)

def claim(options: object, *, owner: TensorcastStore) -> _FakeSession:
Expand Down
77 changes: 76 additions & 1 deletion test/registered/unit/test_runtime_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from sglang.test.ci.ci_register import register_cpu_ci

register_cpu_ci(est_time=33, suite="base-a-test-cpu")
register_cpu_ci(est_time=45, suite="base-a-test-cpu")

import dataclasses
import json
Expand Down Expand Up @@ -3026,6 +3026,81 @@ def test_the_censuses_would_notice_one(self):
self.assertEqual(_calls_named(legal, "dp_gather_slot"), 0)


class TestEveryParallelReadNamesAParallelField(CustomTestCase):
"""Every ``get_parallel().<name>`` read in the package names a parallel field.

``ParallelContext`` rejects an unknown name only when the read runs, so a
renamed or mistyped name on a path whose tests stub the context out ships
as an ``AttributeError``.
"""

#: Reads of a name no parallel field declares yet, each with its reason.
UNDECLARED = {
# The KV-shard control plane's enable flag has no declared field;
# nothing calls that path yet.
("srt/mem_cache/page_interleave.py", "enable_kv_cache_sharding"),
}

def _reads(self):
"""Yield ``(path, line, name)`` for each attribute read off the context.

A read goes through ``get_parallel()`` directly or through a name the
file binds to it, as in ``parallel = get_parallel()``.
"""
import ast as _ast

for path in _PACKAGE.rglob("*.py"):
tree = _ast.parse(path.read_text(encoding="utf-8-sig"))
relative = path.relative_to(_PACKAGE).as_posix()
bound = {
target.id
for node in _ast.walk(tree)
if isinstance(node, _ast.Assign)
and isinstance(node.value, _ast.Call)
and isinstance(node.value.func, _ast.Name)
and node.value.func.id == "get_parallel"
for target in node.targets
if isinstance(target, _ast.Name)
}
for node in _ast.walk(tree):
if not isinstance(node, _ast.Attribute):
continue
value = node.value
direct = (
isinstance(value, _ast.Call)
and isinstance(value.func, _ast.Name)
and value.func.id == "get_parallel"
)
if direct or (isinstance(value, _ast.Name) and value.id in bound):
yield relative, node.lineno, node.attr

def test_every_read_names_a_declared_field(self):
from sglang.srt.runtime_context import ParallelContext, _parallel_fields

known = set(_parallel_fields()) | set(dir(ParallelContext))
reads = list(self._reads())
self.assertGreater(
len(reads), 100, "found almost no context reads; the census is broken"
)
offenders = sorted(
f"{path}:{line} get_parallel().{name}"
for path, line, name in reads
if name not in known
and not name.startswith("_")
and (path, name) not in self.UNDECLARED
)
self.assertEqual(
offenders,
[],
"these read a name the parallel context does not declare; read the "
"field under its current name:\n " + "\n ".join(offenders),
)
stale = self.UNDECLARED - {(path, name) for path, _, name in reads}
self.assertEqual(
stale, set(), f"these are listed as undeclared but no longer read: {stale}"
)


class TestTheRetiredNamesAreGoneEverywhere(CustomTestCase):
"""Classify parallel getters and reject retired package imports."""

Expand Down
Loading