Skip to content

Commit

Permalink
More peculiar handling of resource devices
Browse files Browse the repository at this point in the history
  • Loading branch information
hylje committed Dec 1, 2023
1 parent bc5b464 commit 0c53324
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 11 deletions.
13 changes: 12 additions & 1 deletion tests/test_workload_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
"devices": {"foo": 1, "bar": 2},
}

RESOURCE_DATA_WITH_DELIBERATE_EMPTY_DEVICES: dict = {
"devices": {},
}


def test_create_resources():
"""All YAML properties are correctly parsed into the object."""
Expand Down Expand Up @@ -53,12 +57,19 @@ def test_missing_resources():
assert resources.memory.max is None

assert resources.devices is not None
assert resources.devices.devices == {}
assert resources.devices.devices is None

# the empty dict-initialized resources also serialize back into an empty dict
assert resources.serialize() == {}


def test_cleared_devices():
resources = WorkloadResources.parse(RESOURCE_DATA_WITH_DELIBERATE_EMPTY_DEVICES)

assert resources.devices.devices == {}
assert resources.serialize() == RESOURCE_DATA_WITH_DELIBERATE_EMPTY_DEVICES


@pytest.mark.parametrize(
"resource_name,missing_key",
[
Expand Down
34 changes: 24 additions & 10 deletions valohai_yaml/objs/workload_resources.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
from typing import Dict, Optional
import functools
from typing import Any, Callable, Dict, Optional

from valohai_yaml.objs.base import Item
from valohai_yaml.types import SerializedDict


def none_if_empty(f: Callable) -> Callable:
@functools.wraps(f)
def wrap(*args: list, **kwargs: dict) -> Any:
ret = f(*args, **kwargs)
if not ret:
return None
return ret

return wrap


class ResourceCPU(Item):
"""CPU configuration."""

Expand All @@ -19,7 +31,8 @@ def __repr__(self) -> str:
"""CPU data."""
return f'ResourceCPU("max": {self.max}, "min": {self.min})'

def get_data(self) -> SerializedDict:
@none_if_empty
def get_data_or_none(self) -> SerializedDict:
return {
key: value for key, value in super().get_data().items() if value is not None
}
Expand All @@ -40,7 +53,8 @@ def __repr__(self) -> str:
"""Memory data."""
return f'ResourceMemory("max": {self.max}, "min": {self.min})'

def get_data(self) -> SerializedDict:
@none_if_empty
def get_data_or_none(self) -> SerializedDict:
return {
key: value for key, value in super().get_data().items() if value is not None
}
Expand All @@ -49,17 +63,17 @@ def get_data(self) -> SerializedDict:
class ResourceDevices(Item):
"""Devices configuration."""

def __init__(self, devices: SerializedDict) -> None:
def __init__(self, devices: SerializedDict | None) -> None:
"""
Devices list device name: nr of devices.
Keys (and number of items) unknown, e.g.:
'nvidia.com/cpu': 2, 'nvidia.com/gpu': 1.
"""
self.devices: Dict[str, int] = devices
self.devices: Optional[Dict[str, int]] = devices

@classmethod
def parse(cls, data: SerializedDict) -> "ResourceDevices":
def parse(cls, data: SerializedDict | None) -> "ResourceDevices":
"""
Initialize a devices resource.
Expand All @@ -72,7 +86,7 @@ def __repr__(self) -> str:
"""List the devices."""
return f"ResourceDevices({self.devices})"

def get_data(self) -> SerializedDict:
def get_data_or_none(self) -> SerializedDict | None:
return self.devices


Expand All @@ -99,7 +113,7 @@ def __init__(
def parse(cls, data: SerializedDict) -> "WorkloadResources":
cpu_data = data.get("cpu", {})
memory_data = data.get("memory", {})
device_data = data.get("devices", {})
device_data = data.get("devices")
data_with_resources = dict(
data,
cpu=ResourceCPU.parse(cpu_data),
Expand All @@ -111,8 +125,8 @@ def parse(cls, data: SerializedDict) -> "WorkloadResources":
def get_data(self) -> SerializedDict:
data = {}
for key, value in super().get_data().items():
item_data = value.get_data()
if item_data:
item_data = value.get_data_or_none()
if item_data is not None:
data[key] = item_data
return data

Expand Down

0 comments on commit 0c53324

Please sign in to comment.