stdlib: Add ShadowResource

The purpose of a `ShadowResource` is a resource which only contains the
ID and Version information, not any additional information about the
resource thus avoiding the `obtain_resource` call.

When attributes of the `ShadowResource` are accessed which can only be
obtained via `obtain_resource` the `ShowResource` calls the function and
returns what is required.

This is useful for `Suite` resources which contain several workloads
and resources which may not all be needed when the `Suite` object is
first instantiated.

Change-Id: Icc56261b2c4d74e4079ee66486ddae677bb35cfa
This commit is contained in:
Bobby R. Bruce
2023-12-01 00:24:49 -08:00
parent 743b2aada6
commit 88601d3ac5

View File

@@ -118,6 +118,10 @@ class AbstractResource:
self._version = resource_version
self._downloader = downloader
def get_id(self) -> str:
"""Returns the ID of the resource."""
return self._id
def get_category_name(cls) -> str:
raise NotImplementedError
@@ -803,6 +807,40 @@ class SuiteResource(AbstractResource):
}
class ShadowResource(AbstractResource):
"""A special resource class which delays the `obtain_resource` call. It is,
in a sense, half constructed. Only when a function or attribute is called
which is is neither `get_id` or `get_resource_version` does this class
fully construct itself by calling the `obtain_resource_call` partial
function.
"""
def __init__(
self,
id: str,
resource_version: str,
obtain_resource_call: partial,
):
super().__init__(
id=id,
resource_version=resource_version,
)
self._workload: Optional[AbstractResource] = None
self._obtain_resource_call = obtain_resource_call
def __getattr__(self, attr):
"""if getting the id or resource version, we keep the object in the
"shdow state" where the `obtain_resource` function has not been called.
When more information is needed by calling another attribute, we call
the `obtain_resource` function and store the result in the `_workload`.
"""
if attr in {"get_id", "get_resource_version"}:
return getattr(super(), attr)
if not self._workload:
self._workload = self._obtain_resource_call()
return getattr(self._workload, attr)
class WorkloadResource(AbstractResource):
"""A workload resource. This resource is used to specify a workload to run
on a board. It contains the function to call and the parameters to pass to
@@ -1012,12 +1050,17 @@ def obtain_resource(
workloads_obj = {}
for workload in workloads:
workloads_obj[
obtain_resource(
workload["id"],
ShadowResource(
id=workload["id"],
resource_version=workload["resource_version"],
resource_directory=resource_directory,
clients=clients,
gem5_version=gem5_version,
obtain_resource_call=partial(
obtain_resource,
workload["id"],
resource_version=workload["resource_version"],
resource_directory=resource_directory,
clients=clients,
gem5_version=gem5_version,
),
)
] = set(workload["input_group"])
resource_json["workloads"] = workloads_obj