Bobby R. Bruce has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/49304 )
Change subject: python,configs: Add Resource class to gem5 components
......................................................................
python,configs: Add Resource class to gem5 components
The `Resource` class can be used to obtain a gem5 resource. The
`Resource` class, via the `downloader` package, parses the gem5
resources `resources.json` file:
https://gem5.googlesource.com/public/gem5-resources/+/refs/heads/develop/resources.json
From this it can determine the available resources and where to download
them. This allows for automatic retrieval of resources.
The `CustomResource` can be used to specify a local resource not part of
gem5 resources.
The board's `set_workload` function has been updated to use the
resources.
The components library example scripts have been updated to demonstrate
the `Resource`/`CustomResource` class usage.
Issue-on: https://gem5.atlassian.net/browse/GEM5-1022
Change-Id: I59cfe81d5ec9c64576c0dab55af52aede96976fb
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49304
Reviewed-by: Austin Harris <[email protected]>
Maintainer: Jason Lowe-Power <[email protected]>
Tested-by: kokoro <[email protected]>
---
M components_library/boards/simple_board.py
M components_library/boards/x86_board.py
A components_library/resources/downloader.py
A components_library/resources/resource.py
A components_library/utils/filelock.py
M configs/example/components-library/boot_exit_disk_run.py
M configs/example/components-library/parsec_disk_run.py
M configs/example/components-library/simple_binary_run.py
8 files changed, 502 insertions(+), 68 deletions(-)
Approvals:
Austin Harris: Looks good to me, approved
Jason Lowe-Power: Looks good to me, approved
kokoro: Regressions pass
diff --git a/components_library/boards/simple_board.py
b/components_library/boards/simple_board.py
index 8ecaefc..86e6890 100644
--- a/components_library/boards/simple_board.py
+++ b/components_library/boards/simple_board.py
@@ -24,6 +24,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+from components_library.resources.resource import AbstractResource
from m5.objects import (
AddrRange,
SrcClockDomain,
@@ -145,7 +146,7 @@
self.mem_ranges = [AddrRange(memory.get_size())]
memory.set_memory_range(self.mem_ranges)
- def set_workload(self, binary: str) -> None:
+ def set_workload(self, binary: AbstractResource) -> None:
"""Set up the system to run a specific binary.
**Limitations**
@@ -153,11 +154,11 @@
* Dynamically linked executables are partially supported when the
host
ISA and the simulated ISA are the same.
- :param binary: The path on the *host* to the binary to run in gem5.
+ :param binary: The resource encapsulating the binary to be run.
"""
- self.workload = SEWorkload.init_compatible(binary)
+ self.workload = SEWorkload.init_compatible(binary.get_local_path())
process = Process()
- process.cmd = [binary]
+ process.cmd = [binary.get_local_path()]
self.get_processor().get_cores()[0].set_workload(process)
diff --git a/components_library/boards/x86_board.py
b/components_library/boards/x86_board.py
index dd9ad13..6470379 100644
--- a/components_library/boards/x86_board.py
+++ b/components_library/boards/x86_board.py
@@ -25,6 +25,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+from components_library.resources.resource import AbstractResource
from components_library.utils.override import overrides
from components_library.boards.abstract_board import AbstractBoard
from components_library.isas import ISA
@@ -273,7 +274,10 @@
def set_workload(
- self, kernel: str, disk_image: str, command: Optional[str] = None
+ self,
+ kernel: AbstractResource,
+ disk_image: AbstractResource,
+ command: Optional[str] = None,
):
"""Setup the full system files
@@ -287,14 +291,14 @@
* Only supports a Linux kernel
* Disk must be configured correctly to use the command option
- :param kernel: The compiled kernel binary
- :param disk_image: A disk image containing the OS data. The first
- partition should be the root partition.
+ :param kernel: The compiled kernel binary resource
+ :param disk_image: A disk image resource containing the OS data.
The
+ first partition should be the root partition.
:param command: The command(s) to run with bash once the OS is
booted
"""
# Set the Linux kernel to use.
- self.workload.object_file = kernel
+ self.workload.object_file = kernel.get_local_path()
# Options specified on the kernel command line.
self.workload.command_line = " ".join(
@@ -312,7 +316,7 @@
ide_disk.image = CowDiskImage(
child=RawDiskImage(read_only=True), read_only=False
)
- ide_disk.image.child.image_file = disk_image
+ ide_disk.image.child.image_file = disk_image.get_local_path()
# Attach the SimObject to the system.
self.pc.south_bridge.ide.disks = [ide_disk]
diff --git a/components_library/resources/downloader.py
b/components_library/resources/downloader.py
new file mode 100644
index 0000000..5163724
--- /dev/null
+++ b/components_library/resources/downloader.py
@@ -0,0 +1,255 @@
+# Copyright (c) 2021 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 json
+import urllib.request
+import hashlib
+import os
+import shutil
+import gzip
+import hashlib
+import base64
+from typing import List, Dict, Optional
+
+from ..utils.filelock import FileLock
+
+"""
+This Python module contains functions used to download, list, and obtain
+information about resources from resources.gem5.org.
+"""
+
+
+def _get_resources_json_uri() -> str:
+ # TODO: This is hardcoded to develop. This will need updated for each
+ # release to the stable branch.
+ uri = (
+ "https://gem5.googlesource.com/public/gem5-resources/"
+ + "+/refs/heads/develop/resources.json?format=TEXT"
+ )
+
+ return uri
+
+
+def _get_resources_json() -> Dict:
+ """
+ Gets the Resources JSON.
+
+ :returns: The Resources JSON (as a Python Dictionary).
+ """
+
+ # Note: Google Source does not properly support obtaining files as raw
+ # text. Therefore when we open the URL we receive the JSON in base64
+ # format. Conversion is needed before it can be loaded.
+ with urllib.request.urlopen(_get_resources_json_uri()) as url:
+ return json.loads(base64.b64decode(url.read()).decode("utf-8"))
+
+
+def _get_resources(resources_group: Dict) -> Dict[str, Dict]:
+ """
+ A recursive function to get all the resources.
+
+ :returns: A dictionary of resource names to the resource JSON objects.
+ """
+
+ to_return = {}
+ for resource in resources_group:
+ if resource["type"] == "artifact":
+ # If the type is "artifact" then we add it directly to the map
+ # after a check that the name is unique.
+ if resource["name"] in to_return.keys():
+ raise Exception(
+ "Error: Duplicate artifact with name '{}'.".format(
+ resource["name"]
+ )
+ )
+ to_return[resource["name"]] = resource
+ elif resource["type"] == "group":
+ # If it's a group we get recursive. We then check to see if
there
+ # are any duplication of keys.
+ new_map = _get_resources(resource["contents"])
+ intersection =
set(new_map.keys()).intersection(to_return.keys())
+ if len(intersection) > 0:
+ # Note: if this error is received it's likely an error with
+ # the resources.json file. The resources names need to be
+ # unique keyes.
+ raise Exception(
+ "Error: Duplicate artifacts with names: {}.".format(
+ str(intersection)
+ )
+ )
+ to_return.update(new_map)
+ else:
+ raise Exception(
+ "Error: Unknown type '{}'.".format(resource["type"])
+ )
+
+ return to_return
+
+
+def _get_md5(file: str) -> str:
+ """
+ Gets the md5 of a file.
+
+ :param file: The file needing an md5 value.
+
+ :returns: The md5 of the input file.
+ """
+
+ # Note: This code is slightly more complex than you might expect as
+ # `hashlib.md5(<file>)` returns malloc errors for large files (such as
+ # disk images).
+ md5_object = hashlib.md5()
+ block_size = 128 * md5_object.block_size
+ a_file = open(file, "rb")
+ chunk = a_file.read(block_size)
+
+ while chunk:
+ md5_object.update(chunk)
+ chunk = a_file.read(block_size)
+
+ return md5_object.hexdigest()
+
+
+def _download(url: str, download_to: str) -> None:
+ """
+ Downloads a file.
+
+ :param url: The URL of the file to download.
+
+ :param download_to: The location the downloaded file is to be stored.
+ """
+
+ # TODO: This whole setup will only work for single files we can get via
+ # wget. We also need to support git clones going forward.
+ urllib.request.urlretrieve(url, download_to)
+
+
+def list_resources() -> List[str]:
+ """
+ Lists all available resources by name.
+
+ :returns: A list of resources by name.
+ """
+ return _get_resources(_get_resources_json()["resources"]).keys()
+
+
+def get_resources_json_obj(resource_name: str) -> Dict:
+ """
+ Get a JSON object of a specified resource.
+
+ :param resource_name: The name of the resource.
+
+ :returns: The JSON object (in the form of a dictionary).
+
+ :raises Exception: An exception is raised if the specified resources
does
+ not exist.
+ """
+ artifact_map = _get_resources(_get_resources_json()["resources"])
+
+ if resource_name not in artifact_map:
+ raise Exception(
+ "Error: Resource with name '{}' does not exist".format(
+ resource_name
+ )
+ )
+
+ return artifact_map[resource_name]
+
+
+def get_resource(
+ resource_name: str,
+ to_path: str,
+ unzip: Optional[bool] = True,
+ override: Optional[bool] = False,
+) -> None:
+ """
+ Obtains a gem5 resource and stored it to a specified location. If the
+ specified resource is already at the location, no action is taken.
+
+ :param resource_name: The resource to be obtained.
+
+ :param to_path: The location in the file system the resource is to be
+ stored. The filename should be included.
+
+ :param unzip: If true, gzipped resources will be unzipped prior to
saving
+ to `to_path`. True by default.
+
+ :param override: If a resource is present with an incorrect hash (e.g.,
+ an outdated version of the resource is present), `get_resource` will
delete
+ this local resource and re-download it if this parameter is True.
False by
+ default.
+
+ :raises Exception: An exception is thrown if a file is already present
at
+ `to_path` but it does not have the correct md5 sum. An exception will
also
+ be thrown is a directory is present at `to_path`
+ """
+
+ # We apply a lock for a specific resource. This is to avoid
circumstances
+ # where multiple instances of gem5 are running and trying to obtain the
+ # same resources at once. The timeout here is somewhat arbitarily put
at 15
+ # minutes.Most resources should be downloaded and decompressed in this
+ # timeframe, even on the most constrained of systems.
+ with FileLock("{}.lock".format(to_path), timeout=900):
+
+ resource_json = get_resources_json_obj(resource_name)
+
+ if os.path.exists(to_path):
+
+ if not os.path.isfile(to_path):
+ raise Exception(
+ "There is a directory at '{}'.".format(to_path)
+ )
+
+ if _get_md5(to_path) == resource_json["md5sum"]:
+ # In this case, the file has already been download, no
need to
+ # do so again.
+ return
+ elif override:
+ os.remove(to_path)
+ else:
+ raise Exception(
+ "There already a file present at '{}' but "
+ "its md5 value is invalid.".format(to_path)
+ )
+
+ download_dest = to_path
+ run_unzip = unzip and resource_json["is_zipped"].lower() == "true"
+ if run_unzip:
+ download_dest += ".gz"
+
+ # TODO: Might be nice to have some kind of download status bar
here.
+ # TODO: There might be a case where this should be silenced.
+ print("'{}' not found locally.
Downloading...".format(resource_name))
+ _download(url=resource_json["url"], download_to=download_dest)
+ print("Finished downloading '{}'.".format(resource_name))
+
+ if run_unzip:
+ print("Decompressing '{}'...".format(resource_name))
+ with gzip.open(download_dest, "rb") as f:
+ with open(to_path, "wb") as o:
+ shutil.copyfileobj(f, o)
+ os.remove(download_dest)
+ print("Finished decompressing '{}.".format(resource_name))
diff --git a/components_library/resources/resource.py
b/components_library/resources/resource.py
new file mode 100644
index 0000000..4e7a459
--- /dev/null
+++ b/components_library/resources/resource.py
@@ -0,0 +1,109 @@
+# Copyright (c) 2021 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.
+
+from abc import ABCMeta
+import os
+
+from .downloader import get_resource
+
+from typing import Optional
+
+"""
+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>.
+
+The purpose of this encapsulation is two fold:
+
+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.
+"""
+
+
+class AbstractResource:
+
+ __metaclass__ = ABCMeta
+
+ def __init__(self, local_path: str):
+ self._local_path = local_path
+
+ def get_local_path(self) -> str:
+ return self._local_path
+
+
+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.
+ """
+
+ def __init__(self, local_path: str):
+ """
+ :param local_path: The path of the resource on the host system.
+ """
+ super().__init__(local_path=local_path)
+
+
+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,
+ override: Optional[bool] = False,
+ ):
+ """
+ :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.
+ :param override: 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. False by
+ default.
+ """
+
+ if resource_directory != None:
+ if not os.path.exists(resource_directory):
+ os.makedirs(resource_directory)
+ to_path = os.path.join(resource_directory, resource_name)
+ else:
+ to_path = resource_name
+
+ super(Resource, self).__init__(local_path=to_path)
+ get_resource(
+ resource_name=resource_name, to_path=to_path, override=override
+ )
diff --git a/components_library/utils/filelock.py
b/components_library/utils/filelock.py
new file mode 100644
index 0000000..82e1122
--- /dev/null
+++ b/components_library/utils/filelock.py
@@ -0,0 +1,111 @@
+# Copyright (c) 2009, Evan Fosmark
+# 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 <organization> 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 <COPYRIGHT HOLDER> 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 time
+import errno
+
+
+class FileLockException(Exception):
+ pass
+
+
+class FileLock(object):
+ """A file locking mechanism that has context-manager support so
+ you can use it in a with statement. This should be relatively cross
+ compatible as it doesn't rely on msvcrt or fcntl for the locking.
+ """
+
+ def __init__(self, file_name, timeout=10, delay=0.05):
+ """Prepare the file locker. Specify the file to lock and optionally
+ the maximum timeout and the delay between each attempt to lock.
+ """
+ if timeout is not None and delay is None:
+ raise ValueError(
+ "If timeout is not None, then delay must not be None."
+ )
+ self.is_locked = False
+ self.lockfile = os.path.join(os.getcwd(), "%s.lock" % file_name)
+ self.file_name = file_name
+ self.timeout = timeout
+ self.delay = delay
+
+ def acquire(self):
+ """Acquire the lock, if possible. If the lock is in use, it check
again
+ every `wait` seconds. It does this until it either gets the lock or
+ exceeds `timeout` number of seconds, in which case it throws
+ an exception.
+ """
+ start_time = time.time()
+ while True:
+ try:
+ self.fd = os.open(
+ self.lockfile, os.O_CREAT | os.O_EXCL | os.O_RDWR
+ )
+ self.is_locked = True # moved to ensure tag only when
locked
+ break
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
+ if self.timeout is None:
+ raise FileLockException(
+ "Could not acquire lock on
{}".format(self.file_name)
+ )
+ if (time.time() - start_time) >= self.timeout:
+ raise FileLockException("Timeout occured.")
+ time.sleep(self.delay)
+
+ # self.is_locked = True
+
+ def release(self):
+ """Get rid of the lock by deleting the lockfile.
+ When working in a `with` statement, this gets automatically
+ called at the end.
+ """
+ if self.is_locked:
+ os.close(self.fd)
+ os.unlink(self.lockfile)
+ self.is_locked = False
+
+ def __enter__(self):
+ """Activated when used in the with statement.
+ Should automatically acquire a lock to be used in the with block.
+ """
+ if not self.is_locked:
+ self.acquire()
+ return self
+
+ def __exit__(self, type, value, traceback):
+ """Activated at the end of the with statement.
+ It automatically releases the lock if it isn't locked.
+ """
+ if self.is_locked:
+ self.release()
+
+ def __del__(self):
+ """Make sure that the FileLock instance doesn't leave a lockfile
+ lying around.
+ """
+ self.release()
diff --git a/configs/example/components-library/boot_exit_disk_run.py
b/configs/example/components-library/boot_exit_disk_run.py
index 67b0fea..ae8f87c 100644
--- a/configs/example/components-library/boot_exit_disk_run.py
+++ b/configs/example/components-library/boot_exit_disk_run.py
@@ -60,11 +60,9 @@
from components_library.processors.cpu_types import CPUTypes
from components_library.isas import ISA
from components_library.coherence_protocol import CoherenceProtocol
+from components_library.resources.resource import Resource
import os
-import subprocess
-import gzip
-import shutil
# Run a check to ensure the right version of gem5 is being used.
if (
@@ -110,31 +108,10 @@
motherboard.connect_things()
-# Download the resources as necessary.
-thispath = os.path.dirname(os.path.realpath(__file__))
-
-kernel_url = (
- "http://dist.gem5.org/dist/v21-0/kernels/x86/static/vmlinux-5.4.49"
-)
-kernel_path = os.path.join(thispath, "vmlinux-5.4.49")
-if not os.path.exists(kernel_path):
- subprocess.run(["wget", "-P", thispath, kernel_url])
-
-boot_img_url = (
- "http://dist.gem5.org/dist/v21-0/images/x86/ubuntu-18-04/boot-exit.img.gz"
-)
-boot_img_path_gz = os.path.join(thispath, "boot-exit.img.gz")
-boot_img_path = os.path.join(thispath, "boot-exit.img")
-
-if not os.path.exists(boot_img_path):
- subprocess.run(["wget", "-P", thispath, boot_img_url])
- with gzip.open(boot_img_path_gz, "rb") as f:
- with open(boot_img_path, "wb") as o:
- shutil.copyfileobj(f, o)
-
# Set the Full System workload.
motherboard.set_workload(
- kernel=kernel_path, disk_image=boot_img_path, command="m5 exit \n"
+ kernel=Resource("x86-linux-kernel-5.4.49"),
+ disk_image=Resource("x86-boot-exit"), command="m5 exit \n"
)
diff --git a/configs/example/components-library/parsec_disk_run.py
b/configs/example/components-library/parsec_disk_run.py
index 9285d6d..1570d1c 100644
--- a/configs/example/components-library/parsec_disk_run.py
+++ b/configs/example/components-library/parsec_disk_run.py
@@ -52,6 +52,7 @@
)
)
+from components_library.resources.resource import Resource
from components_library.boards.x86_board import X86Board
from components_library.cachehierarchies.classic.\
private_l1_private_l2_cache_hierarchy import (
@@ -67,10 +68,7 @@
get_runtime_coherence_protocol,
)
-import subprocess
-import gzip
import time
-import shutil
import time
@@ -110,31 +108,6 @@
motherboard.connect_things()
-
-# Download the linux kernel and parsec disk image needed to run the
-# simuluation.
-thispath = os.path.dirname(os.path.realpath(__file__))
-
-kernel_url = (
- "http://dist.gem5.org/dist/v21-0/kernels/x86/static/vmlinux-5.4.49"
-)
-kernel_path = os.path.join(thispath, "vmlinux-5.4.49")
-if not os.path.exists(kernel_path):
- subprocess.run(["wget", "-P", thispath, kernel_url])
-
-parsec_img_url = (
- "http://dist.gem5.org/dist/v21-0/images/x86/ubuntu-18-04/parsec.img.gz"
-)
-parsec_img_path_gz = os.path.join(thispath, "parsec.img.gz")
-parsec_img_path = os.path.join(thispath, "parsec.img")
-
-if not os.path.exists(parsec_img_path):
- subprocess.run(["wget", "-P", thispath, parsec_img_url])
- with gzip.open(parsec_img_path_gz, "rb") as f:
- with open(parsec_img_path, "wb") as o:
- shutil.copyfileobj(f, o)
-
-
# The command to run. In this case the blackscholes app with the simsmall
# workload.
command = "cd /home/gem5/parsec-benchmark\n"
@@ -145,7 +118,9 @@
command += "m5 exit \n"
motherboard.set_workload(
- kernel=kernel_path, disk_image=parsec_img_path, command=command
+ kernel=Resource("x86-linux-kernel-5.4.49"),
+ disk_image=Resource("x86-parsec"),
+ command=command,
)
print("Running with ISA: " + get_runtime_isa().name)
diff --git a/configs/example/components-library/simple_binary_run.py
b/configs/example/components-library/simple_binary_run.py
index c73d31e..212c5cd 100644
--- a/configs/example/components-library/simple_binary_run.py
+++ b/configs/example/components-library/simple_binary_run.py
@@ -48,6 +48,7 @@
)
)
+from components_library.resources.resource import CustomResource
from components_library.boards.simple_board import SimpleBoard
from components_library.cachehierarchies.classic.no_cache import NoCache
from components_library.memory.single_channel import SingleChannelDDR3_1600
@@ -76,9 +77,10 @@
# Set the workload
thispath = os.path.dirname(os.path.realpath(__file__))
-binary = os.path.join(
- thispath, "../../../tests/test-progs/hello/bin/x86/linux/hello"
-)
+binary = CustomResource(os.path.join(
+ thispath,
+ "../../../tests/test-progs/hello/bin/x86/linux/hello"
+))
motherboard.set_workload(binary)
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/49304
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I59cfe81d5ec9c64576c0dab55af52aede96976fb
Gerrit-Change-Number: 49304
Gerrit-PatchSet: 9
Gerrit-Owner: Bobby R. Bruce <[email protected]>
Gerrit-Reviewer: Andreas Sandberg <[email protected]>
Gerrit-Reviewer: Austin Harris <[email protected]>
Gerrit-Reviewer: Bobby R. Bruce <[email protected]>
Gerrit-Reviewer: Jason Lowe-Power <[email protected]>
Gerrit-Reviewer: Jason Lowe-Power <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s