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
2 changes: 1 addition & 1 deletion gcm/monitoring/cli/scontrol_topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def collect_scontrol_topology(
)

topo = instantiate_dataclass(ScontrolTopology, message, logger=logger)
topo.Nodes = expanded
topo.Nodes = ",".join(expanded) if expanded else None
topo.node_count = node_count

yield topo
Expand Down
8 changes: 7 additions & 1 deletion gcm/schemas/slurm/scontrol_topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,11 @@ class ScontrolTopology(DerivedCluster):
LinkSpeed: int | None = parsed_field(parser=maybe_int)
Switches: str | None = parsed_field(parser=str)

Nodes: list[str] | None = None
# Slurm's hostlist notation (`g3-129-[057,059,063]`) expanded and re-joined
# as a comma-separated string. Kept as a string rather than a `list[str]`
# because sinks flatten list fields into one indexed column per element
# (`Nodes.0`, `Nodes.1`, ...), which is both unqueryable as a single value
# and lossy: Scuba caps the columns it keeps per sample, so node lists
# longer than ~507 entries silently lose their leading elements.
Nodes: str | None = parsed_field(parser=str)
node_count: int | None = None
17 changes: 8 additions & 9 deletions gcm/tests/test_scontrol_topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,15 @@ def test_cli_block_topology(tmp_path: Path) -> None:
assert parsed[0]["BlockName"] == "block_DH1-062-US-EAST-04B"
assert parsed[0]["BlockIndex"] == 0
assert parsed[0]["BlockSize"] == 18
assert parsed[0]["Nodes"] == ["g3-129-057", "g3-129-059", "g3-129-063"]
assert parsed[0]["Nodes"] == "g3-129-057,g3-129-059,g3-129-063"
assert parsed[0]["node_count"] == 3
assert "SwitchName" not in parsed[0]
# The node list must land as one column, not one column per element.
assert "Nodes.0" not in parsed[0]

assert parsed[2]["BlockName"] == "block_DH1-067-US-EAST-04B"
assert parsed[2]["BlockIndex"] == 3
assert parsed[2]["Nodes"] == [
"g3-129-235",
"g3-129-237",
"g3-130-001",
"g3-130-003",
]
assert parsed[2]["Nodes"] == "g3-129-235,g3-129-237,g3-130-001,g3-130-003"
assert parsed[2]["node_count"] == 4


Expand All @@ -114,12 +111,13 @@ def test_cli_switch_topology(tmp_path: Path) -> None:
assert parsed[0]["SwitchName"] == "cpu"
assert parsed[0]["Level"] == 0
assert parsed[0]["LinkSpeed"] == 1
assert parsed[0]["Nodes"] == ["cpu-000-109", "cpu-002-219", "cpu-003-040"]
assert parsed[0]["Nodes"] == "cpu-000-109,cpu-002-219,cpu-003-040"
assert parsed[0]["node_count"] == 3
assert "BlockName" not in parsed[0]
assert "Nodes.0" not in parsed[0]

assert parsed[1]["SwitchName"] == "h100"
assert parsed[1]["Nodes"] == ["h100-008-154", "h100-236-009"]
assert parsed[1]["Nodes"] == "h100-008-154,h100-236-009"
assert parsed[1]["node_count"] == 2

assert parsed[2]["SwitchName"] == "spine-use2-az3-0"
Expand All @@ -128,3 +126,4 @@ def test_cli_switch_topology(tmp_path: Path) -> None:

assert parsed[3]["SwitchName"] == "data-transfer"
assert parsed[3]["node_count"] == 0
assert "Nodes" not in parsed[3]
Loading