"""``tu remote setup <slug>`` — bring one provider's environment, kit and weights
to what its manifest declares, then prove it by running the model once.
The design follows the optimization kits' own install step, whose choices are
worth stating because each answers a failure this project has actually had:
*Idempotence comes from checking, not from a flag.* There is no ``--force`` and
no state file. Every step asks the filesystem whether it is already done,
reports ``present``, and skips. Re-running after a failure is the normal way to
continue.
*Nothing upstream owns is restated here.* Weights are fetched by the provider's
own declared command, which calls upstream's downloader with upstream's URL
lists and fallbacks. No URL appears in this file or in any manifest, so a
mirror change upstream cannot break setup.
*Nothing is deleted and nothing is retried automatically.* A file whose digest
is not the pin's is named and left in place: upstream writes straight to the
final name, so a truncated transfer and a corrupt file are indistinguishable,
and deleting one to retry would destroy the evidence that says which it was. A
2,286 MB checkpoint that arrived as 28.5 MB of itself served predictions from
this repository for over a month because nothing compared it to anything.
*The environment is verified, not created.* Setup installs into an interpreter
the manifest names through a variable; it does not build venvs, because the
outcome is what matters and uv, ``python -m venv``, conda and pixi all reach it.
An unset variable is refused with the recipe from the lock file's own header.
*It ends by running the model, under a deadline.* Installing successfully is not
evidence that anything works: of the four problems hit bringing up the first
provider, three appeared only at run time, and one of those presented as a
stall rather than an error. Without a deadline a setup waits forever and reports
nothing.
"""
from __future__ import annotations
import contextlib
import fnmatch
import json
import os
import shutil
import socket
import subprocess
import sys
import time
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Dict, List, Optional
from .manifest import ManifestError, ProviderManifest
from .manifest import load as load_manifest
EXIT_OK, EXIT_FAILED, EXIT_USAGE, EXIT_REFUSED, EXIT_NO_ACCELERATOR = 0, 1, 2, 3, 5
# Three verbs, as the kits use them: OK is done, REFUSED is "this does not match
# what was declared", FAILED is "something broke". A caller branches on the word.
OK, REFUSED, FAILED, PRESENT, SKIPPED = "OK", "REFUSED", "FAILED", "present", "skipped"
[docs]
@dataclass
class StepResult:
step: str
verdict: str
detail: str = ""
# One blank-free token when this went wrong, so a skill's table can key on it.
reason: str = ""
lines: List[str] = field(default_factory=list)
seconds: float = 0.0
@property
def ok(self) -> bool:
return self.verdict in (OK, PRESENT, SKIPPED)
[docs]
def kit_root() -> Path:
return Path(
os.environ.get("TOOLUNIVERSE_KIT_ROOT")
or os.path.expanduser("~/.cache/tooluniverse/kits")
)
[docs]
def kit_checkout(manifest: ProviderManifest) -> Optional[Path]:
"""Where this provider's kit lives: content-addressed by its pinned commit.
Two providers pinning the same commit share one checkout, and fetching a
newer commit lands beside the working one instead of over it.
"""
kit = manifest.kit
if not kit.get("upstream") or not kit.get("commit"):
return None
name = kit["upstream"].rstrip("/").rsplit("/", 1)[-1].removesuffix(".git")
return kit_root() / f"{name}@{kit['commit']}"
def _run(
argv: List[str],
*,
cwd: Optional[Path] = None,
env: Optional[Dict[str, str]] = None,
timeout: float = 3600,
) -> subprocess.CompletedProcess:
return subprocess.run(
argv,
cwd=None if cwd is None else os.fspath(cwd),
env=env,
capture_output=True,
text=True,
timeout=timeout,
check=False,
)
def _tail(text: str, n: int = 12) -> List[str]:
return [ln for ln in (text or "").strip().splitlines()[-n:] if ln.strip()]
# ------------------------------------------------------------------- preflight
[docs]
def step_preflight(manifest: ProviderManifest) -> StepResult:
"""Refuse for a host reason before anything large is downloaded.
Every check here is cheap and local. The expensive steps below assume it
passed, so that a machine that cannot run this provider learns so in a
second rather than after 16 GB.
"""
t = time.time()
problems: List[str] = []
notes: List[str] = []
free_gb = shutil.disk_usage(Path.home()).free / 2**30
# The first provider needs ~16 GB: 9.0 weights, 6.4 environment, 0.5 kit.
if free_gb < 20:
problems.append(
f"disk_low: {free_gb:.1f} GiB free under {Path.home()}, this needs ~20"
)
if manifest.gpu_policy != "none":
smi = shutil.which("nvidia-smi")
if not smi:
problems.append("no_nvidia_smi: nvidia-smi is not on PATH")
else:
out = _run(
[
smi,
"--query-gpu=name,driver_version,compute_cap",
"--format=csv,noheader",
],
timeout=30,
)
row = (out.stdout or "").strip().splitlines()
if out.returncode != 0 or not row:
problems.append(f"no_gpu: nvidia-smi returned {out.returncode}")
else:
name, driver, cap = (c.strip() for c in row[0].split(",")[:3])
notes.append(f"GPU {name}, driver {driver}, compute capability {cap}")
# The floor comes from the manifest, not from a constant. It
# is a property of the provider's pinned CUDA and only the
# provider knows it: cu130 needs the 580 series, cu128 runs on
# 570. A hard-coded 580 refused three providers that work, with
# a message asserting a CUDA version they do not pin.
floor = manifest.driver_min
try:
if floor is not None and float(driver.split(".")[0]) < floor:
problems.append(
f"driver_old: {driver}; this provider declares a "
f"floor of {floor:.0f} because {manifest.driver_min_reason}"
)
elif floor is None:
notes.append(
"no [gpu] driver_min declared, so the driver is "
"reported and not judged"
)
except ValueError:
pass
try:
if float(cap) < 8.0:
problems.append(
f"cc_below_floor: compute capability {cap}; the kits' "
f"floor is 8.0 and no configuration lowers it"
)
except ValueError:
pass
if not shutil.which("cc") and not shutil.which("gcc"):
# Triton builds kernels at first use. Not installable without root, so
# this is refused rather than worked around.
problems.append(
"compiler_missing: no cc or gcc on PATH; Triton compiles the kit's "
"kernels at run time (Debian/Ubuntu: apt-get install build-essential)"
)
try:
shm = shutil.disk_usage("/dev/shm").total / 2**30
if shm < 1:
notes.append(
f"/dev/shm is {shm:.2f} GiB — small (a container default); "
f"this provider's worker sets num_workers=0 and does not rely on it"
)
except OSError:
pass
if problems:
return StepResult(
"preflight",
REFUSED,
"; ".join(problems),
reason=problems[0].split(":")[0],
lines=notes,
seconds=time.time() - t,
)
return StepResult(
"preflight",
OK,
"host meets the declared prerequisites",
lines=notes,
seconds=time.time() - t,
)
# ----------------------------------------------------------------- environment
@contextlib.contextmanager
def _build_context(dest: Path, dockerfile: Path):
"""A build context that is the kit tree, without writing into the kit tree.
Two things are in tension. The kit checkout must stay byte-identical to its
pinned commit -- that is what the tamper check enforces, and it is
third-party code we execute. But the kits' Dockerfiles take an optional
pre-filled compile cache from a `_jitcache/` directory in the context, and
their own STOCK.md notes that "a builder that refuses an unmatched COPY glob
needs an empty archive there first". BuildKit is such a builder, and without
one the build stops at `lstat /_jitcache: no such file or directory`.
So the context is a hard-linked shadow of the checkout: no file is copied,
nothing in the checkout is touched, and the empty archive the builder wants
exists only in the shadow, which is removed afterwards.
"""
import tarfile
import tempfile
root = Path(tempfile.mkdtemp(prefix="tu-build-ctx-"))
try:
shadow = root / "ctx"
link = subprocess.run(
["cp", "-al", os.fspath(dest), os.fspath(shadow)],
capture_output=True,
text=True,
)
if link.returncode != 0: # a different filesystem, or no hard links
shutil.copytree(dest, shadow, ignore=shutil.ignore_patterns(".git"))
if "_jitcache" in dockerfile.read_text():
jit = shadow / "_jitcache"
jit.mkdir(exist_ok=True)
# The name has to satisfy the Dockerfile's own glob, which is
# keyed on the kit: `COPY _jitcache/<kit>-*-jit.ta[r]`. An archive
# the glob does not match leaves the pattern unmatched, which is
# the failure this exists to prevent.
kit_name = dockerfile.resolve().parents[1].name
with tarfile.open(jit / f"{kit_name}-empty-jit.tar", "w"):
pass
yield shadow
finally:
shutil.rmtree(root, ignore_errors=True)
def _build_image(manifest, dest: Path, t: float) -> Optional[StepResult]:
"""Build the provider's image from the kit's own recipe, if it is absent.
The kits ship `environment/Dockerfile` and `environment/apptainer.def` for
every one of the thirty-six, and the Dockerfile expects the bundle root as
its build context (it copies `common/` as well as the kit). Neither recipe
is copied or rewritten here; the checkout is the context.
"""
kit = manifest.kit
subdir = kit.get("subdir")
if not subdir:
return StepResult(
"environment",
REFUSED,
"a container environment needs [kit] subdir: the image is built from "
"that kit's own environment/ recipe",
reason="no_kit_subdir",
seconds=time.time() - t,
)
if manifest.env_kind == "docker":
if not shutil.which("docker"):
return StepResult(
"environment",
REFUSED,
"docker is not on PATH",
reason="docker_missing",
seconds=time.time() - t,
)
have = _run(["docker", "image", "inspect", manifest.env_image], timeout=120)
if "permission denied" in (have.stderr or "").lower():
return StepResult(
"environment",
REFUSED,
f"this process cannot reach the docker daemon. Being added to the "
f"docker group does not change a session already running: start a "
f"new login shell, or run this under `sg docker -c ...`",
reason="docker_permission",
seconds=time.time() - t,
)
if have.returncode == 0:
return StepResult(
"environment",
PRESENT,
f"docker image {manifest.env_image} is present",
seconds=time.time() - t,
)
dockerfile = dest / subdir / "environment" / "Dockerfile"
if not dockerfile.is_file():
return StepResult(
"environment",
REFUSED,
f"{dockerfile} does not exist",
reason="no_dockerfile",
seconds=time.time() - t,
)
# The kit's apptainer.def bootstraps from a Docker tag of its own
# choosing. Applying that tag here as well lets the Apptainer route use
# the kit's recipe unchanged -- its %post creates the libcuda symlinks
# Triton's launcher stub wants -- instead of editing a file in a
# checkout that has to stay byte-identical to its pinned commit.
tags = ["-t", manifest.env_image]
definition = dest / subdir / "environment" / "apptainer.def"
if definition.is_file():
for line in definition.read_text().splitlines():
if line.strip().lower().startswith("from:"):
wanted = line.split(":", 1)[1].strip()
if wanted and wanted != manifest.env_image:
tags += ["-t", wanted]
break
with _build_context(dest, dockerfile) as context:
out = _run(
[
"docker",
"build",
"-f",
os.fspath(context / dockerfile.relative_to(dest)),
*tags,
os.fspath(context),
],
timeout=14400,
)
if out.returncode != 0:
return StepResult(
"environment",
FAILED,
f"building {manifest.env_image} from {dockerfile} failed",
reason="docker_build_failed",
lines=_tail(out.stderr or out.stdout, 12),
seconds=time.time() - t,
)
return StepResult(
"environment",
OK,
f"built docker image {manifest.env_image}",
lines=_tail(out.stdout, 3),
seconds=time.time() - t,
)
runner = shutil.which("apptainer") or shutil.which("singularity")
if not runner:
return StepResult(
"environment",
REFUSED,
"neither apptainer nor singularity is on PATH",
reason="apptainer_missing",
seconds=time.time() - t,
)
sif = Path(manifest.env_sif).expanduser()
if sif.is_file():
return StepResult(
"environment", PRESENT, f"{sif} is present", seconds=time.time() - t
)
definition = dest / subdir / "environment" / "apptainer.def"
if not definition.is_file():
return StepResult(
"environment",
REFUSED,
f"{definition} does not exist",
reason="no_apptainer_def",
seconds=time.time() - t,
)
# The kits' .def bootstraps from the Docker image built first; a published
# tag would change its two header lines, which is the kit's business.
sif.parent.mkdir(parents=True, exist_ok=True)
out = _run(
[runner, "build", os.fspath(sif), os.fspath(definition)],
cwd=dest,
timeout=14400,
)
if out.returncode != 0:
return StepResult(
"environment",
FAILED,
f"building {sif} from {definition} failed",
reason="apptainer_build_failed",
lines=_tail(out.stderr or out.stdout, 12),
seconds=time.time() - t,
)
return StepResult("environment", OK, f"built {sif}", seconds=time.time() - t)
_ARCH_PROBE = r"""
import json, sys
out = {}
try:
import torch
out["torch"] = torch.__version__
out["arch_list"] = list(torch.cuda.get_arch_list())
if torch.cuda.is_available():
out["device_sm"] = "sm_%d%d" % torch.cuda.get_device_capability(0)
out["device"] = torch.cuda.get_device_name(0)
except Exception as exc:
out["error"] = "%s: %s" % (type(exc).__name__, exc)
try:
import glob as _glob, os as _os, re as _re, subprocess as _sp
import triton as _triton
_d = _os.path.dirname(_triton.__file__)
out["triton"] = _triton.__version__
_llvm = set()
for _lib in (_glob.glob(_os.path.join(_d, "_C", "libtriton*.so"))
+ _glob.glob(_os.path.join(_d, "**", "libtriton*.so"), recursive=True))[:2]:
with open(_lib, "rb") as _f:
_llvm |= {m.decode() for m in _re.findall(rb"sm_\d+a?", _f.read())}
out["triton_llvm"] = sorted(_llvm)
_ptx = {}
for _p in sorted(_glob.glob(_os.path.join(_d, "backends", "nvidia", "bin", "ptxas*"))):
try:
_r = _sp.run([_p, "--help"], capture_output=True, text=True, timeout=60)
_ptx[_os.path.basename(_p)] = sorted(
set(_re.findall(r"sm_\d+a?", (_r.stdout or "") + (_r.stderr or ""))))
except Exception:
_ptx[_os.path.basename(_p)] = []
out["triton_ptxas"] = _ptx
except Exception:
pass
try:
# A provider's accelerator is not always torch's. af3_jax pins a CPU-only
# torch because its weights converter is a torch script, and judging that
# provider's card by `torch.cuda.is_available()` refused it while JAX drove
# the GPU. So the probe reports what every framework present can see and
# the caller decides, rather than assuming one of them is authoritative.
import jax as _jax
out["jax"] = _jax.__version__
out["jax_backend"] = _jax.default_backend()
_devs = _jax.local_devices(backend="gpu") if out["jax_backend"] == "gpu" else []
if _devs:
out["jax_device"] = str(_devs[0])
out["jax_device_cc"] = str(getattr(_devs[0], "compute_capability", "") or "")
except Exception:
pass
sys.stdout.write("ARCH " + json.dumps(out))
"""
def _probe_arch(exec_env) -> Optional[Dict[str, Any]]:
"""What the model interpreter says about torch and Triton, probed once.
Both toolchain checks read this, so the interpreter is started once rather
than once per check.
"""
argv, env = exec_env.argv(["-c", _ARCH_PROBE])
try:
out = _run(argv, env=env, timeout=600)
except (OSError, subprocess.TimeoutExpired) as exc:
return {"probe_error": type(exc).__name__}
for line in (out.stdout or "").splitlines():
if line.startswith("ARCH "):
return json.loads(line[5:])
return None
def _toolchain_problems(exec_env, gpu_required: bool) -> tuple:
"""``(refusal, reason, notes)``: torch's cubins refuse; Triton's two stages note."""
info = _probe_arch(exec_env)
if info is None:
return None, "", []
if "probe_error" in info:
return (
f"the installed torch could not be probed ({info['probe_error']})",
"torch_arch_unsupported",
[],
)
problem = _arch_problem(info, gpu_required)
if problem:
return problem, "torch_arch_unsupported", []
notes = _check_triton_targets_this_gpu(info)
if info.get("triton") and info.get("device_sm"):
probed = _probe_triton_compile(exec_env)
if probed and not probed.get("skipped") and not probed.get("ok"):
notes.insert(
0,
f"MEASURED: this interpreter cannot compile and run a "
f"warp-shuffle kernel on {info['device_sm']} "
f"(rc={probed.get('rc')}: {probed.get('why', 'no reason')}). "
f"Any kernel reaching tl.sum, tl.max or tl.dot aborts the "
f"process, which no worker can catch. This is the question the "
f"string reads below only approximate: atlasfold passed them "
f"and still died, because cuEquivariance ships Triton kernels "
f"of its own. Three real routes out -- ablate the Triton levers "
f"through the kit's door where it has one, switch upstream's "
f"own kernel flag where it has one (atlasfold needed BOTH), or "
f"a host whose Triton knows this card",
)
return None, "", notes
# The kernel the probe compiles. `tl.sum` is the construct that emits the warp
# shuffle, which is the instruction a Triton too old for this card cannot lower.
_REDUCE_SRC = "\n".join(
[
"import torch, triton, triton.language as tl",
"",
"@triton.jit",
"def _k(x_ptr, o_ptr, N: tl.constexpr):",
" tl.store(o_ptr, tl.sum(tl.load(x_ptr + tl.arange(0, N)), axis=0))",
"",
"x = torch.ones(256, device='cuda', dtype=torch.float32)",
"o = torch.zeros(1, device='cuda', dtype=torch.float32)",
"_k[(1,)](x, o, N=256)",
"torch.cuda.synchronize()",
"assert abs(float(o[0]) - 256.0) < 1e-3, float(o[0])",
"print('REDUCE_OK')",
]
)
# Written to a FILE and run as a CHILD, for two reasons that each cost an agent
# an hour. ``@triton.jit`` reads its own body with ``inspect.getsource``, so a
# kernel defined inside ``python -c`` fails with "could not get source code" --
# the right verdict for the wrong reason. And the failure being tested for is an
# abort(), which no try/except in the calling process could survive.
_TRITON_COMPILE_PROBE = "\n".join(
[
"import json, os, subprocess, sys, tempfile",
"SRC = " + repr(_REDUCE_SRC),
"out = {}",
"try:",
" import triton",
"except Exception:",
" sys.stdout.write('TRITONC ' + json.dumps({'skipped': 'no triton'}))",
" raise SystemExit",
"d = tempfile.mkdtemp(prefix='tu-triton-probe-')",
"f = os.path.join(d, 'probe_reduce.py')",
"open(f, 'w').write(SRC)",
"try:",
" r = subprocess.run([sys.executable, f], capture_output=True,",
" text=True, timeout=600)",
" out['rc'] = r.returncode",
" out['ok'] = 'REDUCE_OK' in (r.stdout or '')",
" if not out['ok']:",
" tail = ((r.stderr or '') + (r.stdout or '')).strip().splitlines()",
" out['why'] = tail[-1][:200] if tail else 'no output'",
"except Exception as exc:",
" out['rc'], out['ok'] = None, False",
" out['why'] = '%s: %s' % (type(exc).__name__, exc)",
"sys.stdout.write('TRITONC ' + json.dumps(out))",
]
)
def _probe_triton_compile(exec_env) -> Optional[Dict[str, Any]]:
"""Can this interpreter compile AND RUN a warp-shuffle kernel on this card?
Strictly stronger than reading ``libtriton.so``'s target strings, and the
atlasfold bring-up is why it exists: that provider's static reads were
correct and still did not predict its failure, because **cuEquivariance
ships Triton kernels of its own** and nothing in Triton's target list says
whether a second consumer's kernels will build. The question a host
actually has is "can this interpreter emit a shuffle kernel for this GPU",
and one kernel answers it in about two seconds.
"""
argv, env = exec_env.argv(["-c", _TRITON_COMPILE_PROBE])
try:
out = _run(argv, env=env, timeout=900)
except (OSError, subprocess.TimeoutExpired):
return None
for line in (out.stdout or "").splitlines():
if line.startswith("TRITONC "):
return json.loads(line[8:])
return None
def _check_triton_targets_this_gpu(info: Dict[str, Any]) -> List[str]:
"""Notes on Triton's two separate abilities to emit code for this card.
Triton is a SECOND toolchain beside torch's cubins, and the existing arch
check cannot see it: a stack whose ``torch.cuda.get_arch_list()`` covers
this card can still fail its kernels. There are two places it fails:
* **LLVM.** Triton's target machine must list ``sm_<cc>a``. triton 3.3.1
does not, and a kernel reducing ACROSS LANES then aborts the process:
``LLVM ERROR: Cannot select: intrinsic %llvm.nvvm.shfl.sync.bfly.i32``.
* **ptxas.** Triton shells out to the ``ptxas`` bundled in its own wheel.
triton 3.4.0's is CUDA 12.8, which has no sm_121 of any spelling, while
Triton asks for ``sm_121a`` above cc 90.
**Both are notes and neither is a refusal, and the first version of this
check got that wrong.** It refused the LLVM case on the grounds that "every
kernel this stack compiles would abort", which is false. evo2 runs on triton
3.3.1 on this card: its kit spells its reductions out by hand for bitwise
reproducibility, and nothing on its path calls ``tl.sum``, ``tl.reduce`` or
``tl.dot``. atlasfold, on the identical triton, dies. A bare ``tl.sum``
kernel probed in both environments core-dumps in both -- so the stack's
inability is real, and whether it matters is a property of the provider's
kernels, which this layer cannot see. It reports what it measured and names
the audit. A refusal was a false refusal on a provider that works, which is
worse than having no check.
Measured across twelve provider environments on one card: ten clean, e1
(3.4.0) ptxas only, atlasfold and evo2 (3.3.1) both -- and of those two, one
runs. triton 3.6.0 onward bundles a ``ptxas-blackwell`` and needs nothing.
"""
sm = info.get("device_sm")
if not sm or "triton" not in info:
return []
notes: List[str] = []
wanted = {sm, sm + "a"}
llvm = set(info.get("triton_llvm") or ())
if llvm and not (wanted & llvm):
notes.append(
f"triton {info['triton']}'s LLVM target machine does not list {sm} "
f"and ignores it. A kernel that reduces ACROSS LANES -- tl.sum, "
f'tl.max, tl.dot -- then aborts the process with "LLVM ERROR: '
f'Cannot select: intrinsic %llvm.nvvm.shfl.sync.bfly.i32", which '
f"no worker can catch. A kernel that does not reduce compiles and "
f"runs correctly: on this card atlasfold dies and evo2 does not, on "
f"the same triton 3.3.1, because evo2's kit spells its reductions "
f"out by hand. So AUDIT the kernels on this provider's path for "
f"tl.sum, tl.reduce and tl.dot, and record the audit in the "
f"manifest. The first Triton to list {sm} is 3.4.0; raising it "
f"deviates from the kit's lock, which is a decision, not a fix"
)
ptxas = info.get("triton_ptxas") or {}
if ptxas and not any(wanted & set(v) for v in ptxas.values()):
notes.append(
f"triton {info['triton']} bundles no ptxas that targets {sm} "
f"({', '.join(sorted(ptxas)) or 'none found'}), so kernels fail "
f"with \"ptxas fatal: Value '{sm}a' is not defined\" unless the "
f"provider supplies one. The fix is nvidia-cuda-nvcc-cu12==12.9.86 "
f"in the lock, pointed at by the worker only when triton's own does "
f"not list this card (see remote/e1 and remote/evo2). The variable "
f"name is derived rather than literal: triton builds it as "
f"TRITON_<BINARY>_PATH and selects ptxas-blackwell above cc 100, so "
f"on this card it reads TRITON_PTXAS-BLACKWELL_PATH, hyphen "
f"included, and a worker should set both spellings. triton 3.6.0 "
f"onward bundles its own 12.9 and needs none of this"
)
return notes
def _check_torch_targets_this_gpu(exec_env, gpu_required: bool) -> Optional[str]:
"""Why the installed torch cannot drive this card, or None.
A pinned stack can be perfectly installable and still unable to emit code
for the GPU in front of it. Five of the thirty-six kits pin torch below 2.7
-- flashzoi 2.5.1, proteinmpnn 2.5.1, rfdiffusion1 2.4.0, caliby 2.6.0 --
whose CUDA builds stop at sm_90, and this project's card is sm_121. Without
this the first sign is a kernel error after several gigabytes have been
downloaded and an environment built.
Read from torch rather than inferred from a version: ``get_arch_list`` is
what the build actually carries, and a build can carry PTX for an older
architecture that the driver then compiles forward, which a version
comparison would call a failure.
"""
info = _probe_arch(exec_env)
if info is None:
return None # no torch in this environment: not every provider has one
if "probe_error" in info:
return f"the installed torch could not be probed ({info['probe_error']})"
return _arch_problem(info, gpu_required)
def _arch_problem(info: Dict[str, Any], gpu_required: bool) -> Optional[str]:
"""Why torch's own cubins cannot drive this card, or None."""
if info.get("error") or not info.get("device_sm"):
if info.get("jax_backend") == "gpu" and info.get("jax_device"):
# Another framework has the card. This was a false refusal on
# af3_jax, whose kit must pin a CPU-only torch because its weights
# converter is a torch script: `torch_arch_unsupported` fired while
# jax reported a CudaDevice and drove the GPU. The lesson is the one
# the Triton note already carries -- a check written from one
# framework's assumptions refuses providers that work.
return None
return (
None
if not gpu_required
else f"torch reports no usable GPU: {info.get('error', 'no device')}"
)
sm, arches = info["device_sm"], info.get("arch_list") or []
def parse(name):
digits = "".join(c for c in name.split("_")[-1] if c.isdigit())
return (int(digits[:-1]), int(digits[-1])) if len(digits) >= 2 else None
want = parse(sm)
if want is None:
return None
for arch in arches:
got = parse(arch)
if got is None:
continue
# CUDA binaries are compatible within one major compute capability,
# later minor versions included: an sm_120 cubin runs on sm_121, which
# is how both of this project's stacks drive a card neither lists.
if got[0] == want[0] and got[1] <= want[1]:
return None
# PTX for an earlier architecture is compiled forward by the driver.
if (arch.endswith("+PTX") or "compute_" in arch) and got <= want:
return None
return (
f"torch {info.get('torch')} was built for {', '.join(arches) or 'nothing'} "
f"and this card is {sm} ({info.get('device')}); nothing there is binary "
f"compatible with it and there is no PTX to compile forward from"
)
[docs]
def step_environment(manifest: ProviderManifest) -> StepResult:
"""Install the lock into the interpreter the manifest names. Never create one."""
t = time.time()
if manifest.env_kind != "venv":
# A container carries the stack; there is no lock to install into it.
# What has to exist is the image, and the kit's own recipe builds it.
dest = kit_checkout(manifest)
if dest is None or not dest.is_dir():
return StepResult(
"environment",
REFUSED,
f'[env] kind = "{manifest.env_kind}" builds from the kit\'s recipe, '
f"which is not checked out yet — run the kit step first",
reason="kit_not_checked_out",
seconds=time.time() - t,
)
return _build_image(manifest, dest, t)
try:
python = manifest.python_executable()
except ManifestError as exc:
lock = manifest.resolve(manifest.env_lock)
recipe = ""
if lock and lock.is_file():
recipe = (
f"\n the recipe is in the header of {lock}; in short:\n"
f" uv venv --seed --managed-python --python 3.11.12 ~/{manifest.slug}-venv\n"
f" export {str(manifest.env_python or '').lstrip('$')}=~/{manifest.slug}-venv/bin/python"
)
return StepResult(
"environment",
REFUSED,
f"{exc}{recipe}",
reason="env_python_unset",
seconds=time.time() - t,
)
if not Path(python).is_file():
return StepResult(
"environment",
REFUSED,
f"{python} is not a file — it must be the interpreter of "
f"{manifest.slug}'s own environment",
reason="env_python_missing",
seconds=time.time() - t,
)
if manifest.env_verify:
probe = _run([python, "-c", manifest.env_verify], timeout=300)
if probe.returncode == 0:
from .exec_env import from_manifest
problem, why, notes = _toolchain_problems(
from_manifest(manifest), manifest.gpu_policy == "required"
)
if problem:
return StepResult(
"environment",
REFUSED,
problem,
reason=why,
seconds=time.time() - t,
)
return StepResult(
"environment",
PRESENT,
f"{python} already satisfies [env] verify",
lines=[f"NOTE: {n}" for n in notes],
seconds=time.time() - t,
)
lock = manifest.resolve(manifest.env_lock)
if lock is None:
return StepResult(
"environment",
REFUSED,
"[env] lock is not declared, so the environment cannot be rebuilt",
reason="no_lock",
seconds=time.time() - t,
)
# --no-deps because the lock is complete; letting a resolver re-derive the
# set is how a stack stops being the one that was measured.
text = lock.read_text().splitlines()
# A lock may declare ORDERED passes with `# --- pass break ---`, and one
# kit needs it. pip does not honour requirement order within a single
# install, so a lock carrying two CUDA generations installs whichever of a
# colliding pair pip reaches last: protenix_v1's keeps both the CUDA 12.9
# and 13.0 runtimes, and 27 paths under nvidia/{cudnn,nccl,cusparselt}
# collide. Measured, one pass leaves nvidia/cudnn/lib/libcudnn.so.9 at
# 124,920 bytes -- the cu12 wheel's file -- where two passes with CUDA 13
# last leave the cu13 wheel's 6,328,728-byte one, which is the single path
# torch 2.13.0+cu130 preloads. The result imports fine and is simply not
# the stack that was measured, which is the kind of wrong that survives a
# smoke. The kit's own Dockerfile uses two passes and says why.
groups: List[List[str]] = [[]]
for ln in text:
if ln.strip().startswith("#"):
if "pass break" in ln:
groups.append([])
continue
if ln.strip():
groups[-1].append(ln)
pins = [ln for g in groups for ln in g]
boot = [ln for ln in pins if ln.split("==")[0] in ("pip", "wheel")]
passes = [[ln for ln in g if ln not in boot] for g in groups]
passes = [g for g in passes if g]
lines: List[str] = []
batches = [("pip/wheel", boot, [])]
if len(passes) <= 1:
batches.append(("stack", passes[0] if passes else [], []))
else:
batches += [
(f"stack pass {i + 1}/{len(passes)}", g, []) for i, g in enumerate(passes)
]
for label, batch, extra in batches:
if not batch:
continue
listing = lock.parent / f".{manifest.slug}-{label.replace('/', '-')}.txt"
listing.write_text("\n".join(batch) + "\n")
try:
out = _run(
[
python,
"-m",
"pip",
"install",
"--no-deps",
"--disable-pip-version-check",
*extra,
"-r",
os.fspath(listing),
],
timeout=7200,
)
finally:
listing.unlink(missing_ok=True)
if out.returncode != 0:
return StepResult(
"environment",
FAILED,
f"installing the {label} of {lock.name} into {python} failed",
reason="lock_install_failed",
lines=_tail(out.stderr or out.stdout),
seconds=time.time() - t,
)
lines.append(f"{label}: {len(batch)} distributions")
from .exec_env import from_manifest
problem, why, notes = _toolchain_problems(
from_manifest(manifest), manifest.gpu_policy == "required"
)
if problem:
return StepResult(
"environment",
REFUSED,
problem,
reason=why,
lines=lines
+ [
"the stack installed correctly; it simply cannot emit code for "
"this card. A kit pinning an older torch needs newer hardware, "
"or a host of the architecture it was pinned for",
],
seconds=time.time() - t,
)
return StepResult(
"environment",
OK,
f"{len(pins)} pinned distributions in {python}",
lines=lines + [f"NOTE: {n}" for n in notes],
seconds=time.time() - t,
)
# Running the kit and installing it editable leave byproducts in its tree:
# bytecode caches and the egg-info of the editable install. They are untracked,
# they are not the kit's code, and treating them as tampering would refuse
# every tree that has ever been used. Anything else untracked is still
# reported: a new file beside a module can be imported by name.
_BYPRODUCTS = ("__pycache__/", ".egg-info/", ".pyc", ".pyo", ".jit/", "/.seeded")
def _foreign_objects(root: Path, limit: int = 40) -> List[str]:
"""Prebuilt shared objects in ``root`` that this machine cannot load.
Eight of the thirty-six upstream kits carry prebuilt host objects and all
of them are x86-64; none ships an aarch64 build. A kit's own `check` does
not catch this — it reports the GPU architecture its CUDA objects target,
which says nothing about the ELF machine type of the file holding them — so
the first sign is an ImportError reading "cannot open shared object file"
minutes into a smoke run, which is `dlopen`'s wording for a file that is
right there.
**This scans one directory, and the message says so.** The caller passes
``dest / subdir``, not the whole sparse set, so objects under ``common/``
are not examined — and that is where the shared core keeps 48 x86-64 ``.so``
files and 113 cubins that ten providers' levers reach. Widening the scan
would refuse all ten, because those files sit under
``...x86_64-linux-gnu-sm90/`` paths that are never selected on aarch64 and
the core falls back to NVRTC. A false refusal on ten working providers is
worse than a narrow check, so the check stays narrow and stops claiming
more than it did. The question it cannot answer — "will this interpreter's
kernels actually build for this card" — is answered by the Triton compile
probe instead.
"""
import platform
import struct
want = {"x86_64": 0x3E, "aarch64": 0xB7, "ppc64le": 0x15, "s390x": 0x16}.get(
platform.machine()
)
if want is None:
return []
foreign = []
for path in list(root.rglob("*.so"))[:limit]:
try:
with open(path, "rb") as f:
head = f.read(20)
except OSError:
continue
if len(head) < 20 or head[:4] != b"\x7fELF":
continue
machine = struct.unpack_from("<H", head, 18)[0]
if machine != want:
foreign.append(
f"{path.name}: ELF machine 0x{machine:02x}, this host is {platform.machine()}"
)
return foreign
def _is_tampering(porcelain_line: str) -> bool:
line = porcelain_line.rstrip()
if not line:
return False
path = line[3:]
if not line.startswith("?? "):
return True # a tracked file that differs from the pinned commit
return not any(mark in path for mark in _BYPRODUCTS)
# ------------------------------------------------------------------------ kit
[docs]
def step_kit(manifest: ProviderManifest) -> StepResult:
"""Fetch the pinned third-party kit, if this provider uses one, and install it."""
t = time.time()
dest = kit_checkout(manifest)
if dest is None:
return StepResult(
"kit", SKIPPED, "this provider declares no kit", seconds=time.time() - t
)
kit = manifest.kit
lines: List[str] = []
if dest.is_dir() and (dest / ".git").is_dir():
lines.append(f"present at {dest}")
# The checkout is shared by every provider pinning this commit, and each
# declares only the paths it needs. A second provider arriving at an
# existing checkout must widen the sparse set rather than find its kit
# missing from a directory that looks complete.
want = list(kit.get("sparse") or [])
subdir = kit.get("subdir")
if want and subdir and not (dest / subdir).is_dir():
have = _run(["git", "sparse-checkout", "list"], cwd=dest, timeout=300)
merged = sorted(set((have.stdout or "").split()) | set(want))
widen = _run(
["git", "sparse-checkout", "set", *merged], cwd=dest, timeout=600
)
if widen.returncode != 0 or not (dest / subdir).is_dir():
return StepResult(
"kit",
FAILED,
f"{subdir}/ is absent from the shared checkout at {dest} and the "
f"sparse set could not be widened to {merged}",
reason="kit_sparse_widen_failed",
lines=_tail(widen.stderr),
seconds=time.time() - t,
)
lines.append(f"sparse set widened to {' '.join(merged)}")
else:
if not shutil.which("git"):
return StepResult(
"kit",
REFUSED,
"git is not on PATH",
reason="git_missing",
seconds=time.time() - t,
)
dest.parent.mkdir(parents=True, exist_ok=True)
sparse = list(kit.get("sparse") or [])
argv = ["git", "clone", "--filter=blob:none", "--depth", "1", "--no-checkout"]
if sparse:
argv.append("--sparse")
argv += [kit["upstream"], os.fspath(dest)]
out = _run(argv, timeout=3600)
if out.returncode != 0:
return StepResult(
"kit",
FAILED,
f"cloning {kit['upstream']} failed",
reason="kit_clone_failed",
lines=_tail(out.stderr),
seconds=time.time() - t,
)
if sparse:
_run(["git", "sparse-checkout", "init", "--cone"], cwd=dest, timeout=300)
_run(["git", "sparse-checkout", "set", *sparse], cwd=dest, timeout=300)
# --depth 1 fetched only the tip; ask for the pinned commit by name so a
# pin that is not the tip still resolves.
fetch = _run(
["git", "fetch", "--depth", "1", "origin", kit["commit"]],
cwd=dest,
timeout=3600,
)
checkout = _run(
["git", "checkout", "--detach", kit["commit"]], cwd=dest, timeout=600
)
if checkout.returncode != 0:
return StepResult(
"kit",
FAILED,
f"the pinned commit {kit['commit'][:12]} could not be "
f"checked out (the clone is left at {dest} for inspection)",
reason="kit_commit_missing",
lines=_tail(checkout.stderr) + _tail(fetch.stderr, 4),
seconds=time.time() - t,
)
lines.append(f"cloned at {kit['commit'][:12]} into {dest}")
head = _run(["git", "rev-parse", "HEAD"], cwd=dest, timeout=60)
got = (head.stdout or "").strip()
if got != kit["commit"]:
return StepResult(
"kit",
REFUSED,
f"{dest} is at {got[:12]}, the pin is {kit['commit'][:12]} — "
f"left in place; remove it by hand and re-run",
reason="kit_wrong_commit",
seconds=time.time() - t,
)
dirty = _run(["git", "status", "--porcelain"], cwd=dest, timeout=300)
changed = [ln for ln in (dirty.stdout or "").splitlines() if _is_tampering(ln)]
if changed:
return StepResult(
"kit",
REFUSED,
f"{dest} has local modifications; this is third-party code "
f"we execute, so a changed tree is refused rather than run",
reason="kit_modified",
lines=changed[:6],
seconds=time.time() - t,
)
subdir = kit.get("subdir")
# Under mode = "off" the kit installs no finder and loads none of its
# objects, so their architecture does not matter.
checking_objects = subdir and kit.get("mode", "fast") != "off"
foreign = _foreign_objects(dest / subdir) if checking_objects else []
if foreign:
return StepResult(
"kit",
REFUSED,
f"{subdir}/ carries prebuilt shared objects this machine cannot "
f"load; a lever that dlopens one fails at import, not at check",
reason="kit_foreign_objects",
lines=foreign[:6]
+ [
'set [kit] mode = "off" to run the provider without the kit\'s '
"levers, or use a host of the architecture the kit was built for",
"note this scanned only "
f"{subdir}/: objects under common/ are not examined, because the "
"shared core's x86-64 files sit under paths never selected on "
"this architecture and refusing on them would refuse every "
"provider that works. Whether the kernels actually build is a "
"different question, answered by the Triton compile probe in the "
"environment step",
],
seconds=time.time() - t,
)
if manifest.env_kind != "venv":
# The image carries the kit: its own Dockerfile ran the install step at
# build time, into the interpreter the image holds. Running it again on
# the host would install into whatever python is on the host's PATH,
# which is not where the model lives.
lines.append(f"install is the image's ({manifest.env_kind}); not re-run here")
return StepResult(
"kit",
OK,
f"checkout present for the image build at {dest}",
lines=lines,
seconds=time.time() - t,
)
install = kit.get("install")
if not install:
return StepResult(
"kit",
OK,
"; ".join(lines) + " (no install step declared)",
seconds=time.time() - t,
)
python = manifest.python_executable()
workdir = dest / kit.get("subdir", "")
env = dict(os.environ)
# NOT resolve(): a venv's bin/python is a symlink to the interpreter it was
# built from, and following it lands in that interpreter's bin directory.
env["PATH"] = (
str(Path(python).expanduser().absolute().parent)
+ os.pathsep
+ env.get("PATH", "")
)
root = manifest.weights_root()
# The weights root is exported here as well as in the weights step. A kit's
# own `run.sh install --weights DIR` often reads the root from the
# environment rather than from its argument, and without this every such
# manifest has to restate it on the command line -- atlasfold had to write
# `ATLASFOLD_WEIGHTS_DIR={weights_root} bash run.sh install ...`. The
# placeholder is computed two lines below either way, so this costs nothing.
if root is not None and manifest.weights_root_env:
env[manifest.weights_root_env] = os.fspath(root)
command = install.format(
weights_root=os.fspath(root) if root else "",
python=python,
kit=os.fspath(workdir),
)
out = _run(["bash", "-c", command], cwd=workdir, env=env, timeout=7200)
lines += _tail(out.stdout, 6)
if out.returncode != 0:
return StepResult(
"kit",
FAILED,
f"the kit's own install step exited {out.returncode} "
f"(`{command}` in {workdir})",
reason="kit_install_failed",
lines=lines + _tail(out.stderr, 8),
seconds=time.time() - t,
)
return StepResult(
"kit", OK, f"installed from {dest}", lines=lines, seconds=time.time() - t
)
# -------------------------------------------------------------------- weights
[docs]
def step_weights(manifest: ProviderManifest) -> StepResult:
"""Every declared file present and at its pin. Deep: what is certified is read."""
t = time.time()
if not manifest.weights:
return StepResult(
"weights",
SKIPPED,
"this provider declares no weights",
seconds=time.time() - t,
)
root = manifest.weights_root()
lines: List[str] = []
problems = manifest.verify_weights(deep=True)
if problems and manifest.weights_fetch:
# Not every kit fetches weights in its install step: some models pull
# their own from a hub at first load. The provider declares the command
# that does it, which calls upstream's own downloader -- no URL is
# restated in ToolUniverse, so a mirror change upstream cannot break us.
lines.append(f"{len(problems)} entr(ies) absent or off pin: fetching")
python = manifest.python_executable()
env = dict(os.environ)
# The same PATH the kit step gives its install command. A kit's own
# fetcher runs through its run.sh, and those look for `python` on PATH
# rather than reading a PYTHON= variable -- chai1's and openfold3's
# both do. Without this the fetch fails with "no python on PATH" at
# exactly the moment a weight file is missing.
if manifest.env_kind == "venv":
bin_dir = str(Path(python).expanduser().absolute().parent)
env["PATH"] = bin_dir + (
os.pathsep + env["PATH"] if env.get("PATH") else ""
)
if root is not None and manifest.weights_root_env:
env[manifest.weights_root_env] = os.fspath(root)
out = _run(
[
"bash",
"-c",
# The same fields [kit] install and [runtime] worker_args get.
# A placeholder the caller can write but this cannot fill is a
# KeyError at the moment the weights are actually missing,
# which is the worst moment to discover it.
manifest.weights_fetch.format(
python=python,
weights_root=os.fspath(root) if root else "",
kit=os.fspath(kit_checkout(manifest) or ""),
slug=manifest.slug,
),
],
env=env,
timeout=7200,
)
if out.returncode == 3:
# The kits' own vocabulary, which STANDARD.md section 8 adopts: 3 is
# "refused, and here is the fix", 1 is "it broke". Reporting a
# refusal as a failure loses that distinction at the exit code a
# caller branches on -- af3_torch's fetch refuses by name because
# its weights are produced by a second interpreter, which is a
# correct answer, not a fault.
return StepResult(
"weights",
REFUSED,
"the declared fetch command refused (exit 3); its own words follow",
reason="weights_fetch_refused",
lines=lines + _tail(out.stderr or out.stdout, 8),
seconds=time.time() - t,
)
if out.returncode != 0:
return StepResult(
"weights",
FAILED,
f"the declared fetch command exited {out.returncode}",
reason="weights_fetch_failed",
lines=lines + _tail(out.stderr or out.stdout, 8),
seconds=time.time() - t,
)
problems = manifest.verify_weights(deep=True)
if problems:
return StepResult(
"weights",
REFUSED,
f"{len(problems)} of {len(manifest.weights)} declared files are not at "
f"their pins under {root}",
reason="weights_off_pin",
# Nothing is deleted: upstream writes straight to the final name, so a
# truncated transfer and a corrupt file look alike, and removing one to
# retry destroys the evidence that says which it was.
lines=problems
+ [
"files are left in place for inspection; remove the named one by "
"hand and re-run this step to fetch it again",
],
seconds=time.time() - t,
)
total = sum(w.size or 0 for w in manifest.weights) / 2**30
return StepResult(
"weights",
OK,
f"{len(manifest.weights)}/{len(manifest.weights)} entries at "
f"their pins under {root} ({total:.1f} GiB)",
seconds=time.time() - t,
)
# ---------------------------------------------------------------------- smoke
[docs]
def measured_path(slug: str) -> Path:
root = os.environ.get("TOOLUNIVERSE_MEASURED_DIR") or os.path.expanduser(
"~/.cache/tooluniverse/measured"
)
return Path(root) / f"{slug}.json"
def _write_measured(slug: str, record: Dict[str, Any]) -> str:
"""Persist one smoke record; return the phrase describing where it went."""
path = measured_path(slug)
try:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(record, indent=1, sort_keys=True))
return f"; recorded in {path}"
except OSError as exc:
return f"; the record could not be written ({exc})"
def _what_it_produced(
manifest: ProviderManifest, result: Dict[str, Any], out_dir: Path
) -> tuple:
"""``(matched, refusal)`` for the manifest's declared success condition.
An exit code is not evidence that a model ran. OpenFold3's runner catches
a per-query exception, writes a summary saying "Failed Queries: 1" and
returns normally; the smoke step saw a reply, a timing and a GPU peak, and
called that verified. What it had never asked was whether a structure came
out. This asks.
Files are matched against ``[runtime] outputs`` -- both the paths the
worker reported and a walk of the output directory, because a provider is
not obliged to list what it wrote. ``[runtime] output_keys`` covers the
providers that answer with arrays and write nothing at all.
"""
matched: Dict[str, Any] = {}
if manifest.outputs:
seen = [Path(f) for f in (result.get("files") or [])]
if out_dir.is_dir():
seen.extend(q for q in out_dir.rglob("*") if q.is_file())
hits = sorted(
{
os.fspath(q)
for q in seen
for pattern in manifest.outputs
if fnmatch.fnmatch(q.name, pattern)
}
)
matched["outputs"] = hits
if not hits:
listing = sorted({q.name for q in seen})[:8] or ["nothing at all"]
return matched, (
f"the model answered but produced none of {list(manifest.outputs)} "
f"\u2014 what it wrote was {listing}. An exit code is not evidence "
f"that a model ran: upstream may have caught its own per-request "
f"exception and returned normally. Read the worker transcript and "
f"any summary file in {out_dir}"
)
missing = [
k
for k in manifest.output_keys
if result.get(k) is None or result.get(k) == [] or result.get(k) == {}
]
if manifest.output_keys:
matched["output_keys"] = [k for k in manifest.output_keys if k not in missing]
if missing:
return matched, (
f"the model answered but its reply has nothing under {missing} "
f"\u2014 the keys [runtime] output_keys says a successful run fills. "
f"Read the worker transcript"
)
return matched, ""
[docs]
def step_smoke(manifest: ProviderManifest) -> StepResult:
"""Run the model once, under a deadline, and record what this machine did.
Installing is not evidence. Of the four problems hit bringing up the first
provider, three appeared only here — a kit lever whose featurizer hangs, a
Triton kernel that reports OutOfResources on this compute capability, and
an ``nvidia-smi`` field that returns ``[N/A]`` on unified memory. The first
of those presents as a stall, which is why the deadline is not optional.
What it writes is the point of the step. ``provider.toml``'s numbers are the
reference they were measured against; the file this writes is what this
machine actually did, and a scheduler reads that one.
"""
t = time.time()
if manifest.mode != "resident":
return StepResult(
"smoke",
SKIPPED,
f"[runtime] mode = {manifest.mode!r}: nothing is held to test",
seconds=time.time() - t,
)
smoke_input = manifest.resolve(manifest.smoke)
if smoke_input is None:
return StepResult(
"smoke",
SKIPPED,
"[runtime] smoke is not declared, so nothing was run — "
"this provider stays untested on this machine",
reason="no_smoke_declared",
seconds=time.time() - t,
)
from . import backend # imported late: starting nothing is the default
worker = backend.worker_for(manifest.path)
smoke_out = (
Path(manifest.work_root).expanduser() / f"{manifest.slug}-smoke"
if manifest.work_root
else measured_path(manifest.slug).parent / f"{manifest.slug}-smoke"
)
# Emptied, not reused. The outputs assertion walks this directory, so a
# structure left by an earlier run would keep a provider green after it
# stopped producing one -- the same false pass the assertion exists to
# catch, arriving through the back door. Guarded on the "-smoke" suffix
# because this removes a tree.
if smoke_out.name.endswith("-smoke") and smoke_out.is_dir():
shutil.rmtree(smoke_out, ignore_errors=True)
smoke_out.mkdir(parents=True, exist_ok=True)
record: Dict[str, Any] = {
"slug": manifest.slug,
"at": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
"host": socket.gethostname(),
"manifest_vram_budget_gb": manifest.vram_budget_gb,
}
try:
deadline = manifest.smoke_timeout_s
worker.request_timeout_s = deadline
worker.start_timeout_s = max(worker.start_timeout_s, deadline)
pong = worker.request({"op": "ping"})
record["build_s"] = pong.get("build_s")
reply = worker.request(
{
"op": "predict",
# Neutral: the provider decides what its input text means.
"input": smoke_input.read_text(),
# Under work_root when the provider declares one: a container
# sees only what was bound, and that is the path bound for
# exactly this.
"out_dir": os.fspath(smoke_out),
"name": "smoke",
"seed": 0,
"options": {},
}
)
except Exception as exc: # noqa: BLE001 — every failure here is the answer
reason = getattr(exc, "reason", "") or type(exc).__name__
where = f" (its transcript is in {worker.log_path})" if worker.log_path else ""
return StepResult(
"smoke",
FAILED,
f"the model did not answer within {manifest.smoke_timeout_s:.0f}s "
f"or failed: {exc}{where}",
reason=f"smoke_{reason}".lower()[:40],
seconds=time.time() - t,
)
finally:
worker.stop(grace_s=60)
result = reply.get("result", {})
record.update(
{
"wall_s": round(time.time() - t, 1),
"timing": result.get("timing"),
"peak_reserved_gib": result.get("peak_reserved_gib"),
"files": len(result.get("files") or []),
}
)
produced, refusal = _what_it_produced(manifest, result, smoke_out)
record["produced"] = produced
if refusal:
where = f" (its transcript is in {worker.log_path})" if worker.log_path else ""
_write_measured(manifest.slug, record)
return StepResult(
"smoke",
FAILED,
refusal + where,
reason="smoke_produced_nothing",
seconds=time.time() - t,
)
gpu = _run(
[
"nvidia-smi",
"--query-gpu=name,driver_version,compute_cap",
"--format=csv,noheader",
],
timeout=30,
)
if gpu.returncode == 0 and gpu.stdout.strip():
record["gpu"] = gpu.stdout.strip().splitlines()[0]
written = _write_measured(manifest.slug, record)
budget = record.get("peak_reserved_gib")
over = (
budget is not None
and manifest.vram_budget_gb is not None
and budget > manifest.vram_budget_gb
)
detail = f"one prediction in {record['wall_s']:.0f}s, peak reserved {budget} GiB{written}"
lines = [f"timing: {result.get('timing')}"]
if over:
lines.append(
f"NOTE: peak {budget} GiB exceeds the manifest's {manifest.vram_budget_gb} GiB — "
f"that figure was measured on other hardware; schedule on the recorded value"
)
return StepResult("smoke", OK, detail, lines=lines, seconds=time.time() - t)
# --------------------------------------------------------------------- driver
STEPS = (step_preflight, step_environment, step_kit, step_weights, step_smoke)
# A container image is built FROM the kit's recipe, so for those providers the
# checkout has to come first. Everything else keeps the declared order.
CONTAINER_STEPS = (step_preflight, step_kit, step_environment, step_weights, step_smoke)
[docs]
def run_setup(slug_or_path: str, *, only: Optional[str] = None) -> List[StepResult]:
"""Every step in order, stopping at the first that is not ok.
Stopping is deliberate: each step assumes the previous one holds, and a
cascade of failures caused by one missing thing buries the one that
mattered. Re-running after fixing it continues from where it stopped,
because every step reports ``present`` for work already done.
"""
manifest = (
load_manifest(slug_or_path)
if os.path.exists(slug_or_path)
else load_manifest(_provider_dir(slug_or_path))
)
results: List[StepResult] = []
steps = STEPS if manifest.env_kind == "venv" else CONTAINER_STEPS
for step in steps:
name = step.__name__.removeprefix("step_")
if only and name != only:
continue
result = step(manifest)
results.append(result)
if not result.ok:
break
return results
def _provider_dir(slug: str) -> Path:
import importlib.util
spec = importlib.util.find_spec(f"tooluniverse.remote.{slug}")
if spec is None or not spec.submodule_search_locations:
raise ManifestError(f"no provider package for slug {slug!r}")
return Path(list(spec.submodule_search_locations)[0])
[docs]
def exit_code(results: List[StepResult]) -> int:
for r in results:
if r.verdict == REFUSED:
return EXIT_REFUSED
if r.verdict == FAILED:
return EXIT_FAILED
return EXIT_OK