Skip to content

Commit 982ad1d

Browse files
committed
chore: reconcile srt-bound-versions with lower branch after linearizing
1 parent cde903e commit 982ad1d

4 files changed

Lines changed: 54 additions & 31 deletions

File tree

‎inferencex-e2e/infx/srt_slurm/single_node.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from infx.srt_slurm.workload import (
1818
add_fabric_argument,
1919
bind_workload,
20+
check_setup_script,
2021
compose_recipe,
2122
resolve_fabric,
2223
)
@@ -231,6 +232,7 @@ def main() -> None:
231232
if parsed.command == "prepare":
232233
_, recipe = select_recipe(parsed.recipe, os.environ)
233234
recipe = resolve_fabric(recipe, parsed.fabric)
235+
check_setup_script(recipe, Path(parsed.recipe.partition(":")[0]), repository_root())
234236
arguments = runtime_arguments(parsed.recipe, os.environ)
235237
# srtctl gets the bound variant, never the fragment.
236238
config = parsed.output.with_name("recipe.yaml")

‎inferencex-e2e/infx/srt_slurm/workload.py‎

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -146,21 +146,20 @@ def _block(path: Path) -> dict[str, Any]:
146146
return block
147147

148148

149-
def _check_setup_scripts(recipe: Mapping[str, Any], source: Path, root: Path) -> None:
150-
"""Fail where srtctl would only warn: a setup_script in none of the configs/ it stages."""
151-
blocks = [block for name, block in recipe.items() if name != "schema"]
152-
for block in blocks if "base" in recipe else [recipe]:
153-
scripts = block.get("setup_script") if isinstance(block, Mapping) else None
154-
for script in scripts if isinstance(scripts, list) else [scripts]:
155-
if isinstance(script, str) and not any(
156-
(root / directory / sub / script).is_file()
157-
for directory in SETUP_SCRIPT_DIRS
158-
for sub in ("", "patches")
159-
):
160-
raise ValueError(
161-
f"{source}: setup_script {script} is in none of "
162-
f"{', '.join(map(str, SETUP_SCRIPT_DIRS))} or their patches/"
163-
)
149+
def check_setup_script(recipe: Mapping[str, Any], source: Path, root: Path) -> None:
150+
"""Fail where srtctl would only warn: a bound recipe's setup_script in none of the
151+
configs/ it stages. Launch and ``infx generate`` only: planner snapshots lack the
152+
srt-slurm submodule."""
153+
script = recipe.get("setup_script")
154+
if isinstance(script, str) and not any(
155+
(root / directory / sub / script).is_file()
156+
for directory in SETUP_SCRIPT_DIRS
157+
for sub in ("", "patches")
158+
):
159+
raise ValueError(
160+
f"{source}: setup_script {script} is in none of "
161+
f"{', '.join(map(str, SETUP_SCRIPT_DIRS))} or their patches/"
162+
)
164163

165164

