stdlib: Specialize the gem5-resources
This commit specializes the Resource class into specific sub-types. The `Resource`, `CustomResource` and `CustomDiskImageResource` classes have been deprecated in favor of the `AbstractResource` subclasses. Custom Resources can be created via the resource specialization constructor. Resources can be obtained via the gem5-resource infrastructure with the `obtain_resource` function. Fully implemented: - DiskImageResource - BinaryResource - KernelResource - BootloaderResource - FileResource - DirectoryResource Partially implemented: - SimpointResource - CheckpointResource While the schema of the resource.json file has changed, efforts have been made to ensure backwards compatibility is maintained during this transition. Tests are included in this commit to verify this feature works as expected. **Note:** The Simpoint tests are disabled in this commit, to be reenabled when Simpoint resource specialization is fully incorporated here: https://gem5-review.googlesource.com/c/public/gem5/+/67339 Change-Id: I77277ecaffc7abc86db08526aacc0b606ef04fe8 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67175 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu> Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
This commit is contained in:
committed by
Zhantong Qiu
parent
3892ee029a
commit
4ee724e054
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2021 The Regents of the University of California
|
||||
# Copyright (c) 2021, 2023 The Regents of the University of California
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -27,7 +27,12 @@
|
||||
from abc import abstractmethod
|
||||
|
||||
from .abstract_board import AbstractBoard
|
||||
from ...resources.resource import AbstractResource
|
||||
from ...resources.resource import (
|
||||
DiskImageResource,
|
||||
BootloaderResource,
|
||||
CheckpointResource,
|
||||
KernelResource,
|
||||
)
|
||||
|
||||
from typing import List, Optional, Union
|
||||
import os
|
||||
@@ -89,7 +94,7 @@ class KernelDiskWorkload:
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def _add_disk_to_board(self, disk_image: AbstractResource) -> None:
|
||||
def _add_disk_to_board(self, disk_image: DiskImageResource) -> None:
|
||||
"""
|
||||
Sets the configuration needed to add the disk image to the board.
|
||||
|
||||
@@ -101,7 +106,7 @@ class KernelDiskWorkload:
|
||||
raise NotImplementedError
|
||||
|
||||
def get_disk_root_partition(
|
||||
cls, disk_image: AbstractResource
|
||||
cls, disk_image: DiskImageResource
|
||||
) -> Optional[str]:
|
||||
"""
|
||||
Obtains the root partition of a disk image by inspecting the resource's
|
||||
@@ -109,14 +114,11 @@ class KernelDiskWorkload:
|
||||
|
||||
:returns: The disk image's root partition.
|
||||
"""
|
||||
try:
|
||||
return disk_image.get_metadata()["additional_metadata"][
|
||||
"root_partition"
|
||||
]
|
||||
except KeyError:
|
||||
return None
|
||||
return disk_image.get_root_partition()
|
||||
|
||||
def get_default_kernel_root_val(self, disk_image: AbstractResource) -> str:
|
||||
def get_default_kernel_root_val(
|
||||
self, disk_image: DiskImageResource
|
||||
) -> str:
|
||||
"""
|
||||
Get the default kernel root value to be passed to the kernel. This is
|
||||
determined by the value implemented in the `get_disk_device()`
|
||||
@@ -134,14 +136,14 @@ class KernelDiskWorkload:
|
||||
|
||||
def set_kernel_disk_workload(
|
||||
self,
|
||||
kernel: AbstractResource,
|
||||
disk_image: AbstractResource,
|
||||
bootloader: Optional[AbstractResource] = None,
|
||||
kernel: KernelResource,
|
||||
disk_image: DiskImageResource,
|
||||
bootloader: Optional[BootloaderResource] = None,
|
||||
readfile: Optional[str] = None,
|
||||
readfile_contents: Optional[str] = None,
|
||||
kernel_args: Optional[List[str]] = None,
|
||||
exit_on_work_items: bool = True,
|
||||
checkpoint: Optional[Union[Path, AbstractResource]] = None,
|
||||
checkpoint: Optional[Union[Path, CheckpointResource]] = None,
|
||||
) -> None:
|
||||
"""
|
||||
This function allows the setting of a full-system run with a Kernel
|
||||
@@ -212,11 +214,11 @@ class KernelDiskWorkload:
|
||||
if checkpoint:
|
||||
if isinstance(checkpoint, Path):
|
||||
self._checkpoint = checkpoint
|
||||
elif isinstance(checkpoint, AbstractResource):
|
||||
elif isinstance(checkpoint, CheckpointResource):
|
||||
self._checkpoint = Path(checkpoint.get_local_path())
|
||||
else:
|
||||
# The checkpoint_dir must be None, Path, Or AbstractResource.
|
||||
raise Exception(
|
||||
"Checkpoints must be passed as a Path or an "
|
||||
"AbstractResource."
|
||||
"CheckpointResource."
|
||||
)
|
||||
|
||||
@@ -25,7 +25,13 @@
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from .abstract_board import AbstractBoard
|
||||
from ...resources.resource import AbstractResource
|
||||
from ...resources.resource import (
|
||||
FileResource,
|
||||
AbstractResource,
|
||||
BinaryResource,
|
||||
CheckpointResource,
|
||||
SimpointResource,
|
||||
)
|
||||
from gem5.utils.simpoint import SimPoint
|
||||
|
||||
from m5.objects import SEWorkload, Process
|
||||
@@ -51,13 +57,13 @@ class SEBinaryWorkload:
|
||||
|
||||
def set_se_binary_workload(
|
||||
self,
|
||||
binary: AbstractResource,
|
||||
binary: BinaryResource,
|
||||
exit_on_work_items: bool = True,
|
||||
stdin_file: Optional[AbstractResource] = None,
|
||||
stdin_file: Optional[FileResource] = None,
|
||||
stdout_file: Optional[Path] = None,
|
||||
stderr_file: Optional[Path] = None,
|
||||
arguments: List[str] = [],
|
||||
checkpoint: Optional[Union[Path, AbstractResource]] = None,
|
||||
checkpoint: Optional[Union[Path, CheckpointResource]] = None,
|
||||
) -> None:
|
||||
"""Set up the system to run a specific binary.
|
||||
|
||||
@@ -117,10 +123,10 @@ class SEBinaryWorkload:
|
||||
|
||||
def set_se_simpoint_workload(
|
||||
self,
|
||||
binary: AbstractResource,
|
||||
binary: BinaryResource,
|
||||
arguments: List[str] = [],
|
||||
simpoint: Union[AbstractResource, SimPoint] = None,
|
||||
checkpoint: Optional[Union[Path, AbstractResource]] = None,
|
||||
simpoint: Union[SimpointResource, SimPoint] = None,
|
||||
checkpoint: Optional[Union[Path, CheckpointResource]] = None,
|
||||
) -> None:
|
||||
"""Set up the system to run a SimPoint workload.
|
||||
|
||||
@@ -141,7 +147,7 @@ class SEBinaryWorkload:
|
||||
"""
|
||||
|
||||
# convert input to SimPoint if necessary
|
||||
if isinstance(simpoint, AbstractResource):
|
||||
if isinstance(simpoint, SimpointResource):
|
||||
self._simpoint_object = SimPoint(simpoint)
|
||||
else:
|
||||
assert isinstance(simpoint, SimPoint)
|
||||
|
||||
@@ -323,7 +323,11 @@ def list_resources() -> List[str]:
|
||||
|
||||
:returns: A list of resources by name.
|
||||
"""
|
||||
return _get_resources(valid_types={"resource"}).keys()
|
||||
from .resource import _get_resource_json_type_map
|
||||
|
||||
return _get_resources(
|
||||
valid_types=_get_resource_json_type_map.keys()
|
||||
).keys()
|
||||
|
||||
|
||||
def get_workload_json_obj(workload_name: str) -> Dict:
|
||||
@@ -356,7 +360,11 @@ def get_resources_json_obj(resource_name: str) -> Dict:
|
||||
:raises Exception: An exception is raised if the specified resources does
|
||||
not exist.
|
||||
"""
|
||||
resource_map = _get_resources(valid_types={"resource"})
|
||||
from .resource import _get_resource_json_type_map
|
||||
|
||||
resource_map = _get_resources(
|
||||
valid_types=_get_resource_json_type_map.keys()
|
||||
)
|
||||
|
||||
if resource_name not in resource_map:
|
||||
raise Exception(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2021 The Regents of the University of California
|
||||
# Copyright (c) 2021-2023 The Regents of the University of California
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -27,43 +27,401 @@
|
||||
from abc import ABCMeta
|
||||
import os
|
||||
from pathlib import Path
|
||||
from m5.util import warn
|
||||
|
||||
from .downloader import get_resource, get_resources_json_obj
|
||||
|
||||
from typing import Optional, Dict
|
||||
from ..isas import ISA, get_isa_from_str
|
||||
|
||||
from typing import Optional, Dict, Union, Type
|
||||
|
||||
"""
|
||||
A Resource object encapsulates a gem5 resource. Resources are items needed to
|
||||
run a simulation, such as a disk image, kernel, or binary. The gem5 project
|
||||
provides pre-built resources, with sources, at <resources.gem5.org>.
|
||||
Resources are items needed to run a simulation, such as a disk image, kernel,
|
||||
or binary. The gem5 project provides pre-built resources, with sources, at
|
||||
<resources.gem5.org>. Here we provide the `AbstractResource` class and its
|
||||
various implementations which are designed to encapsulate a resource for use
|
||||
in the gem5 Standard Library.
|
||||
|
||||
The purpose of this encapsulation is two fold:
|
||||
These classes may be contructed directly. E.g.:
|
||||
|
||||
1. It allows automatic retrieval of gem5 resources. E.g., specifying a resource
|
||||
which is not local will initiate a download.
|
||||
2. It provides a location where code may be added to record the resources used
|
||||
within a simulation. At present this is a TODO work-item.
|
||||
```python
|
||||
binary = BinaryResource(local_path="/path/to/binary")
|
||||
```
|
||||
|
||||
or obtained via the gem5-resources infrastructure with the `obtain_resource`
|
||||
function:
|
||||
|
||||
```python
|
||||
binary = obtain_resource("resource name here")
|
||||
```
|
||||
"""
|
||||
|
||||
|
||||
class AbstractResource:
|
||||
"""
|
||||
An abstract class which all Resource classes inherit from.
|
||||
"""
|
||||
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
def __init__(self, local_path: str, metadata: Dict = {}):
|
||||
def __init__(
|
||||
self,
|
||||
local_path: str,
|
||||
documentation: Optional[str] = None,
|
||||
source: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
:param local_path: The path on the host system where this resource is
|
||||
located
|
||||
:param documentation: Documentation describing this resource. Not a
|
||||
required parameter. By default is None.
|
||||
:param source: The source (as in "source code") for this resource. This
|
||||
string should navigate users to where the source for this resource
|
||||
may be found. Not a required parameter. By default is None.
|
||||
"""
|
||||
|
||||
if not os.path.exists(local_path):
|
||||
raise Exception(
|
||||
f"Local path specified for resource, '{local_path}', does not "
|
||||
"exist."
|
||||
)
|
||||
|
||||
self._local_path = local_path
|
||||
self._metadata = metadata
|
||||
self._documentation = documentation
|
||||
self._source = source
|
||||
|
||||
def get_local_path(self) -> str:
|
||||
"""Returns the local path of the resource."""
|
||||
return self._local_path
|
||||
|
||||
def get_metadata(self) -> Dict:
|
||||
def get_documentation(self) -> Optional[str]:
|
||||
"""Returns documentation associated with this resource."""
|
||||
return self._documentation
|
||||
|
||||
def get_source(self) -> Optional[str]:
|
||||
"""Returns information as to where the source for this resource may be
|
||||
found.
|
||||
"""
|
||||
Returns the raw data from this resource, as seen in the
|
||||
`resources.json` file. A user may specify the metadata of a local
|
||||
resource.
|
||||
"""
|
||||
return self._metadata
|
||||
return self._source
|
||||
|
||||
|
||||
class FileResource(AbstractResource):
|
||||
"""A resource consisting of a single file."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
local_path: str,
|
||||
documentation: Optional[str] = None,
|
||||
source: Optional[str] = None,
|
||||
**kwargs,
|
||||
):
|
||||
if not os.path.isfile(local_path):
|
||||
raise Exception(
|
||||
f"FileResource path specified, '{local_path}', is not a file."
|
||||
)
|
||||
|
||||
super().__init__(
|
||||
local_path=local_path,
|
||||
documentation=documentation,
|
||||
source=source,
|
||||
)
|
||||
|
||||
|
||||
class DirectoryResource(AbstractResource):
|
||||
"""A resource consisting of a directory."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
local_path: str,
|
||||
documentation: Optional[str] = None,
|
||||
source: Optional[str] = None,
|
||||
**kwargs,
|
||||
):
|
||||
|
||||
if not os.path.isdir(local_path):
|
||||
raise Exception(
|
||||
f"DirectoryResource path specified, {local_path}, is not a "
|
||||
"directory."
|
||||
)
|
||||
|
||||
super().__init__(
|
||||
local_path=local_path,
|
||||
documentation=documentation,
|
||||
source=source,
|
||||
)
|
||||
|
||||
|
||||
class DiskImageResource(FileResource):
|
||||
"""A Disk Image resource."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
local_path: str,
|
||||
documentation: Optional[str] = None,
|
||||
source: Optional[str] = None,
|
||||
root_partition: Optional[str] = None,
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(
|
||||
local_path=local_path,
|
||||
documentation=documentation,
|
||||
source=source,
|
||||
)
|
||||
self._root_partition = root_partition
|
||||
|
||||
def get_root_partition(self) -> Optional[str]:
|
||||
"""Returns, if applicable, the Root Partition of the disk image."""
|
||||
return self._root_partition
|
||||
|
||||
|
||||
class BinaryResource(FileResource):
|
||||
"""A binary resource."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
local_path: str,
|
||||
documentation: Optional[str] = None,
|
||||
source: Optional[str] = None,
|
||||
architecture: Optional[Union[ISA, str]] = None,
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(
|
||||
local_path=local_path,
|
||||
documentation=documentation,
|
||||
source=source,
|
||||
)
|
||||
|
||||
self._architecture = None
|
||||
if architecture:
|
||||
if isinstance(architecture, str):
|
||||
self._architecture = get_isa_from_str(architecture)
|
||||
elif isinstance(architecture, ISA):
|
||||
self._architecture = architecture
|
||||
|
||||
def get_architecture(self) -> Optional[ISA]:
|
||||
"""Returns the ISA this binary is compiled to."""
|
||||
return self._architecture
|
||||
|
||||
|
||||
class BootloaderResource(BinaryResource):
|
||||
"""A bootloader resource."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
local_path: str,
|
||||
documentation: Optional[str] = None,
|
||||
source: Optional[str] = None,
|
||||
architecture: Optional[Union[ISA, str]] = None,
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(
|
||||
local_path=local_path,
|
||||
documentation=documentation,
|
||||
architecture=architecture,
|
||||
source=source,
|
||||
)
|
||||
|
||||
|
||||
class GitResource(DirectoryResource):
|
||||
"""A git resource."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
local_path: str,
|
||||
documentation: Optional[str] = None,
|
||||
source: Optional[str] = None,
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(
|
||||
local_path=local_path,
|
||||
documentation=documentation,
|
||||
source=source,
|
||||
)
|
||||
|
||||
|
||||
class KernelResource(BinaryResource):
|
||||
"""A kernel resource."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
local_path: str,
|
||||
documentation: Optional[str] = None,
|
||||
source: Optional[str] = None,
|
||||
architecture: Optional[Union[ISA, str]] = None,
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(
|
||||
local_path=local_path,
|
||||
documentation=documentation,
|
||||
source=source,
|
||||
architecture=architecture,
|
||||
)
|
||||
|
||||
|
||||
class CheckpointResource(DirectoryResource):
|
||||
"""A checkpoint resource. The following directory structure is expected:
|
||||
|
||||
<local_path>:
|
||||
- board.physmem.store0.pmem
|
||||
- m5.cpt
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
local_path: str,
|
||||
documentation: Optional[str] = None,
|
||||
source: Optional[str] = None,
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(
|
||||
local_path=local_path,
|
||||
documentation=documentation,
|
||||
source=source,
|
||||
)
|
||||
|
||||
|
||||
class SimpointResource(DirectoryResource):
|
||||
"""A simpoint resource."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
local_path: str,
|
||||
documentation: Optional[str] = None,
|
||||
source: Optional[str] = None,
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(
|
||||
local_path=local_path,
|
||||
documentation=documentation,
|
||||
source=source,
|
||||
)
|
||||
|
||||
|
||||
def obtain_resource(
|
||||
resource_name: str,
|
||||
resource_directory: Optional[str] = None,
|
||||
download_md5_mismatch: bool = True,
|
||||
) -> AbstractResource:
|
||||
"""
|
||||
This function primarily serves as a factory for resources. It will return
|
||||
the correct `AbstractResource` implementation based on the resource
|
||||
requested, by referencing the "resource.json" file (by default, that hosted
|
||||
at https://resources.gem5.org/resources.json). In addition to this, this
|
||||
function will download the resource if not detected in the
|
||||
`resource_directory`.
|
||||
|
||||
:param resource_name: The name of the gem5 resource as it appears under the
|
||||
"name" field in the `resource.json` file.
|
||||
:param resource_directory: The location of the directory in which the
|
||||
resource is to be stored. If this parameter is not set, it will set to
|
||||
the environment variable `GEM5_RESOURCE_DIR`. If the environment is not
|
||||
set it will default to `~/.cache/gem5` if available, otherwise the CWD.
|
||||
:param download_md5_mismatch: If the resource is present, but does not
|
||||
have the correct md5 value, the resoruce will be deleted and
|
||||
re-downloaded if this value is True. Otherwise an exception will be
|
||||
thrown. True by default.
|
||||
"""
|
||||
|
||||
# If the `resource_directory` parameter is not set via this function, we
|
||||
# check the "GEM5_RESOURCE_DIR" environment variable. If this too is not
|
||||
# set we call `_get_default_resource_dir()` to determine where the
|
||||
# resource directory is, or should be, located.
|
||||
if resource_directory == None:
|
||||
resource_directory = os.getenv(
|
||||
"GEM5_RESOURCE_DIR", _get_default_resource_dir()
|
||||
)
|
||||
|
||||
# Small checks here to ensure the resource directory is valid.
|
||||
if os.path.exists(resource_directory):
|
||||
if not os.path.isdir(resource_directory):
|
||||
raise Exception(
|
||||
"gem5 resource directory, "
|
||||
"'{}', exists but is not a directory".format(
|
||||
resource_directory
|
||||
)
|
||||
)
|
||||
else:
|
||||
# `exist_ok=True` here as, occasionally, if multiple instance of
|
||||
# gem5 are started simultaneously, a race condition can exist to
|
||||
# create the resource directory. Without `exit_ok=True`, threads
|
||||
# which lose this race will thrown a `FileExistsError` exception.
|
||||
# `exit_ok=True` ensures no exception is thrown.
|
||||
os.makedirs(resource_directory, exist_ok=True)
|
||||
|
||||
# This is the path to which the resource is to be stored.
|
||||
to_path = os.path.join(resource_directory, resource_name)
|
||||
|
||||
# Download the resource if it does not already exist.
|
||||
get_resource(
|
||||
resource_name=resource_name,
|
||||
to_path=os.path.join(resource_directory, resource_name),
|
||||
download_md5_mismatch=download_md5_mismatch,
|
||||
)
|
||||
|
||||
# Obtain the JSON resource entry for this resource
|
||||
resource_json = get_resources_json_obj(resource_name)
|
||||
|
||||
# Obtain the type from the JSON. From this we will determine what subclass
|
||||
# of `AbstractResource` we are to create and return.
|
||||
resources_type = resource_json["type"]
|
||||
|
||||
if resources_type == "resource":
|
||||
# This is a stop-gap measure to ensure to work with older versions of
|
||||
# the "resource.json" file. These should be replaced with their
|
||||
# respective specializations ASAP and this case removed.
|
||||
if (
|
||||
"additional_metadata" in resource_json
|
||||
and "root_partition" in resource_json["additional_metadata"]
|
||||
):
|
||||
# In this case we should return a DiskImageResource.
|
||||
root_partition = resource_json["additional_metadata"][
|
||||
"root_partition"
|
||||
]
|
||||
return DiskImageResource(
|
||||
local_path=to_path, root_partition=root_partition
|
||||
)
|
||||
return CustomResource(local_path=to_path)
|
||||
|
||||
assert resources_type in _get_resource_json_type_map
|
||||
resource_class = _get_resource_json_type_map[resources_type]
|
||||
|
||||
# Once we know what AbstractResource subclass we are using, we create it.
|
||||
# The fields in the JSON object are assumed to map like-for-like to the
|
||||
# subclass contructor, so we can pass the resource_json map directly.
|
||||
return resource_class(local_path=to_path, **resource_json)
|
||||
|
||||
|
||||
def _get_default_resource_dir() -> str:
|
||||
"""
|
||||
Obtain the default gem5 resources directory on the host system. This
|
||||
function will iterate through sensible targets until it finds one that
|
||||
works on the host system.
|
||||
|
||||
:returns: The default gem5 resources directory.
|
||||
"""
|
||||
test_list = [
|
||||
# First try `~/.cache/gem5`.
|
||||
os.path.join(Path.home(), ".cache", "gem5"),
|
||||
# Last resort, just put things in the cwd.
|
||||
os.path.join(Path.cwd(), "resources"),
|
||||
]
|
||||
|
||||
for path in test_list:
|
||||
if os.path.exists(path): # If the path already exists...
|
||||
if os.path.isdir(path): # Check to see the path is a directory.
|
||||
return path # If so, the path is valid and can be used.
|
||||
else: # If the path does not exist, try to create it.
|
||||
try:
|
||||
os.makedirs(path, exist_ok=False)
|
||||
return path
|
||||
except OSError:
|
||||
continue # If the path cannot be created, then try another.
|
||||
|
||||
raise Exception("Cannot find a valid location to download resources")
|
||||
|
||||
|
||||
# The following classes exist to preserve backwards functionality between the
|
||||
# API for obtaining resources in v21.1.0 and prior.
|
||||
|
||||
|
||||
class CustomResource(AbstractResource):
|
||||
@@ -71,134 +429,101 @@ class CustomResource(AbstractResource):
|
||||
A custom gem5 resource. This can be used to encapsulate a resource provided
|
||||
by a gem5 user as opposed to one available within the gem5 resources
|
||||
repository.
|
||||
|
||||
**Warning**: This class is deprecated and will be removed in future
|
||||
releases of gem5. Please use the correct `AbstractResource` subclass
|
||||
instead.
|
||||
"""
|
||||
|
||||
def __init__(self, local_path: str, metadata: Dict = {}):
|
||||
"""
|
||||
:param local_path: The path of the resource on the host system.
|
||||
:param metadata: Add metadata for the custom resource.
|
||||
:param metadata: Add metadata for the custom resource. **Warning:**
|
||||
As of v22.1.1, this parameter is not used.
|
||||
"""
|
||||
super().__init__(local_path=local_path, metadata=metadata)
|
||||
warn(
|
||||
"The `CustomResource` class is deprecated. Please use an "
|
||||
"`AbstractResource` subclass instead."
|
||||
)
|
||||
if bool(metadata): # Empty dicts cast to False
|
||||
warn(
|
||||
"the `metadata` parameter was set via the `CustomResource` "
|
||||
"constructor. This parameter is not used."
|
||||
)
|
||||
super().__init__(local_path=local_path)
|
||||
|
||||
|
||||
class CustomDiskImageResource(CustomResource):
|
||||
class CustomDiskImageResource(DiskImageResource):
|
||||
"""
|
||||
A custom disk image gem5 resource. It can be used to specify a custom,
|
||||
local disk image.
|
||||
|
||||
**Warning**: This class is deprecated and will be removed in future
|
||||
releases of gem5. Please use the `DiskImageResource` class instead. This
|
||||
class is merely a wrapper for it.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
local_path: str,
|
||||
disk_root_partition: Optional[str] = None,
|
||||
root_partition: Optional[str] = None,
|
||||
metadata: Dict = {},
|
||||
):
|
||||
"""
|
||||
:param local_path: The path of the disk image on the host system.
|
||||
:param disk_root_partition: The root disk partition to use.
|
||||
:param metadata: Metadata for the resource.
|
||||
:param root_partition: The root disk partition to use.
|
||||
:param metadata: Metadata for the resource. **Warning:** As of "
|
||||
"v22.1.1, this parameter is not used.
|
||||
"""
|
||||
|
||||
# Behind the scenes, we set the the root partition via the metadata.
|
||||
# For a traditional, non-custom, resource it is the metadata that is
|
||||
# used to specify the disk image partition root. Therefore, when the
|
||||
# root disk partition specified during the construction, we apply it as
|
||||
# metadata.
|
||||
if disk_root_partition:
|
||||
disk_root_partition_dict = {
|
||||
"additional_metadata": {"root_partition": disk_root_partition}
|
||||
}
|
||||
metadata.update(disk_root_partition_dict)
|
||||
|
||||
super().__init__(local_path=local_path, metadata=metadata)
|
||||
|
||||
|
||||
class Resource(AbstractResource):
|
||||
"""
|
||||
An official gem5 resources as hosted within our gem5 resources repository
|
||||
(<resources.gem5.org>).
|
||||
|
||||
A user need only specify the name of the resource during construction. The
|
||||
resource will be downloaded if needed. A list of available resources can
|
||||
be obtained via `downloader.list_resources()`.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
resource_name: str,
|
||||
resource_directory: Optional[str] = None,
|
||||
download_md5_mismatch: bool = True,
|
||||
):
|
||||
"""
|
||||
:param resource_name: The name of the gem5 resource.
|
||||
:param resource_directory: The location of the directory in which the
|
||||
resource is to be stored. If this parameter is not set, it will set to
|
||||
the environment variable `GEM5_RESOURCE_DIR`. If the environment is not
|
||||
set it will default to `~/.cache/gem5` if available, otherwise the CWD.
|
||||
:param download_md5_mismatch: If the resource is present, but does not
|
||||
have the correct md5 value, the resoruce will be deleted and
|
||||
re-downloaded if this value is True. Otherwise an exception will be
|
||||
thrown. True by default.
|
||||
"""
|
||||
|
||||
if resource_directory == None:
|
||||
resource_directory = os.getenv(
|
||||
"GEM5_RESOURCE_DIR", self._get_default_resource_dir()
|
||||
warn(
|
||||
"The `CustomDiskImageResource` class is deprecated. Please use "
|
||||
"`DiskImageResource` instead."
|
||||
)
|
||||
if bool(metadata): # Empty dicts cast to False
|
||||
warn(
|
||||
"the `metadata` parameter was set via the "
|
||||
"`CustomDiskImageResource` constructor. This parameter is not "
|
||||
"used."
|
||||
)
|
||||
super().__init__(local_path=local_path, root_partition=root_partition)
|
||||
|
||||
if os.path.exists(resource_directory):
|
||||
if not os.path.isdir(resource_directory):
|
||||
raise Exception(
|
||||
"gem5 resource directory, "
|
||||
"'{}', exists but is not a directory".format(
|
||||
resource_directory
|
||||
)
|
||||
)
|
||||
else:
|
||||
# `exist_ok=True` here as, occasionally, if multiple instance of
|
||||
# gem5 are started simultaneously, a race condition can exist to
|
||||
# create the resource directory. Without `exit_ok=True`, threads
|
||||
# which lose this race will thrown a `FileExistsError` exception.
|
||||
# `exit_ok=True` ensures no exception is thrown.
|
||||
os.makedirs(resource_directory, exist_ok=True)
|
||||
|
||||
to_path = os.path.join(resource_directory, resource_name)
|
||||
def Resource(
|
||||
resource_name: str,
|
||||
resource_directory: Optional[str] = None,
|
||||
download_md5_mismatch: bool = True,
|
||||
) -> AbstractResource:
|
||||
"""
|
||||
This function was created to maintain backwards compability for v21.1.0
|
||||
and prior releases of gem5 where `Resource` was a class.
|
||||
|
||||
super().__init__(
|
||||
local_path=to_path, metadata=get_resources_json_obj(resource_name)
|
||||
)
|
||||
get_resource(
|
||||
resource_name=resource_name,
|
||||
to_path=to_path,
|
||||
download_md5_mismatch=download_md5_mismatch,
|
||||
)
|
||||
In the interests of gem5-resource specialization, the `Resource` class
|
||||
has been dropped. Instead users are advized to use the `obtain_resource`
|
||||
function which will return the correct `AbstractResource` implementation.
|
||||
This function (disguised as a class) wraps this function.
|
||||
"""
|
||||
|
||||
def _get_default_resource_dir(cls) -> str:
|
||||
"""
|
||||
Obtain the default gem5 resources directory on the host system. This
|
||||
function will iterate through sensible targets until it finds one that
|
||||
works on the host system.
|
||||
warn(
|
||||
"`Resource` has been deprecated. Please use the `obtain_resource` "
|
||||
"function instead."
|
||||
)
|
||||
|
||||
:returns: The default gem5 resources directory.
|
||||
"""
|
||||
test_list = [
|
||||
# First try `~/.cache/gem5`.
|
||||
os.path.join(Path.home(), ".cache", "gem5"),
|
||||
# Last resort, just put things in the cwd.
|
||||
os.path.join(Path.cwd(), "resources"),
|
||||
]
|
||||
return obtain_resource(
|
||||
resource_name=resource_name,
|
||||
resource_directory=resource_directory,
|
||||
download_md5_mismatch=download_md5_mismatch,
|
||||
)
|
||||
|
||||
for path in test_list:
|
||||
if os.path.exists(path): # If the path already exists...
|
||||
if os.path.isdir(
|
||||
path
|
||||
): # Check to see the path is a directory.
|
||||
return path # If so, the path is valid and can be used.
|
||||
else: # If the path does not exist, try to create it.
|
||||
try:
|
||||
os.makedirs(path, exist_ok=False)
|
||||
return path
|
||||
except OSError:
|
||||
continue # If the path cannot be created, then try another.
|
||||
|
||||
raise Exception("Cannot find a valid location to download resources")
|
||||
_get_resource_json_type_map = {
|
||||
"disk-image": DiskImageResource,
|
||||
"binary": BinaryResource,
|
||||
"kernel": KernelResource,
|
||||
"checkpoint": CheckpointResource,
|
||||
"git": GitResource,
|
||||
"bootloader": BootloaderResource,
|
||||
"file": FileResource,
|
||||
"directory": DirectoryResource,
|
||||
"simpoint": SimpointResource,
|
||||
"resource": Resource,
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from .downloader import get_workload_json_obj
|
||||
from .resource import Resource
|
||||
from .resource import obtain_resource
|
||||
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
@@ -209,7 +209,7 @@ class Workload(AbstractWorkload):
|
||||
assert isinstance(key, str)
|
||||
value = workload_json["resources"][key]
|
||||
assert isinstance(value, str)
|
||||
params[key] = Resource(
|
||||
params[key] = obtain_resource(
|
||||
value, resource_directory=resource_directory
|
||||
)
|
||||
|
||||
|
||||
@@ -94,44 +94,44 @@ gem5_verify_config(
|
||||
length=constants.quick_tag,
|
||||
)
|
||||
|
||||
gem5_verify_config(
|
||||
name="test-simpoints-se-checkpoint",
|
||||
fixtures=(),
|
||||
verifiers=(),
|
||||
config=joinpath(
|
||||
config.base_dir,
|
||||
"configs",
|
||||
"example",
|
||||
"gem5_library",
|
||||
"checkpoints",
|
||||
"simpoints-se-checkpoint.py",
|
||||
),
|
||||
config_args=[
|
||||
"--checkpoint-path",
|
||||
joinpath(resource_path, "se_checkpoint_folder-save"),
|
||||
],
|
||||
valid_isas=(constants.all_compiled_tag,),
|
||||
valid_hosts=constants.supported_hosts,
|
||||
length=constants.quick_tag,
|
||||
)
|
||||
# gem5_verify_config(
|
||||
# name="test-simpoints-se-checkpoint",
|
||||
# fixtures=(),
|
||||
# verifiers=(),
|
||||
# config=joinpath(
|
||||
# config.base_dir,
|
||||
# "configs",
|
||||
# "example",
|
||||
# "gem5_library",
|
||||
# "checkpoints",
|
||||
# "simpoints-se-checkpoint.py",
|
||||
# ),
|
||||
# config_args=[
|
||||
# "--checkpoint-path",
|
||||
# joinpath(resource_path, "se_checkpoint_folder-save"),
|
||||
# ],
|
||||
# valid_isas=(constants.all_compiled_tag,),
|
||||
# valid_hosts=constants.supported_hosts,
|
||||
# length=constants.quick_tag,
|
||||
# )
|
||||
|
||||
gem5_verify_config(
|
||||
name="test-simpoints-se-restore",
|
||||
fixtures=(),
|
||||
verifiers=(),
|
||||
config=joinpath(
|
||||
config.base_dir,
|
||||
"configs",
|
||||
"example",
|
||||
"gem5_library",
|
||||
"checkpoints",
|
||||
"simpoints-se-restore.py",
|
||||
),
|
||||
config_args=[],
|
||||
valid_isas=(constants.all_compiled_tag,),
|
||||
valid_hosts=constants.supported_hosts,
|
||||
length=constants.quick_tag,
|
||||
)
|
||||
# gem5_verify_config(
|
||||
# name="test-simpoints-se-restore",
|
||||
# fixtures=(),
|
||||
# verifiers=(),
|
||||
# config=joinpath(
|
||||
# config.base_dir,
|
||||
# "configs",
|
||||
# "example",
|
||||
# "gem5_library",
|
||||
# "checkpoints",
|
||||
# "simpoints-se-restore.py",
|
||||
# ),
|
||||
# config_args=[],
|
||||
# valid_isas=(constants.all_compiled_tag,),
|
||||
# valid_hosts=constants.supported_hosts,
|
||||
# length=constants.quick_tag,
|
||||
# )
|
||||
|
||||
if os.access("/dev/kvm", mode=os.R_OK | os.W_OK):
|
||||
# The x86-ubuntu-run uses KVM cores, this test will therefore only be run
|
||||
|
||||
196
tests/pyunit/stdlib/resources/pyunit_resource_specialization.py
Normal file
196
tests/pyunit/stdlib/resources/pyunit_resource_specialization.py
Normal file
@@ -0,0 +1,196 @@
|
||||
# Copyright (c) 2023 The Regents of the University of California
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met: redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer;
|
||||
# redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution;
|
||||
# neither the name of the copyright holders nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from gem5.resources.resource import *
|
||||
from gem5.isas import ISA
|
||||
|
||||
|
||||
class ResourceSpecializationSuite(unittest.TestCase):
|
||||
"""This suite tests that `gem5.resource.resource` casts to the correct
|
||||
`AbstractResource` specialization when using the `obtain_resource`
|
||||
function.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
"""Prior to running the suite we set the resource directory to
|
||||
"ref/resource-specialization.json"
|
||||
"""
|
||||
os.environ["GEM5_RESOURCE_JSON"] = os.path.join(
|
||||
os.path.realpath(os.path.dirname(__file__)),
|
||||
"refs",
|
||||
"resource-specialization.json",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls) -> None:
|
||||
"""After running the suite we unset the gem5-resource JSON file, as to
|
||||
not interfere with others tests.
|
||||
"""
|
||||
del os.environ["GEM5_RESOURCE_JSON"]
|
||||
|
||||
def get_resource_dir(cls) -> str:
|
||||
"""To ensure the resources are cached to the same directory as all
|
||||
other tests, this function returns the location of the testing
|
||||
directories "resources" directory.
|
||||
"""
|
||||
return os.path.join(
|
||||
os.path.realpath(os.path.dirname(__file__)),
|
||||
os.pardir,
|
||||
os.pardir,
|
||||
os.pardir,
|
||||
"gem5",
|
||||
"resources",
|
||||
)
|
||||
|
||||
def test_binary_resource(self) -> None:
|
||||
"""Tests the loading of of a BinaryResource"""
|
||||
resource = obtain_resource(
|
||||
resource_name="binary-example",
|
||||
resource_directory=self.get_resource_dir(),
|
||||
)
|
||||
|
||||
self.assertIsInstance(resource, BinaryResource)
|
||||
|
||||
self.assertEquals(
|
||||
"binary-example documentation.", resource.get_documentation()
|
||||
)
|
||||
self.assertEquals("src/simple", resource.get_source())
|
||||
self.assertEquals(ISA.ARM, resource.get_architecture())
|
||||
|
||||
def test_kernel_resource(self) -> None:
|
||||
"""Tests the loading of a KernelResource."""
|
||||
resource = obtain_resource(
|
||||
resource_name="kernel-example",
|
||||
resource_directory=self.get_resource_dir(),
|
||||
)
|
||||
|
||||
self.assertIsInstance(resource, KernelResource)
|
||||
|
||||
self.assertEquals(
|
||||
"kernel-example documentation.", resource.get_documentation()
|
||||
)
|
||||
self.assertEquals("src/linux-kernel", resource.get_source())
|
||||
self.assertEquals(ISA.RISCV, resource.get_architecture())
|
||||
|
||||
def test_bootloader_resource(self) -> None:
|
||||
"""Tests the loading of a BootloaderResource."""
|
||||
resource = obtain_resource(
|
||||
resource_name="bootloader-example",
|
||||
resource_directory=self.get_resource_dir(),
|
||||
)
|
||||
|
||||
self.assertIsInstance(resource, BootloaderResource)
|
||||
|
||||
self.assertEquals(
|
||||
"bootloader documentation.", resource.get_documentation()
|
||||
)
|
||||
self.assertIsNone(resource.get_source())
|
||||
self.assertIsNone(resource.get_architecture())
|
||||
|
||||
def test_disk_image_resource(self) -> None:
|
||||
"""Tests the loading of a DiskImageResource."""
|
||||
resource = obtain_resource(
|
||||
resource_name="disk-image-example",
|
||||
resource_directory=self.get_resource_dir(),
|
||||
)
|
||||
|
||||
self.assertIsInstance(resource, DiskImageResource)
|
||||
|
||||
self.assertEquals(
|
||||
"disk-image documentation.", resource.get_documentation()
|
||||
)
|
||||
self.assertEquals("src/x86-ubuntu", resource.get_source())
|
||||
self.assertEquals("1", resource.get_root_partition())
|
||||
|
||||
def test_checkpoint_resource(self) -> None:
|
||||
"""Tests the loading of a CheckpointResource."""
|
||||
resource = obtain_resource(
|
||||
resource_name="checkpoint-example",
|
||||
resource_directory=self.get_resource_dir(),
|
||||
)
|
||||
|
||||
self.assertIsInstance(resource, CheckpointResource)
|
||||
|
||||
self.assertEquals(
|
||||
"checkpoint-example documentation.", resource.get_documentation()
|
||||
)
|
||||
self.assertIsNone(resource.get_source())
|
||||
|
||||
def test_git_resource(self) -> None:
|
||||
"""Tests the loading of a GitResource."""
|
||||
resource = obtain_resource(
|
||||
resource_name="git-example",
|
||||
resource_directory=self.get_resource_dir(),
|
||||
)
|
||||
|
||||
self.assertIsInstance(resource, GitResource)
|
||||
|
||||
self.assertIsNone(resource.get_documentation())
|
||||
self.assertIsNone(resource.get_source())
|
||||
|
||||
def test_simpoint_resource(self) -> None:
|
||||
"""Tests the loading of a Simpoint resource."""
|
||||
resource = obtain_resource(
|
||||
resource_name="simpoint-example",
|
||||
resource_directory=self.get_resource_dir(),
|
||||
)
|
||||
|
||||
self.assertIsInstance(resource, SimpointResource)
|
||||
|
||||
self.assertEquals(
|
||||
"simpoint documentation.", resource.get_documentation()
|
||||
)
|
||||
self.assertIsNone(resource.get_source())
|
||||
|
||||
def test_file_resource(self) -> None:
|
||||
"""Tests the loading of a FileResource."""
|
||||
resource = obtain_resource(
|
||||
resource_name="file-example",
|
||||
resource_directory=self.get_resource_dir(),
|
||||
)
|
||||
|
||||
self.assertIsInstance(resource, FileResource)
|
||||
|
||||
self.assertIsNone(resource.get_documentation())
|
||||
self.assertIsNone(resource.get_source())
|
||||
|
||||
def test_directory_resource(self) -> None:
|
||||
"""Tests the loading of a DirectoryResource."""
|
||||
resource = obtain_resource(
|
||||
resource_name="directory-example",
|
||||
resource_directory=self.get_resource_dir(),
|
||||
)
|
||||
|
||||
self.assertIsInstance(resource, DirectoryResource)
|
||||
|
||||
self.assertEquals(
|
||||
"directory-example documentation.", resource.get_documentation()
|
||||
)
|
||||
self.assertIsNone(resource.get_source())
|
||||
@@ -29,7 +29,11 @@ import tempfile
|
||||
import os
|
||||
|
||||
from gem5.resources.workload import Workload, CustomWorkload
|
||||
from gem5.resources.resource import Resource
|
||||
from gem5.resources.resource import (
|
||||
BinaryResource,
|
||||
DiskImageResource,
|
||||
obtain_resource,
|
||||
)
|
||||
from gem5.resources.downloader import _resources_json_version_required
|
||||
|
||||
from typing import Dict
|
||||
@@ -50,7 +54,7 @@ class CustomWorkloadTestSuite(unittest.TestCase):
|
||||
"previous-versions" : {},
|
||||
"resources": [
|
||||
{
|
||||
"type" : "resource",
|
||||
"type" : "binary",
|
||||
"name" : "x86-hello64-static",
|
||||
"documentation" : "A 'Hello World!' binary.",
|
||||
"architecture" : "X86",
|
||||
@@ -73,7 +77,7 @@ class CustomWorkloadTestSuite(unittest.TestCase):
|
||||
cls.custom_workload = CustomWorkload(
|
||||
function="set_se_binary_workload",
|
||||
parameters={
|
||||
"binary": Resource("x86-hello64-static"),
|
||||
"binary": obtain_resource("x86-hello64-static"),
|
||||
"arguments": ["hello", 6],
|
||||
},
|
||||
)
|
||||
@@ -100,7 +104,7 @@ class CustomWorkloadTestSuite(unittest.TestCase):
|
||||
self.assertEquals(2, len(parameters))
|
||||
|
||||
self.assertTrue("binary" in parameters)
|
||||
self.assertTrue(isinstance(parameters["binary"], Resource))
|
||||
self.assertTrue(isinstance(parameters["binary"], BinaryResource))
|
||||
|
||||
self.assertTrue("arguments" in parameters)
|
||||
self.assertTrue(isinstance(parameters["arguments"], list))
|
||||
@@ -156,7 +160,7 @@ class WorkloadTestSuite(unittest.TestCase):
|
||||
"previous-versions" : {},
|
||||
"resources": [
|
||||
{
|
||||
"type" : "resource",
|
||||
"type" : "kernel",
|
||||
"name" : "x86-linux-kernel-5.2.3",
|
||||
"documentation" : "The linux kernel (v5.2.3), compiled to X86.",
|
||||
"architecture" : "X86",
|
||||
@@ -166,7 +170,7 @@ class WorkloadTestSuite(unittest.TestCase):
|
||||
"source" : "src/linux-kernel"
|
||||
},
|
||||
{
|
||||
"type" : "resource",
|
||||
"type" : "disk-image",
|
||||
"name" : "x86-ubuntu-18.04-img",
|
||||
"documentation" : "A disk image containing Ubuntu 18.04 for x86..",
|
||||
"architecture" : "X86",
|
||||
@@ -174,9 +178,7 @@ class WorkloadTestSuite(unittest.TestCase):
|
||||
"md5sum" : "90e363abf0ddf22eefa2c7c5c9391c49",
|
||||
"url" : "{url_base}/images/x86/ubuntu-18-04/x86-ubuntu.img.gz",
|
||||
"source" : "src/x86-ubuntu",
|
||||
"additional_metadata" : {
|
||||
"root_partition": "1"
|
||||
}
|
||||
"root_partition": "1"
|
||||
},
|
||||
{
|
||||
"type" : "workload",
|
||||
@@ -226,10 +228,12 @@ class WorkloadTestSuite(unittest.TestCase):
|
||||
self.assertEqual(3, len(parameters))
|
||||
|
||||
self.assertTrue("kernel" in parameters)
|
||||
self.assertTrue(isinstance(parameters["kernel"], Resource))
|
||||
self.assertTrue(isinstance(parameters["kernel"], BinaryResource))
|
||||
|
||||
self.assertTrue("disk_image" in parameters)
|
||||
self.assertTrue(isinstance(parameters["disk_image"], Resource))
|
||||
self.assertTrue(
|
||||
isinstance(parameters["disk_image"], DiskImageResource)
|
||||
)
|
||||
|
||||
self.assertTrue("readfile_contents" in parameters)
|
||||
self.assertTrue(
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
|
||||
{
|
||||
"version" : "develop",
|
||||
"url_base" : "http://dist.gem5.org/dist/v22-1",
|
||||
"previous-versions" : {
|
||||
"develop" : "https://gem5.googlesource.com/public/gem5-resources/+/refs/heads/develop/resources.json?format=TEXT",
|
||||
"21.2" : "http://resources.gem5.org/prev-resources-json/resources-21-2.json"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type" : "kernel",
|
||||
"name" : "kernel-example",
|
||||
"documentation" : "kernel-example documentation.",
|
||||
"architecture" : "RISCV",
|
||||
"is_zipped" : false,
|
||||
"md5sum" : "60a53c7d47d7057436bf4b9df707a841",
|
||||
"url" : "{url_base}/kernels/x86/static/vmlinux-5.4.49",
|
||||
"source" : "src/linux-kernel"
|
||||
},
|
||||
{
|
||||
"type" : "disk-image",
|
||||
"name" : "disk-image-example",
|
||||
"documentation" : "disk-image documentation.",
|
||||
"architecture" : "X86",
|
||||
"is_zipped" : true,
|
||||
"md5sum" : "90e363abf0ddf22eefa2c7c5c9391c49",
|
||||
"url" : "{url_base}/images/x86/ubuntu-18-04/x86-ubuntu.img.gz",
|
||||
"source" : "src/x86-ubuntu",
|
||||
"root_partition": "1"
|
||||
},
|
||||
{
|
||||
"type" : "binary",
|
||||
"name" : "binary-example",
|
||||
"documentation" : "binary-example documentation.",
|
||||
"architecture" : "ARM",
|
||||
"is_zipped" : false,
|
||||
"md5sum" : "71b2cb004fe2cda4556f0b1a38638af6",
|
||||
"url" : "{url_base}/test-progs/hello/bin/arm/linux/hello64-static",
|
||||
"source" : "src/simple"
|
||||
},
|
||||
{
|
||||
"type" : "bootloader",
|
||||
"name" : "bootloader-example",
|
||||
"documentation" : "bootloader documentation.",
|
||||
"is_zipped" : false,
|
||||
"md5sum" : "71b2cb004fe2cda4556f0b1a38638af6",
|
||||
"url" : "{url_base}/test-progs/hello/bin/arm/linux/hello64-static"
|
||||
},
|
||||
{
|
||||
"type" : "checkpoint",
|
||||
"name" : "checkpoint-example",
|
||||
"documentation" : "checkpoint-example documentation.",
|
||||
"architecture": "RISCV",
|
||||
"is_zipped" : false,
|
||||
"md5sum" : "3a57c1bb1077176c4587b8a3bf4f8ace",
|
||||
"source" : null,
|
||||
"is_tar_archive" : true,
|
||||
"url": "{url_base}/checkpoints/riscv-hello-example-checkpoint.tar"
|
||||
},
|
||||
{
|
||||
"type" : "git",
|
||||
"name" : "git-example",
|
||||
"documentation" : null,
|
||||
"is_zipped" : false,
|
||||
"is_tar_archive" : true,
|
||||
"md5sum" : "71b2cb004fe2cda4556f0b1a38638af6",
|
||||
"url": "{url_base}/checkpoints/riscv-hello-example-checkpoint.tar"
|
||||
},
|
||||
{
|
||||
"type" : "file",
|
||||
"name" : "file-example",
|
||||
"documentation" : null,
|
||||
"is_zipped" : false,
|
||||
"md5sum" : "71b2cb004fe2cda4556f0b1a38638af6",
|
||||
"url": "{url_base}/checkpoints/riscv-hello-example-checkpoint.tar",
|
||||
"source" : null
|
||||
},
|
||||
{
|
||||
"type" : "directory",
|
||||
"name" : "directory-example",
|
||||
"documentation" : "directory-example documentation.",
|
||||
"is_zipped" : false,
|
||||
"md5sum" : "3a57c1bb1077176c4587b8a3bf4f8ace",
|
||||
"source" : null,
|
||||
"is_tar_archive" : true,
|
||||
"url": "{url_base}/checkpoints/riscv-hello-example-checkpoint.tar"
|
||||
},
|
||||
{
|
||||
"type" : "simpoint",
|
||||
"name" : "simpoint-example",
|
||||
"documentation" : "simpoint documentation.",
|
||||
"is_zipped" : false,
|
||||
"md5sum" : "3a57c1bb1077176c4587b8a3bf4f8ace",
|
||||
"source" : null,
|
||||
"is_tar_archive" : true,
|
||||
"url": "{url_base}/checkpoints/riscv-hello-example-checkpoint.tar"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user