Name the sizes a node can ask for
Raw cpus and gpus are a property of the machines an installation has, so a node written against a cluster quietly stops meaning anything when the cluster is replaced. A node says "gpu-small" instead, and what that is stored here — editable, and read again every time the node is built, so changing the flavor changes what the next run gets. Memory joins the schema properly (`ram`, in MB, accepting "2G"), along with `duration_s` for how long a node is expected to take. That one is recorded and shown and nothing else yet: a statement for whoever is planning around the node, not a limit — the limit is still `timeout`. A flavor and a number for the same thing is refused, compared by value so an editor writing the whole object back with its defaults still round-trips. A name nothing stores is refused at the save, which covers the canvas and `fluksio sync` at once, and deleting one a node still asks for says which node. Four sizes are seeded on an installation that has none, and never re-seeded: re-adding one somebody deliberately removed is an argument nobody wins. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A6HeySA27EkGANZN95QySW
This commit is contained in:
@@ -268,7 +268,7 @@ def node(
|
||||
device: str | None = None,
|
||||
device_policy: str = "require",
|
||||
cache: bool = True,
|
||||
resources: dict[str, Any] | None = None,
|
||||
resources: dict[str, Any] | str | None = None,
|
||||
) -> Callable[[F], F]:
|
||||
"""Mark a function as a node, declaring its ports.
|
||||
|
||||
@@ -302,14 +302,22 @@ def node(
|
||||
library that sizes itself to every visible core is told otherwise. ``env``
|
||||
is for the tuning the engine must not invent, such as ``XLA_FLAGS``.
|
||||
Declaring nothing is the default and changes nothing.
|
||||
|
||||
A string is a stored flavor — ``resources="gpu-small"`` — which is the same
|
||||
thing as ``{"flavor": "gpu-small"}`` and stands in for cpus, gpus and ram.
|
||||
Sizes accept ``"2G"``; ``duration_s`` accepts ``"30m"``.
|
||||
"""
|
||||
if device_policy not in ("require", "prefer"):
|
||||
raise SyncError("device_policy is 'require' or 'prefer'")
|
||||
if isinstance(resources, str):
|
||||
resources = {"flavor": resources}
|
||||
if resources is not None:
|
||||
unknown = sorted(set(resources) - {"cpus", "gpus", "env"})
|
||||
known = {"cpus", "gpus", "ram", "flavor", "duration_s", "env"}
|
||||
unknown = sorted(set(resources) - known)
|
||||
if unknown:
|
||||
raise SyncError(
|
||||
f"resources={{'{unknown[0]}': ...}} is not one of cpus, gpus, env"
|
||||
f"resources={{'{unknown[0]}': ...}} is not one of "
|
||||
f"{', '.join(sorted(known))}"
|
||||
)
|
||||
if timeout is not None and timeout < 0:
|
||||
raise SyncError(
|
||||
|
||||
Reference in New Issue
Block a user