166165
def compose_recipe(
@@ -179,11 +178,8 @@ def compose_recipe(
179178
exporter = {"telemetry": {"dcgm_exporter": {"port": power_port}}}
180179
shared = merge_blocks(shared, merge_blocks(_block(root / TELEMETRY_BLOCK), exporter))
181180
if "base" in raw:
182-
composed = {**raw, "base": merge_blocks(shared, raw["base"])}
183-
else:
184-
composed = merge_blocks(shared, raw)
185-
_check_setup_scripts(composed, path, root)
186-
return composed
181+
return {**raw, "base": merge_blocks(shared, raw["base"])}
182+
return merge_blocks(shared, raw)
187183

188184

189185
def _required(environment: Mapping[str, str], name: str) -> str:
@@ -375,12 +371,9 @@ def main(argv: list[str] | None = None) -> None:
375371
path, _, selector = args.recipe.partition(":")
376372
agentic = os.environ.get("IS_AGENTIC") == "1"
377373
try:
374+
root = repository_root()
378375
composed = compose_recipe(
379-
Path(path),
380-
agentic=agentic,
381-
multinode=True,
382-
root=repository_root(),
383-
power_port=args.power_port,
376+
Path(path), agentic=agentic, multinode=True, root=root, power_port=args.power_port
384377
)
385378
variants = selected_recipes(composed, selector or None)
386379
if len(variants) != 1:
@@ -394,6 +387,7 @@ def main(argv: list[str] | None = None) -> None:
394387
source=Path(path),
395388
)
396389
bound = resolve_fabric(bound, args.fabric)
390+
check_setup_script(bound, Path(path), root)
397391
except (OSError, ValueError, KeyError, TypeError, yaml.YAMLError) as error:
398392
parser.error(str(error))
399393
args.output.write_text(yaml.safe_dump(bound, sort_keys=False))

‎inferencex-e2e/infx/tests/matrix/test_fingerprint.py‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import pytest
66
import yaml
77

8-
from infx.matrix.fingerprint import recipe_fingerprint
8+
from infx.matrix.fingerprint import concrete_recipes, recipe_fingerprint
99
from infx.matrix.generate import generate_config_matrix
1010
from infx.matrix.validation import load_config_files, load_runner_file
1111
from infx.tests.srt_recipes import single_node_fragment, write_shared_blocks
@@ -225,3 +225,20 @@ def test_rows_without_an_srt_recipe_hash_the_row_alone():
225225
assert recipe_fingerprint(row, Path("/nonexistent")) == (
226226
"adfebb88b80b867b258d2e9f972eb51f9f8c8bb2ae2bef10ab80ca8226913878"
227227
)
228+
229+
230+
def test_the_planner_binds_a_script_installed_version_from_the_row(project):
231+
edit(project, f"{MULTI}/disagg.yaml", lambda recipe: recipe["base"].update(
232+
setup_script="vllm-router.sh")) # fmt: skip
233+
edit(project, "configs/master.yaml", lambda master: master["multi"].update(
234+
router={"name": "vllm-router", "version": "0.1.14"})) # fmt: skip
235+
master = load_config_files([str(project / "configs/master.yaml")])
236+
runners = load_runner_file(str(project / "configs/runners.yaml"))
237+
[row, *_] = generate_config_matrix(["multi"], master, runners, eval_mode="none", root=project)
238+
239+
# The checkout's setup scripts are not needed to plan.
240+
[recipe] = concrete_recipes(row, project)
241+
assert recipe["environment"] == {"ROUTER_VERSION": "0.1.14"}
242+
del row["router"]
243+
with pytest.raises(ValueError, match="vllm-router.sh installs vllm-router, so the master"):
244+
recipe_fingerprint(row, project)

‎inferencex-e2e/infx/tests/srt_slurm/test_workload.py‎

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -257,21 +257,31 @@ def test_a_router_pinned_in_setup_pip_packages_must_be_the_master_router():
257257
assert (bound["frontend"], bound["roles"]) == (recipe["frontend"], recipe["roles"])
258258

259259

260-
def test_a_setup_script_must_be_one_srtctl_stages(project):
260+
def test_the_launcher_binder_fails_on_a_setup_script_srtctl_would_not_find(project, tmp_path):
261261
patches = project / "utils/srt-slurm/configs/patches"
262262
patches.mkdir(parents=True)
263263
(patches / "upstream.sh").write_text("true\n")
264264
path = fragment(project, {
265265
"base": {"setup_script": "upstream.sh"}, "override_own": {"setup_script": "own.sh"},
266266
}) # fmt: skip
267+
env = {**os.environ, **MULTI_ENV, "INFERENCEX_REPOSITORY_ROOT": str(project),
268+
"PYTHONPATH": os.pathsep.join([str(ROOT), str(ROOT / "utils/srt-slurm/src")])} # fmt: skip
269+
270+
def bind(variant: str) -> subprocess.CompletedProcess[str]:
271+
return subprocess.run(
272+
[sys.executable, "-m", "infx.srt_slurm.workload", f"{path}:{variant}",
273+
str(tmp_path / "bound.yaml"), "--fabric", "{}"],
274+
env=env, capture_output=True, text=True, check=False,
275+
) # fmt: skip
267276

268-
with pytest.raises(ValueError, match="setup_script own.sh is in none of"):
269-
compose_recipe(path, agentic=False, multinode=True, root=project)
277+
assert bind("base").returncode == 0
278+
missing = bind("override_own")
279+
assert missing.returncode == 2
280+
assert f"{path}: setup_script own.sh is in none of" in missing.stderr
270281
configs = project / "benchmarks/multi_node/srt-slurm-recipes/configs"
271282
configs.mkdir(parents=True)
272283
(configs / "own.sh").write_text("true\n")
273-
composed = compose_recipe(path, agentic=False, multinode=True, root=project)
274-
assert composed["override_own"] == {"setup_script": "own.sh"}
284+
assert bind("override_own").returncode == 0
275285

276286

277287
def test_the_multinode_binder_writes_the_one_selected_variant(project, tmp_path):

0 commit comments

Comments
 (0)